From 52b663b256293995ac635967932a2cf68fe46328 Mon Sep 17 00:00:00 2001 From: kerozcak Date: Thu, 9 Jun 2011 17:52:42 +0200 Subject: [PATCH] merge from default --- code/CMakeLists.txt | 39 +- code/CMakeModules/ConfigureChecks.cmake | 4 + code/CMakeModules/FindCustomMFC.cmake | 11 +- code/CMakeModules/FindDirectXSDK.cmake | 13 +- code/CMakeModules/FindExternal.cmake | 49 +- code/CMakeModules/FindIconv.cmake | 83 + code/CMakeModules/FindLuabind.cmake | 33 +- code/CMakeModules/FindSTLport.cmake | 4 +- code/CMakeModules/FindWindowsSDK.cmake | 25 +- code/CMakeModules/FindZLIB.cmake | 39 - code/CMakeModules/PCHSupport.cmake | 31 +- code/CMakeModules/nel.cmake | 139 +- code/README | 2 +- code/config.h.cmake | 1 + code/nel/include/nel/3d/scene_group.h | 4 +- code/nel/include/nel/3d/track_keyframer.h | 1 + code/nel/include/nel/cegui/nelrenderer.h | 76 +- code/nel/include/nel/georges/load_form.h | 12 +- code/nel/include/nel/ligo/primitive_utils.h | 4 +- code/nel/include/nel/misc/config_file.h | 2 +- code/nel/include/nel/misc/debug.h | 12 +- code/nel/include/nel/misc/diff_tool.h | 4 +- code/nel/include/nel/misc/i_xml.h | 2 +- code/nel/include/nel/misc/o_xml.h | 2 +- code/nel/include/nel/misc/sha1.h | 3 + code/nel/include/nel/misc/smart_ptr.h | 2 +- code/nel/include/nel/misc/sstring.h | 3 + code/nel/include/nel/misc/types_nl.h | 42 +- code/nel/include/nel/net/module.h | 2 +- code/nel/samples/3d/cluster_viewer/main.cpp | 2 +- code/nel/samples/3d/font/main.cpp | 3 +- code/nel/samples/misc/configfile/main.cpp | 2 +- code/nel/samples/misc/debug/main.cpp | 2 +- code/nel/samples/net/chat/client.cpp | 2 +- .../net/login_system/frontend_service.cpp | 4 +- code/nel/samples/net/udp/bench_service.cpp | 14 +- code/nel/samples/net/udp/client.cpp | 4 +- code/nel/samples/net/udp/receive_task.cpp | 2 +- code/nel/samples/pacs/main.cpp | 2 +- code/nel/samples/sound_sources/main.cpp | 2 +- code/nel/src/3d/animation_set.cpp | 2 +- code/nel/src/3d/async_file_manager_3d.cpp | 6 +- .../3d/driver/direct3d/driver_direct3d.cpp | 2 +- .../direct3d/driver_direct3d_inputs.cpp | 6 +- .../direct3d/driver_direct3d_material.cpp | 2 +- .../direct3d/driver_direct3d_shader.cpp | 2 +- .../direct3d/driver_direct3d_texture.cpp | 2 +- code/nel/src/3d/driver/opengl/CMakeLists.txt | 1 + .../src/3d/driver/opengl/driver_opengl.cpp | 8 +- .../opengl/driver_opengl_extension_def.h | 63 +- .../3d/driver/opengl/driver_opengl_inputs.cpp | 6 +- .../3d/driver/opengl/driver_opengl_light.cpp | 5 + .../driver/opengl/driver_opengl_material.cpp | 55 +- .../3d/driver/opengl/driver_opengl_matrix.cpp | 15 +- .../3d/driver/opengl/driver_opengl_states.cpp | 145 +- .../3d/driver/opengl/driver_opengl_states.h | 14 +- .../driver/opengl/driver_opengl_texture.cpp | 37 +- .../3d/driver/opengl/driver_opengl_vertex.cpp | 54 +- .../driver_opengl_vertex_buffer_hard.cpp | 126 +- .../opengl/driver_opengl_vertex_buffer_hard.h | 9 +- .../opengl/driver_opengl_vertex_program.cpp | 20 +- .../3d/driver/opengl/driver_opengl_window.cpp | 34 +- .../driver/opengl/mac/cocoa_event_emitter.cpp | 6 +- code/nel/src/3d/driver_user.cpp | 2 +- code/nel/src/3d/fasthls_modifier.cpp | 4 +- code/nel/src/3d/instance_group_user.cpp | 2 +- code/nel/src/3d/landscape_user.cpp | 2 +- code/nel/src/3d/mesh_mrm_skinned.cpp | 2 +- code/nel/src/3d/packed_zone.cpp | 1 + code/nel/src/3d/ps_mesh.cpp | 5 +- code/nel/src/3d/shader.cpp | 2 +- code/nel/src/3d/texture_grouped.cpp | 4 +- code/nel/src/3d/tile_bank.cpp | 2 +- code/nel/src/3d/vegetable_manager.cpp | 2 +- code/nel/src/3d/zone_lighter.cpp | 6 +- code/nel/src/georges/form_elm.cpp | 1 + code/nel/src/georges/form_loader.cpp | 6 +- code/nel/src/ligo/ligo_config.cpp | 2 +- code/nel/src/ligo/zone_bank.cpp | 4 +- code/nel/src/misc/command.cpp | 2 +- code/nel/src/misc/config_file/cf_lexical.lpp | 15 + code/nel/src/misc/config_file/config_file.cpp | 2 +- code/nel/src/misc/debug.cpp | 32 +- code/nel/src/misc/diff_tool.cpp | 2 +- code/nel/src/misc/displayer.cpp | 2 +- code/nel/src/misc/file.cpp | 2 +- code/nel/src/misc/inter_window_msg_queue.cpp | 2 +- code/nel/src/misc/sha1.cpp | 71 + code/nel/src/misc/shared_memory.cpp | 7 +- code/nel/src/misc/system_info.cpp | 14 +- code/nel/src/misc/words_dictionary.cpp | 2 +- code/nel/src/net/buf_client.cpp | 2 +- code/nel/src/net/buf_server.cpp | 6 +- code/nel/src/net/callback_client.cpp | 2 +- code/nel/src/net/callback_net_base.cpp | 2 +- code/nel/src/net/email.cpp | 2 +- code/nel/src/net/login_client.cpp | 8 +- code/nel/src/net/login_server.cpp | 6 +- code/nel/src/net/module.cpp | 2 +- code/nel/src/net/module_gateway.cpp | 2 +- code/nel/src/net/module_gateway_transport.cpp | 2 +- code/nel/src/net/naming_client.cpp | 2 +- code/nel/src/net/net_displayer.cpp | 4 +- code/nel/src/net/service.cpp | 10 +- code/nel/src/net/sock.cpp | 4 +- code/nel/src/net/tcp_sock.cpp | 4 +- code/nel/src/net/transport_class.cpp | 2 +- code/nel/src/net/unified_network.cpp | 10 +- code/nel/src/pacs/global_retriever.cpp | 2 +- code/nel/src/pacs/retriever_bank.h | 2 +- code/nel/src/sound/audio_mixer_user.cpp | 12 +- .../driver/dsound/sound_driver_dsound.cpp | 2 +- .../nel/src/sound/driver/openal/source_al.cpp | 22 +- code/nel/src/sound/sample_bank.cpp | 4 +- code/nel/src/sound/sample_bank_manager.cpp | 2 +- code/nel/src/sound/simple_sound.cpp | 2 +- code/nel/src/sound/stdsound.h | 1 + .../tools/3d/anim_builder/anim_builder.cpp | 6 +- .../animation_set_builder.cpp | 2 +- .../3d/build_clod_bank/build_clod_bank.cpp | 6 +- code/nel/tools/3d/build_clodtex/main.cpp | 4 +- .../build_coarse_mesh/build_coarse_mesh.cpp | 4 +- .../3d/build_far_bank/build_far_bank.cpp | 4 +- code/nel/tools/3d/build_interface/main.cpp | 2 +- .../3d/build_smallbank/build_smallbank.cpp | 2 +- code/nel/tools/3d/cluster_viewer/view_cs.cpp | 2 +- code/nel/tools/3d/file_info/main.cpp | 6 +- .../3d/hls_bank_maker/hls_bank_maker.cpp | 4 +- code/nel/tools/3d/ig_add/main.cpp | 4 +- code/nel/tools/3d/ig_elevation/main.cpp | 12 +- code/nel/tools/3d/ig_info/ig_info.cpp | 2 +- code/nel/tools/3d/ig_lighter/ig_lighter.cpp | 2 +- code/nel/tools/3d/lightmap_optimizer/main.cpp | 12 +- .../tools/3d/object_viewer_qt/CMakeLists.txt | 4 + .../tools/3d/object_viewer_qt/doc/ovqt.dox | 4 +- .../3d/object_viewer_qt/src/description.h | 134 +- .../src/extension_system/iplugin_manager.h | 1 - .../src/extension_system/plugin_manager.cpp | 6 +- .../src/extension_system/plugin_manager.h | 2 +- .../src/extension_system/plugin_spec.cpp | 2 +- .../src/extension_system/plugin_spec.h | 2 +- .../tools/3d/object_viewer_qt/src/main.cpp | 17 +- .../src/plugins/CMakeLists.txt | 4 +- .../src/plugins/core/CMakeLists.txt | 9 +- .../src/plugins/core/context_manager.cpp | 150 + .../src/plugins/core/context_manager.h | 70 + .../src/plugins/core/core.cpp | 6 + .../object_viewer_qt/src/plugins/core/core.h | 1 + .../src/plugins/core/core.qrc | 3 + .../src/plugins/core/core_constants.h | 197 +- .../src/plugins/core/core_plugin.cpp | 45 +- .../src/plugins/core/core_plugin.h | 10 +- .../plugins/core/general_settings_page.cpp | 192 + .../src/plugins/core/general_settings_page.h | 72 + .../src/plugins/core/general_settings_page.ui | 199 + .../src/plugins/core/icons/ic_nel_new.png | Bin 0 -> 21396 bytes .../src/plugins/core/icons/ic_nel_save.png | Bin 0 -> 43738 bytes .../src/plugins/core/icons/ic_nel_save_as.png | Bin 0 -> 52871 bytes .../src/plugins/core/icontext.h | 5 + .../object_viewer_qt/src/plugins/core/icore.h | 3 + .../src/plugins/core/ioptions_page.h | 3 + .../src/plugins/core/main_window.cpp | 247 +- .../src/plugins/core/main_window.h | 39 +- .../core/search_paths_settings_page.cpp | 50 +- .../plugins/core/search_paths_settings_page.h | 5 +- .../plugins/example/example_settings_page.cpp | 5 + .../plugins/example/example_settings_page.h | 1 + .../src/plugins/example/plugin1.cpp | 1 - .../src/plugins/example/plugin1.h | 9 + .../src/plugins/example/qnel_widget.cpp | 3 + .../src/plugins/example/simple_viewer.cpp | 2 + .../src/plugins/example/simple_viewer.h | 4 +- .../src/plugins/georges_editor/CMakeLists.txt | 43 + .../georges_editor/georges_dirtree_dialog.cpp | 99 + .../georges_editor/georges_dirtree_dialog.h | 62 + .../georges_editor/georges_dirtree_form.ui | 54 + .../plugins/georges_editor/georges_editor.qrc | 5 + .../georges_editor/georges_editor_constants.h | 31 + .../georges_editor/georges_editor_form.cpp | 139 + .../georges_editor/georges_editor_form.h | 64 + .../georges_editor/georges_editor_form.ui | 28 + .../georges_editor/georges_editor_plugin.cpp | 128 + .../georges_editor/georges_editor_plugin.h | 105 + .../georges_filesystem_model.cpp | 95 + .../georges_editor/georges_filesystem_model.h | 50 + .../images/ic_nel_georges_editor.png | Bin 0 -> 37356 bytes .../plugins/landscape_editor/CMakeLists.txt | 48 + .../icons/ic_nel_landscape_item.png | Bin 0 -> 56924 bytes .../icons/ic_nel_landscape_settings.png | Bin 0 -> 30656 bytes .../icons/ic_nel_world_editor.png | Bin 0 -> 44031 bytes .../landscape_editor/icons/ic_nel_zone.png | Bin 0 -> 47312 bytes .../landscape_editor/icons/ic_nel_zonel.png | Bin 0 -> 57867 bytes .../landscape_editor/landscape_editor.qrc | 9 + .../landscape_editor_constants.h | 37 + .../landscape_editor_global.h | 30 + .../landscape_editor_plugin.cpp | 128 + .../landscape_editor_plugin.h | 108 + .../landscape_editor_window.cpp | 93 + .../landscape_editor_window.h | 56 + .../landscape_editor_window.ui | 43 + .../src/plugins/log/CMakeLists.txt | 6 +- .../src/plugins/log/log_plugin.cpp | 262 +- .../src/plugins/log/log_plugin.h | 27 +- .../src/plugins/log/log_settings_page.cpp | 102 +- .../src/plugins/log/log_settings_page.h | 50 +- .../src/plugins/log/qt_displayer.cpp | 35 +- .../plugins/object_viewer/animation_form.ui | 2 +- .../src/plugins/object_viewer/attrib_form.ui | 2 +- .../plugins/object_viewer/global_wind_form.ui | 10 +- .../object_viewer/graphics_settings_page.cpp | 22 +- .../object_viewer/graphics_settings_page.h | 1 + .../object_viewer/graphics_settings_page.ui | 51 +- .../object_viewer/graphics_viewport.cpp | 50 +- .../plugins/object_viewer/graphics_viewport.h | 4 - .../src/plugins/object_viewer/main_window.cpp | 52 +- .../src/plugins/object_viewer/main_window.h | 16 +- .../src/plugins/object_viewer/modules.cpp | 2 +- .../object_viewer/object_viewer_plugin.cpp | 14 +- .../object_viewer/object_viewer_plugin.h | 7 + .../plugins/object_viewer/particle_editor.h | 2 +- .../object_viewer/particle_system_page.cpp | 4 - .../object_viewer/particle_tree_model.cpp | 2 +- .../particle_workspace_dialog.cpp | 9 +- .../plugins/object_viewer/scheme_manager.h | 11 +- .../object_viewer/sound_settings_page.cpp | 5 + .../object_viewer/sound_settings_page.h | 1 + .../plugins/object_viewer/tune_timer_form.ui | 14 +- .../object_viewer/value_gradient_dialog.cpp | 33 +- .../object_viewer/value_gradient_dialog.h | 30 +- .../object_viewer/vegetable_settings_page.cpp | 6 + .../object_viewer/vegetable_settings_page.h | 1 + .../object_viewer/vegetable_settings_page.ui | 11 + .../src/plugins/translation_manager/README | 3 + .../zone_painter/zone_painter_main_window.cpp | 2 +- .../zone_painter/zone_painter_main_window.h | 5 +- .../zone_painter/zone_painter_plugin.cpp | 2 + .../zone_painter/zone_painter_plugin.h | 75 +- .../zone_painter_settings_page.cpp | 7 +- .../zone_painter/zone_painter_settings_page.h | 1 + .../src/object_viewer_widget.cpp | 20 +- .../src/object_viewer_widget.h | 4 + .../tools/3d/panoply_maker/panoply_maker.cpp | 46 +- .../nel_patch_paint/nel_patch_paint.h | 13 +- .../3d/shapes_exporter/shapes_exporter.cpp | 44 +- code/nel/tools/3d/tga_2_dds/tga2dds.cpp | 4 +- code/nel/tools/3d/tga_cut/tga_cut.cpp | 2 +- code/nel/tools/3d/tga_resize/main.cpp | 2 +- .../3d/zone_check_bind/zone_check_bind.cpp | 2 +- .../zone_dependencies/zone_dependencies.cpp | 12 +- code/nel/tools/3d/zone_dump/zone_dump.cpp | 2 +- .../3d/zone_ig_lighter/zone_ig_lighter.cpp | 8 +- .../tools/3d/zone_lighter/zone_lighter.cpp | 16 +- code/nel/tools/3d/zone_welder/zone_welder.cpp | 2 +- code/nel/tools/3d/zviewer/zviewer.cpp | 14 +- .../tools/georges/georges2csv/georges2csv.cpp | 2 +- code/nel/tools/misc/bnp_make/main.cpp | 11 +- .../extract_filename/extract_filename.cpp | 2 +- code/nel/tools/misc/lock/lock.cpp | 2 +- code/nel/tools/nel_unit_test/ut_net_module.h | 2 +- code/nel/tools/pacs/build_ig_boxes/main.cpp | 4 +- .../tools/pacs/build_indoor_rbank/main.cpp | 6 +- .../tools/pacs/build_rbank/build_rbank.cpp | 12 +- .../nel/tools/pacs/build_rbank/build_surf.cpp | 2 +- code/nel/tools/pacs/build_rbank/main.cpp | 4 +- .../tools/pacs/build_rbank/prim_checker.cpp | 2 +- code/ryzom/client/client_default.cfg | 8 +- .../gamedev/adds/interfaces/color_palette.dds | Bin 0 -> 22032 bytes .../new_texture_interfaces_dxtc.tga | Bin 4194322 -> 4194322 bytes .../new_texture_interfaces_dxtc.txt | 949 +-- .../adds/sfx/ul_mission_hall_of_fame.ps | Bin 0 -> 955 bytes .../gamedev/adds/shapes/Ge_gift_blue.shape | Bin 0 -> 9727 bytes .../adds/shapes/Ge_gift_blue_yubo.shape | Bin 0 -> 9730 bytes .../gamedev/adds/shapes/Ge_gift_green.shape | Bin 0 -> 9584 bytes .../adds/shapes/Ge_gift_green_yubo.shape | Bin 0 -> 9587 bytes .../gamedev/adds/shapes/Ge_gift_red.shape | Bin 0 -> 9582 bytes .../adds/shapes/Ge_gift_red_yubo.shape | Bin 0 -> 9585 bytes .../gamedev/adds/shapes/Ge_gift_yellow.shape | Bin 0 -> 9585 bytes .../adds/shapes/Ge_gift_yellow_yubo.shape | Bin 0 -> 9588 bytes .../adds/shapes/UL_Mission_Hall_Of_Fame.shape | Bin 0 -> 74362 bytes .../data/gamedev/interfaces_v3/actions.xml | 27 + .../gamedev/interfaces_v3/bot_chat_v4.xml | 4 + .../data/gamedev/interfaces_v3/config.xml | 3 + .../data/gamedev/interfaces_v3/guild.xml | 169 +- .../data/gamedev/interfaces_v3/hierarchy.xml | 1 + .../gamedev/interfaces_v3/info_player.xml | 258 +- .../data/gamedev/interfaces_v3/inventory.xml | 163 +- .../data/gamedev/interfaces_v3/keys.xml | 22 + .../data/gamedev/interfaces_v3/reset.xml | 228 +- .../data/gamedev/interfaces_v3/taskbar.xml | 9 +- code/ryzom/client/src/attached_fx.h | 4 + .../ryzom/client/src/bg_downloader_access.cpp | 10 +- code/ryzom/client/src/camera_recorder.cpp | 4 +- code/ryzom/client/src/cdb_branch.cpp | 2 +- code/ryzom/client/src/cdb_synchronised.cpp | 2 +- code/ryzom/client/src/character_cl.cpp | 67 +- code/ryzom/client/src/character_cl.h | 1 + code/ryzom/client/src/client.cpp | 4 +- code/ryzom/client/src/client_cfg.cpp | 4 +- code/ryzom/client/src/client_chat_manager.cpp | 15 +- code/ryzom/client/src/color_slot_manager.cpp | 6 +- code/ryzom/client/src/commands.cpp | 32 +- code/ryzom/client/src/connection.cpp | 6 +- code/ryzom/client/src/continent.cpp | 10 +- code/ryzom/client/src/cursor_functions.cpp | 4 +- code/ryzom/client/src/entity_cl.cpp | 12 +- code/ryzom/client/src/far_tp.cpp | 4 +- code/ryzom/client/src/fog_map.cpp | 2 +- code/ryzom/client/src/http_client.cpp | 2 +- code/ryzom/client/src/init.cpp | 8 +- code/ryzom/client/src/init_main_loop.cpp | 5 +- .../src/interface_v3/action_handler.cpp | 4 +- .../src/interface_v3/action_handler_game.cpp | 4 +- .../src/interface_v3/action_handler_help.cpp | 3 +- .../src/interface_v3/action_handler_item.cpp | 2 +- .../interface_v3/action_handler_phrase.cpp | 27 +- .../src/interface_v3/action_phrase_faber.cpp | 3 +- .../src/interface_v3/bot_chat_page_trade.cpp | 2 +- .../client/src/interface_v3/chat_filter.cpp | 4 +- .../client/src/interface_v3/chat_window.cpp | 19 +- .../client/src/interface_v3/chat_window.h | 2 +- .../client/src/interface_v3/ctrl_base.cpp | 1 - .../src/interface_v3/ctrl_base_button.cpp | 9 +- .../src/interface_v3/ctrl_base_button.h | 3 +- .../client/src/interface_v3/ctrl_button.cpp | 14 +- .../client/src/interface_v3/ctrl_button.h | 2 + .../src/interface_v3/ctrl_text_button.cpp | 9 +- .../client/src/interface_v3/dbctrl_sheet.cpp | 6 +- .../client/src/interface_v3/group_editbox.cpp | 83 +- .../client/src/interface_v3/group_editbox.h | 5 +- .../client/src/interface_v3/group_html.cpp | 222 +- .../client/src/interface_v3/group_html.h | 17 + .../src/interface_v3/group_html_webig.cpp | 2 +- .../client/src/interface_v3/group_map.cpp | 2 +- .../client/src/interface_v3/group_menu.cpp | 4 +- .../src/interface_v3/group_quick_help.cpp | 7 +- .../client/src/interface_v3/group_tab.cpp | 6 +- .../client/src/interface_v3/group_tree.h | 2 +- .../client/src/interface_v3/guild_manager.cpp | 6 + .../interface_v3/input_handler_manager.cpp | 2 +- .../src/interface_v3/interface_element.cpp | 2 +- .../src/interface_v3/interface_element.h | 5 + .../src/interface_v3/interface_manager.cpp | 16 +- .../src/interface_v3/interface_options.cpp | 6 +- .../src/interface_v3/interface_parser.cpp | 4 +- .../interface_v3/item_consumable_effect.cpp | 82 + .../client/src/interface_v3/lua_helper.cpp | 2 +- .../ryzom/client/src/interface_v3/lua_ihm.cpp | 35 +- code/ryzom/client/src/interface_v3/lua_ihm.h | 1 + .../client/src/interface_v3/lua_object.cpp | 2 +- .../src/interface_v3/people_interraction.cpp | 25 +- .../client/src/interface_v3/people_list.cpp | 23 +- .../client/src/interface_v3/people_list.h | 2 +- .../client/src/interface_v3/player_trade.cpp | 6 +- .../src/interface_v3/sphrase_manager.cpp | 69 +- .../client/src/interface_v3/sphrase_manager.h | 3 + .../client/src/interface_v3/yubo_chat.cpp | 6 +- code/ryzom/client/src/libwww.cpp | 10 + code/ryzom/client/src/libwww.h | 7 + code/ryzom/client/src/light_cycle_manager.cpp | 2 +- .../client/src/lod_character_user_manager.cpp | 2 +- code/ryzom/client/src/login.cpp | 6 +- code/ryzom/client/src/login_patch.cpp | 24 +- .../client/src/login_progress_post_thread.cpp | 2 +- .../include/cj60/CJOutlookBar.h | 6 +- code/ryzom/client/src/main_loop.cpp | 10 +- .../ryzom/client/src/motion/user_controls.cpp | 1 + code/ryzom/client/src/net_manager.cpp | 88 +- code/ryzom/client/src/network_connection.cpp | 22 +- code/ryzom/client/src/pacs_client.cpp | 2 +- code/ryzom/client/src/permanent_ban.cpp | 2 +- code/ryzom/client/src/prim_file.cpp | 2 +- .../client/src/r2/displayer_visual_entity.cpp | 2 +- .../client/src/r2/dmc/com_lua_module.cpp | 2 +- code/ryzom/client/src/r2/editor.cpp | 8 +- code/ryzom/client/src/r2/island_collision.cpp | 6 +- code/ryzom/client/src/r2/tool_select_move.cpp | 2 +- .../ryzom/client/src/session_browser_impl.cpp | 12 +- code/ryzom/client/src/sky.cpp | 2 +- code/ryzom/client/src/sound_manager.cpp | 6 +- code/ryzom/client/src/stdpch.h | 1 + .../client/src/string_manager_client.cpp | 83 +- code/ryzom/client/src/user_entity.cpp | 3 +- .../world_editor_classes.xml | 85 +- .../common/src/game_share/action_nature.cpp | 1 + .../common/src/game_share/action_nature.h | 1 + .../src/game_share/character_sync_itf.h | 8 +- code/ryzom/common/src/game_share/magic_fx.h | 3 + code/ryzom/common/src/game_share/mirror.cpp | 26 +- .../common/src/game_share/mirror_prop_value.h | 35 +- .../common/src/game_share/msg_ais_egs_gen.h | 4 +- code/ryzom/common/src/game_share/object.cpp | 6 +- code/ryzom/common/src/game_share/object.h | 5 +- .../common/src/game_share/r2_modules_itf.h | 4 +- .../common/src/game_share/r2_share_itf.h | 4 +- .../time_weather_season/weather_predict.cpp | 2 +- .../data_shard/client_commands_privileges.txt | 33 +- .../ai_service/ai_entity_physical_inline.h | 3 +- .../server/src/ai_service/ai_generic_fight.h | 7 +- .../ai_service/ai_generic_fight_helpers.cpp | 11 +- .../server/src/ai_service/ai_grp_npc.cpp | 11 +- .../server/src/ai_service/ai_instance.cpp | 65 +- .../server/src/ai_service/ai_outpost.cpp | 5 +- .../src/ai_service/ai_outpost_actions.cpp | 2 +- .../server/src/ai_service/ai_script_comp.cpp | 24 +- .../src/ai_service/ai_script_data_manager.cpp | 4 +- code/ryzom/server/src/ai_service/ai_spire.cpp | 5 +- code/ryzom/server/src/ai_service/commands.cpp | 13 +- .../server/src/ai_service/continent_inline.h | 2 +- .../src/ai_service/generic_logic_action.cpp | 16 +- code/ryzom/server/src/ai_service/nf_grp.cpp | 37 +- .../server/src/ai_service/nf_grp_npc.cpp | 207 +- .../src/ai_service/nf_state_instance.cpp | 5 +- .../ryzom/server/src/ai_service/nf_static.cpp | 2 +- .../src/ai_service/npc_description_msg.cpp | 2 +- .../server/src/ai_service/path_behaviors.h | 3 +- .../server/src/ai_service/script_compiler.cpp | 28 +- .../ryzom/server/src/ai_service/script_vm.cpp | 3 +- code/ryzom/server/src/ai_service/sheets.cpp | 4 +- code/ryzom/server/src/ai_service/stdpch.h | 2 + .../server/src/ai_service/world_container.cpp | 2 +- code/ryzom/server/src/ai_share/ai_event.cpp | 14 +- .../server/src/ai_share/primitive_parser.cpp | 7 +- code/ryzom/server/src/ai_share/world_map.cpp | 41 +- code/ryzom/server/src/ai_share/world_map.h | 34 +- .../src/backup_service/backup_file_access.cpp | 4 +- .../src/backup_service/backup_service.cpp | 4 +- .../src/backup_service/web_connection.cpp | 4 +- .../src/entities_game_service/admin.cpp | 967 ++- .../building_manager/room_instance.cpp | 4 +- .../cdb_struct_banks.cpp | 2 +- .../entities_game_service/client_messages.cpp | 12 +- .../common_shard_callbacks.cpp | 2 +- .../creature_manager/creature.cpp | 6 +- .../creature_manager/creature.h | 2 + .../egs_sheets/egs_static_brick.cpp | 30 + .../egs_sheets/egs_static_brick.cpp.h | 148 +- .../entities_game_service.cpp | 16 +- .../entity_manager/entity_base.cpp | 6 +- .../entity_manager/entity_callbacks.cpp | 10 +- .../game_item_manager/game_item.cpp | 5 +- .../game_item_manager/game_item.h | 4 +- .../game_item_manager/game_item_manager.cpp | 4 +- .../guild_manager/guild_charge.cpp | 6 +- .../guild_manager/guild_commands.cpp | 2 +- .../guild_manager/guild_manager.cpp | 2 +- .../guild_manager/guild_unifier_itf.h | 4 +- .../mission_manager/mission_event.cpp | 23 +- .../mission_manager/mission_event.h | 13 + .../mission_manager/mission_queue_manager.cpp | 2 +- .../mission_manager/mission_step_kill.cpp | 206 +- .../modules/character_control.cpp | 2 +- .../outpost_manager/outpost_manager.cpp | 2 +- .../outpost_manager/outpost_squad.cpp | 3 +- .../phrase_manager/aura_effect.cpp | 22 +- .../phrase_manager/aura_effect.h | 4 + .../phrase_manager/combat_phrase.cpp | 5 + .../phrase_manager/faber_action.cpp | 15 +- .../phrase_manager/faber_phrase.cpp | 7 +- .../phrase_manager/magic_phrase.cpp | 20 +- .../phrase_manager/phrase_manager.h | 3 +- .../phrase_manager/s_effect.h | 19 +- .../phrase_manager/special_power.cpp | 7 +- .../phrase_manager/special_power.h | 14 +- .../special_power_basic_aura.cpp | 9 +- .../phrase_manager/special_power_phrase.cpp | 70 +- .../phrase_manager/timed_actions.cpp | 11 + .../player_manager/cdb_leaf.cpp | 6 +- .../player_manager/character.cpp | 177 +- .../player_manager/character.h | 18 +- .../character_inventory_manipulation.cpp | 104 +- .../player_manager/player.cpp | 12 +- .../player_manager/player_manager.cpp | 12 +- .../position_flag_manager.cpp | 2 +- .../primitives_parser.cpp | 2 +- .../progression/progression_pve.cpp | 35 +- .../progression/progression_pve.h | 5 +- .../progression/progression_pvp.cpp | 3 + .../pvp_manager/pvp_manager_2.cpp | 104 +- .../pvp_manager/pvp_manager_2.h | 8 + .../shop_type/named_items.cpp | 2 +- .../shop_type/shop_type_manager.cpp | 2 +- .../server/src/entities_game_service/stdpch.h | 1 + .../team_manager/reward_sharing.cpp | 2 +- .../frontend_service/distance_prioritizer.h | 14 +- .../src/frontend_service/fe_receive_sub.cpp | 10 +- .../src/frontend_service/fe_receive_task.cpp | 4 +- .../src/frontend_service/fe_send_sub.cpp | 2 +- .../src/frontend_service/frontend_service.cpp | 2 +- .../src/frontend_service/id_impulsions.cpp | 16 +- .../server/src/frontend_service/stdpch.h | 1 + .../src/frontend_service/uid_impulsions.cpp | 4 +- .../server/src/gpm_service/CMakeLists.txt | 4 + code/ryzom/server/src/gpm_service/cell.cpp | 1 + .../src/gpm_service/client_messages.cpp | 1 + .../ryzom/server/src/gpm_service/commands.cpp | 1 + .../server/src/gpm_service/gpm_service.cpp | 5 +- .../ryzom/server/src/gpm_service/messages.cpp | 1 + .../server/src/gpm_service/move_checker.cpp | 2 + .../server/src/gpm_service/patat_grid.cpp | 1 + .../gpm_service/patat_subscribe_manager.cpp | 1 + code/ryzom/server/src/gpm_service/sheets.cpp | 1 + code/ryzom/server/src/gpm_service/stdpch.cpp | 17 + code/ryzom/server/src/gpm_service/stdpch.h | 98 + .../server/src/gpm_service/variables.cpp | 1 + .../src/gpm_service/vision_delta_manager.cpp | 2 + .../server/src/gpm_service/world_entity.cpp | 1 + .../gpm_service/world_position_manager.cpp | 8 +- .../src/input_output_service/commands.cpp | 2 +- .../input_output_service.cpp | 4 +- .../src/input_output_service/messages.cpp | 72 +- .../server/src/input_output_service/stdpch.h | 1 + .../input_output_service/string_manager.cpp | 6 +- .../string_manager_parser.cpp | 6 +- .../src/log_analyser_service/commands.cpp | 4 +- .../log_analyser_service.cpp | 4 +- .../server/src/logger_service/log_query.cpp | 2 +- .../server/src/logger_service/log_query.h | 1 + .../src/logger_service/logger_service.cpp | 2 +- .../src/mail_forum_service/hof_generator.cpp | 2 +- .../mail_forum_service/mail_forum_service.cpp | 10 +- .../src/mirror_service/mirror_service.cpp | 16 +- .../src/mirror_service/mirror_service.h | 2 +- .../server/src/monitor_service/CMakeLists.txt | 12 +- .../src/monitor_service/service_main.cpp | 2 +- .../ryzom/server/src/monitor_service/stdpch.h | 1 + .../ryzom/server/src/pd_lib/db_delta_file.cpp | 4 +- .../src/pd_lib/db_description_parser.cpp | 2 +- .../server/src/pd_lib/db_reference_file.cpp | 6 +- code/ryzom/server/src/pd_lib/pd_lib.cpp | 2 +- code/ryzom/server/src/pd_lib/pd_messages.cpp | 4 +- .../server/src/pd_lib/pd_server_utils.cpp | 8 +- .../persistant_data_service/db_manager.cpp | 2 +- .../persistant_data_service/pds_database.cpp | 2 +- .../ryzom_naming_service.cpp | 4 +- .../ryzom_welcome_service.cpp | 8 +- .../src/server_share/continent_container.cpp | 16 +- .../src/server_share/login_service_itf.h | 4 +- code/ryzom/server/src/server_share/stdpch.h | 1 + .../shard_unifier_service/database_mapping.h | 4 +- .../shard_unifier_service/name_manager.cpp | 2 +- .../nel_database_mapping.h | 4 +- .../src/tick_service/range_mirror_manager.cpp | 4 +- .../server/src/tick_service/tick_service.cpp | 14 +- code/ryzom/tools/leveldesign/CMakeLists.txt | 7 +- .../ryzom/tools/leveldesign/export/export.cpp | 12 +- .../georges_dll/cool_dialog_bar.cpp | 9 +- .../src/georges_treeview_dialog.cpp | 6 +- .../src/georges_treeview_form.ui | 3 + .../src/georgesform_model.cpp | 13 +- .../georges_plugin_sound/listener_view.cpp | 11 +- .../mission_compiler_fe/CMakeLists.txt | 16 + .../mission_compiler_lib/CMakeLists.txt | 27 + .../leveldesign/mission_compiler_lib/main.cpp | 4 +- .../mission_compiler_lib/mission_compiler.cpp | 45 +- .../mission_compiler_lib/step_content.cpp | 14 +- .../mission_compiler_lib/steps.cpp | 77 +- .../tools/leveldesign/mp_generator/main.cpp | 4 +- .../named_items_2_csv/named_items_2_csv.cpp | 4 +- .../tools/leveldesign/prim_export/main.cpp | 18 +- .../world_editor/land_export/main.cpp | 10 +- .../world_editor/land_export_lib/export.cpp | 28 +- .../tools/make_alias_file/make_alias_file.cpp | 6 +- .../tools/make_anim_melee_impact/main.cpp | 6 +- .../tools/patch_gen/patch_gen_common.cpp | 22 +- code/ryzom/tools/pd_parser/parser.cpp | 32 +- .../build_world_packed_col.cpp | 16 +- .../packed_world_builder.cpp | 6 +- .../build_world_packed_col/test_col_world.cpp | 12 +- .../server/build_world_packed_col/village.cpp | 6 +- .../tools/sheets_packer/sheets_packer.cpp | 12 +- .../tools/sheets_packer/sheets_packer_cfg.cpp | 8 +- .../tools/skill_extractor/skill_extractor.cpp | 2 +- .../extract_new_sheet_names.cpp | 2 +- code/ryzom/tools/translation_tools/main.cpp | 12 +- .../client/src/snowballs_client.cpp | 5 +- .../visual_studio_macros/autoexp_vc10.dat | 6130 +++++++++++++++++ 576 files changed, 16127 insertions(+), 2824 deletions(-) create mode 100644 code/CMakeModules/FindIconv.cmake delete mode 100644 code/CMakeModules/FindZLIB.cmake create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.ui create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_new.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_save.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_save_as.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/CMakeLists.txt create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_form.ui create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor.qrc create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_constants.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.ui create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/images/ic_nel_georges_editor.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_landscape_item.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_landscape_settings.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_world_editor.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_zone.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_zonel.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor.qrc create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_global.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/README create mode 100644 code/ryzom/client/data/gamedev/adds/interfaces/color_palette.dds create mode 100644 code/ryzom/client/data/gamedev/adds/sfx/ul_mission_hall_of_fame.ps create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_blue.shape create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_blue_yubo.shape create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_green.shape create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_green_yubo.shape create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_red.shape create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_red_yubo.shape create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_yellow.shape create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_yellow_yubo.shape create mode 100644 code/ryzom/client/data/gamedev/adds/shapes/UL_Mission_Hall_Of_Fame.shape create mode 100644 code/ryzom/server/src/gpm_service/stdpch.cpp create mode 100644 code/ryzom/server/src/gpm_service/stdpch.h create mode 100644 code/ryzom/tools/leveldesign/mission_compiler_fe/CMakeLists.txt create mode 100644 code/ryzom/tools/leveldesign/mission_compiler_lib/CMakeLists.txt create mode 100644 code/tool/visual_studio_macros/autoexp_vc10.dat diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index a8efd9dfa..630ff4414 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -41,10 +41,6 @@ INCLUDE(${CMAKE_ROOT}/Modules/Documentation.cmake OPTIONAL) # Force out of source builds. CHECK_OUT_OF_SOURCE() -# Variables which must be set before PROJECT -NL_SETUP_BUILD() -NL_SETUP_BUILD_FLAGS() - CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(RyzomCore CXX C) SET(NL_VERSION_MAJOR 0) @@ -52,6 +48,9 @@ SET(NL_VERSION_MINOR 8) SET(NL_VERSION_PATCH 0) SET(NL_VERSION "${NL_VERSION_MAJOR}.${NL_VERSION_MINOR}.${NL_VERSION_PATCH}") +NL_SETUP_BUILD() +NL_SETUP_BUILD_FLAGS() + #----------------------------------------------------------------------------- # Redirect output files SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) @@ -91,20 +90,11 @@ NL_CONFIGURE_CHECKS() #----------------------------------------------------------------------------- #Platform specifics +SETUP_EXTERNAL() + IF(WIN32) - INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) SET(WINSOCK2_LIB ws2_32.lib) - FIND_PACKAGE(External REQUIRED) - - IF(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") - # convert IDE fullpath to VC++ path - STRING(REGEX REPLACE "Common7/IDE/.+" "VC" VC_DIR ${CMAKE_MAKE_PROGRAM}) - ELSE(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") - # convert compiler fullpath to VC++ path - STRING(REGEX REPLACE "VC/bin/.+" "VC" VC_DIR ${CMAKE_CXX_COMPILER}) - ENDIF(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") - IF(WITH_MFC) FIND_PACKAGE(CustomMFC REQUIRED) ENDIF(WITH_MFC) @@ -119,20 +109,15 @@ IF(WITH_STATIC) # libxml2 could need winsock2 library SET(LIBXML2_DEFINITIONS ${LIBXML2_DEFINITIONS} -DLIBXML_STATIC) SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${WINSOCK2_LIB}) + + # on Mac OS X libxml2 requieres iconv + IF(APPLE) + FIND_PACKAGE(Iconv REQUIRED) + SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${ICONV_LIBRARIES}) + INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR}) + ENDIF(APPLE) ENDIF(WITH_STATIC) -IF(WITH_STLPORT) - FIND_PACKAGE(STLport REQUIRED) - INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR}) - IF(WIN32) - SET(VC_INCLUDE_DIR "${VC_DIR}/include") - - FIND_PACKAGE(WindowsSDK REQUIRED) - # use VC++ and Windows SDK include paths - INCLUDE_DIRECTORIES(${VC_INCLUDE_DIR} ${WINSDK_INCLUDE_DIR}) - ENDIF(WIN32) -ENDIF(WITH_STLPORT) - INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/PCHSupport.cmake) IF(FINAL_VERSION) diff --git a/code/CMakeModules/ConfigureChecks.cmake b/code/CMakeModules/ConfigureChecks.cmake index 707b85c86..baf6e0e7c 100644 --- a/code/CMakeModules/ConfigureChecks.cmake +++ b/code/CMakeModules/ConfigureChecks.cmake @@ -47,6 +47,10 @@ MACRO(NL_CONFIGURE_CHECKS) IF(WITH_DRIVER_OPENGL) SET(NL_OPENGL_AVAILABLE 1) ENDIF(WITH_DRIVER_OPENGL) + + IF(WITH_DRIVER_OPENGLES) + SET(NL_OPENGLES_AVAILABLE 1) + ENDIF(WITH_DRIVER_OPENGLES) IF(WITH_DRIVER_DIRECT3D) SET(NL_DIRECT3D_AVAILABLE 1) diff --git a/code/CMakeModules/FindCustomMFC.cmake b/code/CMakeModules/FindCustomMFC.cmake index e37936ef0..7dd87c15f 100644 --- a/code/CMakeModules/FindCustomMFC.cmake +++ b/code/CMakeModules/FindCustomMFC.cmake @@ -40,17 +40,12 @@ ENDIF(WITH_STLPORT OR NOT MFC_FOUND) # Only if using a custom path IF(CUSTOM_MFC_DIR) - IF(NOT CMAKE_SIZEOF_VOID_P) - INCLUDE (CheckTypeSize) - CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P) - ENDIF(NOT CMAKE_SIZEOF_VOID_P) - # Using 32 or 64 bits libraries - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + IF(TARGET_X64) SET(MFC_LIBRARY_DIR "${MFC_DIR}/lib/amd64") - ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + ELSE(TARGET_X64) SET(MFC_LIBRARY_DIR "${MFC_DIR}/lib") - ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) + ENDIF(TARGET_X64) # Add MFC libraries directory to default library path LINK_DIRECTORIES(${MFC_LIBRARY_DIR}) diff --git a/code/CMakeModules/FindDirectXSDK.cmake b/code/CMakeModules/FindDirectXSDK.cmake index d21261b95..1f832cf95 100644 --- a/code/CMakeModules/FindDirectXSDK.cmake +++ b/code/CMakeModules/FindDirectXSDK.cmake @@ -30,16 +30,11 @@ ENDMACRO(FIND_DXSDK_LIBRARY MYLIBRARY MYLIBRARYNAME) IF(DXSDK_DIR) SET(DXSDK_INCLUDE_DIR "${DXSDK_DIR}/Include") - IF(NOT CMAKE_SIZEOF_VOID_P) - INCLUDE (CheckTypeSize) - CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P) - ENDIF(NOT CMAKE_SIZEOF_VOID_P) - - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + IF(TARGET_X64) SET(DXSDK_LIBRARY_DIR "${DXSDK_DIR}/Lib/x64") - ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + ELSE(TARGET_X64) SET(DXSDK_LIBRARY_DIR "${DXSDK_DIR}/Lib/x86") - ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) + ENDIF(TARGET_X64) FIND_DXSDK_LIBRARY(DXSDK_GUID_LIBRARY dxguid) FIND_DXSDK_LIBRARY(DXSDK_DINPUT_LIBRARY dinput8) @@ -59,7 +54,7 @@ ENDIF(DXSDK_DIR) # all listed variables are TRUE. INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(DIRECTXSDK DEFAULT_MSG DXSDK_DIR DXSDK_GUID_LIBRARY DXSDK_DINPUT_LIBRARY) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(DirectXSDK DEFAULT_MSG DXSDK_DIR DXSDK_GUID_LIBRARY DXSDK_DINPUT_LIBRARY) MARK_AS_ADVANCED(DXSDK_INCLUDE_DIR DXSDK_GUID_LIBRARY diff --git a/code/CMakeModules/FindExternal.cmake b/code/CMakeModules/FindExternal.cmake index 3ca7774ba..fae4af92d 100644 --- a/code/CMakeModules/FindExternal.cmake +++ b/code/CMakeModules/FindExternal.cmake @@ -3,11 +3,12 @@ # The following values are defined # EXTERNAL_PATH - where to find external # EXTERNAL_INCLUDE_PATH - where to find external includes +# EXTERNAL_BINARY_PATH - where to find external binaries # EXTERNAL_LIBRARY_PATH - where to find external libraries # EXTERNAL_FOUND - True if the external libraries are available SET(EXTERNAL_TEMP_PATH ${CMAKE_CURRENT_SOURCE_DIR}/external ${CMAKE_CURRENT_SOURCE_DIR}/../external ${CMAKE_CURRENT_SOURCE_DIR}/3rdParty ${CMAKE_CURRENT_SOURCE_DIR}/../3rdParty ${EXTERNAL_PATH}) -SET(EXTERNAL_TEMP_FILE "include/png.h") +SET(EXTERNAL_TEMP_FILE "include/zlib.h") SET(EXTERNAL_NAME "external") # If using STLport preprend external_stlport @@ -17,36 +18,42 @@ IF(WITH_STLPORT) SET(EXTERNAL_NAME "external with STLport") ENDIF(WITH_STLPORT) -SET(EXTERNAL_FOUND FALSE) -FOREACH(ITEM ${EXTERNAL_TEMP_PATH}) - IF(EXISTS "${ITEM}/${EXTERNAL_TEMP_FILE}" AND NOT EXTERNAL_FOUND) - SET(EXTERNAL_FOUND TRUE) - # Get absolute path to avoid .. - GET_FILENAME_COMPONENT(ITEM ${ITEM} ABSOLUTE) - SET(EXTERNAL_PATH ${ITEM} CACHE PATH "" FORCE) - ENDIF(EXISTS "${ITEM}/${EXTERNAL_TEMP_FILE}" AND NOT EXTERNAL_FOUND) -ENDFOREACH(ITEM ${EXTERNAL_TEMP_PATH}) +FIND_PATH(EXTERNAL_PATH + ${EXTERNAL_TEMP_FILE} + PATHS + $ENV{EXTERNAL_PATH} + ${EXTERNAL_TEMP_PATH} + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt +) -IF(EXTERNAL_FOUND) +IF(EXTERNAL_PATH) + SET(EXTERNAL_FOUND TRUE) SET(EXTERNAL_INCLUDE_PATH "${EXTERNAL_PATH}/include") - IF(NOT CMAKE_SIZEOF_VOID_P) - INCLUDE (CheckTypeSize) - CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P) - ENDIF(NOT CMAKE_SIZEOF_VOID_P) - + # Using 32 or 64 bits binaries + IF(TARGET_X64) + SET(EXTERNAL_BINARY_PATH "${EXTERNAL_PATH}/bin64") + ELSE(TARGET_X64) + SET(EXTERNAL_BINARY_PATH "${EXTERNAL_PATH}/bin") + ENDIF(TARGET_X64) + # Using 32 or 64 bits libraries - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + IF(TARGET_X64) SET(EXTERNAL_LIBRARY_PATH "${EXTERNAL_PATH}/lib64") - ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + ELSE(TARGET_X64) SET(EXTERNAL_LIBRARY_PATH "${EXTERNAL_PATH}/lib") - ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) + ENDIF(TARGET_X64) SET(CMAKE_INCLUDE_PATH "${EXTERNAL_INCLUDE_PATH};${CMAKE_INCLUDE_PATH}") # Stupid hack for FindOpenAL.cmake SET(CMAKE_INCLUDE_PATH "${EXTERNAL_PATH};${CMAKE_INCLUDE_PATH}") SET(CMAKE_LIBRARY_PATH "${EXTERNAL_LIBRARY_PATH};${CMAKE_LIBRARY_PATH}") -ENDIF(EXTERNAL_FOUND) +ENDIF(EXTERNAL_PATH) IF(EXTERNAL_FOUND) IF(NOT External_FIND_QUIETLY) @@ -62,4 +69,4 @@ ELSE(EXTERNAL_FOUND) ENDIF(External_FIND_REQUIRED) ENDIF(EXTERNAL_FOUND) -MARK_AS_ADVANCED(EXTERNAL_INCLUDE_PATH EXTERNAL_LIBRARY_PATH) +MARK_AS_ADVANCED(EXTERNAL_INCLUDE_PATH EXTERNAL_BINARY_PATH EXTERNAL_LIBRARY_PATH) diff --git a/code/CMakeModules/FindIconv.cmake b/code/CMakeModules/FindIconv.cmake new file mode 100644 index 000000000..5e9e48250 --- /dev/null +++ b/code/CMakeModules/FindIconv.cmake @@ -0,0 +1,83 @@ +# - Try to find Iconv on Mac OS X +# Once done this will define +# +# ICONV_FOUND - system has Iconv +# ICONV_INCLUDE_DIR - the Iconv include directory +# ICONV_LIBRARIES - Link these to use Iconv +# ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const +# + +IF(APPLE) + include(CheckCCompilerFlag) + include(CheckCSourceCompiles) + + IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + # Already in cache, be silent + SET(ICONV_FIND_QUIETLY TRUE) + ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + + IF(APPLE) + FIND_PATH(ICONV_INCLUDE_DIR iconv.h + PATHS + /opt/local/include/ + NO_CMAKE_SYSTEM_PATH + ) + + FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c + PATHS + /opt/local/lib/ + NO_CMAKE_SYSTEM_PATH + ) + ENDIF(APPLE) + + FIND_PATH(ICONV_INCLUDE_DIR iconv.h PATHS /opt/local/include /sw/include) + + string(REGEX REPLACE "(.*)/include/?" "\\1" ICONV_INCLUDE_BASE_DIR "${ICONV_INCLUDE_DIR}") + + FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c HINTS "${ICONV_INCLUDE_BASE_DIR}/lib" PATHS /opt/local/lib) + + IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + SET(ICONV_FOUND TRUE) + ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + + set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES}) + IF(ICONV_FOUND) + check_c_compiler_flag("-Werror" ICONV_HAVE_WERROR) + set (CMAKE_C_FLAGS_BACKUP "${CMAKE_C_FLAGS}") + if(ICONV_HAVE_WERROR) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + endif(ICONV_HAVE_WERROR) + check_c_source_compiles(" + #include + int main(){ + iconv_t conv = 0; + const char* in = 0; + size_t ilen = 0; + char* out = 0; + size_t olen = 0; + iconv(conv, &in, &ilen, &out, &olen); + return 0; + } + " ICONV_SECOND_ARGUMENT_IS_CONST ) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BACKUP}") + ENDIF(ICONV_FOUND) + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + + IF(ICONV_FOUND) + IF(NOT ICONV_FIND_QUIETLY) + MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") + ENDIF(NOT ICONV_FIND_QUIETLY) + ELSE(ICONV_FOUND) + IF(Iconv_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Iconv") + ENDIF(Iconv_FIND_REQUIRED) + ENDIF(ICONV_FOUND) + + MARK_AS_ADVANCED( + ICONV_INCLUDE_DIR + ICONV_LIBRARIES + ICONV_SECOND_ARGUMENT_IS_CONST + ) +ENDIF(APPLE) diff --git a/code/CMakeModules/FindLuabind.cmake b/code/CMakeModules/FindLuabind.cmake index b73530ef5..c94a61e30 100644 --- a/code/CMakeModules/FindLuabind.cmake +++ b/code/CMakeModules/FindLuabind.cmake @@ -6,7 +6,7 @@ IF(LUABIND_LIBRARIES AND LUABIND_INCLUDE_DIR) # in cache already - SET(LUABIND_FIND_QUIETLY TRUE) + SET(Luabind_FIND_QUIETLY TRUE) ENDIF(LUABIND_LIBRARIES AND LUABIND_INCLUDE_DIR) FIND_PATH(LUABIND_INCLUDE_DIR @@ -22,7 +22,7 @@ FIND_PATH(LUABIND_INCLUDE_DIR ) SET(LIBRARY_NAME_RELEASE luabind libluabind) -SET(LIBRARY_NAME_DEBUG luabind_d libluabind_d libluabindd) +SET(LIBRARY_NAME_DEBUG luabind_d luabindd libluabind_d libluabindd) IF(WITH_STLPORT) SET(LIBRARY_NAME_RELEASE luabind_stlport ${LIBRARY_NAME_RELEASE}) @@ -62,30 +62,35 @@ FIND_LIBRARY(LUABIND_LIBRARY_DEBUG FIND_PACKAGE(Boost REQUIRED) IF(LUABIND_INCLUDE_DIR AND Boost_INCLUDE_DIR) - IF(LUABIND_LIBRARY_RELEASE) + IF(LUABIND_LIBRARY_RELEASE AND LUABIND_LIBRARY_DEBUG) + # Case where both Release and Debug versions are provided SET(LUABIND_FOUND TRUE) - SET(LUABIND_INCLUDE_DIR ${LUABIND_INCLUDE_DIR} ${Boost_INCLUDE_DIR}) - IF(LUABIND_LIBRARY_DEBUG) - SET(LUABIND_LIBRARIES "optimized;${LUABIND_LIBRARY_RELEASE};debug;${LUABIND_LIBRARY_DEBUG}") - ELSE(LUABIND_LIBRARY_DEBUG) - SET(LUABIND_LIBRARIES "${LUABIND_LIBRARY_RELEASE}") - ENDIF(LUABIND_LIBRARY_DEBUG) - ENDIF(LUABIND_LIBRARY_RELEASE) + SET(LUABIND_LIBRARIES optimized ${LUABIND_LIBRARY_RELEASE} debug ${LUABIND_LIBRARY_DEBUG}) + ELSEIF(LUABIND_LIBRARY_RELEASE) + # Normal case + SET(LUABIND_FOUND TRUE) + SET(LUABIND_LIBRARIES ${LUABIND_LIBRARY_RELEASE}) + ELSEIF(LUABIND_LIBRARY_DEBUG) + # Case where Luabind is compiled from sources (debug version is compiled by default) + SET(LUABIND_FOUND TRUE) + SET(LUABIND_LIBRARIES ${LUABIND_LIBRARY_DEBUG}) + ENDIF(LUABIND_LIBRARY_RELEASE AND LUABIND_LIBRARY_DEBUG) ENDIF(LUABIND_INCLUDE_DIR AND Boost_INCLUDE_DIR) IF(LUABIND_FOUND) + SET(LUABIND_INCLUDE_DIR ${LUABIND_INCLUDE_DIR} ${Boost_INCLUDE_DIR}) # Check if luabind/version.hpp exists FIND_FILE(LUABIND_VERSION_FILE luabind/version.hpp PATHS ${LUABIND_INCLUDE_DIR}) IF(LUABIND_VERSION_FILE) SET(LUABIND_DEFINITIONS "-DHAVE_LUABIND_VERSION") ENDIF(LUABIND_VERSION_FILE) - IF(NOT LUABIND_FIND_QUIETLY) + IF(NOT Luabind_FIND_QUIETLY) MESSAGE(STATUS "Found Luabind: ${LUABIND_LIBRARIES}") - ENDIF(NOT LUABIND_FIND_QUIETLY) + ENDIF(NOT Luabind_FIND_QUIETLY) ELSE(LUABIND_FOUND) - IF(NOT LUABIND_FIND_QUIETLY) + IF(NOT Luabind_FIND_QUIETLY) MESSAGE(STATUS "Warning: Unable to find Luabind!") - ENDIF(NOT LUABIND_FIND_QUIETLY) + ENDIF(NOT Luabind_FIND_QUIETLY) ENDIF(LUABIND_FOUND) MARK_AS_ADVANCED(LUABIND_LIBRARY_RELEASE LUABIND_LIBRARY_DEBUG Boost_LIB_DIAGNOSTIC_DEFINITIONS) diff --git a/code/CMakeModules/FindSTLport.cmake b/code/CMakeModules/FindSTLport.cmake index a235d42f3..22e0745ba 100644 --- a/code/CMakeModules/FindSTLport.cmake +++ b/code/CMakeModules/FindSTLport.cmake @@ -71,9 +71,9 @@ IF(STLPORT_INCLUDE_DIR) IF(STLPORT_LIBRARY_RELEASE) SET(STLPORT_FOUND TRUE) - SET(STLPORT_LIBRARIES "optimized;${STLPORT_LIBRARY_RELEASE}") + SET(STLPORT_LIBRARIES ${STLPORT_LIBRARY_RELEASE}) IF(STLPORT_LIBRARY_DEBUG) - SET(STLPORT_LIBRARIES "${STLPORT_LIBRARIES};debug;${STLPORT_LIBRARY_DEBUG}") + SET(STLPORT_LIBRARIES optimized ${STLPORT_LIBRARIES} debug ${STLPORT_LIBRARY_DEBUG}) ENDIF(STLPORT_LIBRARY_DEBUG) ENDIF(STLPORT_LIBRARY_RELEASE) ENDIF(STLPORT_INCLUDE_DIR) diff --git a/code/CMakeModules/FindWindowsSDK.cmake b/code/CMakeModules/FindWindowsSDK.cmake index 04059a6a5..30e507f85 100644 --- a/code/CMakeModules/FindWindowsSDK.cmake +++ b/code/CMakeModules/FindWindowsSDK.cmake @@ -9,17 +9,32 @@ IF(WINSDK_INCLUDE_DIR) SET(WINSDK_FIND_QUIETLY TRUE) ENDIF(WINSDK_INCLUDE_DIR) +GET_FILENAME_COMPONENT(WINSDK71_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.1;InstallationFolder]" ABSOLUTE CACHE) +GET_FILENAME_COMPONENT(WINSDK71_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.1;ProductVersion]" NAME) + +IF(WINSDK71_DIR) + IF(NOT WINSDK_FIND_QUIETLY) + MESSAGE(STATUS "Found Windows SDK ${WINSDK71_VERSION} in ${WINSDK71_DIR}") + ENDIF(NOT WINSDK_FIND_QUIETLY) +ENDIF(WINSDK71_DIR) + +GET_FILENAME_COMPONENT(WINSDKCURRENT_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" ABSOLUTE CACHE) +GET_FILENAME_COMPONENT(WINSDKCURRENT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentVersion]" NAME) + +IF(WINSDKCURRENT_DIR) + IF(NOT WINSDK_FIND_QUIETLY) + MESSAGE(STATUS "Found Windows SDK ${WINSDKCURRENT_VERSION} in ${WINSDKCURRENT_DIR}") + ENDIF(NOT WINSDK_FIND_QUIETLY) +ENDIF(WINSDKCURRENT_DIR) + FIND_PATH(WINSDK_INCLUDE_DIR Windows.h PATHS - "[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]/Include" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]/Include" + ${WINSDK71_DIR}/Include + ${WINSDKCURRENT_DIR}/Include ) IF(WINSDK_INCLUDE_DIR) SET(WINSDK_FOUND TRUE) - IF(NOT WINSDK_FIND_QUIETLY) - MESSAGE(STATUS "Found Windows SDK.") - ENDIF(NOT WINSDK_FIND_QUIETLY) ELSE(WINSDK_INCLUDE_DIR) IF(NOT WINSDK_FIND_QUIETLY) MESSAGE(STATUS "Warning: Unable to find Windows SDK!") diff --git a/code/CMakeModules/FindZLIB.cmake b/code/CMakeModules/FindZLIB.cmake deleted file mode 100644 index cb055740e..000000000 --- a/code/CMakeModules/FindZLIB.cmake +++ /dev/null @@ -1,39 +0,0 @@ -# - Find zlib -# Find the native ZLIB includes and library -# -# ZLIB_INCLUDE_DIRS - where to find zlib.h, etc. -# ZLIB_LIBRARIES - List of libraries when using zlib. -# ZLIB_FOUND - True if zlib found. - -#============================================================================= -# Copyright 2001-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - -IF (ZLIB_INCLUDE_DIR) - # Already in cache, be silent - SET(ZLIB_FIND_QUIETLY TRUE) -ENDIF (ZLIB_INCLUDE_DIR) - -FIND_PATH(ZLIB_INCLUDE_DIR zlib.h) - -SET(ZLIB_NAMES z zlib zdll) -FIND_LIBRARY(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} ) -MARK_AS_ADVANCED( ZLIB_LIBRARY ZLIB_INCLUDE_DIR ) - -# Per-recommendation -SET(ZLIB_INCLUDE_DIRS "${ZLIB_INCLUDE_DIR}") -SET(ZLIB_LIBRARIES "${ZLIB_LIBRARY}") - -# handle the QUIETLY and REQUIRED arguments and set ZLIB_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB DEFAULT_MSG ZLIB_LIBRARIES ZLIB_INCLUDE_DIRS) diff --git a/code/CMakeModules/PCHSupport.cmake b/code/CMakeModules/PCHSupport.cmake index 74d009864..bb34aebfe 100644 --- a/code/CMakeModules/PCHSupport.cmake +++ b/code/CMakeModules/PCHSupport.cmake @@ -45,8 +45,6 @@ MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags) IF(${_targetType} STREQUAL SHARED_LIBRARY OR ${_targetType} STREQUAL MODULE_LIBRARY) LIST(APPEND ${_out_compile_flags} "-fPIC") ENDIF(${_targetType} STREQUAL SHARED_LIBRARY OR ${_targetType} STREQUAL MODULE_LIBRARY) - ELSE(CMAKE_COMPILER_IS_GNUCXX) - ## TODO ... ? or does it work out of the box ENDIF(CMAKE_COMPILER_IS_GNUCXX) GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES ) @@ -54,13 +52,23 @@ MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags) LIST(APPEND ${_out_compile_flags} " ${_PCH_include_prefix}\"${item}\"") ENDFOREACH(item) + # Required for CMake 2.6 + SET(GLOBAL_DEFINITIONS "") + GET_DIRECTORY_PROPERTY(DEFINITIONS COMPILE_DEFINITIONS) + FOREACH(item ${DEFINITIONS}) + LIST(APPEND GLOBAL_DEFINITIONS -D${item}) + ENDFOREACH(item) + GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS) - GET_DIRECTORY_PROPERTY(_global_definitions DIRECTORY ${CMAKE_SOURCE_DIR} DEFINITIONS) + GET_DIRECTORY_PROPERTY(_directory_definitions DIRECTORY ${CMAKE_SOURCE_DIR} DEFINITIONS) + LIST(APPEND ${_out_compile_flags} ${GLOBAL_DEFINITIONS}) LIST(APPEND ${_out_compile_flags} ${_directory_flags}) - LIST(APPEND ${_out_compile_flags} ${_global_definitions}) + LIST(APPEND ${_out_compile_flags} ${_directory_definitions}) LIST(APPEND ${_out_compile_flags} ${CMAKE_CXX_FLAGS}) + # Format definitions and remove duplicates SEPARATE_ARGUMENTS(${_out_compile_flags}) + LIST(REMOVE_DUPLICATES ${_out_compile_flags}) ENDMACRO(_PCH_GET_COMPILE_FLAGS) MACRO(_PCH_GET_PDB_FILENAME out_filename _target) @@ -115,6 +123,11 @@ MACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input _output) ENDMACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input) MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use ) + GET_TARGET_PROPERTY(oldProps ${_targetName} COMPILE_FLAGS) + IF(${oldProps} MATCHES NOTFOUND) + SET(oldProps "") + ENDIF(${oldProps} MATCHES NOTFOUND) + IF(CMAKE_COMPILER_IS_GNUCXX) # to do: test whether compiler flags match between target _targetName # and _pch_output_to_use @@ -123,19 +136,17 @@ MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use ) # for use with distcc and gcc >4.0.1 if preprocessed files are accessible # on all remote machines set # PCH_ADDITIONAL_COMPILER_FLAGS to -fpch-preprocess - SET(_target_cflags "${PCH_ADDITIONAL_COMPILER_FLAGS}-include ${_input} -Winvalid-pch") + SET(_target_cflags "${oldProps} ${PCH_ADDITIONAL_COMPILER_FLAGS}-include ${_input} -Winvalid-pch") ELSE(CMAKE_COMPILER_IS_GNUCXX) IF(MSVC) - GET_TARGET_PROPERTY(oldProps ${_targetName} COMPILE_FLAGS) - IF(${oldProps} MATCHES NOTFOUND) - SET(oldProps "") - ENDIF(${oldProps} MATCHES NOTFOUND) - SET(_target_cflags "${oldProps} /Yu\"${_input}\" /FI\"${_input}\" /Fp\"${_pch_output_to_use}\"") ENDIF(MSVC) ENDIF(CMAKE_COMPILER_IS_GNUCXX) SET_TARGET_PROPERTIES(${_targetName} PROPERTIES COMPILE_FLAGS ${_target_cflags}) + IF(oldProps) + SET_TARGET_PROPERTIES(${_targetName}_pch_dephelp PROPERTIES COMPILE_FLAGS ${oldProps}) + ENDIF(oldProps) ADD_CUSTOM_TARGET(pch_Generate_${_targetName} DEPENDS ${_pch_output_to_use}) ADD_DEPENDENCIES(${_targetName} pch_Generate_${_targetName}) ENDMACRO(ADD_PRECOMPILED_HEADER_TO_TARGET) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index dc6b477d0..fbd70c842 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -37,16 +37,17 @@ ENDMACRO(NL_TARGET_DRIVER) # Argument: ### MACRO(NL_DEFAULT_PROPS name label) + IF(NOT MSVC10) + SET_TARGET_PROPERTIES(${name} PROPERTIES PROJECT_LABEL ${label}) + ENDIF(NOT MSVC10) GET_TARGET_PROPERTY(type ${name} TYPE) IF(${type} STREQUAL SHARED_LIBRARY) # Set versions only if target is a shared library SET_TARGET_PROPERTIES(${name} PROPERTIES - VERSION ${NL_VERSION} SOVERSION ${NL_VERSION_MAJOR} - INSTALL_NAME_DIR ${NL_LIB_PREFIX} - PROJECT_LABEL ${label}) - ELSE(${type} STREQUAL SHARED_LIBRARY) - SET_TARGET_PROPERTIES(${name} PROPERTIES - PROJECT_LABEL ${label}) + VERSION ${NL_VERSION} SOVERSION ${NL_VERSION_MAJOR}) + IF(NL_LIB_PREFIX) + SET_TARGET_PROPERTIES(${name} PROPERTIES INSTALL_NAME_DIR ${NL_LIB_PREFIX}) + ENDIF(NL_LIB_PREFIX) ENDIF(${type} STREQUAL SHARED_LIBRARY) IF(WITH_STLPORT AND WIN32) SET_TARGET_PROPERTIES(${name} PROPERTIES COMPILE_FLAGS "/X") @@ -93,6 +94,14 @@ MACRO(NL_ADD_STATIC_VID_DRIVERS name) TARGET_LINK_LIBRARIES(${name} nel_drv_opengl) ENDIF(WIN32) ENDIF(WITH_DRIVER_OPENGL) + + IF(WITH_DRIVER_OPENGLES) + IF(WIN32) + TARGET_LINK_LIBRARIES(${name} nel_drv_opengles_win) + ELSE(WIN32) + TARGET_LINK_LIBRARIES(${name} nel_drv_opengles) + ENDIF(WIN32) + ENDIF(WITH_DRIVER_OPENGLES) ENDIF(WITH_STATIC_DRIVERS) ENDMACRO(NL_ADD_STATIC_VID_DRIVERS) @@ -208,6 +217,7 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) # Drivers Support ### OPTION(WITH_DRIVER_OPENGL "Build OpenGL Driver (3D)" ON ) + OPTION(WITH_DRIVER_OPENGLES "Build OpenGL ES Driver (3D)" OFF) OPTION(WITH_DRIVER_DIRECT3D "Build Direct3D Driver (3D)" OFF) OPTION(WITH_DRIVER_OPENAL "Build OpenAL Driver (Sound)" ON ) OPTION(WITH_DRIVER_FMOD "Build FMOD Driver (Sound)" OFF) @@ -278,19 +288,56 @@ MACRO(NL_SETUP_BUILD) ENDIF(CMAKE_BUILD_TYPE MATCHES "Release") ENDIF(CMAKE_BUILD_TYPE MATCHES "Debug") + # Determine target CPU +# IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") + IF(NOT CMAKE_SIZEOF_VOID_P) + INCLUDE (CheckTypeSize) + CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P) + ENDIF(NOT CMAKE_SIZEOF_VOID_P) + + # Using 32 or 64 bits libraries + SET(TARGET_X86 1) + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(ARCH "x86_64") + SET(TARGET_X64 1) + ADD_DEFINITIONS(-DHAVE_X86_64) + ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(ARCH "x86") + ADD_DEFINITIONS(-DHAVE_X86) + ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) +# ADD_DEFINITIONS(-DHAVE_IA64) +# ENDIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") + IF(WIN32) - # don't use a /O[012x] flag if you want custom optimizations - SET(SPEED_OPTIMIZATIONS "/Ob2 /Oi /Ot /Oy /GT /GF /GS-") - # without inlining it's unusable, use custom optimizations again - SET(MIN_OPTIMIZATIONS "/Ob1") + IF(MSVC10) + # /Ox is working with VC++ 2010, but custom optimizations don't exist + SET(SPEED_OPTIMIZATIONS "/Ox /GF /GS-") + # without inlining it's unusable, use custom optimizations again + SET(MIN_OPTIMIZATIONS "/Od /Ob1") + ELSE(MSVC10) + # don't use a /O[012x] flag if you want custom optimizations + SET(SPEED_OPTIMIZATIONS "/Ob2 /Oi /Ot /Oy /GT /GF /GS-") + # without inlining it's unusable, use custom optimizations again + SET(MIN_OPTIMIZATIONS "/Ob1") + ENDIF(MSVC10) - SET(PLATFORM_CFLAGS "/D_CRT_SECURE_NO_WARNINGS /DWIN32 /D_WINDOWS /W3 /Zi /Zm1000") - - # Exceptions are only set for C++ - SET(PLATFORM_CXXFLAGS "${PLATFORM_CFLAGS} /EHa") + SET(PLATFORM_CFLAGS "/D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DWIN32 /D_WINDOWS /W3 /Zi /Zm1000 /MP /Gy-") # Common link flags SET(PLATFORM_LINKFLAGS "-DEBUG") + + IF(TARGET_X64) + # Fix a bug with Intellisense + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} /D_WIN64") + # Fix a compilation error for some big C++ files + SET(MIN_OPTIMIZATIONS "${MIN_OPTIMIZATIONS} /bigobj") + ELSE(TARGET_X64) + # Allows 32 bits applications to use 3 GB of RAM + SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /LARGEADDRESSAWARE") + ENDIF(TARGET_X64) + + # Exceptions are only set for C++ + SET(PLATFORM_CXXFLAGS "${PLATFORM_CFLAGS} /EHa") SET(NL_DEBUG_CFLAGS "/MDd /RTC1 /D_DEBUG ${MIN_OPTIMIZATIONS}") SET(NL_RELEASE_CFLAGS "/MD /D NDEBUG ${SPEED_OPTIMIZATIONS}") @@ -314,33 +361,10 @@ MACRO(NL_SETUP_BUILD) SET(NL_DEBUG_CFLAGS "-DNL_DEBUG -D_DEBUG") SET(NL_RELEASE_CFLAGS "-DNL_RELEASE -DNDEBUG -O6") - ENDIF(WIN32) - - # Determine host CPU - IF(UNIX AND NOT WIN32) - FIND_PROGRAM(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin ) - IF(CMAKE_UNAME) - EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR) - SET(CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR} CACHE INTERNAL "processor type (i386 and x86_64)") - IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") - ADD_DEFINITIONS(-DHAVE_X86_64) - ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "ia64") - ADD_DEFINITIONS(-DHAVE_IA64) - ELSE(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") - ADD_DEFINITIONS(-DHAVE_X86) - ENDIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") - ELSE(CMAKE_UNAME) # Assume that if uname is not found that we're x86. - ADD_DEFINITIONS(-DHAVE_X86) - ENDIF(CMAKE_UNAME) - ENDIF(UNIX AND NOT WIN32) - ENDMACRO(NL_SETUP_BUILD) MACRO(NL_SETUP_BUILD_FLAGS) - #SET(CMAKE_DEBUG_POSTFIX "_d") - #SET(CMAKE_RELEASE_POSTFIX "_r") - SET(CMAKE_C_FLAGS ${PLATFORM_CFLAGS} CACHE STRING "" FORCE) SET(CMAKE_CXX_FLAGS ${PLATFORM_CXXFLAGS} CACHE STRING "" FORCE) @@ -472,3 +496,44 @@ MACRO(RYZOM_SETUP_PREFIX_PATHS) ENDIF(NOT RYZOM_GAMES_PREFIX) ENDMACRO(RYZOM_SETUP_PREFIX_PATHS) + +MACRO(SETUP_EXTERNAL) + IF(WIN32) + FIND_PACKAGE(External REQUIRED) + + INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) + IF(MSVC10) + GET_FILENAME_COMPONENT(VC_ROOT_DIR "[HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\10.0_Config;InstallDir]" ABSOLUTE) + # VC_ROOT_DIR is set to "registry" when a key is not found + IF(VC_ROOT_DIR MATCHES "registry") + GET_FILENAME_COMPONENT(VC_ROOT_DIR "[HKEY_CURRENT_USER\\Software\\Microsoft\\VCExpress\\10.0_Config;InstallDir]" ABSOLUTE) + IF(VC_ROOT_DIR MATCHES "registry") + MESSAGE(FATAL_ERROR "Unable to find VC++ 2010 directory!") + ENDIF(VC_ROOT_DIR MATCHES "registry") + ENDIF(VC_ROOT_DIR MATCHES "registry") + # convert IDE fullpath to VC++ path + STRING(REGEX REPLACE "Common7/.*" "VC" VC_DIR ${VC_ROOT_DIR}) + ELSE(MSVC10) + IF(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") + # convert IDE fullpath to VC++ path + STRING(REGEX REPLACE "Common7/.*" "VC" VC_DIR ${CMAKE_MAKE_PROGRAM}) + ELSE(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") + # convert compiler fullpath to VC++ path + STRING(REGEX REPLACE "VC/bin/.+" "VC" VC_DIR ${CMAKE_CXX_COMPILER}) + ENDIF(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") + ENDIF(MSVC10) + ENDIF(WIN32) + + IF(WITH_STLPORT) + FIND_PACKAGE(STLport REQUIRED) + INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR}) + IF(WIN32) + SET(VC_INCLUDE_DIR "${VC_DIR}/include") + + FIND_PACKAGE(WindowsSDK REQUIRED) + # use VC++ and Windows SDK include paths + INCLUDE_DIRECTORIES(${VC_INCLUDE_DIR} ${WINSDK_INCLUDE_DIR}) + ENDIF(WIN32) + ENDIF(WITH_STLPORT) + +ENDMACRO(SETUP_EXTERNAL) diff --git a/code/README b/code/README index 3c19258ee..4f1b1d51b 100644 --- a/code/README +++ b/code/README @@ -29,4 +29,4 @@ file for for more details on license terms and other legal issues. Installation ------------ -Please check the dev.ryzom.com for more information +Please visit http://dev.ryzom.com for more information. diff --git a/code/config.h.cmake b/code/config.h.cmake index a2f65aa41..2f2ff8095 100644 --- a/code/config.h.cmake +++ b/code/config.h.cmake @@ -35,6 +35,7 @@ #cmakedefine HAVE_STAT64 1 #cmakedefine NL_OPENGL_AVAILABLE ${NL_OPENGL_AVAILABLE} +#cmakedefine NL_OPENGLES_AVAILABLE ${NL_OPENGLES_AVAILABLE} #cmakedefine NL_DIRECT3D_AVAILABLE ${NL_DIRECT3D_AVAILABLE} #cmakedefine NL_FMOD_AVAILABLE ${NL_FMOD_AVAILABLE} diff --git a/code/nel/include/nel/3d/scene_group.h b/code/nel/include/nel/3d/scene_group.h index 9b4f8d792..d587f23d9 100644 --- a/code/nel/include/nel/3d/scene_group.h +++ b/code/nel/include/nel/3d/scene_group.h @@ -107,7 +107,7 @@ public: bool Visible; /// Precomputed Lighting. - // If true (false by default), then the instance don't cast shadow (used by ig_lighter.exe). + // If true (false by default), then the instance don't cast shadow (used by ig_lighter). bool DontCastShadow; // If true (false by default), then the instance's lighting will not be precomputed. bool AvoidStaticLightPreCompute; @@ -120,7 +120,7 @@ public: * If 0xFF => take Ambient of the sun. */ uint8 LocalAmbientId; - /** if true (false by default), the instance don't cast shadow, but ONLY FOR ig_lighter.exe (ig_lighter_lib) + /** if true (false by default), the instance don't cast shadow, but ONLY FOR ig_lighter (ig_lighter_lib) * (zone_lighter and zone_ig_lighter ignore it). * This is a special trick for the "Matis Serre" where the exterior mesh cast shadow in the interior, but * is not visible in the interior in realTime because of cluster clipping.... omg :( diff --git a/code/nel/include/nel/3d/track_keyframer.h b/code/nel/include/nel/3d/track_keyframer.h index 2ae43c011..5f2cde6da 100644 --- a/code/nel/include/nel/3d/track_keyframer.h +++ b/code/nel/include/nel/3d/track_keyframer.h @@ -697,6 +697,7 @@ public: virtual bool addLinearFloatKey(const UKeyLinearFloat &key) { CKeyFloat k; + k.OODeltaTime= 0.f; k.Value= key.Value; addKey(k, key.Time); return true; diff --git a/code/nel/include/nel/cegui/nelrenderer.h b/code/nel/include/nel/cegui/nelrenderer.h index ba1340f5c..84e1221c1 100644 --- a/code/nel/include/nel/cegui/nelrenderer.h +++ b/code/nel/include/nel/cegui/nelrenderer.h @@ -142,11 +142,14 @@ namespace CEGUI void captureCursor(bool capture) { m_Captured=capture; - if(capture) { + if(capture) + { m_Driver->setCapture(true); m_Driver->showCursor(false); m_InputDriver.activateMouse(); - } else { + } + else + { m_Driver->setCapture(false); m_Driver->showCursor(true); m_InputDriver.deactivateMouse(); @@ -178,7 +181,8 @@ namespace CEGUI class NeLInputDriver : public NLMISC::IEventListener { public: - NeLInputDriver() { + NeLInputDriver() + { m_MouseX=0.5f; m_MouseY=0.5f; m_Active=false; @@ -189,7 +193,8 @@ namespace CEGUI } virtual ~NeLInputDriver() { ; } - void addToServer(NLMISC::CEventServer& server) { + void addToServer(NLMISC::CEventServer& server) + { server.addListener(NLMISC::EventMouseMoveId, this); server.addListener(NLMISC::EventMouseDownId, this); server.addListener(NLMISC::EventMouseUpId, this); @@ -200,7 +205,8 @@ namespace CEGUI m_AsyncListener.addToServer(server); } - void removeFromServer(NLMISC::CEventServer& server) { + void removeFromServer(NLMISC::CEventServer& server) + { server.removeListener(NLMISC::EventMouseMoveId, this); server.removeListener(NLMISC::EventMouseDownId, this); server.removeListener(NLMISC::EventMouseUpId, this); @@ -226,9 +232,11 @@ namespace CEGUI * * \param event An event, probably a CEventMouse or CEventKey/Char. */ - virtual void operator ()(const NLMISC::CEvent& event) { + virtual void operator ()(const NLMISC::CEvent& event) + { // don't process any input if we're inactive. - if(m_Active==false) { + if(m_Active==false) + { return; // not processing ANY input } @@ -236,36 +244,51 @@ namespace CEGUI { // otherwise, on with the festivities. // catch ALL mouse event, just in case. - if(event==NLMISC::EventMouseDownId||event==NLMISC::EventMouseUpId||event==NLMISC::EventMouseMoveId||event==NLMISC::EventMouseDblClkId||event==NLMISC::EventMouseWheelId) { - if(!m_MouseActive) { + if(event==NLMISC::EventMouseDownId||event==NLMISC::EventMouseUpId||event==NLMISC::EventMouseMoveId||event==NLMISC::EventMouseDblClkId||event==NLMISC::EventMouseWheelId) + { + if(!m_MouseActive) + { // we're not processing any mouse activity. The cursor isn't captured maybe? return; } NLMISC::CEventMouse *mouseEvent=(NLMISC::CEventMouse *)&event; // a mouse button was pressed. - if(event == NLMISC::EventMouseDownId) { + if(event == NLMISC::EventMouseDownId) + { // it was the left button... - if (mouseEvent->Button & NLMISC::leftButton) { + if (mouseEvent->Button & NLMISC::leftButton) + { CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton); // it was the right button... - } else if (mouseEvent->Button & NLMISC::rightButton) { + } + else if (mouseEvent->Button & NLMISC::rightButton) + { CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton); - } else if (mouseEvent->Button & NLMISC::middleButton) { + } + else if (mouseEvent->Button & NLMISC::middleButton) + { CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton); } // a mouse button was released - } else if (event == NLMISC::EventMouseUpId) { + } + else if (event == NLMISC::EventMouseUpId) + { // it was the left button... - if(mouseEvent->Button & NLMISC::leftButton) { + if(mouseEvent->Button & NLMISC::leftButton) + { CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton); // it was the right button... - } else if (mouseEvent->Button & NLMISC::rightButton) { + } + else if (mouseEvent->Button & NLMISC::rightButton) + { CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton); } else if (mouseEvent->Button & NLMISC::middleButton) { CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton); } - } else if (event == NLMISC::EventMouseMoveId) { + } + else if (event == NLMISC::EventMouseMoveId) + { // convert into screen coordinates. float delta_x=(float)(mouseEvent->X - m_MouseX)*m_Width; float delta_y=(float)((1.0f-mouseEvent->Y) - m_MouseY)*m_Height; @@ -276,18 +299,26 @@ namespace CEGUI // and save for delta. m_MouseX=mouseEvent->X; m_MouseY=1.0f-mouseEvent->Y; - } else if (event == NLMISC::EventMouseWheelId) { + } + else if (event == NLMISC::EventMouseWheelId) + { NLMISC::CEventMouseWheel *ev=(NLMISC::CEventMouseWheel *)&event; float dir=0.0f; if(ev->Direction) dir=0.5f; else dir=-0.5f; CEGUI::System::getSingleton().injectMouseWheelChange(dir); } - } else { // assume otherwise that it's a character. - if(event==NLMISC::EventCharId) { + } + else + { + // assume otherwise that it's a character. + if(event==NLMISC::EventCharId) + { unsigned char c = (char)((NLMISC::CEventChar&)event).Char; CEGUI::System::getSingleton().injectChar((CEGUI::utf32)c); - } else if(event==NLMISC::EventKeyDownId) { + } + else if(event==NLMISC::EventKeyDownId) + { NLMISC::CEventKeyDown *keyvent=(NLMISC::CEventKeyDown *)&event; CEGUI::System::getSingleton().injectKeyDown(m_KeyMap[keyvent->Key]); } @@ -296,7 +327,8 @@ namespace CEGUI catch (CEGUI::Exception) { } } - void initKeyMap() { + void initKeyMap() + { m_KeyMap[NLMISC::Key0 ]=CEGUI::Key::Zero; m_KeyMap[NLMISC::Key1 ]=CEGUI::Key::One; m_KeyMap[NLMISC::Key2 ]=CEGUI::Key::Two; diff --git a/code/nel/include/nel/georges/load_form.h b/code/nel/include/nel/georges/load_form.h index 1a9a759f9..3a2e6d839 100644 --- a/code/nel/include/nel/georges/load_form.h +++ b/code/nel/include/nel/georges/load_form.h @@ -201,7 +201,7 @@ void loadForm (const std::vector &sheetFilters, const std::string & ifile.serialCont (container); ifile.close (); } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { // clear the container because it can contains partially loaded sheet so we must clean it before continue container.clear (); @@ -456,7 +456,7 @@ void loadForm (const std::vector &sheetFilters, const std::string & ofile.close (); } } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { nlinfo ("loadForm(): Exception during saving the packed file, it will be recreated next launch (%s)", e.what()); } @@ -564,7 +564,7 @@ void loadForm2(const std::vector &sheetFilters, const std::string & ifile.serialPtrCont (container); ifile.close (); } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { // clear the container because it can contains partially loaded sheet so we must clean it before continue container.clear (); @@ -819,7 +819,7 @@ void loadForm2(const std::vector &sheetFilters, const std::string & ofile.close (); } } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { nlinfo ("loadForm(): Exception during saving the packed file, it will be recreated next launch (%s)", e.what()); } @@ -925,7 +925,7 @@ void loadForm (const std::vector &sheetFilters, const std::string & ifile.serialCont (container); ifile.close (); } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { // clear the container because it can contains partially loaded sheet so we must clean it before continue container.clear (); @@ -1183,7 +1183,7 @@ void loadForm (const std::vector &sheetFilters, const std::string & ofile.close (); } } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { nlinfo ("loadForm(): Exception during saving the packed file, it will be recreated next launch (%s)", e.what()); } diff --git a/code/nel/include/nel/ligo/primitive_utils.h b/code/nel/include/nel/ligo/primitive_utils.h index cc71e2d50..c5049b06b 100644 --- a/code/nel/include/nel/ligo/primitive_utils.h +++ b/code/nel/include/nel/ligo/primitive_utils.h @@ -261,7 +261,7 @@ inline bool loadXmlPrimitiveFile(CPrimitives &primDoc, const std::string &fileNa // Read it return primDoc.read (xmlIn.getRootNode (), NLMISC::CFile::getFilename(fileName).c_str(), ligoConfig); } - catch(NLMISC::Exception e) + catch(const NLMISC::Exception &e) { nlwarning("Error reading input file '%s': '%s'", fileName.c_str(), e.what()); return false; @@ -294,7 +294,7 @@ inline bool saveXmlPrimitiveFile(CPrimitives &primDoc, const std::string &fileNa // return xmlSaveFile(fileName.c_str(), xmlDoc) != -1; } - catch(NLMISC::Exception e) + catch(const NLMISC::Exception &e) { nlwarning("Error writing output file '%s': '%s'", fileName.c_str(), e.what()); return false; diff --git a/code/nel/include/nel/misc/config_file.h b/code/nel/include/nel/misc/config_file.h index eb7239b14..b1223fa14 100644 --- a/code/nel/include/nel/misc/config_file.h +++ b/code/nel/include/nel/misc/config_file.h @@ -63,7 +63,7 @@ namespace NLMISC * printf ("%d ", bar.asInt (i)); * printf("\n"); * } - * catch (EConfigFile &e) + * catch (const EConfigFile &e) * { * // Something goes wrong... catch that * printf ("%s\n", e.what ()); diff --git a/code/nel/include/nel/misc/debug.h b/code/nel/include/nel/misc/debug.h index f794e6fca..af92c4a16 100644 --- a/code/nel/include/nel/misc/debug.h +++ b/code/nel/include/nel/misc/debug.h @@ -169,7 +169,7 @@ void setCrashAlreadyReported(bool state); *\endcode */ #ifdef NL_NO_DEBUG -# if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +# if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) # define nldebug __noop # else # define nldebug 0&& @@ -184,7 +184,7 @@ void setCrashAlreadyReported(bool state); * Same as nldebug but it will be display in debug and in release mode. */ #ifdef NL_NO_DEBUG -# if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +# if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) # define nlinfo __noop # else # define nlinfo 0&& @@ -212,7 +212,7 @@ void setCrashAlreadyReported(bool state); */ #ifdef NL_NO_DEBUG -# if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +# if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) # define nlwarning __noop # else # define nlwarning 0&& @@ -583,7 +583,11 @@ template inline T type_cast(U o) /** Compile time assertion */ -#define nlctassert(cond) sizeof(uint[(cond) ? 1 : 0]) +#ifdef NL_ISO_CPP0X_AVAILABLE +# define nlctassert(cond) static_assert(cond, "Compile time assert in "#cond) +#else +# define nlctassert(cond) sizeof(uint[(cond) ? 1 : 0]) +#endif /** * Allow to verify an object was accessed before its destructor call. diff --git a/code/nel/include/nel/misc/diff_tool.h b/code/nel/include/nel/misc/diff_tool.h index b8a8db327..64989fcaf 100644 --- a/code/nel/include/nel/misc/diff_tool.h +++ b/code/nel/include/nel/misc/diff_tool.h @@ -238,11 +238,11 @@ namespace STRING_MANAGER return false; } - bool findCol(ucstring colName, uint &colIndex) + bool findCol(const ucstring &colName, uint &colIndex) { if (Data.empty()) return false; - TWorksheet::TRow::iterator it = std::find(Data[0].begin(), Data[0].end(), ucstring(colName)); + TWorksheet::TRow::iterator it = std::find(Data[0].begin(), Data[0].end(), colName); if (it == Data[0].end()) return false; diff --git a/code/nel/include/nel/misc/i_xml.h b/code/nel/include/nel/misc/i_xml.h index e988375f7..7d2ff86b7 100644 --- a/code/nel/include/nel/misc/i_xml.h +++ b/code/nel/include/nel/misc/i_xml.h @@ -71,7 +71,7 @@ struct EXmlParsingError : public EStream // File not found } } - catch (Exception &e) + catch (const Exception &e) { // Something wrong appends } diff --git a/code/nel/include/nel/misc/o_xml.h b/code/nel/include/nel/misc/o_xml.h index af4e830ff..bbaa2e951 100644 --- a/code/nel/include/nel/misc/o_xml.h +++ b/code/nel/include/nel/misc/o_xml.h @@ -64,7 +64,7 @@ namespace NLMISC { // Close the file file.close (); } - catch (Exception &e) + catch (const Exception &e) { } \endcode diff --git a/code/nel/include/nel/misc/sha1.h b/code/nel/include/nel/misc/sha1.h index 6a32d47e3..d0bee0cd9 100644 --- a/code/nel/include/nel/misc/sha1.h +++ b/code/nel/include/nel/misc/sha1.h @@ -105,4 +105,7 @@ CHashKey getSHA1(const std::string &filename, bool forcePath = false); // This function get a buffer with size and returns his SHA hash key CHashKey getSHA1(const uint8 *buffer, uint32 size); +// This function get a buffer and key with size and returns his HMAC-SHA1 hash key +CHashKey getHMacSHA1(const uint8 *text, uint32 text_len, const uint8 *key, uint32 key_len); + #endif // NL_SHA1_H diff --git a/code/nel/include/nel/misc/smart_ptr.h b/code/nel/include/nel/misc/smart_ptr.h index 50fbf4a4a..81b5c0e75 100644 --- a/code/nel/include/nel/misc/smart_ptr.h +++ b/code/nel/include/nel/misc/smart_ptr.h @@ -352,7 +352,7 @@ public: } }; -#if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +#if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) // This operator only purpose is to compare with NULL value template diff --git a/code/nel/include/nel/misc/sstring.h b/code/nel/include/nel/misc/sstring.h index 7b4fa717d..513c681c9 100644 --- a/code/nel/include/nel/misc/sstring.h +++ b/code/nel/include/nel/misc/sstring.h @@ -945,10 +945,13 @@ inline CSString operator+(const char* s0,const CSString& s1) return CSString(s0)+s1; } +#ifndef NL_COMP_VC10 +// TODO: check if it can be disabled for other compilers too inline CSString operator+(const std::string& s0,const CSString& s1) { return s0+static_cast(s1); } +#endif // NL_COMP_VC10 } // NLMISC diff --git a/code/nel/include/nel/misc/types_nl.h b/code/nel/include/nel/misc/types_nl.h index 04b56f63e..08db88924 100644 --- a/code/nel/include/nel/misc/types_nl.h +++ b/code/nel/include/nel/misc/types_nl.h @@ -51,14 +51,10 @@ # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0500 // Minimal OS = Windows 2000 (NeL is not supported on Windows 95/98) # endif -# if _MSC_VER >= 1500 +# if _MSC_VER >= 1600 +# define NL_COMP_VC10 +# elif _MSC_VER >= 1500 # define NL_COMP_VC9 -# ifndef _STLPORT_VERSION // STLport doesn't depend on MS STL features -# if defined(_HAS_TR1) && (_HAS_TR1 + 0) // VC9 TR1 feature pack -# define NL_ISO_STDTR1_AVAILABLE -# define NL_ISO_STDTR1_HEADER(header)
-# endif -# endif # elif _MSC_VER >= 1400 # define NL_COMP_VC8 # undef nl_time @@ -79,6 +75,10 @@ # define NL_COMP_VC6 # define NL_COMP_NEED_PARAM_ON_METHOD # endif +# if defined(_HAS_TR1) && (_HAS_TR1 + 0) // VC9 TR1 feature pack or later +# define NL_ISO_STDTR1_AVAILABLE +# define NL_ISO_STDTR1_HEADER(header)
+# endif # ifdef _DEBUG # define NL_DEBUG # elif defined (NDEBUG) @@ -117,6 +117,10 @@ # define NL_COMP_GCC #endif +#if defined(_HAS_CPP0X) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define NL_ISO_CPP0X_AVAILABLE +#endif + // gcc 3.4 introduced ISO C++ with tough template rules // // NL_ISO_SYNTAX can be used using #if NL_ISO_SYNTAX or #if !NL_ISO_SYNTAX @@ -149,7 +153,7 @@ # pragma warning (disable : 4390) // don't warn in empty block "if(exp) ;" # pragma warning (disable : 4996) // 'vsnprintf': This function or variable may be unsafe. Consider using vsnprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. // Debug : Sept 01 2006 -# if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +# if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) # pragma warning (disable : 4005) // don't warn on redefinitions caused by xp platform sdk # endif // NL_COMP_VC8 || NL_COMP_VC9 #endif // NL_OS_WINDOWS @@ -287,20 +291,18 @@ typedef unsigned int uint; // at least 32bits (depend of processor) #define __STDC_FORMAT_MACROS #include -#ifdef NL_OS_MAC -#define NL_I64 __PRI_64_LENGTH_MODIFIER__ +#if defined(__PRI_64_LENGTH_MODIFIER__) +# define NL_I64 __PRI_64_LENGTH_MODIFIER__ +#elif defined(__PRI64_PREFIX) +# define NL_I64 __PRI64_PREFIX #else -#define NL_I64 __PRI64_PREFIX +# ifdef _LP64 +# define NL_I64 "l" +# else +# define NL_I64 "ll" +# endif // _LP64 #endif -/* -#ifdef _LP64 -# define NL_I64 "l" -#else -# define NL_I64 "ll" -#endif // _LP64 -*/ - #endif // NL_OS_UNIX // CHashMap, CHashSet and CHashMultiMap definitions @@ -364,7 +366,7 @@ typedef uint16 ucchar; // To define a 64bits constant; ie: UINT64_CONSTANT(0x123456781234) #ifdef NL_OS_WINDOWS -# if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +# if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) # define INT64_CONSTANT(c) (c##LL) # define SINT64_CONSTANT(c) (c##LL) # define UINT64_CONSTANT(c) (c##LL) diff --git a/code/nel/include/nel/net/module.h b/code/nel/include/nel/net/module.h index 70f11f1bc..62d2a0baf 100644 --- a/code/nel/include/nel/net/module.h +++ b/code/nel/include/nel/net/module.h @@ -524,7 +524,7 @@ namespace NLNET // run the module task command control to module task method (_Module->*_TaskMethod)(); } - catch (NLMISC::Exception e) + catch (const NLMISC::Exception &e) { nlwarning("In module task '%s', exception '%e' thrown", typeid(this).name(), e.what()); } diff --git a/code/nel/samples/3d/cluster_viewer/main.cpp b/code/nel/samples/3d/cluster_viewer/main.cpp index bc314e43a..b77a0d669 100644 --- a/code/nel/samples/3d/cluster_viewer/main.cpp +++ b/code/nel/samples/3d/cluster_viewer/main.cpp @@ -94,7 +94,7 @@ CInstanceGroup* LoadInstanceGroup(const char* sFilename) newIG->serial (file); // All is good } - catch (Exception &) + catch (const Exception &) { // Cannot save the file delete newIG; diff --git a/code/nel/samples/3d/font/main.cpp b/code/nel/samples/3d/font/main.cpp index 1a417cae7..e834c4620 100644 --- a/code/nel/samples/3d/font/main.cpp +++ b/code/nel/samples/3d/font/main.cpp @@ -42,7 +42,6 @@ using namespace std; using namespace NL3D; using namespace NLMISC; - #ifdef NL_OS_WINDOWS int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, @@ -139,7 +138,7 @@ int main(int argc, char **argv) tc.setScaleX (scale); tc.setScaleZ (scale); tc.printAt (0.1f, 0.3f, string("printAt Scale String")); - + // display the same string with no scale tc.setHotSpot (CComputedString::TopLeft); tc.setScaleX (1.0f); diff --git a/code/nel/samples/misc/configfile/main.cpp b/code/nel/samples/misc/configfile/main.cpp index f5a3fd472..c23acd652 100644 --- a/code/nel/samples/misc/configfile/main.cpp +++ b/code/nel/samples/misc/configfile/main.cpp @@ -116,7 +116,7 @@ int main (int /* argc */, char ** /* argv */) int val = cf.getVar ("unknown_variable").asInt(); nlinfo("unknown_variable = %d", val); } - catch (EConfigFile &e) + catch (const EConfigFile &e) { nlinfo("something goes wrong with configfile: %s", e.what()); } diff --git a/code/nel/samples/misc/debug/main.cpp b/code/nel/samples/misc/debug/main.cpp index 9d17d158c..84f712c6a 100644 --- a/code/nel/samples/misc/debug/main.cpp +++ b/code/nel/samples/misc/debug/main.cpp @@ -63,7 +63,7 @@ int main (int /* argc */, char ** /* argv */) { nlerror ("nlerror() %d", 4); } - catch(EFatalError &) + catch(const EFatalError &) { // just continue... nlinfo ("nlerror() generated an EFatalError exception, just ignore it"); diff --git a/code/nel/samples/net/chat/client.cpp b/code/nel/samples/net/chat/client.cpp index a22843c0c..c2aee8c86 100644 --- a/code/nel/samples/net/chat/client.cpp +++ b/code/nel/samples/net/chat/client.cpp @@ -109,7 +109,7 @@ int main (int argc, char **argv) CInetAddress addr(LSHost+":3333"); Client->connect(addr); } - catch(ESocket &e) + catch(const ESocket &e) { printf("%s\n", e.what()); return 0; diff --git a/code/nel/samples/net/login_system/frontend_service.cpp b/code/nel/samples/net/login_system/frontend_service.cpp index 189bbaf67..e71e935bf 100644 --- a/code/nel/samples/net/login_system/frontend_service.cpp +++ b/code/nel/samples/net/login_system/frontend_service.cpp @@ -101,7 +101,7 @@ public: { fsPort = IService::ConfigFile.getVar("FSPort").asInt(); } - catch ( EUnknownVar& ) + catch (const EUnknownVar&) { } _FServer.init(fsPort); @@ -148,7 +148,7 @@ public: { fesPort = IService5::ConfigFile.getVar("FESPort").asInt(); } - catch ( EUnknownVar& ) + catch (const EUnknownVar&) { } diff --git a/code/nel/samples/net/udp/bench_service.cpp b/code/nel/samples/net/udp/bench_service.cpp index 0b8db1a71..40786dd26 100644 --- a/code/nel/samples/net/udp/bench_service.cpp +++ b/code/nel/samples/net/udp/bench_service.cpp @@ -190,7 +190,7 @@ void cbInit (CMessage &msgin, TSockId from, CCallbackNetBase &netbase) return; } } - catch (Exception &) + catch (const Exception &) { // bad client version, disconnect it CallbackServer->disconnect (from); @@ -530,7 +530,7 @@ void handleReceivedPong (CClient *client, sint64 pongTime) // init the UDP connection if (client == NULL) { - uint32 session; + uint32 session = 0; msgin.serial (session); // Find a new udp connection, find the linked @@ -568,13 +568,13 @@ void handleReceivedPong (CClient *client, sint64 pongTime) } // Read the message - sint64 pingTime; + sint64 pingTime = 0; msgin.serial(pingTime); - uint32 pongNumber; + uint32 pongNumber = 0; msgin.serial(pongNumber); - uint32 blockNumber; + uint32 blockNumber = 0; msgin.serial(blockNumber); // nlinfo ("receive a pong from %s pongnb %d %"NL_I64"d", CurrentInMsg->AddrFrom.asString().c_str(), pongNumber, pongTime - pingTime); @@ -611,7 +611,7 @@ void sendPing () // send the new ping to the client ReceiveTask->DataSock->sendTo (msgout.buffer(), size, GETCLIENTA(it)->Address); } - catch (Exception &e) + catch (const Exception &e) { nlwarning ("Can't send UDP packet to '%s' (%s)", GETCLIENTA(it)->Address.asString().c_str(), e.what()); } @@ -734,7 +734,7 @@ public: updateStat (); } } - catch (Exception &e) + catch (const Exception &e) { nlerrornoex ("Exception not catched: '%s'", e.what()); } diff --git a/code/nel/samples/net/udp/client.cpp b/code/nel/samples/net/udp/client.cpp index 749797368..dbf15c11d 100644 --- a/code/nel/samples/net/udp/client.cpp +++ b/code/nel/samples/net/udp/client.cpp @@ -232,7 +232,7 @@ void cbInit (CMessage &msgin, TSockId from, CCallbackNetBase &netbase) { UdpSock->connect( CInetAddress (ServerAddr, UDPPort) ); } - catch ( Exception& e ) + catch (const Exception &e) { InfoLog->displayRawNL ("Cannot connect to remote UDP host '%s': %s", ServerAddr.c_str(), e.what() ); exit (""); @@ -291,7 +291,7 @@ int main( int argc, char **argv ) InfoLog->displayRawNL ("Waiting the server answer..."); } - catch(Exception &e) + catch(const Exception &e) { InfoLog->displayRawNL ("Can't connect to %s:%d (%s)\n", ServerAddr.c_str(), TCPPort, e.what()); exit (""); diff --git a/code/nel/samples/net/udp/receive_task.cpp b/code/nel/samples/net/udp/receive_task.cpp index 70276180c..bdfabbe29 100644 --- a/code/nel/samples/net/udp/receive_task.cpp +++ b/code/nel/samples/net/udp/receive_task.cpp @@ -108,7 +108,7 @@ void CReceiveTask::run() DataSock->receivedFrom( _ReceivedMessage.userDataW(), _DatagramLength, _ReceivedMessage.AddrFrom ); d = CTime::getLocalTime (); } - catch ( ESocket& ) + catch (const ESocket&) { // Remove the client corresponding to the address _ReceivedMessage.setTypeEvent( TReceivedMessage::RemoveClient ); diff --git a/code/nel/samples/pacs/main.cpp b/code/nel/samples/pacs/main.cpp index d3d87a938..fcbd7d8a9 100644 --- a/code/nel/samples/pacs/main.cpp +++ b/code/nel/samples/pacs/main.cpp @@ -371,7 +371,7 @@ int main () // Remove mouse listener pDriver->delete3dMouseListener (plistener); } - catch (Exception& e) + catch (const Exception& e) { #ifdef NL_OS_WINDOWS ::MessageBox (NULL, e.what(), "Test collision move", MB_OK|MB_ICONEXCLAMATION); diff --git a/code/nel/samples/sound_sources/main.cpp b/code/nel/samples/sound_sources/main.cpp index 50d28de6a..fb6753f63 100644 --- a/code/nel/samples/sound_sources/main.cpp +++ b/code/nel/samples/sound_sources/main.cpp @@ -85,7 +85,7 @@ void Init() AudioMixer->getListener()->setOrientation( frontvec, upvec ); } - catch( Exception& e ) + catch(const Exception &e) { nlerror( "Error: %s", e.what() ); } diff --git a/code/nel/src/3d/animation_set.cpp b/code/nel/src/3d/animation_set.cpp index 940592396..ec034e300 100644 --- a/code/nel/src/3d/animation_set.cpp +++ b/code/nel/src/3d/animation_set.cpp @@ -227,7 +227,7 @@ bool CAnimationSet::loadFromFiles(const std::string &path, bool recurse /* = tru iFile.close(); } - catch (NLMISC::EStream &e) + catch (const NLMISC::EStream &e) { if (wantWarningMessage) { diff --git a/code/nel/src/3d/async_file_manager_3d.cpp b/code/nel/src/3d/async_file_manager_3d.cpp index 7fbb170d1..382dc0039 100644 --- a/code/nel/src/3d/async_file_manager_3d.cpp +++ b/code/nel/src/3d/async_file_manager_3d.cpp @@ -338,7 +338,7 @@ void CAsyncFileManager3D::CMeshLoad::run() // Finally affect the pointer (Trans-Thread operation -> this operation must be atomic) *_ppShp = mesh.getShapePointer(); } - catch(EPathNotFound &) + catch(const EPathNotFound &) { nlwarning ("Couldn't load '%s'", MeshName.c_str()); *_ppShp = (IShape*)-1; @@ -382,7 +382,7 @@ void CAsyncFileManager3D::CIGLoad::run (void) *_ppIG = pIG; } - catch(EPathNotFound &) + catch(const EPathNotFound &) { nlwarning ("Couldn't load '%s'", _IGName.c_str()); *_ppIG = (CInstanceGroup*)-1; @@ -429,7 +429,7 @@ void CAsyncFileManager3D::CIGLoadUser::run (void) return; } } - catch(EPathNotFound &) + catch(const EPathNotFound &) { nlwarning ("Couldn't load '%s'", _IGName.c_str()); delete pIG; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index e05e52e7c..5ac1d2906 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -1600,7 +1600,7 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r _EventEmitter.addEmitter(diee, true); } } - catch(EDirectInput &e) + catch(const EDirectInput &e) { nlinfo(e.what()); } diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp index e64585ad7..eaae085f9 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp @@ -485,7 +485,7 @@ NLMISC::IMouseDevice* CDriverD3D::enableLowLevelMouse(bool enable, bool exclusiv if (diee) res = diee->getMouseDevice(exclusive); } - catch (EDirectInput &) + catch (const EDirectInput &) { } } @@ -517,7 +517,7 @@ NLMISC::IKeyboardDevice* CDriverD3D::enableLowLevelKeyboard(bool enable) if (diee) res = diee->getKeyboardDevice(); } - catch (EDirectInput &) + catch (const EDirectInput &) { } } @@ -561,7 +561,7 @@ uint CDriverD3D::getDoubleClickDelay(bool hardwareMouse) { md = diee->getMouseDevice(hardwareMouse); } - catch (EDirectInput &) + catch (const EDirectInput &) { // could not get device .. } diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp index 8a9e864cc..a4ccb437a 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp @@ -318,7 +318,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) if (!mat._MatDrvInfo) { // Insert into driver list. (so it is deleted when driver is deleted). - ItMatDrvInfoPtrList it= _MatDrvInfos.insert(_MatDrvInfos.end(), NULL); + ItMatDrvInfoPtrList it= _MatDrvInfos.insert(_MatDrvInfos.end(), (NL3D::IMaterialDrvInfos*)NULL); *it = mat._MatDrvInfo = new CMaterialDrvInfosD3D(this, it); diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp index 445b52451..5f1c1bc43 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp @@ -347,7 +347,7 @@ bool CDriverD3D::activeShader(CShader *shd) if ( !shd->_DrvInfo ) { // insert into driver list. (so it is deleted when driver is deleted). - ItShaderDrvInfoPtrList it= _ShaderDrvInfos.insert(_ShaderDrvInfos.end(), NULL); + ItShaderDrvInfoPtrList it= _ShaderDrvInfos.insert(_ShaderDrvInfos.end(), (NL3D::IShaderDrvInfos*)NULL); // create and set iterator, for future deletion. shaderInfo = new CShaderDrvInfosD3D(this, it); *it= shd->_DrvInfo = shaderInfo; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp index 0c10a3eb8..94615628b 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp @@ -514,7 +514,7 @@ bool CDriverD3D::setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded if ( !tex.TextureDrvShare ) { // insert into driver list. (so it is deleted when driver is deleted). - ItTexDrvSharePtrList it= _TexDrvShares.insert(_TexDrvShares.end(), NULL); + ItTexDrvSharePtrList it= _TexDrvShares.insert(_TexDrvShares.end(), (NL3D::CTextureDrvShare*)NULL); // create and set iterator, for future deletion. *it= tex.TextureDrvShare= new CTextureDrvShare(this, it, &tex); diff --git a/code/nel/src/3d/driver/opengl/CMakeLists.txt b/code/nel/src/3d/driver/opengl/CMakeLists.txt index 25216998c..6fdecab71 100644 --- a/code/nel/src/3d/driver/opengl/CMakeLists.txt +++ b/code/nel/src/3d/driver/opengl/CMakeLists.txt @@ -1,4 +1,5 @@ FILE(GLOB SRC *.cpp *.h *.def) + IF(APPLE) FILE(GLOB MAC_SRC mac/*.h mac/*.m mac/*.mm mac/*.cpp) SET(SRC ${SRC} ${MAC_SRC}) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 02ba70993..f222dc5a7 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -2508,8 +2508,13 @@ void CDriverGL::checkTextureOn() const GLboolean flagCM; GLboolean flagTR; glGetBooleanv(GL_TEXTURE_2D, &flag2D); +#ifdef USE_OPENGLES + glGetBooleanv(GL_TEXTURE_CUBE_MAP_OES, &flagCM); + flagTR = true; // always true in OpenGL ES +#else glGetBooleanv(GL_TEXTURE_CUBE_MAP_ARB, &flagCM); glGetBooleanv(GL_TEXTURE_RECTANGLE_NV, &flagTR); +#endif switch(dgs.getTextureMode()) { case CDriverGLStates::TextureDisabled: @@ -2545,7 +2550,8 @@ bool CDriverGL::supportOcclusionQuery() const // *************************************************************************** bool CDriverGL::supportTextureRectangle() const { - H_AUTO_OGL(CDriverGL_supportTextureRectangle) + H_AUTO_OGL(CDriverGL_supportTextureRectangle); + return (_Extensions.NVTextureRectangle || _Extensions.EXTTextureRectangle || _Extensions.ARBTextureRectangle); } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension_def.h b/code/nel/src/3d/driver/opengl/driver_opengl_extension_def.h index decd4a0c5..c1ecfe8c0 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension_def.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension_def.h @@ -20,22 +20,67 @@ #include "nel/misc/types_nl.h" -#ifdef NL_OS_MAC -# define GL_GLEXT_LEGACY -# include -# include "mac/glext.h" +#ifdef USE_OPENGLES +# include +# include #else -# include -# include // Please download it from http://www.opengl.org/registry/ -# if defined(NL_OS_WINDOWS) -# include -# endif +# ifdef NL_OS_MAC +# define GL_GLEXT_LEGACY +# include +# include "mac/glext.h" +# else +# include +# include +# if defined(NL_OS_WINDOWS) +# include +# endif +# endif #endif #ifdef __cplusplus extern "C" { #endif +#ifdef USE_OPENGLES +// OES_mapbuffer +//============== +typedef void* (APIENTRY * NEL_PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRY * NEL_PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (APIENTRY * NEL_PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void** params); + +typedef void (APIENTRY * NEL_PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); + +// GL_OES_framebuffer_object +//================================== +typedef GLboolean (APIENTRY * NEL_PFNGLISRENDERBUFFEROESPROC) (GLuint renderbuffer); +typedef void (APIENTRY * NEL_PFNGLBINDRENDERBUFFEROESPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRY * NEL_PFNGLDELETERENDERBUFFERSOESPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (APIENTRY * NEL_PFNGLGENRENDERBUFFERSOESPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (APIENTRY * NEL_PFNGLRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRY * NEL_PFNGLGETRENDERBUFFERPARAMETERIVOESPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (APIENTRY * NEL_PFNGLISFRAMEBUFFEROESPROC) (GLuint framebuffer); +typedef void (APIENTRY * NEL_PFNGLBINDFRAMEBUFFEROESPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRY * NEL_PFNGLDELETEFRAMEBUFFERSOESPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (APIENTRY * NEL_PFNGLGENFRAMEBUFFERSOESPROC) (GLsizei n, GLuint* framebuffers); +typedef GLenum (APIENTRY * NEL_PFNGLCHECKFRAMEBUFFERSTATUSOESPROC) (GLenum target); +typedef void (APIENTRY * NEL_PFNGLFRAMEBUFFERRENDERBUFFEROESPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRY * NEL_PFNGLFRAMEBUFFERTEXTURE2DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRY * NEL_PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (APIENTRY * NEL_PFNGLGENERATEMIPMAPOESPROC) (GLenum target); + +// GL_OES_texture_cube_map +//================================== +typedef void (APIENTRY * NEL_PFNGLTEXGENFOESPROC) (GLenum coord, GLenum pname, GLfloat param); +typedef void (APIENTRY * NEL_PFNGLTEXGENFVOESPROC) (GLenum coord, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * NEL_PFNGLTEXGENIOESPROC) (GLenum coord, GLenum pname, GLint param); +typedef void (APIENTRY * NEL_PFNGLTEXGENIVOESPROC) (GLenum coord, GLenum pname, const GLint *params); +typedef void (APIENTRY * NEL_PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); +typedef void (APIENTRY * NEL_PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params); +typedef void (APIENTRY * NEL_PFNGLGETTEXGENFVOESPROC) (GLenum coord, GLenum pname, GLfloat *params); +typedef void (APIENTRY * NEL_PFNGLGETTEXGENIVOESPROC) (GLenum coord, GLenum pname, GLint *params); +typedef void (APIENTRY * NEL_PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params); +#endif + // *************************************************************************** // *************************************************************************** // The NEL Functions Typedefs. diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp index b957b372a..acfdac253 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp @@ -684,7 +684,7 @@ NLMISC::IMouseDevice* CDriverGL::enableLowLevelMouse(bool enable, bool exclusive if (diee) res = diee->getMouseDevice(exclusive); } - catch (EDirectInput &) + catch (const EDirectInput &) { } } @@ -722,7 +722,7 @@ NLMISC::IKeyboardDevice* CDriverGL::enableLowLevelKeyboard(bool enable) if (diee) res = diee->getKeyboardDevice(); } - catch (EDirectInput &) + catch (const EDirectInput &) { } } @@ -778,7 +778,7 @@ uint CDriverGL::getDoubleClickDelay(bool hardwareMouse) { md = diee->getMouseDevice(hardwareMouse); } - catch (EDirectInput &) + catch (const EDirectInput &) { // could not get device .. } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp index 073d39176..e5c3cff6e 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp @@ -139,8 +139,13 @@ void CDriverGL::setLightInternal(uint8 num, const CLight& light) else { // Deactivate spot properties +#ifdef USE_OPENGLES + glLightf (lightNum, GL_SPOT_CUTOFF, 180.f); + glLightf (lightNum, GL_SPOT_EXPONENT, 0.f); +#else glLighti (lightNum, GL_SPOT_CUTOFF, 180); glLighti (lightNum, GL_SPOT_EXPONENT, 0); +#endif } // Flag this light as dirt. diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp index 569aceb0c..4fe6e8c71 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp @@ -35,10 +35,18 @@ static void convBlend(CMaterial::TBlend blend, GLenum& glenum) case CMaterial::srccolor: glenum=GL_SRC_COLOR; break; case CMaterial::invsrccolor:glenum=GL_ONE_MINUS_SRC_COLOR; break; // Extended Blend modes. +#ifdef USE_OPENGLES + case CMaterial::blendConstantColor: glenum=GL_CONSTANT_COLOR; break; + case CMaterial::blendConstantInvColor: glenum=GL_ONE_MINUS_CONSTANT_COLOR; break; + case CMaterial::blendConstantAlpha: glenum=GL_CONSTANT_ALPHA; break; + case CMaterial::blendConstantInvAlpha: glenum=GL_ONE_MINUS_CONSTANT_ALPHA; break; +#else case CMaterial::blendConstantColor: glenum=GL_CONSTANT_COLOR_EXT; break; case CMaterial::blendConstantInvColor: glenum=GL_ONE_MINUS_CONSTANT_COLOR_EXT; break; case CMaterial::blendConstantAlpha: glenum=GL_CONSTANT_ALPHA_EXT; break; case CMaterial::blendConstantInvAlpha: glenum=GL_ONE_MINUS_CONSTANT_ALPHA_EXT; break; +#endif + default: nlstop; } } @@ -137,7 +145,9 @@ void CDriverGL::setTextureEnvFunction(uint stage, CMaterial& mat) _DriverGLStates.setTexGenMode (stage, GL_OBJECT_LINEAR); } else if(mode==CMaterial::TexCoordGenEyeSpace) + { _DriverGLStates.setTexGenMode (stage, GL_EYE_LINEAR); + } } else { @@ -240,7 +250,9 @@ void CDriverGL::setTextureShaders(const uint8 *addressingModes, const CSmartPtr< if (glAddrMode != _CurrentTexAddrMode[stage]) // addressing mode different from the one in the device? { _DriverGLStates.activeTextureARB(stage); +#ifndef USE_OPENGLES glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, glAddrMode); +#endif _CurrentTexAddrMode[stage] = glAddrMode; } } @@ -264,7 +276,7 @@ bool CDriverGL::setupMaterial(CMaterial& mat) if (!mat._MatDrvInfo) { // insert into driver list. (so it is deleted when driver is deleted). - ItMatDrvInfoPtrList it= _MatDrvInfos.insert(_MatDrvInfos.end(), NULL); + ItMatDrvInfoPtrList it= _MatDrvInfos.insert(_MatDrvInfos.end(), (NL3D::IMaterialDrvInfos*)NULL); // create and set iterator, for future deletion. *it= mat._MatDrvInfo= new CShaderGL(this, it); @@ -807,7 +819,7 @@ void CDriverGL::setupLightMapPass(uint pass) // fallBack if extension MulAdd not found. just mul factor with (Ambient+Diffuse) if(_LightMapNoMulAddFallBack) { - // do not use consant color to blend lightmap, but incoming diffuse color, for stage0 only. + // do not use constant color to blend lightmap, but incoming diffuse color, for stage0 only. GLfloat glcol[4]; convColor(lmapFactor, glcol); _DriverGLStates.setEmissive(lmapFactor.getPacked(), glcol); @@ -918,7 +930,11 @@ void CDriverGL::setupLightMapPass(uint pass) if (mat._LightMapsMulx2) { // Multiply x 2 +#ifdef USE_OPENGLES + glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 2); +#else glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2); +#endif } } } @@ -1027,7 +1043,11 @@ void CDriverGL::endLightMapMultiPass() for (uint32 i = 0; i < (_NLightMapPerPass+1); ++i) { _DriverGLStates.activeTextureARB(i); +#ifdef USE_OPENGLES + glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1); +#else glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1); +#endif } } } @@ -1102,13 +1122,16 @@ void CDriverGL::setupSpecularBegin() // todo hulud remove // _DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap); +#ifdef USE_OPENGLES + _DriverGLStates.setTexGenMode (1, GL_REFLECTION_MAP_OES); +#else _DriverGLStates.setTexGenMode (1, GL_REFLECTION_MAP_ARB); +#endif + // setup the good matrix for stage 1. glMatrixMode(GL_TEXTURE); glLoadMatrixf( _SpecularTexMtx.get() ); glMatrixMode(GL_MODELVIEW); - - } // *************************************************************************** @@ -1292,7 +1315,8 @@ void CDriverGL::setupSpecularPass(uint pass) _DriverGLStates.setTextureMode(CDriverGLStates::TextureDisabled); } else - { // Multiply texture1 by alpha_texture0 and display with add + { + // Multiply texture1 by alpha_texture0 and display with add _DriverGLStates.enableBlend(true); _DriverGLStates.blendFunc(GL_ONE, GL_ONE); @@ -1957,7 +1981,9 @@ void CDriverGL::endCloudMultiPass() nlassert(_CurrentMaterial->getShader() == CMaterial::Cloud); if (ATICloudShaderHandle) { +#ifndef USE_OPENGLES glDisable(GL_FRAGMENT_SHADER_ATI); +#endif } } @@ -1975,7 +2001,9 @@ sint CDriverGL::beginWaterMultiPass() */ void CDriverGL::setupWaterPassR200(const CMaterial &mat) { - H_AUTO_OGL(CDriverGL_setupWaterPassR200) + H_AUTO_OGL(CDriverGL_setupWaterPassR200); + +#ifndef USE_OPENGLES uint k; ITexture *tex = mat.getTexture(0); if (tex) @@ -2047,6 +2075,7 @@ void CDriverGL::setupWaterPassR200(const CMaterial &mat) float cst[4] = { 1.f, 1.f, 1.f, 0.f }; nglSetFragmentShaderConstantATI(GL_CON_0_ATI, cst); } +#endif } // *************************************************************************** @@ -2054,7 +2083,9 @@ void CDriverGL::setupWaterPassR200(const CMaterial &mat) */ void CDriverGL::setupWaterPassARB(const CMaterial &mat) { - H_AUTO_OGL(CDriverGL_setupWaterPassARB) + H_AUTO_OGL(CDriverGL_setupWaterPassARB); + +#ifndef USE_OPENGLES uint k; ITexture *tex = mat.getTexture(0); if (tex) @@ -2133,6 +2164,7 @@ void CDriverGL::setupWaterPassARB(const CMaterial &mat) } } } +#endif } // *************************************************************************** @@ -2159,8 +2191,9 @@ static const float IdentityTexMat[4] = { 1.f, 0.f, 0.f, 1.f }; // *************************************************************************** void CDriverGL::setupWaterPassNV20(const CMaterial &mat) { - H_AUTO_OGL(CDriverGL_setupWaterPassNV20) + H_AUTO_OGL(CDriverGL_setupWaterPassNV20); +#ifndef USE_OPENGLES static bool setupDone = false; static CMaterial::CTexEnv texEnvReplace; static CMaterial::CTexEnv texEnvModulate; @@ -2245,6 +2278,7 @@ void CDriverGL::setupWaterPassNV20(const CMaterial &mat) activateTexEnvMode(2, texEnvReplace); activateTexEnvMode(3, texEnvModulate); } +#endif } // *************************************************************************** @@ -2272,7 +2306,9 @@ void CDriverGL::setupWaterPass(uint /* pass */) // *************************************************************************** void CDriverGL::endWaterMultiPass() { - H_AUTO_OGL(CDriverGL_endWaterMultiPass) + H_AUTO_OGL(CDriverGL_endWaterMultiPass); + +#ifndef USE_OPENGLES nlassert(_CurrentMaterial->getShader() == CMaterial::Water); // NB : as fragment shaders / programs bypass the texture envs, no special env enum is added (c.f CTexEnvSpecial) if (_Extensions.NVTextureShader) return; @@ -2284,6 +2320,7 @@ void CDriverGL::endWaterMultiPass() { glDisable(GL_FRAGMENT_SHADER_ATI); } +#endif } } // NL3D diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_matrix.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_matrix.cpp index 0e5cea073..4106c38f2 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_matrix.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_matrix.cpp @@ -15,24 +15,35 @@ // along with this program. If not, see . #include "stdopengl.h" - #include "driver_opengl.h" + namespace NL3D { // *************************************************************************** void CDriverGL::setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective) { - H_AUTO_OGL(CDriverGL_setFrustum) + H_AUTO_OGL(CDriverGL_setFrustum); + glMatrixMode(GL_PROJECTION); glLoadIdentity(); + if (perspective) { +#ifdef USE_OPENGLES + glFrustumf(left,right,bottom,top,znear,zfar); +#else glFrustum(left,right,bottom,top,znear,zfar); +#endif } else { +#ifdef USE_OPENGLES + glOrthof(left,right,bottom,top,znear,zfar); +#else glOrtho(left,right,bottom,top,znear,zfar); +#endif } + _ProjMatDirty = true; // Backup znear and zfar for zbias setup diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp index fb4f14dc2..cf30758dc 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp @@ -77,7 +77,8 @@ void CDriverGLStates::init(bool supportTextureCubeMap, bool supportTextureRect // *************************************************************************** void CDriverGLStates::forceDefaults(uint nbStages) { - H_AUTO_OGL(CDriverGLStates_forceDefaults) + H_AUTO_OGL(CDriverGLStates_forceDefaults); + // Enable / disable. _CurFog= false; _CurBlend= false; @@ -86,6 +87,7 @@ void CDriverGLStates::forceDefaults(uint nbStages) _CurLighting= false; _CurZWrite= true; _CurStencilTest=false; + // setup GLStates. glDisable(GL_FOG); glDisable(GL_BLEND); @@ -144,33 +146,62 @@ void CDriverGLStates::forceDefaults(uint nbStages) for(stage=0;stage +#ifdef USE_OPENGLES +# include #else -# include +# ifdef NL_OS_MAC +# define GL_GLEXT_LEGACY +# include +# else +# include +# endif #endif @@ -41,7 +45,7 @@ namespace NL3D - GL_ALPHA_TEST - GL_LIGHTING - GL_LIGHT0 + i ..... - - GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP_ARB. + - GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP_ARB/OES. - GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_T, GL_TEXTURE_GEN_R - GL_COLOR_MATERIAL - GL_FOG diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index 6079dc6f3..315c9ee2a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -155,7 +155,11 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex) // check status GLenum status; +#ifdef USE_OPENGLES + status = (GLenum) nglCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); +#else status = (GLenum) nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); +#endif switch(status) { case GL_FRAMEBUFFER_COMPLETE_EXT: InitFBO = true; @@ -197,19 +201,31 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex) break; #endif default: - nlwarning("Framebuffer incomplete\n"); + nlwarning("Framebuffer incomplete status %d", (sint)status); //nlassert(0); } // clean up resources if allocation failed if (!InitFBO) { +#ifdef USE_OPENGLES + nglDeleteFramebuffersOES(1, &FBOId); +#else nglDeleteFramebuffersEXT(1, &FBOId); +#endif if (AttachDepthStencil) { +#ifdef USE_OPENGLES + nglDeleteRenderbuffersOES(1, &DepthFBOId); +#else nglDeleteRenderbuffersEXT(1, &DepthFBOId); +#endif if(!UsePackedDepthStencil) +#ifdef USE_OPENGLES + nglDeleteRenderbuffersOES(1, &StencilFBOId); +#else nglDeleteRenderbuffersEXT(1, &StencilFBOId); +#endif } } @@ -226,14 +242,22 @@ bool CTextureDrvInfosGL::activeFrameBufferObject(ITexture * tex) if(initFrameBufferObject(tex)) { glBindTexture(TextureMode, 0); +#ifdef USE_OPENGLES + nglBindFramebufferOES(GL_FRAMEBUFFER_OES, FBOId); +#else nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOId); +#endif } else return false; } else { +#ifdef USE_OPENGLES + nglBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); +#else nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +#endif } return true; @@ -481,7 +505,7 @@ static inline GLenum translateMinFilterToGl(CTextureDrvInfosGL *glText) // *************************************************************************** static inline bool sameDXTCFormat(ITexture &tex, GLint glfmt) { - H_AUTO_OGL(sameDXTCFormat) + H_AUTO_OGL(sameDXTCFormat); if(glfmt==GL_COMPRESSED_RGB_S3TC_DXT1_EXT && tex.PixelFormat==CBitmap::DXTC1) return true; if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && tex.PixelFormat==CBitmap::DXTC1Alpha) @@ -497,7 +521,7 @@ static inline bool sameDXTCFormat(ITexture &tex, GLint glfmt) // *************************************************************************** static inline bool isDXTCFormat(GLint glfmt) { - H_AUTO_OGL(isDXTCFormat) + H_AUTO_OGL(isDXTCFormat); if(glfmt==GL_COMPRESSED_RGB_S3TC_DXT1_EXT) return true; if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) @@ -602,7 +626,7 @@ bool CDriverGL::setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded, { //nldebug("3D: creating CTextureDrvShare()"); // insert into driver list. (so it is deleted when driver is deleted). - ItTexDrvSharePtrList it= _TexDrvShares.insert(_TexDrvShares.end(), NULL); + ItTexDrvSharePtrList it= _TexDrvShares.insert(_TexDrvShares.end(), (NL3D::CTextureDrvShare*)NULL); // create and set iterator, for future deletion. *it= tex.TextureDrvShare= new CTextureDrvShare(this, it, &tex); @@ -840,8 +864,13 @@ bool CDriverGL::setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded, sint size= tex.getPixels(i).size(); if (bUpload) { +#ifdef USE_OPENGLES + glCompressedTexImage2D (GL_TEXTURE_2D, i-decalMipMapResize, glfmt, + tex.getWidth(i),tex.getHeight(i), 0, size, ptr); +#else nglCompressedTexImage2DARB (GL_TEXTURE_2D, i-decalMipMapResize, glfmt, tex.getWidth(i),tex.getHeight(i), 0, size, ptr); +#endif bAllUploaded = true; } else diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp index d739aea0b..502c971f1 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp @@ -140,7 +140,7 @@ bool CDriverGL::setupVertexBuffer(CVertexBuffer& VB) // 1. Retrieve/Create driver shader. //================================== // insert into driver list. (so it is deleted when driver is deleted). - ItVBDrvInfoPtrList it= _VBDrvInfos.insert(_VBDrvInfos.end(), NULL); + ItVBDrvInfoPtrList it= _VBDrvInfos.insert(_VBDrvInfos.end(), (NL3D::IVBDrvInfos*)NULL); // create and set iterator, for future deletion. CVBDrvInfosGL *info = new CVBDrvInfosGL(this, it, &VB); *it= VB.DrvInfos = info; @@ -280,8 +280,12 @@ bool CDriverGL::renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines) } else { +#ifdef USE_OPENGLES + nlerror("not available in OpenGL ES 1.0, only use 16 bits indices"); +#else nlassert(_LastIB._Format == CIndexBuffer::Indices32); glDrawElements(GL_LINES,2*nlines,GL_UNSIGNED_INT,((uint32 *) _LastIB._Values)+firstIndex); +#endif } } } @@ -336,8 +340,12 @@ bool CDriverGL::renderTriangles(CMaterial& mat, uint32 firstIndex, uint32 ntris) } else { +#ifdef USE_OPENGLES + nlerror("not available in OpenGL ES 1.0, only use 16 bits indices"); +#else nlassert(_LastIB._Format == CIndexBuffer::Indices32); glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_INT, ((uint32 *) _LastIB._Values)+firstIndex); +#endif } } } @@ -380,8 +388,12 @@ bool CDriverGL::renderSimpleTriangles(uint32 firstTri, uint32 ntris) } else { +#ifdef USE_OPENGLES + nlerror("not available in OpenGL ES 1.0, only use 16 bits indices"); +#else nlassert(_LastIB._Format == CIndexBuffer::Indices32); glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_INT, ((uint32 *) _LastIB._Values)+firstTri); +#endif } // Profiling. @@ -608,6 +620,9 @@ bool CDriverGL::renderRawQuads(CMaterial& mat, uint32 startIndex, uint32 numQuad } else { +#ifdef USE_OPENGLES + nlerror("not available in OpenGL ES 1.0, only use 16 bits indices"); +#else // indices fits on 32 bits GLint indices[QUAD_BATCH_SIZE]; GLint *curr = indices; @@ -625,6 +640,7 @@ bool CDriverGL::renderRawQuads(CMaterial& mat, uint32 startIndex, uint32 numQuad } while(curr != end); glDrawElements(GL_TRIANGLES, 6 * numQuadsToDraw, GL_UNSIGNED_INT, indices); +#endif } numLeftQuads -= numQuadsToDraw; currIndex += 4 * numQuadsToDraw; @@ -665,10 +681,12 @@ void CDriverGL::setupUVPtr(uint stage, CVertexBufferInfo &VB, uint uvId) // Setup ATI VBHard or std ptr. switch(VB.VBMode) { +#ifndef USE_OPENGLES case CVertexBufferInfo::HwATI: nglArrayObjectATI(GL_TEXTURE_COORD_ARRAY, numTexCoord, GL_FLOAT, VB.VertexSize, VB.VertexObjectId, (ptrdiff_t) VB.ValuePtr[CVertexBuffer::TexCoord0+uvId]); break; +#endif case CVertexBufferInfo::HwARB: _DriverGLStates.bindARBVertexBuffer(VB.VertexObjectId); // with arb buffers, position is relative to the start of the stream @@ -811,6 +829,21 @@ const uint CDriverGL::NumCoordinatesType[CVertexBuffer::NumType]= // *************************************************************************** const uint CDriverGL::GLType[CVertexBuffer::NumType]= { +#ifdef USE_OPENGLES + GL_FLOAT, // Double1 + GL_FLOAT, // Float1 + GL_SHORT, // Short1 + GL_FLOAT, // Double2 + GL_FLOAT, // Float2 + GL_SHORT, // Short2 + GL_FLOAT, // Double3 + GL_FLOAT, // Float3 + GL_SHORT, // Short3 + GL_FLOAT, // Double4 + GL_FLOAT, // Float4 + GL_SHORT, // Short4 + GL_UNSIGNED_BYTE // UChar4 +#else GL_DOUBLE, // Double1 GL_FLOAT, // Float1 GL_SHORT, // Short1 @@ -824,6 +857,7 @@ const uint CDriverGL::GLType[CVertexBuffer::NumType]= GL_FLOAT, // Float4 GL_SHORT, // Short4 GL_UNSIGNED_BYTE // UChar4 +#endif }; // *************************************************************************** @@ -926,6 +960,7 @@ void CDriverGL::setupGlArraysStd(CVertexBufferInfo &vb) } } break; +#ifndef USE_OPENGLES case CVertexBufferInfo::HwATI: { // setup vertex ptr. @@ -963,9 +998,12 @@ void CDriverGL::setupGlArraysStd(CVertexBufferInfo &vb) nglArrayObjectATI(GL_COLOR_ARRAY, 4, GL_UNSIGNED_BYTE, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::PrimaryColor]); } else + { _DriverGLStates.enableColorArray(false); + } } break; +#endif default: nlassert(0); break; @@ -1035,7 +1073,9 @@ void CDriverGL::toggleGlArraysForARBVertexProgram() // If last was a VertexProgram setup, and now it is a standard GL array setup. if( _LastSetupGLArrayVertexProgram && !isVertexProgramEnabled () ) { +#ifndef USE_OPENGLES if (_Extensions.ATITextureEnvCombine3) +#endif { // fix for ATI : when switching from Vertex Program to fixed Pipe, must clean texture, otherwise texture may be disabled in next render // (seems to be a driver bug) @@ -1046,12 +1086,16 @@ void CDriverGL::toggleGlArraysForARBVertexProgram() // activate the texture, or disable texturing if NULL. activateTexture(stage, NULL); } + +#ifndef USE_OPENGLES glBegin(GL_QUADS); glVertex4f(0.f, 0.f, 0.f, 1.f); glVertex4f(0.f, 0.f, 0.f, 1.f); glVertex4f(0.f, 0.f, 0.f, 1.f); glVertex4f(0.f, 0.f, 0.f, 1.f); glEnd(); +#endif + for(uint stage=0 ; stage_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID); switch(_VBType) { case CVertexBuffer::AGPPreferred: +#ifdef USE_OPENGLES + glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); +#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB); +#endif break; case CVertexBuffer::StaticPreferred: if (_Driver->getStaticMemoryToVRAM()) +#ifdef USE_OPENGLES + glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW); +#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STATIC_DRAW_ARB); +#endif else +#ifdef USE_OPENGLES + glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); +#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB); +#endif break; default: nlassert(0); @@ -1230,7 +1248,12 @@ IVertexBufferHardGL *CVertexArrayRangeARB::createVBHardGL(uint size, CVertexBuff } if (glGetError() != GL_NO_ERROR) { +#ifdef USE_OPENGLES + glDeleteBuffers(1, &vertexBufferID); +#else nglDeleteBuffersARB(1, &vertexBufferID); +#endif + return false; } CVertexBufferHardARB *newVbHard= new CVertexBufferHardARB(_Driver, vb); @@ -1272,8 +1295,13 @@ void CVertexArrayRangeARB::updateLostBuffers() { nlassert((*it)->_VertexObjectId); GLuint id = (GLuint) (*it)->_VertexObjectId; +#ifdef USE_OPENGLES + nlassert(glIsBuffer(id)); + glDeleteBuffers(1, &id); +#else nlassert(nglIsBufferARB(id)); nglDeleteBuffersARB(1, &id); +#endif (*it)->_VertexObjectId = 0; (*it)->VB->setLocation(CVertexBuffer::NotResident); } @@ -1300,6 +1328,12 @@ CVertexBufferHardARB::CVertexBufferHardARB(CDriverGL *drv, CVertexBuffer *vb) : #ifdef NL_DEBUG _Unmapping = false; #endif + +#ifdef USE_OPENGLES + _Buffer = NULL; + _BufferSize = 0; + _LastBufferSize = 0; +#endif } // *************************************************************************** @@ -1316,8 +1350,13 @@ CVertexBufferHardARB::~CVertexBufferHardARB() if (_VertexObjectId) { GLuint id = (GLuint) _VertexObjectId; +#ifdef USE_OPENGLES + nlassert(glIsBuffer(id)); + glDeleteBuffers(1, &id); +#else nlassert(nglIsBufferARB(id)); nglDeleteBuffersARB(1, &id); +#endif } if (_VertexArrayRange) { @@ -1336,12 +1375,21 @@ CVertexBufferHardARB::~CVertexBufferHardARB() _VertexArrayRange->_MappedVBList.erase(_IteratorInMappedVBList); } #endif + +#ifdef USE_OPENGLES + if (_Buffer) + { + delete [] _Buffer; + _Buffer = NULL; + } +#endif } // *************************************************************************** void *CVertexBufferHardARB::lock() { - H_AUTO_OGL(CVertexBufferHardARB_lock) + H_AUTO_OGL(CVertexBufferHardARB_lock); + if (_VertexPtr) return _VertexPtr; // already locked if (_Invalid) { @@ -1352,7 +1400,13 @@ void *CVertexBufferHardARB::lock() } // recreate a vb GLuint vertexBufferID; + +#ifdef USE_OPENGLES + glGenBuffers(1, &vertexBufferID); +#else nglGenBuffersARB(1, &vertexBufferID); +#endif + if (glGetError() != GL_NO_ERROR) { _Driver->incrementResetCounter(); @@ -1363,13 +1417,25 @@ void *CVertexBufferHardARB::lock() switch(_MemType) { case CVertexBuffer::AGPPreferred: +#ifdef USE_OPENGLES + glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); +#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB); +#endif break; case CVertexBuffer::StaticPreferred: if (_Driver->getStaticMemoryToVRAM()) +#ifdef USE_OPENGLES + glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW); +#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STATIC_DRAW_ARB); +#endif else +#ifdef USE_OPENGLES + glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); +#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB); +#endif break; default: nlassert(0); @@ -1378,7 +1444,11 @@ void *CVertexBufferHardARB::lock() if (glGetError() != GL_NO_ERROR) { _Driver->incrementResetCounter(); +#ifdef USE_OPENGLES + glDeleteBuffers(1, &vertexBufferID); +#else nglDeleteBuffersARB(1, &vertexBufferID); +#endif return &_DummyVB[0];; } _VertexObjectId = vertexBufferID; @@ -1394,6 +1464,39 @@ void *CVertexBufferHardARB::lock() beforeLock= CTime::getPerformanceTime(); } _Driver->_DriverGLStates.bindARBVertexBuffer(_VertexObjectId); + +#ifdef USE_OPENGLES + if (_Driver->_Extensions.OESMapBuffer) + { + _VertexPtr = nglMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); + if (!_VertexPtr) + { + nglUnmapBufferOES(GL_ARRAY_BUFFER); + nlassert(glIsBuffer(_VertexObjectId)); + invalidate(); + return &_DummyVB[0]; + } + } + else + { + const uint size = VB->getNumVertices() * VB->getVertexSize(); + + if (size > _BufferSize) + { + if (_Buffer) delete [] _Buffer; + + _Buffer = new uint8[size+3]; + _BufferSize = size; + } + + uint8 offset = (size_t)_Buffer % 4; + + if (offset > 0) offset = 4 - offset; + + _VertexPtr = _Buffer + offset; + _LastBufferSize = size; + } +#else _VertexPtr = nglMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); if (!_VertexPtr) { @@ -1402,6 +1505,8 @@ void *CVertexBufferHardARB::lock() invalidate(); return &_DummyVB[0]; } +#endif + #ifdef NL_DEBUG _VertexArrayRange->_MappedVBList.push_front(this); _IteratorInMappedVBList = _VertexArrayRange->_MappedVBList.begin(); @@ -1420,7 +1525,8 @@ void *CVertexBufferHardARB::lock() // *************************************************************************** void CVertexBufferHardARB::unlock() { - H_AUTO_OGL(CVertexBufferHardARB_unlock) + H_AUTO_OGL(CVertexBufferHardARB_unlock); + _VertexPtr = NULL; if (_Invalid) return; if (!_VertexObjectId) return; @@ -1434,7 +1540,17 @@ void CVertexBufferHardARB::unlock() #ifdef NL_DEBUG _Unmapping = true; #endif - GLboolean unmapOk = nglUnmapBufferARB(GL_ARRAY_BUFFER_ARB); + GLboolean unmapOk = false; + +#ifdef USE_OPENGLES + if (_Driver->_Extensions.OESMapBuffer) + { + unmapOk = nglUnmapBufferOES(GL_ARRAY_BUFFER); + } +#else + unmapOk = nglUnmapBufferARB(GL_ARRAY_BUFFER_ARB); +#endif + #ifdef NL_DEBUG _Unmapping = false; #endif diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.h b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.h index a2b7111f4..da454c558 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.h @@ -113,7 +113,7 @@ protected: bool _Invalid; }; - +#ifndef USE_OPENGLES // *************************************************************************** // *************************************************************************** @@ -456,6 +456,8 @@ public: #endif }; +#endif + // *************************************************************************** // *************************************************************************** // ARB_vertex_buffer_object implementation @@ -553,6 +555,11 @@ private: CVertexArrayRangeARB *_VertexArrayRange; CVertexBuffer::TPreferredMemory _MemType; void *_VertexPtr; // pointer on current datas. Null if not locked +#ifdef USE_OPENGLES + uint8 *_Buffer; + uint32 _BufferSize; + uint32 _LastBufferSize; +#endif // if buffer has been invalidated, returns a dummy memory block and silently fails rendering std::vector _DummyVB; // for use by CVertexArrayRangeARB diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp index 4c255e1d9..4915ed1d4 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp @@ -111,7 +111,7 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) } // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), NULL); + ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); @@ -309,7 +309,7 @@ static uint convInputRegisterToVBFlag(uint index) // For debugging with swizzling static void doSwizzle(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW) { - H_AUTO_OGL(doSwizzle) + H_AUTO_OGL(doSwizzle); nglSwizzleEXT(res, in, outX, outY, outZ, outW); #ifdef DEBUG_SETUP_EXT_VERTEX_SHADER std::string swzStr = "Swizzle : "; @@ -359,7 +359,7 @@ static void doSwizzle(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum ou // Perform write mask and output de bug information static void doWriteMask(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW) { - H_AUTO_OGL(doWriteMask) + H_AUTO_OGL(doWriteMask); nglWriteMaskEXT(res, in, outX, outY, outZ, outW); #ifdef DEBUG_SETUP_EXT_VERTEX_SHADER nlinfo("3D: Write Mask : %c%c%c%c", @@ -376,7 +376,7 @@ static void doWriteMask(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum */ bool CDriverGL::setupEXTVertexShader(const CVPParser::TProgram &program, GLuint id, uint variants[EVSNumVariants], uint16 &usedInputRegisters) { - H_AUTO_OGL(CDriverGL_setupEXTVertexShader) + H_AUTO_OGL(CDriverGL_setupEXTVertexShader); // counter to see what is generated uint numOp = 0; uint numOpIndex = 0; @@ -1440,6 +1440,14 @@ bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgra nlassert(0); return false; } + +#ifdef NL_OS_MAC + // Wait for GPU to finish program upload, else draw comands might crash. + // Happened to CVegetableBlendLayerModel (glDrawElements()). + // For more information, see http://dev.ryzom.com/issues/1006 + glFinish(); +#endif + return true; } @@ -1472,7 +1480,7 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) return false; } // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), NULL); + ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); @@ -1554,7 +1562,7 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) */ // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), NULL); + ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 48af6cf05..6501d70c4 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -374,18 +374,25 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc) } #endif // HAVE_XRENDER - // list all supported extensions - sint nextensions = 0; - char **extensions = XListExtensions(_dpy, &nextensions); + nldebug("3D: Available X Extensions:"); - std::string exts; + if (DebugLog) + { + // list all supported extensions + sint nextensions = 0; + char **extensions = XListExtensions(_dpy, &nextensions); - for(sint i = 0; i < nextensions; ++i) - exts += NLMISC::toString(" %s", extensions[i]); + for(sint i = 0; i < nextensions; ++i) + { + if(i%5==0) DebugLog->displayRaw("3D: "); + DebugLog->displayRaw(NLMISC::toString("%s ", extensions[i]).c_str()); + if(i%5==4) DebugLog->displayRaw("\n"); + } - XFreeExtensionList(extensions); + DebugLog->displayRaw("\n"); - nlinfo("X Extensions:%s", exts.c_str()); + XFreeExtensionList(extensions); + } // set default X errors handler XSetErrorHandler(nelXErrorsHandler); @@ -906,7 +913,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re _hRC=wglCreateContext(_hDC); wglMakeCurrent(_hDC,_hRC); - } /// release old emitter @@ -929,7 +935,7 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re _EventEmitter.addEmitter(diee, true); } } - catch(EDirectInput &e) + catch(const EDirectInput &e) { nlinfo(e.what()); } @@ -1577,7 +1583,7 @@ bool CDriverGL::destroyWindow() #elif defined(NL_OS_MAC) - if(_DestroyWindow) + if (_DestroyWindow) { [[containerView() window] release]; [containerView() release]; @@ -2297,7 +2303,7 @@ emptyProc CDriverGL::getWindowProc() // -------------------------------------------------- bool CDriverGL::activate() { - H_AUTO_OGL(CDriverGL_activate) + H_AUTO_OGL(CDriverGL_activate); if (_win == EmptyWindow) return false; @@ -2376,11 +2382,15 @@ void CDriverGL::getWindowSize(uint32 &width, uint32 &height) if (_CurrentMode.OffScreen) { #ifdef NL_OS_WINDOWS + +#ifndef USE_OPENGLES if (_PBuffer) { nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_WIDTH_ARB, (int*)&width ); nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_HEIGHT_ARB, (int*)&height ); } +#endif + #endif } else diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp index 525a59171..95c713021 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp @@ -359,7 +359,7 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) // push the key press event to the event server server->postEvent(new NLMISC::CEventKeyDown( virtualKeycodeToNelKey([event keyCode]), - modifierFlagsToNelKeyButton([event modifierFlags]), + modifiers, [event isARepeat] == NO, this)); // if this was a text event @@ -372,7 +372,7 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) // push the text event to event server as well server->postEvent(new NLMISC::CEventChar( - ucstr[0], NLMISC::noKeyButton, this)); + ucstr[0], modifiers, this)); } break; } @@ -381,7 +381,7 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) // push the key release event to the event server server->postEvent(new NLMISC::CEventKeyUp( virtualKeycodeToNelKey([event keyCode]), - modifierFlagsToNelKeyButton([event modifierFlags]), this)); + modifiers, this)); break; } case NSFlagsChanged:break; diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index 220536c4a..118e02141 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -1746,7 +1746,7 @@ void CDriverUser::loadHLSBank(const std::string &fileName) throw EPathNotFound(path); fIn.serial(*hlsBank); } - catch(Exception &) + catch(const Exception &) { delete hlsBank; throw; diff --git a/code/nel/src/3d/fasthls_modifier.cpp b/code/nel/src/3d/fasthls_modifier.cpp index 6f90e574a..fb3fdd31d 100644 --- a/code/nel/src/3d/fasthls_modifier.cpp +++ b/code/nel/src/3d/fasthls_modifier.cpp @@ -109,7 +109,7 @@ CRGBA CFastHLSModifier::convert(uint H, uint L, uint S) return col; } -#if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +#if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) # pragma warning( push ) # pragma warning( disable : 4799 ) #endif @@ -262,7 +262,7 @@ uint16 CFastHLSModifier::applyHLSMod(uint16 colorIn, uint8 dHue, uint dLum, uin #pragma managed(pop) #endif -#if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +#if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) # pragma warning( pop ) #endif diff --git a/code/nel/src/3d/instance_group_user.cpp b/code/nel/src/3d/instance_group_user.cpp index 3e79f3c15..722d867da 100644 --- a/code/nel/src/3d/instance_group_user.cpp +++ b/code/nel/src/3d/instance_group_user.cpp @@ -121,7 +121,7 @@ bool CInstanceGroupUser::init (const std::string &instanceGroup, bool async) // Read the class _InstanceGroup.serial (file); } - catch (EStream& e) + catch (const EStream& e) { // Avoid visual warning EStream ee=e; diff --git a/code/nel/src/3d/landscape_user.cpp b/code/nel/src/3d/landscape_user.cpp index c088dcdb4..ed646470a 100644 --- a/code/nel/src/3d/landscape_user.cpp +++ b/code/nel/src/3d/landscape_user.cpp @@ -283,7 +283,7 @@ void CLandscapeUser::refreshZonesAround(const CVector &pos, float radius, std::s { _Landscape->Landscape.checkBinds(Work.Zone->getZoneId()); } - catch (EBadBind &e) + catch (const EBadBind &e) { nlwarning ("Bind error : %s", e.what()); nlstopex(("Zone Data Bind Error. Please send a report. You may continue but it should crash!")); diff --git a/code/nel/src/3d/mesh_mrm_skinned.cpp b/code/nel/src/3d/mesh_mrm_skinned.cpp index 8b7f1fa63..f1c49bd56 100644 --- a/code/nel/src/3d/mesh_mrm_skinned.cpp +++ b/code/nel/src/3d/mesh_mrm_skinned.cpp @@ -1867,7 +1867,7 @@ void CMeshMRMSkinnedGeom::updateRawSkinNormal(bool enabled, CMeshMRMSkinnedInst CIndexBufferReadWrite ibaWrite; skinLod.RdrPass[i].lock (ibaWrite); #ifndef NL_SKINNED_MESH_MRM_INDEX16 - nlassert(ibaWrite.getFormat() == CIndexBuffer::Indices32) + nlassert(ibaWrite.getFormat() == CIndexBuffer::Indices32); uint32 *dstTriPtr= (uint32 *) ibaWrite.getPtr(); uint32 numIndices= lod.RdrPass[i].PBlock.size(); for(uint j=0;j +#include // diff --git a/code/nel/src/3d/ps_mesh.cpp b/code/nel/src/3d/ps_mesh.cpp index ca354b09d..5cd61aa90 100644 --- a/code/nel/src/3d/ps_mesh.cpp +++ b/code/nel/src/3d/ps_mesh.cpp @@ -1291,7 +1291,7 @@ bool CPSConstraintMesh::update(std::vector *numVertsVect /*= NULL*/) { _ModelBank->load(_MeshShapeFileName[k]); } - catch (NLMISC::EPathNotFound &) + catch (const NLMISC::EPathNotFound &) { nlwarning("mesh not found : %s; used as a constraint mesh particle", _MeshShapeFileName[k].c_str()); // shape not found, so not present in the shape bank -> we create a dummy shape @@ -2083,8 +2083,9 @@ static void DuplicatePrimitiveBlock(const CIndexBuffer &srcBlock, CIndexBuffer & CIndexBufferReadWrite ibaWrite; destBlock.lock (ibaWrite); - +#ifdef NL_FORCE_INDEX_BUFFER_16 nlassert(destBlock.getFormat() == CIndexBuffer::Indices16); +#endif // TMP TMP TMP if (ibaRead.getFormat() == CIndexBuffer::Indices16) diff --git a/code/nel/src/3d/shader.cpp b/code/nel/src/3d/shader.cpp index 1872b8a4f..deddce762 100644 --- a/code/nel/src/3d/shader.cpp +++ b/code/nel/src/3d/shader.cpp @@ -93,7 +93,7 @@ bool CShader::loadShaderFile (const char *filename) nlwarning ("Can't open the file %s for reading", _filename.c_str()); } } - catch (Exception &e) + catch (const Exception &e) { nlwarning ("Error while reading %s : %s", _filename.c_str(), e.what()); } diff --git a/code/nel/src/3d/texture_grouped.cpp b/code/nel/src/3d/texture_grouped.cpp index fbe593d9d..c7dbe0033 100644 --- a/code/nel/src/3d/texture_grouped.cpp +++ b/code/nel/src/3d/texture_grouped.cpp @@ -50,12 +50,12 @@ static inline void GetTextureSize(ITexture *tex, uint &width, uint &height) width = srcWidth; height = srcHeight; } - catch (NLMISC::EPathNotFound &e) + catch (const NLMISC::EPathNotFound &e) { nlinfo("%s", e.what()); width = height = 0; } - catch (NLMISC::EStream &e) + catch (const NLMISC::EStream &e) { nlinfo("unable to load size from a bitmap ! name = %s", tf->getFileName().c_str()); nlinfo("reason = %s", e.what()); diff --git a/code/nel/src/3d/tile_bank.cpp b/code/nel/src/3d/tile_bank.cpp index 361b3ea83..1f50fa7b5 100644 --- a/code/nel/src/3d/tile_bank.cpp +++ b/code/nel/src/3d/tile_bank.cpp @@ -1573,7 +1573,7 @@ void CTileSet::loadTileVegetableDesc() // load the TileVegetableDesc f.serial(_TileVegetableDesc); } - catch(Exception &e) + catch(const Exception &e) { nlinfo("Error loading TileVegetableDesc: %s", e.what()); } diff --git a/code/nel/src/3d/vegetable_manager.cpp b/code/nel/src/3d/vegetable_manager.cpp index bb472e75a..a51e5c83e 100644 --- a/code/nel/src/3d/vegetable_manager.cpp +++ b/code/nel/src/3d/vegetable_manager.cpp @@ -816,7 +816,7 @@ CVegetableShape *CVegetableManager::getVegetableShape(const std::string &shap ret = NULL; } } - catch (Exception &e) + catch (const Exception &e) { // Warning nlwarning ("CVegetableManager::getVegetableShape error while loading shape file '%s' : '%s'", shape.c_str (), e.what ()); diff --git a/code/nel/src/3d/zone_lighter.cpp b/code/nel/src/3d/zone_lighter.cpp index 4f1e53385..980a83278 100644 --- a/code/nel/src/3d/zone_lighter.cpp +++ b/code/nel/src/3d/zone_lighter.cpp @@ -844,7 +844,7 @@ void SaveZBuffer (CZoneLighter::CZBuffer &zbuffer, const char *filename) // Save it bitmap.writeJPG (outputZFile, 128); } - catch (Exception& except) + catch (const Exception& except) { // Error message nlwarning ("ERROR writing %s: %s\n", filename, except.what()); @@ -3080,13 +3080,13 @@ void CZoneLighter::lightWater(CWaterShape &ws, const CMatrix &MT, const CLightDe diffuseTex->writeTGA(of, 24); of.close(); } - catch (NLMISC::Exception &) + catch (const NLMISC::Exception &) { nlwarning("Zone lighter : while lighting a water shape, writing %s failed! ", texFileName.c_str()); } } } - catch(NLMISC::Exception &e) + catch(const NLMISC::Exception &e) { nlwarning("Water shape lighting failed !"); nlwarning(e.what()); diff --git a/code/nel/src/georges/form_elm.cpp b/code/nel/src/georges/form_elm.cpp index 528f6eec9..6f2f4c523 100644 --- a/code/nel/src/georges/form_elm.cpp +++ b/code/nel/src/georges/form_elm.cpp @@ -233,6 +233,7 @@ const CType* CFormElm::getType () warning (false, "getType", "This node is not an atom."); return 0; } + // *************************************************************************** bool CFormElm::getValue (string &/* result */, TEval /* evaluate */) const diff --git a/code/nel/src/georges/form_loader.cpp b/code/nel/src/georges/form_loader.cpp index e3098709f..b7d4a522e 100644 --- a/code/nel/src/georges/form_loader.cpp +++ b/code/nel/src/georges/form_loader.cpp @@ -105,7 +105,7 @@ CType *CFormLoader::loadType (const char *filename) type = NULL; } } - catch (Exception &e) + catch (const Exception &e) { // Output error warning (false, "loadType", "Error while loading the form (%s): %s", filename, e.what()); @@ -179,7 +179,7 @@ CFormDfn *CFormLoader::loadFormDfn (const char *filename, bool forceLoad) _MapFormDfn.erase (lowerStr); } } - catch (Exception &e) + catch (const Exception &e) { // Output error warning (false, "loadFormDfn", "Error while loading the form (%s): %s", filename, e.what()); @@ -276,7 +276,7 @@ UForm *CFormLoader::loadForm (const char *filename) _MapForm.erase (lowerStr); } } - catch (Exception &e) + catch (const Exception &e) { // Output error warning (false, "loadForm", "Error while loading the form (%s): %s", filename, e.what()); diff --git a/code/nel/src/ligo/ligo_config.cpp b/code/nel/src/ligo/ligo_config.cpp index c61b03d03..1d062d109 100644 --- a/code/nel/src/ligo/ligo_config.cpp +++ b/code/nel/src/ligo/ligo_config.cpp @@ -220,7 +220,7 @@ bool CLigoConfig::readPrimitiveClass (const char *_fileName, bool parsePrimitive syntaxError (filename.c_str(), root, "Wrong root node, should be NEL_LIGO_PRIMITIVE_CLASS"); } } - catch (Exception &e) + catch (const Exception &e) { errorMessage ("File read error (%s):%s", filename.c_str(), e.what ()); } diff --git a/code/nel/src/ligo/zone_bank.cpp b/code/nel/src/ligo/zone_bank.cpp index 5f03c4bb5..28f30db4b 100644 --- a/code/nel/src/ligo/zone_bank.cpp +++ b/code/nel/src/ligo/zone_bank.cpp @@ -146,7 +146,7 @@ void CZoneBank::debugSaveInit (CZoneBankElement &zbeTmp, const string &fileName) output.init (&fileOut); zbeTmp.serial (output); } - catch (Exception& /*e*/) + catch (const Exception& /*e*/) { } @@ -541,7 +541,7 @@ bool CZoneBank::addElement (const std::string &elementName, std::string &error) error = "Can't open file " + elementName; } } - catch (Exception& e) + catch (const Exception& e) { error = "Error while loading ligozone "+elementName+" : "+e.what(); } diff --git a/code/nel/src/misc/command.cpp b/code/nel/src/misc/command.cpp index 313f36dcd..80d074386 100644 --- a/code/nel/src/misc/command.cpp +++ b/code/nel/src/misc/command.cpp @@ -188,7 +188,7 @@ bool ICommand::execute (const std::string &commandWithArgs, CLog &log, bool quie { return CCommandRegistry::getInstance().execute(commandWithArgs, log, quiet, human); } - catch(exception e) + catch(const exception &e) { log.displayNL("Command '%s' thrown an exception :", commandWithArgs.c_str()); log.displayNL(e.what()); diff --git a/code/nel/src/misc/config_file/cf_lexical.lpp b/code/nel/src/misc/config_file/cf_lexical.lpp index a6ced1449..0dbab0067 100644 --- a/code/nel/src/misc/config_file/cf_lexical.lpp +++ b/code/nel/src/misc/config_file/cf_lexical.lpp @@ -27,7 +27,10 @@ using namespace NLMISC; #define YY_NEVER_INTERACTIVE 1 #ifdef WIN32 +#define YY_NO_UNISTD_H 1 +#include #define read _read +#define isatty _isatty #endif /* Types */ @@ -122,6 +125,12 @@ string \"[^\"\n]*\" if (!cf_Ignore) { cflval.Val.Type = T_STRING; + if (strlen(yytext+1) >= sizeof(cflval.Val.String)) + { + strcpy (cflval.Val.String, ""); + DEBUG_PRINTF("lex: string '%s' exceeds max length\n", yytext); + return STRING; + } strcpy (cflval.Val.String, yytext+1); cflval.Val.String[strlen(cflval.Val.String)-1] = '\0'; DEBUG_PRINTF("lex: string '%s' '%s'\n", yytext, cflval.Val.String); @@ -133,6 +142,12 @@ string \"[^\"\n]*\" if (!cf_Ignore) { cflval.Val.Type = T_STRING; + if (strlen(yytext+1) >= sizeof(cflval.Val.String)) + { + strcpy (cflval.Val.String, ""); + DEBUG_PRINTF("lex: string '%s' exceeds max length\n", yytext); + return VARIABLE; + } strcpy (cflval.Val.String, yytext); DEBUG_PRINTF("lex: variable '%s' '%s'\n", yytext, cflval.Val.String); return VARIABLE; diff --git a/code/nel/src/misc/config_file/config_file.cpp b/code/nel/src/misc/config_file/config_file.cpp index f85469003..ebbce4867 100644 --- a/code/nel/src/misc/config_file/config_file.cpp +++ b/code/nel/src/misc/config_file/config_file.cpp @@ -832,7 +832,7 @@ void CConfigFile::checkConfigFiles () { (*it)->reparse (); } - catch (EConfigFile &e) + catch (const EConfigFile &e) { nlwarning ("CF: Exception will re-read modified config file '%s': %s", (*it)->getFilename().c_str(), e.what ()); } diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 472e2cd35..b6fc1d85c 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -969,14 +969,12 @@ void force_exception_frame(...) {std::cout.flush();} static void exceptionTranslator(unsigned, EXCEPTION_POINTERS *pexp) { #ifndef NL_NO_DEBUG_FILES - FILE *file = fopen ("exception_catched", "wb"); - fclose (file); + CFile::createEmptyFile(getLogDirectory() + "exception_catched"); #endif if (pexp->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) { #ifndef NL_NO_DEBUG_FILES - FILE *file2 = fopen ("breakpointed", "wb"); - fclose (file2); + CFile::createEmptyFile(getLogDirectory() + "breakpointed"); #endif return; } @@ -1018,7 +1016,7 @@ void getCallStack(std::string &result, sint skipNFirst) array[0] = skipNFirst; RaiseException (0xACE0ACE, 0, 1, array); } - catch (EDebug &e) + catch (const EDebug &e) { result += e.what(); } @@ -1053,7 +1051,7 @@ void getCallStackAndLog (string &result, sint /* skipNFirst */) // array[0] = skipNFirst; // RaiseException (0xACE0ACE, 0, 1, array); // } -// catch (EDebug &e) +// catch (const EDebug &e) // { // result += e.what(); // } @@ -1683,12 +1681,18 @@ NLMISC_CATEGORISED_COMMAND(nel, writeaccess, "write a uint8 value in an invalid uint8 val = 123; uint8 *adr = (uint8*)0; if(args.size() >= 1) + { #ifdef HAVE_X86_64 - adr = (uint8*)(uint64)atoi(args[0].c_str()); + uint64 addr64; + NLMISC::fromString(args[0], addr64); + adr = (uint8*)addr64; #else - adr = (uint8*)atoi(args[0].c_str()); + uint32 addr32; + NLMISC::fromString(args[0], addr32); + adr = (uint8*)addr32; #endif - if(args.size() >= 2) val = (uint8)atoi(args[1].c_str()); + } + if(args.size() >= 2) NLMISC::fromString(args[1], val); *adr = val; return true; } @@ -1698,11 +1702,17 @@ NLMISC_CATEGORISED_COMMAND(nel, readaccess, "read a uint8 value in an invalid ad uint8 val; uint8 *adr = (uint8*)0; if(args.size() == 1) + { #ifdef HAVE_X86_64 - adr = (uint8*)(uint64)atoi(args[0].c_str()); + uint64 addr64; + NLMISC::fromString(args[0], addr64); + adr = (uint8*)addr64; #else - adr = (uint8*)atoi(args[0].c_str()); + uint32 addr32; + NLMISC::fromString(args[0], addr32); + adr = (uint8*)addr32; #endif + } val = *adr; log.displayNL("value is %hu", (uint16)val); return true; diff --git a/code/nel/src/misc/diff_tool.cpp b/code/nel/src/misc/diff_tool.cpp index 27621748f..24d7bcc47 100644 --- a/code/nel/src/misc/diff_tool.cpp +++ b/code/nel/src/misc/diff_tool.cpp @@ -84,7 +84,7 @@ bool loadStringFile(const std::string filename, vector &stringInfos buffer = new uint8[size]; fp.serialBuffer(buffer, size); } - catch(Exception &e) + catch(const Exception &e) { nlinfo("Can't open file [%s] (%s)\n", filename.c_str(), e.what()); return true; diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index cc072fd20..c50935b8f 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -120,7 +120,7 @@ void IDisplayer::display ( const CLog::TDisplayInfo& args, const char *message ) { doDisplay( args, message ); } - catch (Exception &) + catch (const Exception &) { // silence } diff --git a/code/nel/src/misc/file.cpp b/code/nel/src/misc/file.cpp index 515c49014..eb1fa643a 100644 --- a/code/nel/src/misc/file.cpp +++ b/code/nel/src/misc/file.cpp @@ -365,7 +365,7 @@ void CIFile::getline (char *buffer, uint32 bufferSize) // read one byte serialBuffer ((uint8 *)buffer, 1); } - catch (EFile &) + catch (const EFile &) { *buffer = '\0'; return; diff --git a/code/nel/src/misc/inter_window_msg_queue.cpp b/code/nel/src/misc/inter_window_msg_queue.cpp index abdb84338..4cda83a04 100644 --- a/code/nel/src/misc/inter_window_msg_queue.cpp +++ b/code/nel/src/misc/inter_window_msg_queue.cpp @@ -419,7 +419,7 @@ namespace NLMISC } } } - catch(EStream &) + catch(const EStream &) { nlwarning("CInterWindowMsgQueue : Bad message format in inter window communication"); } diff --git a/code/nel/src/misc/sha1.cpp b/code/nel/src/misc/sha1.cpp index bb375a928..92929b469 100644 --- a/code/nel/src/misc/sha1.cpp +++ b/code/nel/src/misc/sha1.cpp @@ -187,6 +187,77 @@ CHashKey getSHA1(const string &filename, bool forcePath) return hk; } +/* +* +* HMAC = hash( (Key ^ 0x5c) .. hash( (Key ^0x36) .. Message ) ) +* +*/ + +CHashKey getHMacSHA1(const uint8 *text, uint32 text_len, const uint8 *key, uint32 key_len) +{ + SHA1Context sha; + + uint8_t SHA1_Key[64]; + uint8_t SHA1_Key1[20]; + uint8_t SHA1_Key2[20]; + + string buffer1; + string buffer2; + + // Init some vars + for (uint i = 0; i < 64; i++) + SHA1_Key[i] = 0; + + // If lenght of key > 64 use sha1 hash + if (key_len > 64) { + uint8_t SHA1_Key0[20]; + SHA1Reset(&sha); + SHA1Input(&sha, (const uint8_t*)key, key_len); + SHA1Result(&sha, SHA1_Key0); + CHashKey hk0 (SHA1_Key0); + for (uint i = 0; i < 20; i++) + SHA1_Key[i] = hk0.HashKeyString[i]; + } else { + for (uint i = 0; i < key_len; i++) + SHA1_Key[i] = key[i]; + } + + // Do 0x36 XOR Key + for (uint i = 0; i < 64; i++) + buffer1 += 0x36 ^ SHA1_Key[i]; + + // Append text + for (uint i = 0; i < text_len; i++) + buffer1 += text[i]; + + // Get hash + SHA1Reset(&sha); + SHA1Input(&sha, (const uint8_t*)buffer1.c_str(), (uint)buffer1.size()); + SHA1Result(&sha, SHA1_Key1); + CHashKey hk1 (SHA1_Key1); + + // Do 0x5c XOR Key + for (uint i = 0; i < 64; i++) + buffer2 += 0x5c ^ SHA1_Key[i]; + + // Append previous hash + for (uint i = 0; i < 20; i++) + buffer2 += hk1.HashKeyString[i]; + + // Get new hash + SHA1Reset(&sha); + SHA1Input(&sha, (const uint8_t*)buffer2.c_str(), (uint)buffer2.size()); + SHA1Result(&sha, SHA1_Key2); + CHashKey hk (SHA1_Key2); + + return hk; +} + + +#ifdef _MFC_VER + #pragma runtime_checks( "", off ) +#endif + /* * Define the SHA1 circular left shift macro */ diff --git a/code/nel/src/misc/shared_memory.cpp b/code/nel/src/misc/shared_memory.cpp index 60d63b7d7..bb19981eb 100644 --- a/code/nel/src/misc/shared_memory.cpp +++ b/code/nel/src/misc/shared_memory.cpp @@ -36,8 +36,8 @@ namespace NLMISC { // Storage for file handles, necessary to close the handles map AccessAddressesToHandles; #else - // Storage for shmid, necessary to destroy the segments - map SharedMemIdsToShmids; + // Storage for shmid, necessary to destroy the segments + map SharedMemIdsToShmids; #endif @@ -71,7 +71,7 @@ void *CSharedMemory::createSharedMemory( TSharedMemId sharedMemId, uint32 size #else // Create a shared memory segment - int shmid = shmget( sharedMemId, size, IPC_CREAT | IPC_EXCL | 0666 ); + sint shmid = shmget( sharedMemId, size, IPC_CREAT | IPC_EXCL | 0666 ); if ( shmid == -1 ) return NULL; SharedMemIdsToShmids.insert( make_pair( sharedMemId, shmid ) ); @@ -82,6 +82,7 @@ void *CSharedMemory::createSharedMemory( TSharedMemId sharedMemId, uint32 size return NULL; else return accessAddress; + #endif } diff --git a/code/nel/src/misc/system_info.cpp b/code/nel/src/misc/system_info.cpp index 97397f001..54273be94 100644 --- a/code/nel/src/misc/system_info.cpp +++ b/code/nel/src/misc/system_info.cpp @@ -66,15 +66,20 @@ namespace NLMISC { vector splitted; explode(string(buffer), string("\n"), splitted, true); + std::string value; + for(uint32 i = 0; i < splitted.size(); i++) { vector sline; explode(splitted[i], string(":"), sline, true); if(sline.size() == 2 && trim(sline[0]) == colname) { - return trim(sline[1]); + value = sline[1]; } } + + if (!value.empty()) + return trim(value); } nlwarning ("SI: Can't find the colname '%s' in /proc/cpuinfo", colname.c_str()); return ""; @@ -549,7 +554,7 @@ string CSystemInfo::getOS() { OSString += " Professional"; } - else + else { if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) OSString += " Datacenter Server"; @@ -805,6 +810,9 @@ string CSystemInfo::getProc () #elif defined NL_OS_UNIX + uint processors = 0; + if (fromString(getCpuInfo("processor"), processors)) ++processors; + ProcString = getCpuInfo("model name"); ProcString += " / ?"; ProcString += " Family " + getCpuInfo("cpu family"); @@ -815,7 +823,7 @@ string CSystemInfo::getProc () ProcString += " / "; ProcString += getCpuInfo("cpu MHz")+"MHz"; ProcString += " / "; - ProcString += "? Processors found"; + ProcString += toString("%u Processors found", processors); #endif diff --git a/code/nel/src/misc/words_dictionary.cpp b/code/nel/src/misc/words_dictionary.cpp index 687f9ea79..d3b32546d 100644 --- a/code/nel/src/misc/words_dictionary.cpp +++ b/code/nel/src/misc/words_dictionary.cpp @@ -55,7 +55,7 @@ bool CWordsDictionary::init( const string& configFileName ) cf.load( configFileName ); cfFound = true; } - catch ( EConfigFile& e ) + catch (const EConfigFile &e) { nlwarning( "WD: %s", e.what() ); } diff --git a/code/nel/src/net/buf_client.cpp b/code/nel/src/net/buf_client.cpp index 7866f81cc..7bf9a7b08 100644 --- a/code/nel/src/net/buf_client.cpp +++ b/code/nel/src/net/buf_client.cpp @@ -451,7 +451,7 @@ void CClientReceiveTask::run() NbLoop++; } - catch ( ESocket& ) + catch (const ESocket&) { LNETL1_DEBUG( "LNETL1: Client connection %s broken", sockId()->asString().c_str() ); sockId()->Sock->disconnect(); diff --git a/code/nel/src/net/buf_server.cpp b/code/nel/src/net/buf_server.cpp index 57df165c8..67fe4b84b 100644 --- a/code/nel/src/net/buf_server.cpp +++ b/code/nel/src/net/buf_server.cpp @@ -829,7 +829,7 @@ void CListenTask::run() NbLoop++; } - catch ( ESocket& e ) + catch (const ESocket &e) { LNETL1_INFO( "LNETL1: Exception in listen thread: %s", e.what() ); // It can occur when too many sockets are open (e.g. 885 connections) @@ -1131,12 +1131,12 @@ void CServerReceiveTask::run() */ } } -// catch ( ESocketConnectionClosed& ) +// catch (const ESocketConnectionClosed&) // { // LNETL1_DEBUG( "LNETL1: Connection %s closed", serverbufsock->asString().c_str() ); // // The socket went to _Connected=false when throwing the exception // } - catch ( ESocket& ) + catch (const ESocket&) { LNETL1_DEBUG( "LNETL1: Connection %s broken", serverbufsock->asString().c_str() ); (*ic)->Sock->disconnect(); diff --git a/code/nel/src/net/callback_client.cpp b/code/nel/src/net/callback_client.cpp index 6f6011f38..181f48c89 100644 --- a/code/nel/src/net/callback_client.cpp +++ b/code/nel/src/net/callback_client.cpp @@ -280,7 +280,7 @@ void CCallbackClient::connect( const CInetAddress& addr ) _MR_Recorder.recordNext( _MR_UpdateCounter, Connecting, _BufSock, addrmsg ); } } - catch ( ESocketConnectionFailed& ) + catch (const ESocketConnectionFailed&) { if ( _MR_RecordingState == Record ) { diff --git a/code/nel/src/net/callback_net_base.cpp b/code/nel/src/net/callback_net_base.cpp index 8620a75b3..24c2b9038 100644 --- a/code/nel/src/net/callback_net_base.cpp +++ b/code/nel/src/net/callback_net_base.cpp @@ -155,7 +155,7 @@ void CCallbackNetBase::processOneMessage () { receive (msgin, &tsid); } - catch (Exception &e) + catch (const Exception &e) { nlwarning(e.what()); return; diff --git a/code/nel/src/net/email.cpp b/code/nel/src/net/email.cpp index 313405983..efafe3e90 100644 --- a/code/nel/src/net/email.cpp +++ b/code/nel/src/net/email.cpp @@ -330,7 +330,7 @@ bool sendEmail (const string &smtpServer, const string &from, const string &to, ok = true; } } - catch (Exception &e) + catch (const Exception &e) { nlwarning ("EMAIL: Can't send email: %s", e.what()); goto end; diff --git a/code/nel/src/net/login_client.cpp b/code/nel/src/net/login_client.cpp index 550b620ee..9c34b41a3 100644 --- a/code/nel/src/net/login_client.cpp +++ b/code/nel/src/net/login_client.cpp @@ -146,7 +146,7 @@ string CLoginClient::authenticateBegin(const string &loginServiceAddr, const ucs _LSCallbackClient->disconnect(); _LSCallbackClient->connect (CInetAddress(addr)); } - catch (ESocket &e) + catch (const ESocket &e) { delete _LSCallbackClient; _LSCallbackClient = 0; @@ -226,7 +226,7 @@ string CLoginClient::connectToShard(CLoginCookie &lc, const std::string &addr, C // have we received the answer? if (!ShardValidate) return "FES disconnect me"; } - catch (ESocket &e) + catch (const ESocket &e) { return string("FES refused the connection (") + e.what () + ")"; } @@ -250,7 +250,7 @@ string CLoginClient::connectToShard (const std::string &addr, CUdpSock &cnx) // cnx.connect (CInetAddress(addr)); } - catch (ESocket &e) + catch (const ESocket &e) { return string("FES refused the connection (") + e.what () + ")"; } @@ -272,7 +272,7 @@ string CLoginClient::connectToShard (const std::string &addr, CUdpSimSock &cnx) // cnx.connect (CInetAddress(addr)); } - catch (ESocket &e) + catch (const ESocket &e) { return string("FES refused the connection (") + e.what () + ")"; } diff --git a/code/nel/src/net/login_server.cpp b/code/nel/src/net/login_server.cpp index 2ff2e3b88..38c3ec321 100644 --- a/code/nel/src/net/login_server.cpp +++ b/code/nel/src/net/login_server.cpp @@ -349,17 +349,17 @@ void CLoginServer::init (const string &listenAddress) try { cfcbDefaultUserPriv(IService::getInstance()->ConfigFile.getVar("DefaultUserPriv")); IService::getInstance()->ConfigFile.setCallback("DefaultUserPriv", cfcbDefaultUserPriv); - } catch(Exception &) { } + } catch(const Exception &) { } try { cfcbAcceptInvalidCookie (IService::getInstance()->ConfigFile.getVar("AcceptInvalidCookie")); IService::getInstance()->ConfigFile.setCallback("AcceptInvalidCookie", cfcbAcceptInvalidCookie); - } catch(Exception &) { } + } catch(const Exception &) { } try { cfcbTimeBeforeEraseCookie (IService::getInstance()->ConfigFile.getVar("TimeBeforeEraseCookie")); IService::getInstance()->ConfigFile.setCallback("TimeBeforeEraseCookie", cfcbTimeBeforeEraseCookie); - } catch(Exception &) { } + } catch(const Exception &) { } // setup the listen address diff --git a/code/nel/src/net/module.cpp b/code/nel/src/net/module.cpp index d09ed3084..41489abfb 100644 --- a/code/nel/src/net/module.cpp +++ b/code/nel/src/net/module.cpp @@ -330,7 +330,7 @@ namespace NLNET _onProcessModuleMessage(currentSender, currentMessage); _CurrentMessageFailed = false; } - catch (NLMISC::Exception e) + catch (const NLMISC::Exception &e) { nlwarning("In module task '%s' (cotask message receiver), exception '%e' thrown", typeid(this).name(), e.what()); // an exception have been thrown diff --git a/code/nel/src/net/module_gateway.cpp b/code/nel/src/net/module_gateway.cpp index 9f838afd1..efe29ae1b 100644 --- a/code/nel/src/net/module_gateway.cpp +++ b/code/nel/src/net/module_gateway.cpp @@ -109,7 +109,7 @@ namespace NLNET sd->serial(s); } } - catch(EStreamOverflow e) + catch(const EStreamOverflow &) { // FAILED to read the security block, rewind to old pos and serial as unknow nlwarning("Error while reading stream for security data type %u", dataTag); diff --git a/code/nel/src/net/module_gateway_transport.cpp b/code/nel/src/net/module_gateway_transport.cpp index 6088ab3e8..b839584d1 100644 --- a/code/nel/src/net/module_gateway_transport.cpp +++ b/code/nel/src/net/module_gateway_transport.cpp @@ -684,7 +684,7 @@ namespace NLNET route->CallbackClient.connect(addr); nldebug("CGatewayL3ClientTransport : Connected to %s with connId %u", addr.asString().c_str(), connId); } - catch (ESocketConnectionFailed e) + catch (const ESocketConnectionFailed &) { nlinfo("CGatewayL3ClientTransport : Failed to connect to server %s, retrying in %u seconds", addr.asString().c_str(), _RetryInterval); } diff --git a/code/nel/src/net/naming_client.cpp b/code/nel/src/net/naming_client.cpp index 5c735cf97..4aac61ea1 100644 --- a/code/nel/src/net/naming_client.cpp +++ b/code/nel/src/net/naming_client.cpp @@ -502,7 +502,7 @@ bool CNamingClient::lookupAndConnect (const std::string &name, CCallbackClient & // connection succeeded return true; } - catch (ESocketConnectionFailed &e) + catch (const ESocketConnectionFailed &e) { nldebug( "NC: Connection to %s failed: %s, tring another service if available", servaddr.asString().c_str(), e.what() ); diff --git a/code/nel/src/net/net_displayer.cpp b/code/nel/src/net/net_displayer.cpp index d9aff2a49..d2a354786 100644 --- a/code/nel/src/net/net_displayer.cpp +++ b/code/nel/src/net/net_displayer.cpp @@ -79,7 +79,7 @@ void CNetDisplayer::setLogServer (const CInetAddress& logServerAddr) { _Server->connect (_ServerAddr); } - catch( ESocket& ) + catch(const ESocket&) { // Silence } @@ -153,7 +153,7 @@ void CNetDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mess msg.serial( s ); _Server->send (msg, 0, false); } - catch( NLMISC::Exception& ) + catch(const NLMISC::Exception& ) { // Silence } diff --git a/code/nel/src/net/service.cpp b/code/nel/src/net/service.cpp index d59dbe5a8..8ed4c10c9 100644 --- a/code/nel/src/net/service.cpp +++ b/code/nel/src/net/service.cpp @@ -914,7 +914,7 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, // Get the localhost name localhost = CInetAddress::localHost().hostName(); } - catch (NLNET::ESocket &) + catch (const NLNET::ESocket &) { localhost = ""; } @@ -1091,7 +1091,7 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, return 10; } } - catch (ESocketConnectionFailed &) + catch (const ESocketConnectionFailed &) { nlinfo ("SERVICE: Could not connect to the Naming Service (%s). Retrying in a few seconds...", loc.asString().c_str()); nlSleep (5000); @@ -1495,13 +1495,13 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, MyTAT.deactivate(); } } - catch (EFatalError &) + catch (const EFatalError &) { // Somebody call nlerror, so we have to quit now, the message already display // so we don't have to to anything setExitStatus (EXIT_FAILURE); } - catch (ESocket &e) + catch (const ESocket &e) { // Catch NeL network exception to release the system cleanly setExitStatus (EXIT_FAILURE); ErrorLog->displayNL( "NeL Exception in \"%s\": %s", _ShortName.c_str(), e.what() ); @@ -1560,7 +1560,7 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, nlinfo ("SERVICE: Service released successfully"); } - catch (EFatalError &) + catch (const EFatalError &) { // Somebody call nlerror, so we have to quit now, the message already display // so we don't have to to anything diff --git a/code/nel/src/net/sock.cpp b/code/nel/src/net/sock.cpp index 475548821..e2a0c4205 100644 --- a/code/nel/src/net/sock.cpp +++ b/code/nel/src/net/sock.cpp @@ -22,10 +22,8 @@ #include "nel/misc/hierarchical_timer.h" #ifdef NL_OS_WINDOWS -# if defined(NL_COMP_VC7) || defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) -# include -# endif # define NOMINMAX +# include # include # define socklen_t int # define ERROR_NUM WSAGetLastError() diff --git a/code/nel/src/net/tcp_sock.cpp b/code/nel/src/net/tcp_sock.cpp index d51281db6..9773e0b00 100644 --- a/code/nel/src/net/tcp_sock.cpp +++ b/code/nel/src/net/tcp_sock.cpp @@ -20,9 +20,7 @@ #include "nel/net/net_log.h" #ifdef NL_OS_WINDOWS -# if defined(NL_COMP_VC7) || defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) -# include -# endif +# include # define NOMINMAX # include # define socklen_t int diff --git a/code/nel/src/net/transport_class.cpp b/code/nel/src/net/transport_class.cpp index 1d9796dd2..a5f826728 100644 --- a/code/nel/src/net/transport_class.cpp +++ b/code/nel/src/net/transport_class.cpp @@ -419,7 +419,7 @@ void getNameOfMessageOrTransportClass( NLNET::CMessage& msgin, std::string& msgN msgin.seek( msgin.getHeaderSize(), NLMISC::IStream::begin ); msgin.serial( msgName ); } - catch ( EStreamOverflow& ) + catch (const EStreamOverflow&) { msgName = ""; } diff --git a/code/nel/src/net/unified_network.cpp b/code/nel/src/net/unified_network.cpp index 8a1a87b85..d3b0d16fe 100644 --- a/code/nel/src/net/unified_network.cpp +++ b/code/nel/src/net/unified_network.cpp @@ -481,7 +481,7 @@ void CAliveCheck::run() CheckList[i].AddressValid = true; cbc.disconnect(); } - catch (ESocketConnectionFailed &e) + catch (const ESocketConnectionFailed &e) { #if FINAL_VERSION nlinfo ("HNETL5: can't connect to %s-%hu now (%s)", CheckList[i].ServiceName.c_str(), CheckList[i].ServiceId.get(), e.what ()); @@ -587,7 +587,7 @@ bool CUnifiedNetwork::init(const CInetAddress *addr, CCallbackNetBase::TRecordin { _CbServer->init(port); } - catch (ESocket &) + catch (const ESocket &) { nlwarning("Failed to init the listen socket on port %u, is the service already running ?", port); // wait a little before retrying @@ -866,7 +866,7 @@ void CUnifiedNetwork::addService(const string &name, const vector cbc->connect(addr[i]); connectSuccess = true; } - catch (ESocketConnectionFailed &e) + catch (const ESocketConnectionFailed &e) { nlwarning ("HNETL5: can't connect to %s (sid %u) now (%s) '%s'", name.c_str(), sid.get(), e.what (), addr[i].asString ().c_str()); connectSuccess = false; @@ -1010,7 +1010,7 @@ void CUnifiedNetwork::update(TTime timeout) laddr[i].setPort(_ServerPort); CNamingClient::resendRegisteration (_Name, laddr, _SId); } - catch (ESocketConnectionFailed &) + catch (const ESocketConnectionFailed &) { nlwarning ("HNETL5: Could not connect to the Naming Service (%s). Retrying in a few seconds...", _NamingServiceAddr.asString().c_str()); } @@ -1209,7 +1209,7 @@ void CUnifiedNetwork::autoReconnect( CUnifiedConnection &uc, uint connectionInde // call the user callback callServiceUpCallback (uc.ServiceName, uc.ServiceId); } - catch (ESocketConnectionFailed &e) + catch (const ESocketConnectionFailed &e) { #if FINAL_VERSION nlinfo ("HNETL5: can't connect to %s-%hu now (%s)", uc.ServiceName.c_str(), uc.ServiceId.get(), e.what ()); diff --git a/code/nel/src/pacs/global_retriever.cpp b/code/nel/src/pacs/global_retriever.cpp index c9ab8cd0c..936846dd2 100644 --- a/code/nel/src/pacs/global_retriever.cpp +++ b/code/nel/src/pacs/global_retriever.cpp @@ -387,7 +387,7 @@ void NLPACS::CGlobalRetriever::makeLinks(uint n) instance.link(neighbor, _RetrieverBank->getRetrievers()); neighbor.link(instance, _RetrieverBank->getRetrievers()); } - catch (Exception &e) + catch (const Exception &e) { nlwarning("in NLPACS::CGlobalRetriever::makeLinks()"); nlwarning("caught an exception during linkage of %d and %d: %s", instance.getInstanceId(), neighbor.getInstanceId(), e.what()); diff --git a/code/nel/src/pacs/retriever_bank.h b/code/nel/src/pacs/retriever_bank.h index bce8b11e6..d98a5db57 100644 --- a/code/nel/src/pacs/retriever_bank.h +++ b/code/nel/src/pacs/retriever_bank.h @@ -150,7 +150,7 @@ public: { f.serial(_Retrievers[i]); } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { nlwarning("Couldn't load retriever file '%s', %s", fname.c_str(), e.what()); _Retrievers[i].clear(); diff --git a/code/nel/src/sound/audio_mixer_user.cpp b/code/nel/src/sound/audio_mixer_user.cpp index 7f17f9d35..367abd0e1 100644 --- a/code/nel/src/sound/audio_mixer_user.cpp +++ b/code/nel/src/sound/audio_mixer_user.cpp @@ -370,7 +370,7 @@ void CAudioMixerUser::initDriver(const std::string &driverName) _SoundDriver = ISoundDriver::createDriver(this, driverType); nlassert(_SoundDriver); } - catch (ESoundDriver &e) + catch (const ESoundDriver &e) { nlwarning(e.what()); delete _SoundDriver; _SoundDriver = NULL; @@ -458,7 +458,7 @@ void CAudioMixerUser::initDevice(const std::string &deviceName, const CInitInfo manualRolloff = false; // not really needed, but set anyway in case this is still used later in this function } } - catch (ESoundDriver &e) + catch (const ESoundDriver &e) { nlwarning(e.what()); delete _SoundDriver; _SoundDriver = NULL; @@ -836,7 +836,7 @@ void CAudioMixerUser::buildSampleBankList() nlinfo("Compiling sample bank [%s]", bankname.c_str()); std::string filename = buildSampleBank(bankDir[i], sbp, bankname); if (bankFile.size() < i + 1) bankFile.resize(i + 1); - else bankFile.insert(bankFile.begin() + i, NULL); + else bankFile.insert(bankFile.begin() + i, std::string()); bankFile[i] = filename; } else if (bankname < CFile::getFilenameWithoutExtension(bankDir[i])) @@ -883,7 +883,7 @@ void CAudioMixerUser::buildSampleBankList() } } } - catch(Exception e) + catch(const Exception &) { upToDate = false; } @@ -2100,7 +2100,7 @@ uint32 CAudioMixerUser::loadSampleBank(bool async, const std::string &name, st { bank->load(async); } - catch (Exception& e) + catch (const Exception& e) { if (notfoundfiles) { @@ -2489,7 +2489,7 @@ void CAudioMixerUser::changeMaxTrack(uint maxTrack) _FreeTracks.insert(_FreeTracks.begin(), _Tracks[i]); } } - catch ( ESoundDriver & ) + catch (const ESoundDriver &) { delete _Tracks[i]; // If the source generation failed, keep only the generated number of sources diff --git a/code/nel/src/sound/driver/dsound/sound_driver_dsound.cpp b/code/nel/src/sound/driver/dsound/sound_driver_dsound.cpp index 62efc1510..15d0d708f 100644 --- a/code/nel/src/sound/driver/dsound/sound_driver_dsound.cpp +++ b/code/nel/src/sound/driver/dsound/sound_driver_dsound.cpp @@ -605,7 +605,7 @@ void CSoundDriverDSound::initDevice(const std::string &device, ISoundDriver::TSo _SourceCount++; } } - catch (ESoundDriver& e) + catch (const ESoundDriver& e) { // Okay, here's the situation: I'm listening to WinAmp while debugging. // The caps told me there were 31 buffers available. In reality, there were diff --git a/code/nel/src/sound/driver/openal/source_al.cpp b/code/nel/src/sound/driver/openal/source_al.cpp index f156bfb7c..fe2dcb086 100644 --- a/code/nel/src/sound/driver/openal/source_al.cpp +++ b/code/nel/src/sound/driver/openal/source_al.cpp @@ -892,12 +892,22 @@ void CSourceAL::setStreamingBuffersMax(uint buffers) for(uint i = 0; i < _BuffersMax; ++i) { - // create a new buffer - CBufferAL *buffer = static_cast(_SoundDriver->createBuffer()); - // use StorageSoftware because buffers will be reused - // deleting and recreating them is a waste of time - buffer->setStorageMode(IBuffer::StorageSoftware); - _Buffers[buffer->bufferName()] = buffer; + try + { + // create a new buffer + CBufferAL *buffer = static_cast(_SoundDriver->createBuffer()); + // use StorageSoftware because buffers will be reused + // deleting and recreating them is a waste of time + buffer->setStorageMode(IBuffer::StorageSoftware); + _Buffers[buffer->bufferName()] = buffer; + } + catch(const ESoundDriverGenBuf &e) + { + nlwarning("Cannot create %d buffers. openal fails after %d buffers", buffers, i); + _BuffersMax = i; + _BuffersName.resize(i); + break; + } } } diff --git a/code/nel/src/sound/sample_bank.cpp b/code/nel/src/sound/sample_bank.cpp index a83166879..8dd764f54 100644 --- a/code/nel/src/sound/sample_bank.cpp +++ b/code/nel/src/sound/sample_bank.cpp @@ -213,7 +213,7 @@ void CSampleBank::load(bool async) _SampleBankManager->m_LoadedSize += _ByteSize; } - catch(Exception &e) + catch(const Exception &e) { // loading failed ! nlwarning("Exception %s during loading of sample bank %s", e.what(), filename.c_str()); @@ -281,7 +281,7 @@ void CSampleBank::load(bool async) // Warn the sound bank that the sample are available. CSoundBank::instance()->bufferLoaded(sampleName, ibuffer); } - catch (ESoundDriver &e) + catch (const ESoundDriver &e) { if (ibuffer != NULL) { delete ibuffer; diff --git a/code/nel/src/sound/sample_bank_manager.cpp b/code/nel/src/sound/sample_bank_manager.cpp index 26b55b25d..374775972 100644 --- a/code/nel/src/sound/sample_bank_manager.cpp +++ b/code/nel/src/sound/sample_bank_manager.cpp @@ -36,7 +36,7 @@ using namespace NLMISC; namespace NLSOUND { -CSampleBankManager::CSampleBankManager(CAudioMixerUser *audioMixer) : m_AudioMixer(audioMixer), m_LoadedSize(NULL) +CSampleBankManager::CSampleBankManager(CAudioMixerUser *audioMixer) : m_AudioMixer(audioMixer), m_LoadedSize(0) { } diff --git a/code/nel/src/sound/simple_sound.cpp b/code/nel/src/sound/simple_sound.cpp index dd69a19bb..405b25264 100644 --- a/code/nel/src/sound/simple_sound.cpp +++ b/code/nel/src/sound/simple_sound.cpp @@ -77,7 +77,7 @@ void CSimpleSound::getSubSoundList(std::vector(this)->getBuffer() == 0) - subsounds.push_back(pair(CStringMapper::unmap(_Buffername)+" (sample)", 0)); + subsounds.push_back(pair(CStringMapper::unmap(_Buffername)+" (sample)", (CSound*)NULL)); } diff --git a/code/nel/src/sound/stdsound.h b/code/nel/src/sound/stdsound.h index a4cc08094..a656fa387 100644 --- a/code/nel/src/sound/stdsound.h +++ b/code/nel/src/sound/stdsound.h @@ -36,6 +36,7 @@ #include #include #include +#include #include "nel/misc/vector.h" #include "nel/misc/path.h" diff --git a/code/nel/tools/3d/anim_builder/anim_builder.cpp b/code/nel/tools/3d/anim_builder/anim_builder.cpp index f210e49a9..e8ec3001e 100644 --- a/code/nel/tools/3d/anim_builder/anim_builder.cpp +++ b/code/nel/tools/3d/anim_builder/anim_builder.cpp @@ -103,7 +103,7 @@ int main(int argc, char* argv[]) animationOptimizer.addLowPrecisionTrack(anim_low_precision_tracks.asString(lpt)); } } - catch(EUnknownVar &) + catch(const EUnknownVar &) { nlwarning("\"anim_low_precision_tracks\" not found in the parameter file. Add \"Finger\" and \"Ponytail\" by default"); animationOptimizer.addLowPrecisionTrack("Finger"); @@ -126,7 +126,7 @@ int main(int argc, char* argv[]) animationOptimizer.setSampleFrameRate(sr); } } - catch(EUnknownVar &) + catch(const EUnknownVar &) { nlwarning("\"anim_sample_rate\" not found in the parameter file. Use Default of 30 fps."); animationOptimizer.setSampleFrameRate(30); @@ -198,7 +198,7 @@ int main(int argc, char* argv[]) nlinfo("Anim skipped: %4d", numSkipped); } - catch (Exception& except) + catch (const Exception& except) { // Error message nlwarning ("ERROR %s\n", except.what()); diff --git a/code/nel/tools/3d/animation_set_builder/animation_set_builder.cpp b/code/nel/tools/3d/animation_set_builder/animation_set_builder.cpp index b5e35a9e3..a423d7ff8 100644 --- a/code/nel/tools/3d/animation_set_builder/animation_set_builder.cpp +++ b/code/nel/tools/3d/animation_set_builder/animation_set_builder.cpp @@ -124,7 +124,7 @@ int main(int argc, char* argv[]) return -1; } } - catch (Exception& e) + catch (const Exception& e) { // Error message fprintf (stderr, "Error: %s\n", e.what()); diff --git a/code/nel/tools/3d/build_clod_bank/build_clod_bank.cpp b/code/nel/tools/3d/build_clod_bank/build_clod_bank.cpp index 332e7ebad..2caf5c235 100644 --- a/code/nel/tools/3d/build_clod_bank/build_clod_bank.cpp +++ b/code/nel/tools/3d/build_clod_bank/build_clod_bank.cpp @@ -173,7 +173,7 @@ int main(int argc, char *argv[]) // NB: the key name here is the entire file, with the .anim, for easier georges editing. lodBuilder.addAnim(animFileName.c_str(), anim, bakeFrameRate); } - catch(EPathNotFound &) + catch(const EPathNotFound &) { printf("ERROR anim not found %s\n", animFileName.c_str()); delete anim; @@ -186,7 +186,7 @@ int main(int argc, char *argv[]) uint32 shapeId= lodShapeBank.addShape(); *lodShapeBank.getShapeFullAcces(shapeId)= lodBuilder.getLodShape(); } - catch(EUnknownVar &evar) + catch(const EUnknownVar &evar) { nlwarning(evar.what()); // Any other exception will make the program quit. @@ -205,7 +205,7 @@ int main(int argc, char *argv[]) oFile.serial(lodShapeBank); oFile.close(); } - catch (Exception& except) + catch (const Exception& except) { // Error message printf ("ERROR %s.\n Aborting.\n", except.what()); diff --git a/code/nel/tools/3d/build_clodtex/main.cpp b/code/nel/tools/3d/build_clodtex/main.cpp index d92a8f7d2..0d43479dc 100644 --- a/code/nel/tools/3d/build_clodtex/main.cpp +++ b/code/nel/tools/3d/build_clodtex/main.cpp @@ -100,7 +100,7 @@ bool computeOneShape(const char *lodFile, const char *shapeIn, const char *shape COFile dbgF("testDBG.tga"); dbg.writeTGA(dbgF, 32);*/ } - catch(Exception &e) + catch(const Exception &e) { nlwarning("ERROR: %s", e.what()); return false; @@ -179,7 +179,7 @@ int main(int argc, char *argv[]) LodFilters[i]= var.asString(i*2+1); } } - catch(Exception &e) + catch(const Exception &e) { // It is not an error to have a bad config file: files will be copied nlwarning(e.what()); diff --git a/code/nel/tools/3d/build_coarse_mesh/build_coarse_mesh.cpp b/code/nel/tools/3d/build_coarse_mesh/build_coarse_mesh.cpp index 236c2727e..854e7bc18 100644 --- a/code/nel/tools/3d/build_coarse_mesh/build_coarse_mesh.cpp +++ b/code/nel/tools/3d/build_coarse_mesh/build_coarse_mesh.cpp @@ -255,12 +255,12 @@ int main(int argc, char* argv[]) nlwarning ("WARNING no coarse mesh to compute, abort.\n"); } } - catch (EConfigFile &e) + catch (const EConfigFile &e) { // Something goes wrong... catch that nlwarning ("ERROR %s\n", e.what ()); } - catch (Exception &e) + catch (const Exception &e) { // Something goes wrong... catch that nlwarning ("ERROR %s\n", e.what ()); diff --git a/code/nel/tools/3d/build_far_bank/build_far_bank.cpp b/code/nel/tools/3d/build_far_bank/build_far_bank.cpp index be8b48e0e..db49575a7 100644 --- a/code/nel/tools/3d/build_far_bank/build_far_bank.cpp +++ b/code/nel/tools/3d/build_far_bank/build_far_bank.cpp @@ -120,7 +120,7 @@ bool fillTileFar (uint tile, const char* sName, CTileFarBank::TFarType type, CTi // Ok. return true; } - catch (Exception& except) + catch (const Exception& except) { nlwarning ("ERROR %s\n", except.what()); } @@ -409,7 +409,7 @@ int main (int argc, char **argv) nlwarning ("ERROR Can't open file %s for writing\n", argv[2]); } } - catch (Exception& except) + catch (const Exception& except) { nlwarning ("ERROR %s\n", except.what()); } diff --git a/code/nel/tools/3d/build_interface/main.cpp b/code/nel/tools/3d/build_interface/main.cpp index b9e9b44f3..40627bab8 100644 --- a/code/nel/tools/3d/build_interface/main.cpp +++ b/code/nel/tools/3d/build_interface/main.cpp @@ -267,7 +267,7 @@ int main(int nNbArg, char **ppArgs) pBtmp->load(inFile); AllMaps[i] = pBtmp; } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { outString (string("ERROR :") + e.what()); return -1; diff --git a/code/nel/tools/3d/build_smallbank/build_smallbank.cpp b/code/nel/tools/3d/build_smallbank/build_smallbank.cpp index 45e995427..888799579 100644 --- a/code/nel/tools/3d/build_smallbank/build_smallbank.cpp +++ b/code/nel/tools/3d/build_smallbank/build_smallbank.cpp @@ -70,7 +70,7 @@ int main(int argc, char* argv[]) } } - catch (Exception& e) + catch (const Exception& e) { // Error nlwarning ("ERROR fatal error: %s", e.what()); diff --git a/code/nel/tools/3d/cluster_viewer/view_cs.cpp b/code/nel/tools/3d/cluster_viewer/view_cs.cpp index bed6a7518..6e19af2f0 100644 --- a/code/nel/tools/3d/cluster_viewer/view_cs.cpp +++ b/code/nel/tools/3d/cluster_viewer/view_cs.cpp @@ -94,7 +94,7 @@ CInstanceGroup* LoadInstanceGroup(const char* sFilename) newIG->serial (file); // All is good } - catch (Exception &) + catch (const Exception &) { // Cannot save the file delete newIG; diff --git a/code/nel/tools/3d/file_info/main.cpp b/code/nel/tools/3d/file_info/main.cpp index 4a14a43c9..306a7fc74 100644 --- a/code/nel/tools/3d/file_info/main.cpp +++ b/code/nel/tools/3d/file_info/main.cpp @@ -331,9 +331,9 @@ void displayInfoFileInStream(FILE *logStream, const char *fileName, const setserial (file); } - catch (Exception &) + catch (const Exception &) { delete newIG; return NULL; @@ -62,7 +62,7 @@ bool SaveInstanceGroup (const char* sFilename, CInstanceGroup *pIG) { pIG->serial (file); } - catch (Exception &) + catch (const Exception &) { return false; } diff --git a/code/nel/tools/3d/ig_elevation/main.cpp b/code/nel/tools/3d/ig_elevation/main.cpp index f0044b651..988cde08e 100644 --- a/code/nel/tools/3d/ig_elevation/main.cpp +++ b/code/nel/tools/3d/ig_elevation/main.cpp @@ -106,7 +106,7 @@ struct SExportOptions CConfigFile::CVar &cvLandFile = cf.getVar("LandFile"); LandFile = cvLandFile.asString(); } - catch (EConfigFile &e) + catch (const EConfigFile &e) { string sTmp = string("ERROR : Error in config file : ") + e.what() + "\n"; outString (sTmp); @@ -173,7 +173,7 @@ CZoneRegion *loadLand (const string &filename) outString (sTmp); } } - catch (Exception& e) + catch (const Exception& e) { string sTmp = string("Error in land file : ") + e.what(); outString (sTmp); @@ -194,7 +194,7 @@ CInstanceGroup* LoadInstanceGroup (const char* sFilename) { newIG->serial (file); } - catch (Exception &) + catch (const Exception &) { // Cannot save the file delete newIG; @@ -220,7 +220,7 @@ void SaveInstanceGroup (const char* sFilename, CInstanceGroup *pIG) { pIG->serial (file); } - catch (Exception &e) + catch (const Exception &e) { outString(string(e.what())); } @@ -339,7 +339,7 @@ int main(int nNbArg, char**ppArgs) HeightMap1 = NULL; } } - catch (Exception &e) + catch (const Exception &e) { string sTmp = string("Cant load height map : ") + options.HeightMapFile1 + " : " + e.what(); outString (sTmp); @@ -365,7 +365,7 @@ int main(int nNbArg, char**ppArgs) HeightMap2 = NULL; } } - catch (Exception &e) + catch (const Exception &e) { string sTmp = string("Cant load height map : ") + options.HeightMapFile2 + " : " + e.what() + "\n"; outString (sTmp); diff --git a/code/nel/tools/3d/ig_info/ig_info.cpp b/code/nel/tools/3d/ig_info/ig_info.cpp index 8de0bcf19..7a765a89c 100644 --- a/code/nel/tools/3d/ig_info/ig_info.cpp +++ b/code/nel/tools/3d/ig_info/ig_info.cpp @@ -83,7 +83,7 @@ int main(int argc, char **argv) printf("TotalCells: %d\n", totalCells); } - catch (std::exception &e) + catch (const std::exception &e) { printf("%s\n", e.what()); } diff --git a/code/nel/tools/3d/ig_lighter/ig_lighter.cpp b/code/nel/tools/3d/ig_lighter/ig_lighter.cpp index f1c30fc20..2a6508399 100644 --- a/code/nel/tools/3d/ig_lighter/ig_lighter.cpp +++ b/code/nel/tools/3d/ig_lighter/ig_lighter.cpp @@ -344,7 +344,7 @@ int main(int argc, char* argv[]) } } - catch (Exception& except) + catch (const Exception& except) { // Error message nlwarning ("ERROR %s\n", except.what()); diff --git a/code/nel/tools/3d/lightmap_optimizer/main.cpp b/code/nel/tools/3d/lightmap_optimizer/main.cpp index 528d85014..7cae0b5f9 100644 --- a/code/nel/tools/3d/lightmap_optimizer/main.cpp +++ b/code/nel/tools/3d/lightmap_optimizer/main.cpp @@ -365,7 +365,7 @@ int main(int nNbArg, char **ppArgs) CMeshBase *pMB = dynamic_cast(mesh.getShapePointer()); AllShapes.push_back (pMB); } - catch (NLMISC::EPathNotFound &e) + catch (const NLMISC::EPathNotFound &e) { outString(string("ERROR: shape not found ")+AllShapeNames[nShp]+" - "+e.what()); return -1; @@ -529,7 +529,7 @@ int main(int nNbArg, char **ppArgs) inFile.open(sTmp2); CBitmap::loadSize(inFile, wRef, hRef); } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { outString (string("ERROR :") + e.what()); return -1; @@ -546,7 +546,7 @@ int main(int nNbArg, char **ppArgs) inFile.open(sTmp3); CBitmap::loadSize(inFile, wCur, hCur); } - catch (NLMISC::Exception &) + catch (const NLMISC::Exception &) { } @@ -595,7 +595,7 @@ int main(int nNbArg, char **ppArgs) pBtmp->load(inFile); AllLightmaps[i] = pBtmp; } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { outString (string("ERROR :") + e.what()); return -1; @@ -671,7 +671,7 @@ int main(int nNbArg, char **ppArgs) BitmapJ.load (inFile); inFile.close (); } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { outString (string("ERROR :") + e.what()); return -1; @@ -883,7 +883,7 @@ int main(int nNbArg, char **ppArgs) meshfile.close (); } } - catch (NLMISC::EPathNotFound &e) + catch (const NLMISC::EPathNotFound &e) { outString(string("ERROR: cannot save shape ")+AllShapeNames[k]+" - "+e.what()); return -1; diff --git a/code/nel/tools/3d/object_viewer_qt/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/CMakeLists.txt index 9341954ab..11196091e 100644 --- a/code/nel/tools/3d/object_viewer_qt/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/CMakeLists.txt @@ -8,6 +8,10 @@ # This tells the application(s) where to fidn the installed data. ADD_DEFINITIONS(-DDATA_DIR="\\"${NL_SHARE_PREFIX}/object_viewer_qt/\\"") +IF(UNIX AND WITH_STATIC) + MESSAGE(FATAL_ERROR "OVQT does not work with static NeL builds on Unix atm.") +ENDIF() + ADD_SUBDIRECTORY(src) INSTALL(DIRECTORY data/ diff --git a/code/nel/tools/3d/object_viewer_qt/doc/ovqt.dox b/code/nel/tools/3d/object_viewer_qt/doc/ovqt.dox index e15e37e5a..b310ad758 100644 --- a/code/nel/tools/3d/object_viewer_qt/doc/ovqt.dox +++ b/code/nel/tools/3d/object_viewer_qt/doc/ovqt.dox @@ -31,7 +31,7 @@ PROJECT_NAME = "Object Viewer Qt" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = r90 +PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -643,7 +643,7 @@ FILE_PATTERNS = *.c \ # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. -RECURSIVE = NO +RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a diff --git a/code/nel/tools/3d/object_viewer_qt/src/description.h b/code/nel/tools/3d/object_viewer_qt/src/description.h index d22a1918b..a1a041de9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/description.h +++ b/code/nel/tools/3d/object_viewer_qt/src/description.h @@ -1,6 +1,6 @@ /** @mainpage Object Viewer Qt -@author Dzmitry Kamiahin , (C) 2010 +@author Dzmitry Kamiahin , (C) 2011 @section introduce Introduce @details @@ -15,130 +15,22 @@ The tool can be used in different tasks: - Create and modify micro-vegetation material (.vegetset files) - Viewing landscape (.zonel files) - Dialog allows to specify graphical, sound, search path and landscape settings. - -@section project_structure Overview of the Object Viewer Qt Project Structure -@details -OVQT - consists of several major subsystems. Each subsystem performs its defined part of the task. -Through Modules:: provides access to all other program subsystems. - -Program has the following subsystems: -- @ref Modules - Main modules aggregated all parts of the program. -- @ref NLQT::CConfiguration - is responsible for loading and saving settings from the configuration file. As well as search path of data. -- @ref NLQT::CObjectViewer - main subsystem of the program, which initializes the driver, creates a scene and other supporting elements. -It is a container for loaded models, which can further be viewed and animated. -- @ref NLQT::CMainWindow - is responsible for the GUI. -- @ref NLQT::CParticleEditor - is responsible for the particle systems and provides access to a container that keeps all the loaded particle systems. -And also allows you to view an animation of particle systems, with the ability to control its parameters. -- @ref NLQT::CVegetableEditor - is responsible for the landscape zones and the editor of vegetation. -Allows you to load and view the landscape. Also has the ability to create and edit the parameters of the micro-vegetation. -- @ref NLQT::CSoundSystem - is responsible for the sound in the program. - - -The structure of the GUI in the editor of the particles. -
-This can be useful for new developers who want to add more new dialogs or to improve the functionality of existing dialogues. -Particle Workspace -ParticleWorkspace dialogue uses the technique of model-view. -Using the signal/slot link QTreeView with QStackWidget, Editor properties dialog. -When you select an item in QTreeView, QStackWidget displays the necessary page(PageWidget) where you can edit the element of the particles system. -Each page is made in the designer and has a separate forms(.ui). -In accordance with the recommendations of dialogues design, with a large number of items,every page uses QTabWidget. -In case when there is a great number of controls, and not everything you want to display, -it's used the dynamic creation of tabs. Moreover, each tab uses a separate forms(.ui). - -@section for_new_developer Guide for new developers of the Object Viewer Qt. -@details - First of all, to begin developing dialogues that add new features ovqt, -it is needed to read the documentation Qt libs (http://doc.qt.nokia.com/) and NeL documentation. - - In order to have convenient using of the tool and its further development, -it is expected to make a unified interface that is why all dialogs should adhere to a standard design, -which will be written further. For this goals program provides some additional widgets, -which are recommended to use. As in the development Qt Designer is actively used. -To get access to founded here widgets from the designer,the technique promotion is used, -which can be found here . -
    -
  1. -CEditRangeUIntWidget / CEditRangeIntWidget / CEditRangeFloatWidget -
    -Widgets provides a slider that allows you to specify an integer (or float, depending on which widget used) number within a set range. -The range is also can be set by the user, or for a more accurate selection of numbers, either for receiving large values. -As there may be situations when the range that a user requests,has to be restricted, and widget provides methods that allow you to do so. -

    -CEditRangeIntWidget -
    -CEditRangeFloatWidget -@see -@ref NLQT::CEditRangeUIntWidget, @ref NLQT::CEditRangeIntWidget, @ref NLQT::CEditRangeFloatWidget - -
  2. -CColorEditWidget -
    -Using this widget you can set the color(RGBA) using the four sliders or through the color selection dialog. -

    -CColorEditWidget -@see -@ref NLQT::CColorEditWidget - -
  3. -CDirectionWidget -
    -This widget helps to choose from several preset directions, or to choose a custom one. -

    -CDirectionWidget -@see -@ref NLQT::CDirectionWidget -


- -To further convinience of instrument using dialogues interface is recommended to make as follows. -The most sophisticated tools of the program, should take the form of three dock windows (example shown in the screenshot). -Object Viewer Qt -
    -
  1. -The first dock window - is a control dock window, it should focus all of the control functions of general purpose -(for example: start/stop/pause animations or particles system). -It is recommended to perform of the horizontal type window and placed in the bottom of the main window. -
  2. -The second dock window - is a list or a tree of items. In which selecting of the current element, -which assumes to modify or viewis possible.Operations "add/remove/insert or other" items are recommended to make as a popur menu. -It is recommended to perform of the vertical type window and placed in the left of the main window. -
  3. -The third dock - is an editor for properties of the element that was selected in the list or in the tree of elements. -As all the controls occupy much space or do not fit at all, you have to use tabs QTabWidget, -which in total can contains quite a lot of elements. -For a small number of tabs it is allowed to use both horizontal and vertical location. -But with a large number of tabs, it is necessary to apply the vertical arrangement. -It is recommended to perform of the vertical type of window and placed in the right of the main window. -
-In the simple dialogues do not necessary to use all three windows, but user has to adhere to the recommendations given above as well. -Also, all dialogs must use the qt layout manager. And if you do not use the designer, -make sure you use the qt tools internationalization applications. -

-In ovqt for most dialogs their owner is NLQT::CMainWindow and in its methods creating and initializing all dependent dialogs occur. -For the convenience of the program using, most dialogues are created in the form of docking windows. -Creating all the dialogues are carried out in a private method NLQT::CMainWindow::createDialogs(). -Hence, it is necessary to add operations in this method to create new dialogues. -But we must take into account that at this moment is fully available only one component of the program CConfiguration, -to read the settings from the configuration file. The remaining components of the program are available only after the main window stays visible. -Calling the dialogues going through the menu or the toolbar, usually it is a checkable item. -Adding of the new menu items or items toolbars is need in methods NLQT::CMainWindow::createMenus(), NLQT::CMainWindow::createToolBars(). +- OVQT supports loading third-party plug-ins. @section license_ovqt License Object Viewer Qt @details - Object Viewer Qt +Object Viewer Qt - MMORPG Framework
- Copyright (C) 2010 Dzmitry Kamiahin +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 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 3 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 Affero 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, see . +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h index e67c9e588..05d4b832c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h @@ -40,7 +40,6 @@ class IPluginSpec; class IPluginManager: public QObject { Q_OBJECT - public: IPluginManager(QObject *parent = 0): QObject(parent) {} virtual ~IPluginManager() {} diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp index 49dcec785..be5f18c74 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp @@ -151,9 +151,9 @@ void CPluginManager::readPluginPaths() { const QDir dir(searchPaths.takeFirst()); #ifdef Q_OS_WIN - const QFileInfoList files = dir.entryInfoList(QStringList() << QString("*.dll"), QDir::Files); + const QFileInfoList files = dir.entryInfoList(QStringList() << QString("ovqt_plugin_*.dll"), QDir::Files); #else - const QFileInfoList files = dir.entryInfoList(QStringList() << QString("*.so"), QDir::Files); + const QFileInfoList files = dir.entryInfoList(QStringList() << QString("libovqt_plugin_*.so"), QDir::Files); #endif Q_FOREACH (const QFileInfo &file, files) pluginsList << file.absoluteFilePath(); @@ -292,4 +292,4 @@ void CPluginManager::deleteAll() } } -}; // namespace NLQT \ No newline at end of file +}; // namespace ExtensionSystem \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h index d1a18485b..4ef3b2208 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h @@ -74,6 +74,6 @@ private: }; // class CPluginManager -} // namespace NLQT +} // namespace ExtensionSystem #endif // PLUGINMANAGER_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp index 7158c8d9f..d77d90962 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp @@ -266,4 +266,4 @@ bool CPluginSpec::reportError(const QString &err) return false; } -} // namespace NLQT \ No newline at end of file +} // namespace ExtensionSystem \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h index e73f3ed93..0cc895ada 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h @@ -79,7 +79,7 @@ private: friend class CPluginManager; }; -} // namespace NLQT +} // namespace ExtensionSystem #endif // PLUGINSPEC_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/main.cpp b/code/nel/tools/3d/object_viewer_qt/src/main.cpp index 64cb1fff2..15173fa5c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/main.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/main.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#include static const char *appNameC = "ObjectViewerQt"; @@ -135,7 +137,7 @@ sint main(int argc, char **argv) QTranslator qtTranslator; QString locale = settings->value("Language", QLocale::system().name()).toString(); QString qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath); - translator.load("object_viewer_qt_" + locale, ":/"); +// translator.load("object_viewer_qt_" + locale, ":/"); qtTranslator.load("qt_" + locale, qtTrPath); app.installTranslator(&translator); app.installTranslator(&qtTranslator); @@ -149,9 +151,9 @@ sint main(int argc, char **argv) pluginManager.setSettings(settings); QStringList pluginPaths; #if !defined(NL_OS_MAC) - pluginPaths << QString("./plugins"); + pluginPaths << settings->value("PluginPath", "./plugins").toString(); #else - pluginPaths << qApp->applicationDirPath() + QString("/../PlugIns/ovqt"); + pluginPaths << settings->value("PluginPath", qApp->applicationDirPath() + QString("/../PlugIns/ovqt")).toString(); #endif pluginManager.setPluginPaths(pluginPaths); @@ -176,6 +178,15 @@ sint main(int argc, char **argv) QString absolutePaths = absolutePluginPaths.absolutePath(); const QString reason = QCoreApplication::translate("Application", "Could not find ovqt_plugin_core in %1").arg(absolutePaths); displayError(msgCoreLoadFailure(reason)); + + QString newPath = QFileDialog::getExistingDirectory(0, QCoreApplication::translate("Application", "Change the plugins path"), QDir::homePath()); + bool ok; + QString text = QInputDialog::getText(0, QCoreApplication::translate("Application", "Enter the plugins path"), + QCoreApplication::translate("Application", "Plugin path:"), QLineEdit::Normal, + newPath, &ok); + if (ok && !text.isEmpty()) + settings->setValue("PluginPath", text); + settings->sync(); return 1; } if (corePlugin->hasError()) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt index d5a792acd..bec71cf94 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt @@ -1,7 +1,9 @@ ADD_SUBDIRECTORY(core) ADD_SUBDIRECTORY(example) ADD_SUBDIRECTORY(ovqt_sheet_builder) +ADD_SUBDIRECTORY(landscape_editor) ADD_SUBDIRECTORY(log) ADD_SUBDIRECTORY(disp_sheet_id) ADD_SUBDIRECTORY(object_viewer) -ADD_SUBDIRECTORY(zone_painter) \ No newline at end of file +ADD_SUBDIRECTORY(zone_painter) +ADD_SUBDIRECTORY(georges_editor) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt index 726cb4a2d..3140f02fb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt @@ -18,13 +18,18 @@ SET(OVQT_CORE_PLUGIN_HDR core.h main_window.h menu_manager.h + context_manager.h settings_dialog.h search_paths_settings_page.h - plugin_view_dialog.h) + general_settings_page.h + plugin_view_dialog.h +) SET(OVQT_CORE_PLUGIN_UIS settings_dialog.ui plugin_view_dialog.ui - search_paths_settings_page.ui) + general_settings_page.ui + search_paths_settings_page.ui +) SET(OVQT_CORE_PLUGIN_RCS core.qrc) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.cpp new file mode 100644 index 000000000..68e28429d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.cpp @@ -0,0 +1,150 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "context_manager.h" +#include "icontext.h" +#include "main_window.h" + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace Core +{ + +struct ContextManagerPrivate +{ + explicit ContextManagerPrivate(Core::MainWindow *mainWindow, QTabWidget *tabWidget); + Core::MainWindow *m_mainWindow; + QTabWidget *m_tabWidget; + QVector m_contexts; + int m_oldCurrent; +}; + +ContextManagerPrivate::ContextManagerPrivate(Core::MainWindow *mainWindow, QTabWidget *tabWidget) + : m_mainWindow(mainWindow), + m_tabWidget(tabWidget), + m_oldCurrent(-1) +{ +} + +ContextManager::ContextManager(Core::MainWindow *mainWindow, QTabWidget *tabWidget) + : d(new ContextManagerPrivate(mainWindow, tabWidget)) +{ + QObject::connect(d->m_mainWindow->pluginManager(), SIGNAL(objectAdded(QObject *)), + this, SLOT(objectAdded(QObject *))); + QObject::connect(d->m_mainWindow->pluginManager(), SIGNAL(aboutToRemoveObject(QObject *)), + this, SLOT(aboutToRemoveObject(QObject *))); + + QObject::connect(d->m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int))); +} + +ContextManager::~ContextManager() +{ + delete d; +} + +Core::IContext *ContextManager::currentContext() const +{ + int currentIndex = d->m_tabWidget->currentIndex(); + if (currentIndex < 0) + return 0; + return d->m_contexts.at(currentIndex); +} + +Core::IContext *ContextManager::context(const QString &id) const +{ + const int index = indexOf(id); + if (index >= 0) + return d->m_contexts.at(index); + return 0; +} + +void ContextManager::activateContext(const QString &id) +{ + const int index = indexOf(id); + if (index >= 0) + d->m_tabWidget->setCurrentIndex(index); +} + +void ContextManager::objectAdded(QObject *obj) +{ + IContext *context = qobject_cast(obj); + if (context) + addContextObject(context); +} + +void ContextManager::aboutToRemoveObject(QObject *obj) +{ + IContext *context = qobject_cast(obj); + if (context) + removeContextObject(context); +} + +void ContextManager::addContextObject(IContext *context) +{ + d->m_contexts.push_back(context); + d->m_mainWindow->addContextObject(context); + + QWidget *tabWidget = new QWidget(d->m_tabWidget); + d->m_tabWidget->addTab(tabWidget, context->icon(), context->trName()); + QGridLayout *gridLayout = new QGridLayout(tabWidget); + gridLayout->setObjectName(QString::fromUtf8("gridLayout_") + context->id()); + gridLayout->setContentsMargins(0, 0, 0, 0); + gridLayout->addWidget(context->widget(), 0, 0, 1, 1); +} + +void ContextManager::removeContextObject(IContext *context) +{ + d->m_mainWindow->removeContextObject(context); + + const int index = indexOf(context->id()); + QWidget *widget = d->m_tabWidget->widget(index); + d->m_tabWidget->removeTab(index); + d->m_contexts.remove(index); + delete widget; +} + +void ContextManager::currentTabChanged(int index) +{ + if (index >= 0) + { + IContext *context = d->m_contexts.at(index); + IContext *oldContext = 0; + if (d->m_oldCurrent >= 0) + oldContext = d->m_contexts.at(d->m_oldCurrent); + d->m_oldCurrent = index; + Q_EMIT currentContextChanged(context, oldContext); + } +} + +int ContextManager::indexOf(const QString &id) const +{ + for (int i = 0; i < d->m_contexts.count(); ++i) + { + if (d->m_contexts.at(i)->id() == id) + return i; + } + nlwarning(QString("Warning, no such context: %1").arg(id).toStdString().c_str()); + return -1; +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.h new file mode 100644 index 000000000..7a3658fff --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.h @@ -0,0 +1,70 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CONTEXT_MANAGER_H +#define CONTEXT_MANAGER_H + +// Project includes +#include "core_global.h" + +// Qt includes +#include + +QT_BEGIN_NAMESPACE +class QTabWidget; +QT_END_NAMESPACE + +namespace Core +{ +class IContext; +class MainWindow; +struct ContextManagerPrivate; + +class CORE_EXPORT ContextManager : public QObject +{ + Q_OBJECT + +public: + explicit ContextManager(Core::MainWindow *mainWindow, QTabWidget *tabWidget); + virtual ~ContextManager(); + + Core::IContext *currentContext() const; + Core::IContext *context(const QString &id) const; + +Q_SIGNALS: + // the default argument '=0' is important for connects without the oldContext argument. + void currentContextChanged(Core::IContext *context, Core::IContext *oldContext = 0); + +public Q_SLOTS: + void activateContext(const QString &id); + +private Q_SLOTS: + void objectAdded(QObject *obj); + void aboutToRemoveObject(QObject *obj); + void addContextObject(IContext *context); + void removeContextObject(IContext *context); + void currentTabChanged(int index); + +private: + int indexOf(const QString &id) const; + + ContextManagerPrivate *d; +}; + +} // namespace Core + +#endif // CONTEXT_MANAGER_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp index 6c681f15a..fa61b5700 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp @@ -18,6 +18,7 @@ #include "core.h" #include "imenu_manager.h" +#include "context_manager.h" #include "main_window.h" #include "../../extension_system/iplugin_manager.h" @@ -54,6 +55,11 @@ IMenuManager *CoreImpl::menuManager() const return m_mainWindow->menuManager(); } +ContextManager *CoreImpl::contextManager() const +{ + return m_mainWindow->contextManager(); +} + QSettings *CoreImpl::settings() const { return m_mainWindow->settings(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h index d3b25b918..2613a06a5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h @@ -38,6 +38,7 @@ public: QWidget *parent = 0); virtual IMenuManager *menuManager() const; + virtual ContextManager *contextManager() const; virtual QSettings *settings() const; virtual QMainWindow *mainWindow() const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.qrc index 85b4702b0..a4c87d29c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.qrc +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.qrc @@ -6,6 +6,9 @@ icons/ic_nel_down_item.png icons/ic_nel_generic_settings.png icons/ic_nel_open.png + icons/ic_nel_new.png + icons/ic_nel_save.png + icons/ic_nel_save_as.png icons/ic_nel_path_settings.png icons/ic_nel_pill.png icons/ic_nel_reset_all.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h index 18dc11c87..2acf4f731 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h @@ -1,80 +1,117 @@ -// Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2010 Dzmitry Kamiahin -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef CORE_CONSTANTS_H -#define CORE_CONSTANTS_H - -namespace Core -{ -namespace Constants -{ - -const char * const OVQT_VERSION_LONG = "0.0.1"; -const char * const OVQT_VENDOR = "Dzmitry Kamiahin"; -const char * const OVQT_YEAR = "2010, 2011"; -const char * const OVQT_CORE_PLUGIN = "Core"; - -//mainwindow -const char * const MAIN_WINDOW = "ObjectViewerQt.MainWindow"; - -//menubar -const char * const MENU_BAR = "ObjectViewerQt.MenuBar"; - -//menus -const char * const M_FILE = "ObjectViewerQt.Menu.File"; -const char * const M_EDIT = "ObjectViewerQt.Menu.Edit"; -const char * const M_VIEW = "ObjectViewerQt.Menu.View"; -const char * const M_SCENE = "ObjectViewerQt.Menu.Scene"; -const char * const M_TOOLS = "ObjectViewerQt.Menu.Tools"; -const char * const M_WINDOW = "ObjectViewerQt.Menu.Window"; -const char * const M_HELP = "ObjectViewerQt.Menu.Help"; - -const char * const M_SHEET = "ObjectViewerQt.Menu.Sheet"; - -//actions -const char * const NEW = "ObjectViewerQt.New"; -const char * const OPEN = "ObjectViewerQt.Open"; -const char * const EXIT = "ObjectViewerQt.Exit"; - -const char * const SETTINGS = "ObjectViewerQt.Settings"; -const char * const TOGGLE_FULLSCREEN = "ObjectViewerQt.ToggleFullScreen"; - -const char * const CLOSE = "ObjectViewerQt.Close"; -const char * const CLOSEALL = "ObjectViewerQt.CloseAll"; -const char * const CLOSEOTHERS = "ObjectViewerQt.CloseOthers"; -const char * const ABOUT = "ObjectViewerQt.About"; -const char * const ABOUT_PLUGINS = "ObjectViewerQt.AboutPlugins"; -const char * const ABOUT_QT = "ObjectViewerQt.AboutQt"; - -//settings -const char * const DATA_PATH_SECTION = "DataPath"; -const char * const SEARCH_PATHS = "SearchPaths"; -const char * const RECURSIVE_SEARCH_PATHS = "RecursiveSearchPathes"; -const char * const LEVELDESIGN_PATH = "LevelDesignPath"; -const char * const ASSETS_PATH = "LevelDesignPath"; - -//resources -const char * const ICON_NEL = ":/core/images/nel.png"; -const char * const ICON_SETTINGS = ":/core/images/preferences.png"; -const char * const ICON_PILL = ":/core/icons/ic_nel_pill.png"; -const char * const ICON_OPEN = ":/core/icons/ic_nel_open.png"; -const char * const ICON_CRASH = ":/core/icons/ic_nel_crash.png"; - -} // namespace Constants -} // namespace Core - -#endif // CORE_CONSTANTS_H +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2010 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CORE_CONSTANTS_H +#define CORE_CONSTANTS_H + +namespace Core +{ +namespace Constants +{ + +const char * const OVQT_VERSION_LONG = "0.1"; +const char * const OVQT_VENDOR = "Ryzom Core"; +const char * const OVQT_YEAR = "2010, 2011"; +const char * const OVQT_CORE_PLUGIN = "Core"; + +//mainwindow +const char * const MAIN_WINDOW = "ObjectViewerQt.MainWindow"; + +//menubar +const char * const MENU_BAR = "ObjectViewerQt.MenuBar"; + +//menus +const char * const M_FILE = "ObjectViewerQt.Menu.File"; +const char * const M_EDIT = "ObjectViewerQt.Menu.Edit"; +const char * const M_VIEW = "ObjectViewerQt.Menu.View"; +const char * const M_SCENE = "ObjectViewerQt.Menu.Scene"; +const char * const M_TOOLS = "ObjectViewerQt.Menu.Tools"; +const char * const M_WINDOW = "ObjectViewerQt.Menu.Window"; +const char * const M_HELP = "ObjectViewerQt.Menu.Help"; + +const char * const M_FILE_RECENTFILES = "ObjectViewerQt.Menu.File.RecentFiles"; +const char * const M_SHEET = "ObjectViewerQt.Menu.Sheet"; + +//actions +const char * const NEW = "ObjectViewerQt.New"; +const char * const OPEN = "ObjectViewerQt.Open"; +const char * const SAVE = "ObjectViewerQt.Save"; +const char * const SAVE_AS = "ObjectViewerQt.SaveAs"; +const char * const SAVE_ALL = "ObjectViewerQt.SaveAll"; +const char * const EXIT = "ObjectViewerQt.Exit"; + +const char * const UNDO = "ObjectViewerQt.Undo"; +const char * const REDO = "ObjectViewerQt.Redo"; +const char * const CUT = "ObjectViewerQt.Cut"; +const char * const COPY = "ObjectViewerQt.Copy"; +const char * const PASTE = "ObjectViewerQt.Paste"; +const char * const DEL = "ObjectViewerQt.Del"; +const char * const FIND = "ObjectViewerQt.Find"; +const char * const SELECT_ALL = "ObjectViewerQt.SelectAll"; +const char * const GOTO_POS = "ObjectViewerQt.Goto"; + +const char * const SETTINGS = "ObjectViewerQt.Settings"; +const char * const TOGGLE_FULLSCREEN = "ObjectViewerQt.ToggleFullScreen"; + +const char * const CLOSE = "ObjectViewerQt.Close"; +const char * const CLOSEALL = "ObjectViewerQt.CloseAll"; +const char * const CLOSEOTHERS = "ObjectViewerQt.CloseOthers"; +const char * const ABOUT = "ObjectViewerQt.About"; +const char * const ABOUT_PLUGINS = "ObjectViewerQt.AboutPlugins"; +const char * const ABOUT_QT = "ObjectViewerQt.AboutQt"; + +//settings +const char * const SETTINGS_CATEGORY_GENERAL = "general"; +const char * const SETTINGS_CATEGORY_GENERAL_ICON = ":/icons/ic_nel_generic_settings.png"; +const char * const SETTINGS_TR_CATEGORY_GENERAL = QT_TR_NOOP("General"); + +const char * const MAIN_WINDOW_SECTION = "MainWindow"; +const char * const MAIN_WINDOW_STATE = "WindowState"; +const char * const MAIN_WINDOW_GEOMETRY = "WindowGeometry"; +const char * const QT_STYLE = "QtStyle"; +const char * const QT_PALETTE = "QtPalette"; + +const char * const LANGUAGE = "Language"; +const char * const PLUGINS_PATH = "PluginPath"; +const char * const DATA_PATH_SECTION = "DataPath"; +const char * const SEARCH_PATHS = "SearchPaths"; +const char * const RECURSIVE_SEARCH_PATHS = "RecursiveSearchPathes"; +const char * const LEVELDESIGN_PATH = "LevelDesignPath"; +const char * const ASSETS_PATH = "AssetsPath"; +const char * const REMAP_EXTENSIONS = "RemapExtensions"; + +const char * const LOG_SECTION = "LogSettings"; +const char * const LOG_ERROR = "LogError"; +const char * const LOG_WARNING = "LogWarning"; +const char * const LOG_DEBUG = "LogDebug"; +const char * const LOG_ASSERT = "LogAssert"; +const char * const LOG_INFO = "LogInfo"; + +//resources +const char * const ICON_NEL = ":/core/images/nel.png"; +const char * const ICON_SETTINGS = ":/core/images/preferences.png"; +const char * const ICON_PILL = ":/core/icons/ic_nel_pill.png"; +const char * const ICON_OPEN = ":/core/icons/ic_nel_open.png"; +const char * const ICON_NEW = ":/core/icons/ic_nel_new.png"; +const char * const ICON_SAVE = ":/core/icons/ic_nel_save.png"; +const char * const ICON_SAVE_AS = ":/core/icons/ic_nel_save_as.png"; +const char * const ICON_CRASH = ":/core/icons/ic_nel_crash.png"; + +} // namespace Constants +} // namespace Core + +#endif // CORE_CONSTANTS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp index 6d051d64d..92e776068 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp @@ -20,8 +20,8 @@ #include "settings_dialog.h" #include "core_constants.h" #include "search_paths_settings_page.h" +#include "general_settings_page.h" #include "../../extension_system/iplugin_spec.h" -#include "qtwin.h" // NeL includes #include "nel/misc/debug.h" @@ -42,37 +42,40 @@ CorePlugin::CorePlugin() CorePlugin::~CorePlugin() { - Q_FOREACH(QObject *obj, _autoReleaseObjects) + Q_FOREACH(QObject *obj, m_autoReleaseObjects) { - _plugMan->removeObject(obj); + m_plugMan->removeObject(obj); } - qDeleteAll(_autoReleaseObjects); - _autoReleaseObjects.clear(); + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); - delete _mainWindow; + delete m_mainWindow; } bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) { Q_UNUSED(errorString); - _plugMan = pluginManager; + m_plugMan = pluginManager; - _mainWindow = new MainWindow(pluginManager); - /*if (QtWin::isCompositionEnabled()) - { - QtWin::extendFrameIntoClientArea(_mainWindow); - _mainWindow->setContentsMargins(0, 0, 0, 0); - }*/ - bool success = _mainWindow->initialize(errorString); - CSearchPathsSettingsPage *serchPathPage = new CSearchPathsSettingsPage(this); - serchPathPage->applySearchPaths(); - addAutoReleasedObject(serchPathPage); + m_mainWindow = new MainWindow(pluginManager); + bool success = m_mainWindow->initialize(errorString); + + GeneralSettingsPage *generalSettings = new GeneralSettingsPage(this); + CSearchPathsSettingsPage *searchPathPage = new CSearchPathsSettingsPage(false, this); + CSearchPathsSettingsPage *recureseSearchPathPage = new CSearchPathsSettingsPage(true, this); + + generalSettings->applyGeneralSettings(); + searchPathPage->applySearchPaths(); + recureseSearchPathPage->applySearchPaths(); + addAutoReleasedObject(generalSettings); + addAutoReleasedObject(searchPathPage); + addAutoReleasedObject(recureseSearchPathPage); return success; } void CorePlugin::extensionsInitialized() { - _mainWindow->extensionsInitialized(); + m_mainWindow->extensionsInitialized(); } void CorePlugin::shutdown() @@ -86,7 +89,7 @@ void CorePlugin::setNelContext(NLMISC::INelContext *nelContext) // This only applies to platforms without PIC, e.g. Windows. nlassert(!NLMISC::INelContext::isContextInitialised()); #endif // NL_OS_WINDOWS - _LibContext = new NLMISC::CLibraryContext(*nelContext); + m_libContext = new NLMISC::CLibraryContext(*nelContext); } QString CorePlugin::name() const @@ -116,8 +119,8 @@ QStringList CorePlugin::dependencies() const void CorePlugin::addAutoReleasedObject(QObject *obj) { - _plugMan->addObject(obj); - _autoReleaseObjects.prepend(obj); + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); } Q_EXPORT_PLUGIN(CorePlugin) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h index ef590e1fc..5c95d22c9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h @@ -63,16 +63,16 @@ public: ExtensionSystem::IPluginManager *pluginManager() const { - return _plugMan; + return m_plugMan; } protected: - NLMISC::CLibraryContext *_LibContext; + NLMISC::CLibraryContext *m_libContext; private: - ExtensionSystem::IPluginManager *_plugMan; - MainWindow *_mainWindow; - QList _autoReleaseObjects; + ExtensionSystem::IPluginManager *m_plugMan; + MainWindow *m_mainWindow; + QList m_autoReleaseObjects; }; } // namespace Core diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.cpp new file mode 100644 index 000000000..51da80f67 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.cpp @@ -0,0 +1,192 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "general_settings_page.h" +#include "core_constants.h" +#include "icore.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include +#include +#include + +namespace Core +{ + +GeneralSettingsPage::GeneralSettingsPage(QObject *parent) + : IOptionsPage(parent), + m_page(0) +{ + m_originalPalette = QApplication::palette(); +} + +GeneralSettingsPage::~GeneralSettingsPage() +{ +} + +QString GeneralSettingsPage::id() const +{ + return QLatin1String("general_settings"); +} + +QString GeneralSettingsPage::trName() const +{ + return tr("General"); +} + +QString GeneralSettingsPage::category() const +{ + return QLatin1String(Constants::SETTINGS_CATEGORY_GENERAL); +} + +QString GeneralSettingsPage::trCategory() const +{ + return tr(Constants::SETTINGS_TR_CATEGORY_GENERAL); +} + +QIcon GeneralSettingsPage::categoryIcon() const +{ + return QIcon(); +} + +void GeneralSettingsPage::applyGeneralSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + QApplication::setStyle(QStyleFactory::create(settings->value(Constants::QT_STYLE, "").toString())); + + if (settings->value(Constants::QT_PALETTE, true).toBool()) + QApplication::setPalette(QApplication::style()->standardPalette()); + else + QApplication::setPalette(m_originalPalette); + settings->endGroup(); +} + +QWidget *GeneralSettingsPage::createPage(QWidget *parent) +{ + m_page = new QWidget(parent); + m_ui.setupUi(m_page); + + readSettings(); + connect(m_ui.languageComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(changeLanguage(QString))); + connect(m_ui.pluginsPathButton, SIGNAL(clicked()), this, SLOT(setPluginsPath())); + connect(m_ui.leveldesignPathButton, SIGNAL(clicked()), this, SLOT(setLevelDesignPath())); + connect(m_ui.assetsPathButton, SIGNAL(clicked()), this, SLOT(setAssetsPath())); + return m_page; +} + +void GeneralSettingsPage::apply() +{ + writeSettings(); + applyGeneralSettings(); +} + +void GeneralSettingsPage::finish() +{ + delete m_page; + m_page = 0; +} + +void GeneralSettingsPage::changeLanguage(const QString &lang) +{ + QMessageBox::information(0, tr("Restart required"), + tr("The language change will take effect after a restart of Object Viewer Qt.")); +} + +void GeneralSettingsPage::setPluginsPath() +{ + QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the plugins path"), + m_ui.pluginsPathLineEdit->text()); + if (!newPath.isEmpty()) + { + m_ui.pluginsPathLineEdit->setText(newPath); + } +} + +void GeneralSettingsPage::setLevelDesignPath() +{ + QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the level design path"), + m_ui.leveldesignPathLineEdit->text()); + if (!newPath.isEmpty()) + { + m_ui.leveldesignPathLineEdit->setText(newPath); + } +} + +void GeneralSettingsPage::setAssetsPath() +{ + QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the assets path"), + m_ui.assetsPathLineEdit->text()); + if (!newPath.isEmpty()) + { + m_ui.assetsPathLineEdit->setText(newPath); + } +} + +void GeneralSettingsPage::readSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + + m_ui.pluginsPathLineEdit->setText(settings->value(Core::Constants::PLUGINS_PATH, "./plugins").toString()); + + settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + m_ui.styleComboBox->addItems(QStyleFactory::keys()); + QString style = settings->value(Constants::QT_STYLE, "").toString(); + if (style == "") + m_ui.styleComboBox->setCurrentIndex(0); + else + m_ui.styleComboBox->setCurrentIndex(m_ui.styleComboBox->findText(style)); + m_ui.paletteCheckBox->setChecked(settings->value(Constants::QT_PALETTE, true).toBool()); + settings->endGroup(); + + QStringList paths; + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + m_ui.leveldesignPathLineEdit->setText(settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString()); + m_ui.assetsPathLineEdit->setText(settings->value(Core::Constants::ASSETS_PATH, "w:/database").toString()); + settings->endGroup(); +} + +void GeneralSettingsPage::writeSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + + settings->setValue(Core::Constants::PLUGINS_PATH, m_ui.pluginsPathLineEdit->text()); + + settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + if (m_ui.styleComboBox->currentIndex() == 0) + settings->setValue(Constants::QT_STYLE, ""); + else + settings->setValue(Constants::QT_STYLE, m_ui.styleComboBox->currentText()); + settings->setValue(Constants::QT_PALETTE, m_ui.paletteCheckBox->isChecked()); + settings->endGroup(); + + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + settings->setValue(Core::Constants::LEVELDESIGN_PATH, m_ui.leveldesignPathLineEdit->text()); + settings->setValue(Core::Constants::ASSETS_PATH, m_ui.assetsPathLineEdit->text()); + settings->endGroup(); + settings->sync(); +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.h new file mode 100644 index 000000000..2fbcb842a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.h @@ -0,0 +1,72 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef GENERAL_SETTINGS_PAGE_H +#define GENERAL_SETTINGS_PAGE_H + +#include + +#include "ioptions_page.h" + +#include "ui_general_settings_page.h" + +class QWidget; + +namespace Core +{ +/** +@class GeneralSettingsPage +*/ +class GeneralSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT + +public: + GeneralSettingsPage(QObject *parent = 0); + ~GeneralSettingsPage(); + + QString id() const; + QString trName() const; + QString category() const; + QString trCategory() const; + QIcon categoryIcon() const; + QWidget *createPage(QWidget *parent); + + void apply(); + void finish(); + + void applyGeneralSettings(); + +private Q_SLOTS: + void changeLanguage(const QString &lang); + void setPluginsPath(); + void setLevelDesignPath(); + void setAssetsPath(); + +private: + void readSettings(); + void writeSettings(); + + QPalette m_originalPalette; + QWidget *m_page; + Ui::GeneralSettingsPage m_ui; +}; + +} // namespace Core + +#endif // GENERAL_SETTINGS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.ui new file mode 100644 index 000000000..d2aa042e3 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.ui @@ -0,0 +1,199 @@ + + + GeneralSettingsPage + + + + 0 + 0 + 267 + 282 + + + + Form + + + + 6 + + + 3 + + + + + Qt Style + + + + 6 + + + 6 + + + + + + default + + + + + + + + Use style's standard palette + + + + + + + + + + Language + + + + 6 + + + + + false + + + + English + + + + + German + + + + + French + + + + + Russian + + + + + + + + + + + Paths + + + + 6 + + + 6 + + + + + Plugins path: + + + + + + + + 0 + 0 + + + + + + + + ... + + + + + + + Level design path: + + + + + + + + 0 + 0 + + + + + + + + ... + + + + + + + Assets path: + + + + + + + + 0 + 0 + + + + + + + + ... + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_new.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_new.png new file mode 100644 index 0000000000000000000000000000000000000000..159e3e18e388c82cb44e1cd0ce628f81d3bd59c0 GIT binary patch literal 21396 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_save.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_save.png new file mode 100644 index 0000000000000000000000000000000000000000..5aeb3bbe94a27c3528cecf0f2e849fb82a85b4b3 GIT binary patch literal 43738 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 %I{nv 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_save_as.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_save_as.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb71a33436e58801b73476821800b1b95a1018e GIT binary patch literal 52871 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 zsettings(); m_coreImpl = new CoreImpl(this); +#ifdef Q_WS_MAC + m_menuBar = new QMenuBar(0); +#else + m_menuBar = new QMenuBar(this); + setMenuBar(m_menuBar); +#endif + m_menuManager = new MenuManager(this); - m_menuManager->setMenuBar(menuBar()); + m_menuManager->setMenuBar(m_menuBar); m_tabWidget = new QTabWidget(this); m_tabWidget->setTabPosition(QTabWidget::South); - m_tabWidget->setMovable(true); + m_tabWidget->setMovable(false); + m_tabWidget->setDocumentMode(true); setCentralWidget(m_tabWidget); + m_contextManager = new ContextManager(this, m_tabWidget); + setDockNestingEnabled(true); m_originalPalette = QApplication::palette(); + m_undoGroup = new QUndoGroup(this); createDialogs(); createActions(); @@ -91,15 +105,11 @@ bool MainWindow::initialize(QString *errorString) void MainWindow::extensionsInitialized() { - QList listContexts = m_pluginManager->getObjects(); - - Q_FOREACH(IContext *context, listContexts) - { - addContextObject(context); - } - - connect(m_pluginManager, SIGNAL(objectAdded(QObject *)), this, SLOT(checkObject(QObject *))); readSettings(); + connect(m_contextManager, SIGNAL(currentContextChanged(Core::IContext*)), + this, SLOT(updateContext(Core::IContext*))); + if (m_contextManager->currentContext() != NULL) + updateContext(m_contextManager->currentContext()); show(); } @@ -108,6 +118,11 @@ IMenuManager *MainWindow::menuManager() const return m_menuManager; } +ContextManager *MainWindow::contextManager() const +{ + return m_contextManager; +} + QSettings *MainWindow::settings() const { return m_settings; @@ -118,11 +133,69 @@ ExtensionSystem::IPluginManager *MainWindow::pluginManager() const return m_pluginManager; } -void MainWindow::checkObject(QObject *obj) +void MainWindow::addContextObject(IContext *context) { - IContext *context = qobject_cast(obj); - if (context) - addContextObject(context); + m_undoGroup->addStack(context->undoStack()); +} + +void MainWindow::removeContextObject(IContext *context) +{ + m_undoGroup->removeStack(context->undoStack()); +} + +void MainWindow::open() +{ + m_contextManager->currentContext()->open(); +} + +void MainWindow::newFile() +{ +} + +void MainWindow::save() +{ +} + +void MainWindow::saveAs() +{ +} + +void MainWindow::saveAll() +{ +} + +void MainWindow::cut() +{ +} + +void MainWindow::copy() +{ +} + +void MainWindow::paste() +{ +} + +void MainWindow::del() +{ +} + +void MainWindow::find() +{ +} + +void MainWindow::gotoPos() +{ +} + +void MainWindow::setFullScreen(bool enabled) +{ + if (bool(windowState() & Qt::WindowFullScreen) == enabled) + return; + if (enabled) + setWindowState(windowState() | Qt::WindowFullScreen); + else + setWindowState(windowState() & ~Qt::WindowFullScreen); } bool MainWindow::showOptionsDialog(const QString &group, @@ -133,7 +206,10 @@ bool MainWindow::showOptionsDialog(const QString &group, parent = this; CSettingsDialog settingsDialog(m_pluginManager, group, page, parent); settingsDialog.show(); - return settingsDialog.execDialog(); + bool ok = settingsDialog.execDialog(); + if (ok) + Q_EMIT m_coreImpl->changeSettings(); + return ok; } void MainWindow::about() @@ -143,6 +219,11 @@ void MainWindow::about() "

Ryzom Core team

Compiled on %1 %2").arg(__DATE__).arg(__TIME__)); } +void MainWindow::updateContext(Core::IContext *context) +{ + m_undoGroup->setActiveStack(context->undoStack()); +} + void MainWindow::closeEvent(QCloseEvent *event) { QList listeners = m_pluginManager->getObjects(); @@ -160,24 +241,41 @@ void MainWindow::closeEvent(QCloseEvent *event) event->accept(); } -void MainWindow::addContextObject(IContext *context) -{ - QWidget *tabWidget = new QWidget(m_tabWidget); - m_tabWidget->addTab(tabWidget, context->icon(), context->trName()); - QGridLayout *gridLayout = new QGridLayout(tabWidget); - gridLayout->setObjectName(QString::fromUtf8("gridLayout_") + context->id()); - gridLayout->setContentsMargins(0, 0, 0, 0); - gridLayout->addWidget(context->widget(), 0, 0, 1, 1); -} - void MainWindow::createActions() { + m_newAction = new QAction(tr("&New"), this); + m_newAction->setIcon(QIcon(Constants::ICON_NEW)); + m_newAction->setShortcut(QKeySequence::New); + menuManager()->registerAction(m_newAction, Constants::NEW); + connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile())); + m_newAction->setEnabled(false); + m_openAction = new QAction(tr("&Open..."), this); m_openAction->setIcon(QIcon(Constants::ICON_OPEN)); m_openAction->setShortcut(QKeySequence::Open); m_openAction->setStatusTip(tr("Open an existing file")); menuManager()->registerAction(m_openAction, Constants::OPEN); -// connect(m_openAction, SIGNAL(triggered()), this, SLOT(open())); + connect(m_openAction, SIGNAL(triggered()), this, SLOT(open())); + + m_saveAction = new QAction(tr("&Save"), this); + m_saveAction->setIcon(QIcon(Constants::ICON_SAVE)); + m_saveAction->setShortcut(QKeySequence::Save); + menuManager()->registerAction(m_saveAction, Constants::SAVE); + connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save())); + m_saveAction->setEnabled(false); + + m_saveAsAction = new QAction(tr("Save &As..."), this); + m_saveAsAction->setIcon(QIcon(Constants::ICON_SAVE_AS)); + m_saveAsAction->setShortcut(QKeySequence::SaveAs); + menuManager()->registerAction(m_saveAsAction, Constants::SAVE_AS); + connect(m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs())); + m_saveAsAction->setEnabled(false); + + m_saveAllAction = new QAction(tr("&Save A&ll"), this); + m_saveAllAction->setShortcut(QKeySequence::SelectAll); + menuManager()->registerAction(m_saveAllAction, Constants::SAVE_ALL); + connect(m_saveAllAction, SIGNAL(triggered()), this, SLOT(saveAll())); + m_saveAllAction->setEnabled(false); m_exitAction = new QAction(tr("E&xit"), this); m_exitAction->setShortcut(QKeySequence(tr("Ctrl+Q"))); @@ -185,6 +283,54 @@ void MainWindow::createActions() menuManager()->registerAction(m_exitAction, Constants::EXIT); connect(m_exitAction, SIGNAL(triggered()), this, SLOT(close())); + m_cutAction = new QAction(tr("Cu&t"), this); + m_cutAction->setShortcut(QKeySequence::Cut); + menuManager()->registerAction(m_cutAction, Constants::CUT); + connect(m_cutAction, SIGNAL(triggered()), this, SLOT(cut())); + m_cutAction->setEnabled(false); + + m_copyAction = new QAction(tr("&Copy"), this); + m_copyAction->setShortcut(QKeySequence::Copy); + menuManager()->registerAction(m_copyAction, Constants::COPY); + connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copy())); + m_copyAction->setEnabled(false); + + m_pasteAction = new QAction(tr("&Paste"), this); + m_pasteAction->setShortcut(QKeySequence::Paste); + menuManager()->registerAction(m_pasteAction, Constants::PASTE); + connect(m_pasteAction, SIGNAL(triggered()), this, SLOT(paste())); + m_pasteAction->setEnabled(false); + + m_delAction = new QAction(tr("&Delete"), this); + m_delAction->setShortcut(QKeySequence::Delete); + menuManager()->registerAction(m_delAction, Constants::DEL); + connect(m_delAction, SIGNAL(triggered()), this, SLOT(del())); + m_delAction->setEnabled(false); + + m_selectAllAction = new QAction(tr("Select &All"), this); + m_selectAllAction->setShortcut(QKeySequence::SelectAll); + menuManager()->registerAction(m_selectAllAction, Constants::SELECT_ALL); + connect(m_selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll())); + m_selectAllAction->setEnabled(false); + + m_findAction = new QAction(tr("&Find"), this); + m_findAction->setShortcut(QKeySequence::Find); + menuManager()->registerAction(m_findAction, Constants::FIND); + connect(m_findAction, SIGNAL(triggered()), this, SLOT(find())); + m_findAction->setEnabled(false); + + m_gotoAction = new QAction(tr("&Go To.."), this); + m_gotoAction->setShortcut(QKeySequence(tr("Ctrl+G"))); + menuManager()->registerAction(m_gotoAction, Constants::GOTO_POS); + connect(m_gotoAction, SIGNAL(triggered()), this, SLOT(gotoPos())); + m_gotoAction->setEnabled(false); + + m_fullscreenAction = new QAction(tr("Fullscreen"), this); + m_fullscreenAction->setCheckable(true); + m_fullscreenAction->setShortcut(QKeySequence(tr("Ctrl+Shift+F11"))); + menuManager()->registerAction(m_fullscreenAction, Constants::TOGGLE_FULLSCREEN); + connect(m_fullscreenAction, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool))); + m_settingsAction = new QAction(tr("&Settings"), this); m_settingsAction->setIcon(QIcon(":/images/preferences.png")); m_settingsAction->setShortcut(QKeySequence::Preferences); @@ -218,18 +364,43 @@ void MainWindow::createActions() void MainWindow::createMenus() { - m_fileMenu = menuBar()->addMenu(tr("&File")); + m_fileMenu = m_menuBar->addMenu(tr("&File")); menuManager()->registerMenu(m_fileMenu, Constants::M_FILE); + m_fileMenu->addAction(m_newAction); + m_fileMenu->addAction(m_openAction); + m_fileMenu->addSeparator(); + m_fileMenu->addAction(m_saveAction); + m_fileMenu->addAction(m_saveAsAction); + m_fileMenu->addAction(m_saveAllAction); + m_fileMenu->addSeparator(); + + m_recentFilesMenu = m_fileMenu->addMenu(tr("Recent &Files")); + m_recentFilesMenu->setEnabled(false); + menuManager()->registerMenu(m_recentFilesMenu, Constants::M_FILE_RECENTFILES); + m_fileMenu->addSeparator(); m_fileMenu->addAction(m_exitAction); - m_editMenu = menuBar()->addMenu(tr("&Edit")); + m_editMenu = m_menuBar->addMenu(tr("&Edit")); + m_editMenu->addAction(m_undoGroup->createUndoAction(this)); + m_editMenu->addAction(m_undoGroup->createRedoAction(this)); + m_editMenu->addSeparator(); + m_editMenu->addAction(m_cutAction); + m_editMenu->addAction(m_copyAction); + m_editMenu->addAction(m_pasteAction); + m_editMenu->addAction(m_delAction); + m_editMenu->addSeparator(); + m_editMenu->addAction(m_selectAllAction); + m_editMenu->addSeparator(); + m_editMenu->addAction(m_findAction); + m_editMenu->addAction(m_gotoAction); menuManager()->registerMenu(m_editMenu, Constants::M_EDIT); - m_viewMenu = menuBar()->addMenu(tr("&View")); + m_viewMenu = m_menuBar->addMenu(tr("&View")); + m_viewMenu->addAction(m_fullscreenAction); menuManager()->registerMenu(m_viewMenu, Constants::M_VIEW); - m_toolsMenu = menuBar()->addMenu(tr("&Tools")); + m_toolsMenu = m_menuBar->addMenu(tr("&Tools")); menuManager()->registerMenu(m_toolsMenu, Constants::M_TOOLS); m_sheetMenu = m_toolsMenu->addMenu(tr("&Sheet")); @@ -239,9 +410,9 @@ void MainWindow::createMenus() m_toolsMenu->addAction(m_settingsAction); - menuBar()->addSeparator(); + m_menuBar->addSeparator(); - m_helpMenu = menuBar()->addMenu(tr("&Help")); + m_helpMenu = m_menuBar->addMenu(tr("&Help")); menuManager()->registerMenu(m_helpMenu, Constants::M_HELP); m_helpMenu->addAction(m_aboutAction); m_helpMenu->addAction(m_aboutQtAction); @@ -260,17 +431,17 @@ void MainWindow::createDialogs() void MainWindow::readSettings() { - m_settings->beginGroup("MainWindow"); - restoreState(m_settings->value("WindowState").toByteArray()); - restoreGeometry(m_settings->value("WindowGeometry").toByteArray()); + m_settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + restoreState(m_settings->value(Constants::MAIN_WINDOW_STATE).toByteArray()); + restoreGeometry(m_settings->value(Constants::MAIN_WINDOW_GEOMETRY).toByteArray()); m_settings->endGroup(); } void MainWindow::writeSettings() { - m_settings->beginGroup("MainWindow"); - m_settings->setValue("WindowState", saveState()); - m_settings->setValue("WindowGeometry", saveGeometry()); + m_settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + m_settings->setValue(Constants::MAIN_WINDOW_STATE, saveState()); + m_settings->setValue(Constants::MAIN_WINDOW_GEOMETRY, saveGeometry()); m_settings->endGroup(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h index 21d091ef3..ce439b885 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h @@ -26,6 +26,7 @@ // Qt includes #include +#include #include namespace Core @@ -35,6 +36,7 @@ class CorePlugin; class IContext; class IMenuManager; class MenuManager; +class ContextManager; class CoreImpl; class MainWindow : public QMainWindow @@ -49,25 +51,39 @@ public: void extensionsInitialized(); IMenuManager *menuManager() const; + ContextManager *contextManager() const; QSettings *settings() const; ExtensionSystem::IPluginManager *pluginManager() const; + void addContextObject(IContext *context); + void removeContextObject(IContext *context); + public Q_SLOTS: bool showOptionsDialog(const QString &group = QString(), const QString &page = QString(), QWidget *parent = 0); private Q_SLOTS: - void checkObject(QObject *obj); + void open(); + void newFile(); + void save(); + void saveAs(); + void saveAll(); + void cut(); + void copy(); + void paste(); + void del(); + void find(); + void gotoPos(); + void setFullScreen(bool enabled); void about(); + void updateContext(Core::IContext *context); protected: virtual void closeEvent(QCloseEvent *event); private: - void addContextObject(IContext *appPage); - void createActions(); void createMenus(); void createStatusBar(); @@ -79,11 +95,13 @@ private: ExtensionSystem::IPluginManager *m_pluginManager; ExtensionSystem::CPluginView *m_pluginView; MenuManager *m_menuManager; + ContextManager *m_contextManager; CoreImpl *m_coreImpl; QPalette m_originalPalette; QString m_lastDir; + QUndoGroup *m_undoGroup; QSettings *m_settings; QTimer *m_mainTimer; @@ -92,15 +110,28 @@ private: QTabWidget *m_tabWidget; QMenu *m_fileMenu; + QMenu *m_recentFilesMenu; QMenu *m_editMenu; QMenu *m_viewMenu; QMenu *m_toolsMenu; QMenu *m_helpMenu; - + QMenuBar *m_menuBar; QMenu *m_sheetMenu; + QAction *m_newAction; QAction *m_openAction; + QAction *m_saveAction; + QAction *m_saveAsAction; + QAction *m_saveAllAction; QAction *m_exitAction; + QAction *m_cutAction; + QAction *m_copyAction; + QAction *m_pasteAction; + QAction *m_delAction; + QAction *m_selectAllAction; + QAction *m_findAction; + QAction *m_gotoAction; + QAction *m_fullscreenAction; QAction *m_settingsAction; QAction *m_pluginViewAction; QAction *m_aboutAction; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.cpp index c52624717..355a9c0e3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.cpp @@ -33,8 +33,9 @@ namespace Core QString lastDir = "."; -CSearchPathsSettingsPage::CSearchPathsSettingsPage(QObject *parent) +CSearchPathsSettingsPage::CSearchPathsSettingsPage(bool recurse, QObject *parent) : IOptionsPage(parent), + m_recurse(recurse), m_page(0) { } @@ -45,22 +46,33 @@ CSearchPathsSettingsPage::~CSearchPathsSettingsPage() QString CSearchPathsSettingsPage::id() const { - return QLatin1String("SearchPaths"); + if (m_recurse) + return QLatin1String("search_recurse_paths"); + else + return QLatin1String("search_paths"); } QString CSearchPathsSettingsPage::trName() const { - return tr("Search Paths"); + if (m_recurse) + return tr("Search Recurse Paths"); + else + return tr("Search Paths"); } QString CSearchPathsSettingsPage::category() const { - return QLatin1String("General"); + return QLatin1String(Constants::SETTINGS_CATEGORY_GENERAL); } QString CSearchPathsSettingsPage::trCategory() const { - return tr("General"); + return tr(Constants::SETTINGS_TR_CATEGORY_GENERAL); +} + +QIcon CSearchPathsSettingsPage::categoryIcon() const +{ + return QIcon(); } QWidget *CSearchPathsSettingsPage::createPage(QWidget *parent) @@ -92,17 +104,24 @@ void CSearchPathsSettingsPage::finish() void CSearchPathsSettingsPage::applySearchPaths() { - QStringList paths; + QStringList paths, remapExt; QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup(Core::Constants::DATA_PATH_SECTION); - paths = settings->value(Core::Constants::SEARCH_PATHS).toStringList(); + if (m_recurse) + paths = settings->value(Core::Constants::RECURSIVE_SEARCH_PATHS).toStringList(); + else + paths = settings->value(Core::Constants::SEARCH_PATHS).toStringList(); + + remapExt = settings->value(Core::Constants::REMAP_EXTENSIONS).toStringList(); settings->endGroup(); + + for (int i = 1; i < remapExt.size(); i += 2) + NLMISC::CPath::remapExtension(remapExt.at(i - 1).toStdString(), remapExt.at(i).toStdString(), true); + Q_FOREACH(QString path, paths) { - NLMISC::CPath::addSearchPath(path.toStdString(), false, false); + NLMISC::CPath::addSearchPath(path.toStdString(), m_recurse, false); } - NLMISC::CPath::remapExtension("png", "tga", true); - NLMISC::CPath::remapExtension("png", "dds", true); } void CSearchPathsSettingsPage::addPath() @@ -156,7 +175,10 @@ void CSearchPathsSettingsPage::readSettings() QStringList paths; QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup(Core::Constants::DATA_PATH_SECTION); - paths = settings->value(Core::Constants::SEARCH_PATHS).toStringList(); + if (m_recurse) + paths = settings->value(Core::Constants::RECURSIVE_SEARCH_PATHS).toStringList(); + else + paths = settings->value(Core::Constants::SEARCH_PATHS).toStringList(); settings->endGroup(); Q_FOREACH(QString path, paths) { @@ -175,8 +197,12 @@ void CSearchPathsSettingsPage::writeSettings() QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup(Core::Constants::DATA_PATH_SECTION); - settings->setValue(Core::Constants::SEARCH_PATHS, paths); + if (m_recurse) + settings->setValue(Core::Constants::RECURSIVE_SEARCH_PATHS, paths); + else + settings->setValue(Core::Constants::SEARCH_PATHS, paths); settings->endGroup(); + settings->sync(); } void CSearchPathsSettingsPage::checkEnabledButton() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.h index 15f28f6c8..c7d4c9734 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.h @@ -37,18 +37,20 @@ class CSearchPathsSettingsPage : public Core::IOptionsPage Q_OBJECT public: - CSearchPathsSettingsPage(QObject *parent = 0); + explicit CSearchPathsSettingsPage(bool recurse, QObject *parent = 0); ~CSearchPathsSettingsPage(); QString id() const; QString trName() const; QString category() const; QString trCategory() const; + QIcon categoryIcon() const; QWidget *createPage(QWidget *parent); void apply(); void finish(); + // Set of the search paths(not recursive) and the remap extensions (loading from settings file) void applySearchPaths(); private Q_SLOTS: @@ -62,6 +64,7 @@ private: void writeSettings(); void checkEnabledButton(); + bool m_recurse; QWidget *m_page; Ui::CSearchPathsSettingsPage m_ui; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.cpp index 0cb885163..50e7c9db5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.cpp @@ -53,6 +53,11 @@ QString CExampleSettingsPage::trCategory() const return tr("General"); } +QIcon CExampleSettingsPage::categoryIcon() const +{ + return QIcon(); +} + QWidget *CExampleSettingsPage::createPage(QWidget *parent) { _currentPage = new QWidget(parent); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.h index 64dd940f8..3475f843f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.h @@ -43,6 +43,7 @@ public: virtual QString trName() const; virtual QString category() const; virtual QString trCategory() const; + QIcon categoryIcon() const; virtual QWidget *createPage(QWidget *parent); virtual void apply(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp index cde1ca199..f218c3230 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp @@ -90,7 +90,6 @@ QStringList MyPlugin::dependencies() const { QStringList list; list.append(Core::Constants::OVQT_CORE_PLUGIN); - list.append("ObjectViewer"); return list; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h index d3be3bc38..5077ff59e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h @@ -86,6 +86,15 @@ public: return m_simpleViewer; } + virtual QUndoStack *undoStack() + { + return m_simpleViewer->m_undoStack; + } + + virtual void open() + { + } + CSimpleViewer *m_simpleViewer; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.cpp index 9a67abb80..4872923db 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.cpp @@ -38,6 +38,9 @@ QNLWidget::QNLWidget(QWidget *parent) m_initialized(false), m_interval(25) { + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_PaintOnScreen); setMouseTracking(true); setFocusPolicy(Qt::StrongFocus); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.cpp index e128710c4..1f6df9117 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.cpp @@ -37,6 +37,8 @@ CSimpleViewer::CSimpleViewer(QWidget *parent) gridLayout->setContentsMargins(0, 0, 0, 0); NLQT::QNLWidget *_nelWidget = new NLQT::QNLWidget(this); gridLayout->addWidget(_nelWidget, 0, 0, 1, 1); + + m_undoStack = new QUndoStack(this); } bool CCoreListener::closeMainWindow() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.h index bbff7e9e0..14b782c22 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.h @@ -25,7 +25,7 @@ // Qt includes #include - +#include class QWidget; namespace Plugin @@ -37,6 +37,8 @@ class CSimpleViewer : public QWidget public: CSimpleViewer(QWidget *parent = 0); virtual ~CSimpleViewer() {} + + QUndoStack *m_undoStack; }; class CCoreListener : public Core::ICoreListener diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/CMakeLists.txt new file mode 100644 index 000000000..d1dd346ba --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/CMakeLists.txt @@ -0,0 +1,43 @@ +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${QT_INCLUDES}) + +FILE(GLOB SRC *.cpp *.h) +SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) + +SET(OVQT_PLUG_GEORGES_EDITOR_HDR georges_editor_plugin.h + georges_editor_form.h + georges_dirtree_dialog.h) + +SET(OVQT_PLUG_GEORGES_EDITOR_UIS georges_editor_form.ui + georges_dirtree_form.ui) + +SET(OVQT_PLUGIN_GEORGES_EDITOR_RCS georges_editor.qrc) + +SET(QT_USE_QTGUI TRUE) +SET(QT_USE_QTOPENGL TRUE) + +QT4_ADD_RESOURCES(OVQT_PLUGIN_GEORGES_EDITOR_RC_SRCS ${OVQT_PLUGIN_GEORGES_EDITOR_RCS}) +QT4_WRAP_CPP(OVQT_PLUG_GEORGES_EDITOR_MOC_SRC ${OVQT_PLUG_GEORGES_EDITOR_HDR}) +QT4_WRAP_UI( OVQT_PLUG_GEORGES_EDITOR_UI_HDRS ${OVQT_PLUG_GEORGES_EDITOR_UIS} ) + +SOURCE_GROUP(QtResources FILES ${OVQT_PLUG_GEORGES_EDITOR_UIS} ${OVQT_PLUGIN_GEORGES_EDITOR_RCS}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${OVQT_PLUG_GEORGES_EDITOR_UI_HDRS}) +SOURCE_GROUP(QtGeneratedMocSrc FILES ${OVQT_PLUG_GEORGES_EDITOR_MOC_SRC}) +SOURCE_GROUP("Georges Editor Plugin" FILES ${SRC}) +SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) + +ADD_LIBRARY(ovqt_plugin_georges_editor MODULE ${SRC} ${OVQT_PLUG_GEORGES_EDITOR_MOC_SRC} ${OVQT_EXT_SYS_SRC} ${OVQT_PLUG_GEORGES_EDITOR_UI_HDRS} ${OVQT_PLUGIN_GEORGES_EDITOR_RC_SRCS}) + +TARGET_LINK_LIBRARIES(ovqt_plugin_georges_editor ovqt_plugin_core nelmisc ${QT_LIBRARIES}) + +NL_DEFAULT_PROPS(ovqt_plugin_georges_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Georges Editor") +NL_ADD_RUNTIME_FLAGS(ovqt_plugin_georges_editor) +NL_ADD_LIB_SUFFIX(ovqt_plugin_georges_editor) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) + +INSTALL(TARGETS ovqt_plugin_georges_editor LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib COMPONENT tools3d) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.cpp new file mode 100644 index 000000000..f7e250cce --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.cpp @@ -0,0 +1,99 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "georges_dirtree_dialog.h" + +// Qt includes +#include +#include + +// NeL includes + +//using namespace NLMISC; + +namespace Plugin +{ + +CGeorgesDirTreeDialog::CGeorgesDirTreeDialog(QString ldPath, QWidget *parent) + :QDockWidget(parent), m_ldPath(ldPath) +{ + + m_ui.setupUi(this); + + m_dirModel = new CGeorgesFileSystemModel(m_ldPath); + m_ui.dirTree->setModel(m_dirModel); + + if (m_dirModel->isCorrectLDPath()) + { + m_dirModel->setRootPath(m_ldPath); + m_ui.dirTree->setRootIndex(m_dirModel->index(m_ldPath)); + } + else + { + m_dirModel->setRootPath(QDir::currentPath()); + } + + m_ui.dirTree->setAnimated(false); + m_ui.dirTree->setIndentation(20); + + connect(m_ui.dirTree, SIGNAL(activated(QModelIndex)), + this, SLOT(fileSelected(QModelIndex))); +} + +CGeorgesDirTreeDialog::~CGeorgesDirTreeDialog() +{ + delete m_dirModel; +} + +void CGeorgesDirTreeDialog::fileSelected(QModelIndex index) +{ + QString name; + if (index.isValid() && !m_dirModel->isDir(index)) + { + Q_EMIT selectedForm(m_dirModel->fileName(index)); + } +} + +void CGeorgesDirTreeDialog::changeFile(QString file) +{ + QModelIndex index = m_dirModel->index(file); + m_ui.dirTree->selectionModel()->select(index,QItemSelectionModel::ClearAndSelect); + m_ui.dirTree->scrollTo(index,QAbstractItemView::PositionAtCenter); + fileSelected(index); +} + +void CGeorgesDirTreeDialog::ldPathChanged(QString path) +{ + m_ldPath = path; + + delete m_dirModel; + + m_dirModel = new CGeorgesFileSystemModel(m_ldPath); + m_ui.dirTree->setModel(m_dirModel); + + if (m_dirModel->isCorrectLDPath()) + { + m_dirModel->setRootPath(m_ldPath); + m_ui.dirTree->setRootIndex(m_dirModel->index(m_ldPath)); + } + else + { + m_dirModel->setRootPath(QDir::currentPath()); + } +} + +} /* namespace NLQT */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.h new file mode 100644 index 000000000..3079f76c2 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.h @@ -0,0 +1,62 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGES_DIRTREE_DIALOG_H +#define GEORGES_DIRTREE_DIALOG_H + +// Qt includes +#include + +// STL includes + +// NeL includes + +// Project includes +#include "ui_georges_dirtree_form.h" +#include "georges_filesystem_model.h" + +namespace Plugin +{ + +class CGeorgesDirTreeDialog: public QDockWidget +{ + Q_OBJECT + +public: + CGeorgesDirTreeDialog(QString ldPath, QWidget *parent = 0); + ~CGeorgesDirTreeDialog(); + + void ldPathChanged(QString); + +private: + Ui::CGeorgesDirTreeDialog m_ui; + + CGeorgesFileSystemModel *m_dirModel; + QString m_ldPath; + +Q_SIGNALS: + void selectedForm(const QString); + +private Q_SLOTS: + void fileSelected(QModelIndex index); + void changeFile(QString file); + + friend class CMainWindow; +}; /* CGEorgesDirTreeDialog */ + +} /* namespace NLQT */ + +#endif // GEORGES_DIRTREE_DIALOG_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_form.ui new file mode 100644 index 000000000..8731d1ca8 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_form.ui @@ -0,0 +1,54 @@ + + + CGeorgesDirTreeDialog + + + + 0 + 0 + 400 + 300 + + + + + 0 + 0 + + + + + 200 + 111 + + + + QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable + + + Leveldesign Path + + + + + 50 + 0 + + + + + + + + 0 + 0 + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor.qrc new file mode 100644 index 000000000..3d514dbc0 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor.qrc @@ -0,0 +1,5 @@ + + + images/ic_nel_georges_editor.png + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_constants.h new file mode 100644 index 000000000..bb9fe3306 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_constants.h @@ -0,0 +1,31 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGES_EDITOR_CONSTANTS_H +#define GEORGES_EDITOR_CONSTANTS_H + +namespace Plugin +{ +namespace Constants +{ +//settings +const char * const GEORGES_EDITOR_SECTION = "GeorgesEditor"; + + +} // namespace Constants +} // namespace Plugin + +#endif // GEORGES_EDITOR_CONSTANTS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.cpp new file mode 100644 index 000000000..aa614a161 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.cpp @@ -0,0 +1,139 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "georges_editor_form.h" +#include "georges_editor_constants.h" +#include "georges_dirtree_dialog.h" + +#include "../core/icore.h" +#include "../core/imenu_manager.h" +#include "../core/core_constants.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include + +namespace Plugin +{ + +GeorgesEditorForm::GeorgesEditorForm(QWidget *parent) + : QMainWindow(parent), + m_georgesDirTreeDialog(0) +{ + m_ui.setupUi(this); + + m_undoStack = new QUndoStack(this); + + _openAction = new QAction(tr("&Open..."), this); + _openAction->setIcon(QIcon(Core::Constants::ICON_OPEN)); + _openAction->setShortcut(QKeySequence::Open); + _openAction->setStatusTip(tr("Open an existing file")); + connect(_openAction, SIGNAL(triggered()), this, SLOT(open())); + + _newAction = new QAction(tr("&New..."), this); + _newAction->setIcon(QIcon(Core::Constants::ICON_NEW)); + _newAction->setShortcut(QKeySequence::New); + _newAction->setStatusTip(tr("Create a new file")); + connect(_newAction, SIGNAL(triggered()), this, SLOT(newFile())); + + _saveAction = new QAction(tr("&Save..."), this); + _saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE)); + _saveAction->setShortcut(QKeySequence::Save); + _saveAction->setStatusTip(tr("Save the current file")); + connect(_saveAction, SIGNAL(triggered()), this, SLOT(save())); + + _fileToolBar = addToolBar(tr("&File")); + _fileToolBar->addAction(_openAction); + _fileToolBar->addAction(_newAction); + _fileToolBar->addAction(_saveAction); + + readSettings(); + + // create leveldesign directory tree dockwidget + m_georgesDirTreeDialog = new CGeorgesDirTreeDialog(m_leveldesignPath, this); + addDockWidget(Qt::LeftDockWidgetArea, m_georgesDirTreeDialog); + //m_georgesDirTreeDialog->setVisible(false); + connect(Core::ICore::instance(), SIGNAL(changeSettings()), + this, SLOT(settingsChanged())); +} + +GeorgesEditorForm::~GeorgesEditorForm() +{ + writeSettings(); +} + +QUndoStack *GeorgesEditorForm::undoStack() const +{ + return m_undoStack; +} + +void GeorgesEditorForm::open() +{ + // TODO: FileDialog & loadFile(); + //QString fileName = QFileDialog::getOpenFileName(); + //loadFile(fileName); +} + +void GeorgesEditorForm::newFile() +{ + +} + +void GeorgesEditorForm::save() +{ + +} + +void GeorgesEditorForm::readSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::GEORGES_EDITOR_SECTION); + settings->endGroup(); + + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + m_leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString(); + settings->endGroup(); +} + +void GeorgesEditorForm::writeSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::GEORGES_EDITOR_SECTION); + settings->endGroup(); + settings->sync(); +} + +void GeorgesEditorForm::settingsChanged() +{ + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + QString oldLDPath = m_leveldesignPath; + m_leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString(); + settings->endGroup(); + + if (oldLDPath != m_leveldesignPath) + { + m_georgesDirTreeDialog->ldPathChanged(m_leveldesignPath); + } +} + +} /* namespace Plugin */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.h new file mode 100644 index 000000000..96fceb4ed --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.h @@ -0,0 +1,64 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGES_EDITOR_FORM_H +#define GEORGES_EDITOR_FORM_H + +// Project includes +#include "ui_georges_editor_form.h" + +// Qt includes +#include + +namespace Plugin +{ + +class CGeorgesDirTreeDialog; +class GeorgesEditorForm: public QMainWindow +{ + Q_OBJECT + +public: + GeorgesEditorForm(QWidget *parent = 0); + ~GeorgesEditorForm(); + + QUndoStack *undoStack() const; + +public Q_SLOTS: + void open(); + void newFile(); + void save(); + void settingsChanged(); + +private: + void readSettings(); + void writeSettings(); + + QUndoStack *m_undoStack; + Ui::GeorgesEditorForm m_ui; + + CGeorgesDirTreeDialog *m_georgesDirTreeDialog; + QToolBar *_fileToolBar; + QAction *_openAction; + QAction *_newAction; + QAction *_saveAction; + + QString m_leveldesignPath; +}; /* class GeorgesEditorForm */ + +} /* namespace Plugin */ + +#endif // GEORGES_EDITOR_FORM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.ui new file mode 100644 index 000000000..905814cc7 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.ui @@ -0,0 +1,28 @@ + + + GeorgesEditorForm + + + + 0 + 0 + 800 + 600 + + + + Georges Editor + + + + QWidget#centralwidget { + image: url(:/images/ic_nel_georges_editor.png); + } + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.cpp new file mode 100644 index 000000000..a97188751 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.cpp @@ -0,0 +1,128 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "georges_editor_plugin.h" +#include "georges_editor_form.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" + +// NeL includes +#include "nel/misc/debug.h" + +// Qt includes +#include + +namespace Plugin +{ + +GeorgesEditorPlugin::~GeorgesEditorPlugin() +{ + Q_FOREACH(QObject *obj, m_autoReleaseObjects) + { + m_plugMan->removeObject(obj); + } + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); +} + +bool GeorgesEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) +{ + Q_UNUSED(errorString); + m_plugMan = pluginManager; + + addAutoReleasedObject(new GeorgesEditorContext(this)); + return true; +} + +void GeorgesEditorPlugin::extensionsInitialized() +{ +} + +void GeorgesEditorPlugin::shutdown() +{ +} + +void GeorgesEditorPlugin::setNelContext(NLMISC::INelContext *nelContext) +{ +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); +#endif // NL_OS_WINDOWS + m_libContext = new NLMISC::CLibraryContext(*nelContext); +} + +QString GeorgesEditorPlugin::name() const +{ + return tr("Georges Editor"); +} + +QString GeorgesEditorPlugin::version() const +{ + return "0.2"; +} + +QString GeorgesEditorPlugin::vendor() const +{ + return "aquiles"; +} + +QString GeorgesEditorPlugin::description() const +{ + return tr("Tool to create & edit sheets or forms."); +} + +QStringList GeorgesEditorPlugin::dependencies() const +{ + QStringList list; + list.append(Core::Constants::OVQT_CORE_PLUGIN); + list.append("ObjectViewer"); // TODO + return list; +} + +void GeorgesEditorPlugin::addAutoReleasedObject(QObject *obj) +{ + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); +} + +GeorgesEditorContext::GeorgesEditorContext(QObject *parent) + : IContext(parent), + m_georgesEditorForm(0) +{ + m_georgesEditorForm = new GeorgesEditorForm(); +} + +QUndoStack *GeorgesEditorContext::undoStack() +{ + return m_georgesEditorForm->undoStack(); +} + +void GeorgesEditorContext::open() +{ + m_georgesEditorForm->open(); +} + +QWidget *GeorgesEditorContext::widget() +{ + return m_georgesEditorForm; +} + +} + +Q_EXPORT_PLUGIN(Plugin::GeorgesEditorPlugin) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.h new file mode 100644 index 000000000..7cc93dfb4 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.h @@ -0,0 +1,105 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGES_EDITOR_PLUGIN_H +#define GEORGES_EDITOR_PLUGIN_H + +// Project includes +#include "../../extension_system/iplugin.h" +#include "../core/icontext.h" + +// NeL includes +#include "nel/misc/app_context.h" + +// Qt includes +#include +#include + +namespace NLMISC +{ +class CLibraryContext; +} + +namespace ExtensionSystem +{ +class IPluginSpec; +} + +namespace Plugin +{ +class GeorgesEditorForm; +class GeorgesEditorPlugin : public QObject, public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_INTERFACES(ExtensionSystem::IPlugin) +public: + + virtual ~GeorgesEditorPlugin(); + + bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); + void extensionsInitialized(); + void shutdown(); + + void setNelContext(NLMISC::INelContext *nelContext); + + QString name() const; + QString version() const; + QString vendor() const; + QString description() const; + QStringList dependencies() const; + + void addAutoReleasedObject(QObject *obj); + +protected: + NLMISC::CLibraryContext *m_libContext; + +private: + ExtensionSystem::IPluginManager *m_plugMan; + QList m_autoReleaseObjects; +}; + +class GeorgesEditorContext: public Core::IContext +{ + Q_OBJECT +public: + GeorgesEditorContext(QObject *parent = 0); + virtual ~GeorgesEditorContext() {} + + virtual QString id() const + { + return QLatin1String("GeorgesEditorContext"); + } + virtual QString trName() const + { + return tr("Georges Editor"); + } + virtual QIcon icon() const + { + return QIcon(":/images/ic_nel_georges_editor.png"); + } + + virtual void open(); + + virtual QUndoStack *undoStack(); + + virtual QWidget *widget(); + + GeorgesEditorForm *m_georgesEditorForm; +}; + +} // namespace Plugin + +#endif // LANDSCAPE_EDITOR_PLUGIN_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.cpp new file mode 100644 index 000000000..20cb30b33 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.cpp @@ -0,0 +1,95 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "georges_filesystem_model.h" + +#include +#include + +namespace Plugin +{ + +CGeorgesFileSystemModel::CGeorgesFileSystemModel(QString ldPath, QObject *parent) + : QFileSystemModel(parent), + m_ldPath(ldPath), + m_correct(false) +{ + checkLDPath(); +} + +CGeorgesFileSystemModel::~CGeorgesFileSystemModel() +{ + +} + +QVariant CGeorgesFileSystemModel::data(const QModelIndex& index, int role) const +{ + + if (role == Qt::DecorationRole) + { + if (!m_correct) + return QVariant(); + if (isDir(index)) + return QApplication::style()->standardIcon(QStyle::SP_DirIcon); + } + if (!m_correct && role == Qt::DisplayRole) + { + if (index.parent().isValid()) + return QVariant(); + return tr("Set a correct leveldesign path ..."); + } + return QFileSystemModel::data(index, role); +} + +int CGeorgesFileSystemModel::columnCount(const QModelIndex &/*parent*/) const +{ + return 1; +} + +int CGeorgesFileSystemModel::rowCount(const QModelIndex &parent) const +{ + + if (!m_correct) + { + if(parent.isValid()) + { + return 0; + } + else + { + return qMin(QFileSystemModel::rowCount(parent),1); + } + } + return QFileSystemModel::rowCount(parent); +} + +void CGeorgesFileSystemModel::checkLDPath() +{ + QFileInfo check1(QString("%1/game_element").arg(m_ldPath)); + QFileInfo check2(QString("%1/DFN").arg(m_ldPath)); + + if (check1.exists() && check2.exists()) + { + m_correct = true; + } + else + { + m_correct = false; + } +} +} /* namespace NLQT */ + +/* end of file */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.h new file mode 100644 index 000000000..775dcb18d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.h @@ -0,0 +1,50 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGES_FILESYSTEM_MODEL_H +#define GEORGES_FILESYSTEM_MODEL_H + +#include + +namespace Plugin +{ + +class CGeorgesFileSystemModel : public QFileSystemModel +{ + QString m_ldPath; + +public: + CGeorgesFileSystemModel(QString ldPath, QObject *parent = 0); + ~CGeorgesFileSystemModel(); + + int columnCount(const QModelIndex &/*parent*/) const; + int rowCount(const QModelIndex &/*parent*/) const; + + QVariant data(const QModelIndex& index, int role) const ; + + bool isCorrectLDPath() + { + return m_correct; + } + void checkLDPath(); + +private: + bool m_correct; +};/* class CGeorgesFileSystemModel */ + +} /* namespace NLQT */ + +#endif // GEORGES_FILESYSTEM_MODEL_H \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/images/ic_nel_georges_editor.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/images/ic_nel_georges_editor.png new file mode 100644 index 0000000000000000000000000000000000000000..b293fec5286b9f86d8ad6e03602b041fdaf18c26 GIT binary patch literal 37356 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt new file mode 100644 index 000000000..3b6a61c5e --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -0,0 +1,48 @@ +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${QT_INCLUDES}) + +FILE(GLOB SRC *.cpp *.h) + +SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) + +SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h + landscape_editor_window.h +) + +SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui +) + +SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc) + +SET(QT_USE_QTGUI TRUE) +SET(QT_USE_QTOPENGL TRUE) + +QT4_ADD_RESOURCES(OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS ${OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS}) +QT4_WRAP_CPP(OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC ${OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR}) +QT4_WRAP_UI(OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS ${OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS}) + +SOURCE_GROUP(QtResources FILES ${OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS}) +SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC} OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS) +SOURCE_GROUP("Landscape Editor Plugin" FILES ${SRC}) +SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) + +ADD_LIBRARY(ovqt_plugin_landscape_editor MODULE ${SRC} + ${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC} + ${OVQT_EXT_SYS_SRC} + ${OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS} + ${OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS}) + +TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY}) + +NL_DEFAULT_PROPS(ovqt_plugin_landscape_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Landscape Editor") +NL_ADD_RUNTIME_FLAGS(ovqt_plugin_landscape_editor) +NL_ADD_LIB_SUFFIX(ovqt_plugin_landscape_editor) + +ADD_DEFINITIONS(-DLANDSCAPE_EDITOR_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) + +INSTALL(TARGETS ovqt_plugin_landscape_editor LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib COMPONENT tools3d) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_landscape_item.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_landscape_item.png new file mode 100644 index 0000000000000000000000000000000000000000..7a51400b39aec9a48b23f573cd091693466b80ce GIT binary patch literal 56924 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_landscape_settings.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_landscape_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..4197f7f974481968f968fd3e9267a5fd7b84d4db GIT binary patch literal 30656 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_world_editor.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_world_editor.png new file mode 100644 index 0000000000000000000000000000000000000000..d41f64e2fa43da9d64f9b528cc173593d4a94c59 GIT binary patch literal 44031 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 GHST}F+s82g literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_zone.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_zone.png new file mode 100644 index 0000000000000000000000000000000000000000..73be2752843040e6e3c0736b03eb3990210a9dc8 GIT binary patch literal 47312 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 b!8cqqH?6*Ah8^bs;iq%o@Lq*FD)RpT^Q{UA literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_zonel.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_zonel.png new file mode 100644 index 0000000000000000000000000000000000000000..40f75828b8f40646b66b9bb2e0fc8e831b629b64 GIT binary patch literal 57867 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 ZK*BeDhjmq-TLANCc+FJ5;;K{B{{a=o&Qt&Z literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor.qrc new file mode 100644 index 000000000..5dba9074b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor.qrc @@ -0,0 +1,9 @@ + + + icons/ic_nel_landscape_item.png + icons/ic_nel_landscape_settings.png + icons/ic_nel_world_editor.png + icons/ic_nel_zone.png + icons/ic_nel_zonel.png + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h new file mode 100644 index 000000000..52775f4c4 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h @@ -0,0 +1,37 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef LANDSCAPE_EDITOR_CONSTANTS_H +#define LANDSCAPE_EDITOR_CONSTANTS_H + +namespace LandscapeEditor +{ +namespace Constants +{ +const char * const LANDSCAPE_EDITOR_PLUGIN = "LandscapeEditor"; + +//settings +const char * const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor"; + +//resources +const char * const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png"; + + +} // namespace Constants +} // namespace LandscapeEditor + +#endif // LANDSCAPE_EDITOR_CONSTANTS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_global.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_global.h new file mode 100644 index 000000000..167c8e24f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_global.h @@ -0,0 +1,30 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef LANDSCAPE_EDITOR_GLOBAL_H +#define LANDSCAPE_EDITOR_GLOBAL_H + +#include + +#if defined(LANDSCAPE_EDITOR_LIBRARY) +# define LANDSCAPE_EDITOR_EXPORT Q_DECL_EXPORT +#else +# define LANDSCAPE_EDITOR_EXPORT Q_DECL_IMPORT +#endif + +#endif // LANDSCAPE_EDITOR_GLOBAL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp new file mode 100644 index 000000000..ac7782343 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp @@ -0,0 +1,128 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "landscape_editor_plugin.h" +#include "landscape_editor_window.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" + +// NeL includes +#include "nel/misc/debug.h" + +// Qt includes +#include + +namespace LandscapeEditor +{ + +LandscapeEditorPlugin::~LandscapeEditorPlugin() +{ + Q_FOREACH(QObject *obj, m_autoReleaseObjects) + { + m_plugMan->removeObject(obj); + } + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); +} + +bool LandscapeEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) +{ + Q_UNUSED(errorString); + m_plugMan = pluginManager; + + addAutoReleasedObject(new LandscapeEditorContext(this)); + return true; +} + +void LandscapeEditorPlugin::extensionsInitialized() +{ +} + +void LandscapeEditorPlugin::shutdown() +{ +} + +void LandscapeEditorPlugin::setNelContext(NLMISC::INelContext *nelContext) +{ +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); +#endif // NL_OS_WINDOWS + m_libContext = new NLMISC::CLibraryContext(*nelContext); +} + +QString LandscapeEditorPlugin::name() const +{ + return tr("LandscapeEditor"); +} + +QString LandscapeEditorPlugin::version() const +{ + return "0.0.1"; +} + +QString LandscapeEditorPlugin::vendor() const +{ + return "GSoC2011_dnk-88"; +} + +QString LandscapeEditorPlugin::description() const +{ + return "Landscape editor ovqt plugin."; +} + +QStringList LandscapeEditorPlugin::dependencies() const +{ + QStringList list; + list.append(Core::Constants::OVQT_CORE_PLUGIN); + return list; +} + +void LandscapeEditorPlugin::addAutoReleasedObject(QObject *obj) +{ + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); +} + +LandscapeEditorContext::LandscapeEditorContext(QObject *parent) + : IContext(parent), + m_landEditorWindow(0) +{ + m_landEditorWindow = new LandscapeEditorWindow(); +} + +QUndoStack *LandscapeEditorContext::undoStack() +{ + return m_landEditorWindow->undoStack(); +} + +void LandscapeEditorContext::open() +{ + m_landEditorWindow->open(); +} + +QWidget *LandscapeEditorContext::widget() +{ + return m_landEditorWindow; +} + +} + +Q_EXPORT_PLUGIN(LandscapeEditor::LandscapeEditorPlugin) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h new file mode 100644 index 000000000..67a3172ee --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h @@ -0,0 +1,108 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef LANDSCAPE_EDITOR_PLUGIN_H +#define LANDSCAPE_EDITOR_PLUGIN_H + +// Project includes +#include "landscape_editor_constants.h" +#include "../../extension_system/iplugin.h" +#include "../core/icontext.h" + +// NeL includes +#include "nel/misc/app_context.h" + +// Qt includes +#include +#include + +namespace NLMISC +{ +class CLibraryContext; +} + +namespace ExtensionSystem +{ +class IPluginSpec; +} + +namespace LandscapeEditor +{ +class LandscapeEditorWindow; + +class LandscapeEditorPlugin : public QObject, public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_INTERFACES(ExtensionSystem::IPlugin) +public: + + virtual ~LandscapeEditorPlugin(); + + bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); + void extensionsInitialized(); + void shutdown(); + + void setNelContext(NLMISC::INelContext *nelContext); + + QString name() const; + QString version() const; + QString vendor() const; + QString description() const; + QStringList dependencies() const; + + void addAutoReleasedObject(QObject *obj); + +protected: + NLMISC::CLibraryContext *m_libContext; + +private: + ExtensionSystem::IPluginManager *m_plugMan; + QList m_autoReleaseObjects; +}; + +class LandscapeEditorContext: public Core::IContext +{ + Q_OBJECT +public: + LandscapeEditorContext(QObject *parent = 0); + virtual ~LandscapeEditorContext() {} + + virtual QString id() const + { + return QLatin1String("LandscapeEditorContext"); + } + virtual QString trName() const + { + return tr("Landscape Editor"); + } + virtual QIcon icon() const + { + return QIcon(); + } + + virtual void open(); + + virtual QUndoStack *undoStack(); + + virtual QWidget *widget(); + + LandscapeEditorWindow *m_landEditorWindow; +}; + +} // namespace LandscapeEditor + +#endif // LANDSCAPE_EDITOR_PLUGIN_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp new file mode 100644 index 000000000..4b075adfc --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -0,0 +1,93 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "landscape_editor_window.h" +#include "landscape_editor_constants.h" + +#include "../core/icore.h" +#include "../core/imenu_manager.h" +#include "../core/core_constants.h" + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace LandscapeEditor +{ +QString _lastDir; + +LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) + : QMainWindow(parent) +{ + m_ui.setupUi(this); + + m_undoStack = new QUndoStack(this); + + createMenus(); + readSettings(); +} + +LandscapeEditorWindow::~LandscapeEditorWindow() +{ + writeSettings(); +} + +QUndoStack *LandscapeEditorWindow::undoStack() const +{ + return m_undoStack; +} + +void LandscapeEditorWindow::open() +{ + QStringList fileNames = QFileDialog::getOpenFileNames(this, + tr("Open NeL Ligo land file"), _lastDir, + tr("All NeL Ligo land files (*.land)")); + + setCursor(Qt::WaitCursor); + if (!fileNames.isEmpty()) + { + QStringList list = fileNames; + _lastDir = QFileInfo(list.front()).absolutePath(); + } + setCursor(Qt::ArrowCursor); +} + +void LandscapeEditorWindow::createMenus() +{ + Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); +} + +void LandscapeEditorWindow::readSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION); + settings->endGroup(); +} + +void LandscapeEditorWindow::writeSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION); + settings->endGroup(); + settings->sync(); +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h new file mode 100644 index 000000000..cc17e6cbc --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -0,0 +1,56 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef LANDSCAPE_EDITOR_WINDOW_H +#define LANDSCAPE_EDITOR_WINDOW_H + +// Project includes +#include "ui_landscape_editor_window.h" + +// Qt includes +#include + +namespace LandscapeEditor +{ + +class LandscapeEditorWindow: public QMainWindow +{ + Q_OBJECT + +public: + LandscapeEditorWindow(QWidget *parent = 0); + ~LandscapeEditorWindow(); + + QUndoStack *undoStack() const; + +Q_SIGNALS: +public Q_SLOTS: + void open(); + +private Q_SLOTS: +private: + void createMenus(); + void readSettings(); + void writeSettings(); + + QUndoStack *m_undoStack; + Ui::LandscapeEditorWindow m_ui; +}; /* class LandscapeEditorWindow */ + +} /* namespace LandscapeEditor */ + +#endif // LANDSCAPE_EDITOR_WINDOW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui new file mode 100644 index 000000000..5d9606ddf --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -0,0 +1,43 @@ + + + LandscapeEditorWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + :/icons/ic_nel_landscape_item.png:/icons/ic_nel_landscape_item.png + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/CMakeLists.txt index 555eac232..b497e3332 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/CMakeLists.txt @@ -1,7 +1,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${LIBXML2_INCLUDE_DIR} - ${QT_INCLUDES}) + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${QT_INCLUDES}) FILE(GLOB SRC *.cpp *.h) SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp index 439cce7d9..2f88200ec 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp @@ -1,24 +1,28 @@ -/* -Log Plugin Qt -Copyright (C) 2010 Adrian Jaekel - -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 3 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. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -*/ +// Object Viewer Qt - Log Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// Project includes #include "log_plugin.h" #include "log_settings_page.h" +#include "qt_displayer.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" +#include "../core/imenu_manager.h" +#include "../../extension_system/iplugin_spec.h" // Qt includes #include @@ -35,103 +39,153 @@ along with this program. If not, see . // NeL includes #include -// Project includes -#include "../core/icore.h" -#include "../core/core_constants.h" -#include "../core/imenu_manager.h" -#include "qt_displayer.h" - -using namespace Plugin; - -namespace ExtensionSystem +namespace Plugin { - class IPluginSpec; -} -CLogPlugin::CLogPlugin(QWidget *parent): QDockWidget(parent) -{ - _ui.setupUi(this); -} + CLogPlugin::CLogPlugin(QWidget *parent): QDockWidget(parent) + { + m_ui.setupUi(this); + } -CLogPlugin::~CLogPlugin() -{ - _plugMan->removeObject(_logSettingsPage); - delete _logSettingsPage; + CLogPlugin::~CLogPlugin() + { + Q_FOREACH(QObject *obj, m_autoReleaseObjects) + { + m_plugMan->removeObject(obj); + } + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); - NLMISC::ErrorLog->removeDisplayer(_displayer); - NLMISC::WarningLog->removeDisplayer(_displayer); - NLMISC::DebugLog->removeDisplayer(_displayer); - NLMISC::AssertLog->removeDisplayer(_displayer); - NLMISC::InfoLog->removeDisplayer(_displayer); - delete _displayer; -} + NLMISC::ErrorLog->removeDisplayer(m_displayer); + NLMISC::WarningLog->removeDisplayer(m_displayer); + NLMISC::DebugLog->removeDisplayer(m_displayer); + NLMISC::AssertLog->removeDisplayer(m_displayer); + NLMISC::InfoLog->removeDisplayer(m_displayer); + delete m_displayer; + } -bool CLogPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) -{ - Q_UNUSED(errorString); - _plugMan = pluginManager; - _logSettingsPage = new CLogSettingsPage(this); - _plugMan->addObject(_logSettingsPage); - return true; -} + bool CLogPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) + { + Q_UNUSED(errorString); + m_plugMan = pluginManager; + m_logSettingsPage = new CLogSettingsPage(this); + addAutoReleasedObject(m_logSettingsPage); + return true; + } -void CLogPlugin::extensionsInitialized() -{ - NLMISC::ErrorLog->addDisplayer(_displayer); - NLMISC::WarningLog->addDisplayer(_displayer); - NLMISC::DebugLog->addDisplayer(_displayer); - NLMISC::AssertLog->addDisplayer(_displayer); - NLMISC::InfoLog->addDisplayer(_displayer); + void CLogPlugin::extensionsInitialized() + { + setDisplayers(); - Core::ICore *core = Core::ICore::instance(); - Core::IMenuManager *menuManager = core->menuManager(); - QMenu *viewMenu = menuManager->menu(Core::Constants::M_VIEW); + Core::ICore *core = Core::ICore::instance(); + Core::IMenuManager *menuManager = core->menuManager(); + QMenu *viewMenu = menuManager->menu(Core::Constants::M_VIEW); - QMainWindow *wnd = Core::ICore::instance()->mainWindow(); - wnd->addDockWidget(Qt::RightDockWidgetArea, this); - hide(); + QMainWindow *wnd = Core::ICore::instance()->mainWindow(); + wnd->addDockWidget(Qt::RightDockWidgetArea, this); + hide(); - viewMenu->addAction(this->toggleViewAction()); -} + viewMenu->addAction(this->toggleViewAction()); + } -void CLogPlugin::setNelContext(NLMISC::INelContext *nelContext) -{ -#ifdef NL_OS_WINDOWS - // Ensure that a context doesn't exist yet. - // This only applies to platforms without PIC, e.g. Windows. - nlassert(!NLMISC::INelContext::isContextInitialised()); + void CLogPlugin::setNelContext(NLMISC::INelContext *nelContext) + { +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); #endif // fdef NL_OS_WINDOWS^M - _LibContext = new NLMISC::CLibraryContext(*nelContext); + m_libContext = new NLMISC::CLibraryContext(*nelContext); - _displayer = new NLQT::CQtDisplayer(_ui.plainTextEdit); + m_displayer = new NLQT::CQtDisplayer(m_ui.plainTextEdit); + } + + QString CLogPlugin::name() const + { + return "NeL Log"; + } + + QString CLogPlugin::version() const + { + return "1.1"; + } + + QString CLogPlugin::vendor() const + { + return "aquiles"; + } + + QString CLogPlugin::description() const + { + return tr("DockWidget to display all log messages from NeL."); + } + + QStringList CLogPlugin::dependencies() const + { + QStringList list; + list.append(Core::Constants::OVQT_CORE_PLUGIN); + return list; + } + + void CLogPlugin::addAutoReleasedObject(QObject *obj) + { + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); + } + + void CLogPlugin::setDisplayers() + { + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::LOG_SECTION); + bool error = settings->value(Core::Constants::LOG_ERROR, true).toBool(); + bool warning = settings->value(Core::Constants::LOG_WARNING, true).toBool(); + bool debug = settings->value(Core::Constants::LOG_DEBUG, true).toBool(); + bool assert = settings->value(Core::Constants::LOG_ASSERT, true).toBool(); + bool info = settings->value(Core::Constants::LOG_INFO, true).toBool(); + settings->endGroup(); + + if (error) { + if (!NLMISC::ErrorLog->attached(m_displayer)) + NLMISC::ErrorLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::ErrorLog->removeDisplayer(m_displayer); + } + } + if (warning) { + if (!NLMISC::WarningLog->attached(m_displayer)) + NLMISC::WarningLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::WarningLog->removeDisplayer(m_displayer); + } + } + if (debug) { + if (!NLMISC::DebugLog->attached(m_displayer)) + NLMISC::DebugLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::DebugLog->removeDisplayer(m_displayer); + } + } + if (assert) { + if (!NLMISC::AssertLog->attached(m_displayer)) + NLMISC::AssertLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::AssertLog->removeDisplayer(m_displayer); + } + } + if (info) { + if (!NLMISC::InfoLog->attached(m_displayer)) + NLMISC::InfoLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::InfoLog->removeDisplayer(m_displayer); + } + } + } } - -QString CLogPlugin::name() const -{ - return "LogPlugin"; -} - -QString CLogPlugin::version() const -{ - return "1.0"; -} - -QString CLogPlugin::vendor() const -{ - return "aquiles"; -} - -QString CLogPlugin::description() const -{ - return "DockWidget to display all log messages from NeL."; -} - -QStringList CLogPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - return list; -} - -Q_EXPORT_PLUGIN(CLogPlugin) +Q_EXPORT_PLUGIN(Plugin::CLogPlugin) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.h index d07469541..6a2d78f79 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.h @@ -1,6 +1,6 @@ /* Log Plugin Qt -Copyright (C) 2010 Adrian Jaekel +Copyright (C) 2011 Adrian Jaekel 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 @@ -20,16 +20,16 @@ along with this program. If not, see . #ifndef LOG_PLUGIN_H #define LOG_PLUGIN_H +// Project includes +#include "ui_log_form.h" #include "../../extension_system/iplugin.h" +// NeL includes #include "nel/misc/app_context.h" // Qt includes #include -// Project includes -#include "ui_log_form.h" - namespace NLMISC { class CLibraryContext; @@ -52,7 +52,7 @@ namespace Plugin class CLogPlugin : public QDockWidget, public ExtensionSystem::IPlugin { Q_OBJECT - Q_INTERFACES(ExtensionSystem::IPlugin) + Q_INTERFACES(ExtensionSystem::IPlugin) public: CLogPlugin(QWidget *parent = 0); ~CLogPlugin(); @@ -61,7 +61,7 @@ namespace Plugin void extensionsInitialized(); void setNelContext(NLMISC::INelContext *nelContext); - NLQT::CQtDisplayer* displayer() { return _displayer; } + NLQT::CQtDisplayer* displayer() { return m_displayer; } QString name() const; QString version() const; @@ -69,16 +69,21 @@ namespace Plugin QString description() const; QStringList dependencies() const; + void addAutoReleasedObject(QObject *obj); + + void setDisplayers(); + protected: - NLMISC::CLibraryContext *_LibContext; + NLMISC::CLibraryContext *m_libContext; private: - ExtensionSystem::IPluginManager *_plugMan; - CLogSettingsPage *_logSettingsPage; + ExtensionSystem::IPluginManager *m_plugMan; + QList m_autoReleaseObjects; + CLogSettingsPage *m_logSettingsPage; - Ui::CLogPlugin _ui; + Ui::CLogPlugin m_ui; - NLQT::CQtDisplayer *_displayer; + NLQT::CQtDisplayer *m_displayer; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp index 83cfdc979..f75d6ab37 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp @@ -1,6 +1,6 @@ // Object Viewer Qt - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin +// Copyright (C) 2011 Adrian Jaekel // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as @@ -15,31 +15,43 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +// Project includes #include "log_settings_page.h" - -// Qt includes -#include +#include "log_plugin.h" +#include "../core/core_constants.h" +#include "../core/icore.h" +#include "../../extension_system/plugin_manager.h" // NeL includes -// Project includes +// Qt includes +#include +#include + namespace ExtensionSystem { - class IPluginManager; + class IPluginManager; } namespace Plugin { + class CLogPlugin; + CLogSettingsPage::CLogSettingsPage(QObject *parent) : IOptionsPage(parent), - _currentPage(NULL) + m_currentPage(NULL), + m_error(true), + m_warning(true), + m_debug(true), + m_assert(true), + m_info(true) { } QString CLogSettingsPage::id() const { - return QLatin1String("Log"); + return QLatin1String("log"); } QString CLogSettingsPage::trName() const @@ -49,32 +61,78 @@ namespace Plugin QString CLogSettingsPage::category() const { - return QLatin1String("General"); + return QLatin1String(Core::Constants::SETTINGS_CATEGORY_GENERAL); } QString CLogSettingsPage::trCategory() const { - return tr("General"); + return tr(Core::Constants::SETTINGS_TR_CATEGORY_GENERAL); + } + + QIcon CLogSettingsPage::categoryIcon() const + { + return QIcon(); } QWidget *CLogSettingsPage::createPage(QWidget *parent) { - _currentPage = new QWidget(parent); - _ui.setupUi(_currentPage); - return _currentPage; + m_currentPage = new QWidget(parent); + m_ui.setupUi(m_currentPage); + + readSettings(); + m_ui.errorCheck->setChecked(m_error); + m_ui.warningCheck->setChecked(m_warning); + m_ui.debugCheck->setChecked(m_debug); + m_ui.assertCheck->setChecked(m_assert); + m_ui.infoCheck->setChecked(m_info); + + return m_currentPage; } void CLogSettingsPage::apply() { - //ExtensionSystem::IPluginSpec *spec, _plugMan->plugins() - //ExtensionSystem::IPluginManager; - //if (_ui.errorCheck->isChecked()) { - //displayer(); - //} - //if (_ui.warningCheck->isChecked()); - //if (_ui.debugCheck->isChecked()); - //if (_ui.assertCheck->isChecked()); - //if (_ui.infoCheck->isChecked()); + m_error = m_ui.errorCheck->isChecked(); + m_warning = m_ui.warningCheck->isChecked(); + m_debug = m_ui.debugCheck->isChecked(); + m_assert = m_ui.assertCheck->isChecked(); + m_info = m_ui.infoCheck->isChecked(); + + writeSettings(); + ExtensionSystem::IPluginManager *p = Core::ICore::instance()->pluginManager(); + ExtensionSystem::IPlugin *plugin = p->pluginByName("LogPlugin")->plugin(); + CLogPlugin* lp = dynamic_cast(plugin); + if (lp) + { + lp->setDisplayers(); + } + } + + void CLogSettingsPage::readSettings() + { + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::LOG_SECTION); + m_error = settings->value(Core::Constants::LOG_ERROR, true).toBool(); + m_warning = settings->value(Core::Constants::LOG_WARNING, true).toBool(); + m_debug = settings->value(Core::Constants::LOG_DEBUG, true).toBool(); + m_assert = settings->value(Core::Constants::LOG_ASSERT, true).toBool(); + m_info = settings->value(Core::Constants::LOG_INFO, true).toBool(); + settings->endGroup(); + } + + void CLogSettingsPage::writeSettings() + { + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::LOG_SECTION); + settings->setValue(Core::Constants::LOG_ERROR, m_error); + settings->setValue(Core::Constants::LOG_WARNING, m_warning); + settings->setValue(Core::Constants::LOG_DEBUG, m_debug); + settings->setValue(Core::Constants::LOG_ASSERT, m_assert); + settings->setValue(Core::Constants::LOG_INFO, m_info); + settings->endGroup(); + + settings->sync(); } } /* namespace Plugin */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.h index 396afcdd3..2c0c5ed98 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.h @@ -29,29 +29,39 @@ class QWidget; namespace Plugin { -/** -@class CLogSettingsPage -*/ -class CLogSettingsPage : public Core::IOptionsPage -{ - Q_OBJECT -public: - CLogSettingsPage(QObject *parent = 0); - virtual ~CLogSettingsPage() {} + /** + @class CLogSettingsPage + */ + class CLogSettingsPage : public Core::IOptionsPage + { + Q_OBJECT + public: + CLogSettingsPage(QObject *parent = 0); + virtual ~CLogSettingsPage() {} - virtual QString id() const; - virtual QString trName() const; - virtual QString category() const; - virtual QString trCategory() const; - virtual QWidget *createPage(QWidget *parent); + virtual QString id() const; + virtual QString trName() const; + virtual QString category() const; + virtual QString trCategory() const; + QIcon categoryIcon() const; + virtual QWidget *createPage(QWidget *parent); - virtual void apply(); - virtual void finish() {} + virtual void apply(); + virtual void finish() {} -private: - QWidget *_currentPage; - Ui::CLogSettingsPage _ui; -}; + private: + void readSettings(); + void writeSettings(); + + QWidget *m_currentPage; + Ui::CLogSettingsPage m_ui; + + bool m_error; + bool m_warning; + bool m_debug; + bool m_assert; + bool m_info; + }; } // namespace Core diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/qt_displayer.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/qt_displayer.cpp index aaeae9a1a..fc694d779 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/qt_displayer.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/qt_displayer.cpp @@ -1,24 +1,21 @@ -/* -Georges Editor Qt -Copyright (C) 2010 Adrian Jaekel - -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 3 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. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -*/ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . // Nel includes - #include "qt_displayer.h" #include #include diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/animation_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/animation_form.ui index 90d496d17..3660afe45 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/animation_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/animation_form.ui @@ -193,7 +193,7 @@ - :/images/animset.png:/images/animset.png + :/icons/ic_nel_animset.png:/icons/ic_nel_animset.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_form.ui index 404444fc0..77c4b895f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_form.ui @@ -91,7 +91,7 @@ - true + false diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/global_wind_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/global_wind_form.ui index 971d16c60..bb266f650 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/global_wind_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/global_wind_form.ui @@ -6,8 +6,8 @@ 0 0 - 195 - 64 + 192 + 52 @@ -21,6 +21,12 @@ + + 3 + + + 3 + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.cpp index 4e11ee15c..6c2736895 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.cpp @@ -25,8 +25,6 @@ // Qt includes #include #include -#include -#include // NeL includes #include @@ -60,6 +58,11 @@ QString GraphicsSettingsPage::trCategory() const return tr("Object Viewer"); } +QIcon GraphicsSettingsPage::categoryIcon() const +{ + return QIcon(); +} + QWidget *GraphicsSettingsPage::createPage(QWidget *parent) { m_page = new QWidget(parent); @@ -75,11 +78,6 @@ QWidget *GraphicsSettingsPage::createPage(QWidget *parent) m_ui.squareBloomCheckBox->setChecked(NL3D::CBloomEffect::instance().getSquareBloom()); m_ui.bloomDensityHorizontalSlider->setValue(NL3D::CBloomEffect::instance().getDensityBloom()); - m_ui.styleComboBox->addItems(QStyleFactory::keys()); - QString style = settings->value(Constants::QT_STYLE, "").toString(); - m_ui.styleComboBox->setCurrentIndex(m_ui.styleComboBox->findText(style)); - m_ui.paletteCheckBox->setChecked(settings->value(Constants::QT_PALETTE, true).toBool()); - settings->endGroup(); connect(m_ui.enableBloomCheckBox, SIGNAL(toggled(bool)), this, SLOT(setEnableBloom(bool))); @@ -103,16 +101,6 @@ void GraphicsSettingsPage::apply() settings->setValue(Constants::ENABLE_BLOOM, m_ui.enableBloomCheckBox->isChecked()); settings->setValue(Constants::ENABLE_SQUARE_BLOOM, m_ui.squareBloomCheckBox->isChecked()); settings->setValue(Constants::BLOOM_DENSITY, m_ui.bloomDensityHorizontalSlider->value()); - settings->setValue(Constants::QT_STYLE, m_ui.styleComboBox->currentText()); - settings->setValue(Constants::QT_PALETTE, m_ui.paletteCheckBox->isChecked()); - - // apply qt style and palette - QApplication::setStyle(QStyleFactory::create(m_ui.styleComboBox->currentText())); - - if (m_ui.paletteCheckBox->isChecked()) - QApplication::setPalette(QApplication::style()->standardPalette()); - else - QApplication::setPalette(Modules::mainWin().getOriginalPalette()); settings->endGroup(); settings->sync(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.h index e1402939f..74df1b140 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.h @@ -42,6 +42,7 @@ public: virtual QString trName() const; virtual QString category() const; virtual QString trCategory() const; + QIcon categoryIcon() const; virtual QWidget *createPage(QWidget *parent); virtual void apply(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.ui index 24058d3d3..e6b4952a5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_settings_page.ui @@ -117,50 +117,7 @@ - - - - Qt Style - - - - - - - - Style - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - Use style's standard palette - - - - - - - + false @@ -170,14 +127,14 @@ - + false - + false @@ -187,7 +144,7 @@ - + Qt::Vertical diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.cpp index 2a15932b7..93bc1043e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.cpp @@ -49,6 +49,9 @@ namespace NLQT CGraphicsViewport::CGraphicsViewport(QWidget *parent) : QNLWidget(parent) { + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_PaintOnScreen); } CGraphicsViewport::~CGraphicsViewport() @@ -77,7 +80,7 @@ void CGraphicsViewport::release() { //H_AUTO2 nldebug("CGraphicsViewport::release"); - + Modules::veget().release(); Modules::psEdit().release(); Modules::objView().release(); @@ -119,39 +122,6 @@ void CGraphicsViewport::resizeEvent(QResizeEvent *resizeEvent) Modules::objView().setSizeViewport(resizeEvent->size().width(), resizeEvent->size().height()); } -#if defined(NL_OS_MAC) -// Qt does not provide wheel events through winEvent() and macEvent() (but it -// does through x11Event(), which is inconsistent...) -// Workaround is to handle wheel events like implemented below. -// -// TODO: this is not a clean solution, because all but wheel events are -// handled using winEvent(), x11Event(), macEvent(). But this seems to be a -// limitation of current (4.7.1) Qt versions. (see e.g. qapplication_mac.mm) -void CGraphicsViewport::wheelEvent(QWheelEvent *event) -{ - // Get relative positions. - float fX = 1.0f - (float)event->pos().x() / this->width(); - float fY = 1.0f - (float)event->pos().y() / this->height(); - - // Get the buttons currently pressed. - uint32 buttons = NLMISC::noButton; - if(event->buttons() & Qt::LeftButton) buttons |= NLMISC::leftButton; - if(event->buttons() & Qt::RightButton) buttons |= NLMISC::rightButton; - if(event->buttons() & Qt::MidButton) buttons |= NLMISC::middleButton; - if(event->modifiers() & Qt::ControlModifier) buttons |= NLMISC::ctrlButton; - if(event->modifiers() & Qt::ShiftModifier) buttons |= NLMISC::shiftButton; - if(event->modifiers() & Qt::AltModifier) buttons |= NLMISC::altButton; - - if(event->delta() > 0) - Modules::objView().getDriver()->EventServer.postEvent( - new NLMISC::CEventMouseWheel(-fX, fY, (NLMISC::TMouseButton)buttons, true, NULL)); - else - Modules::objView().getDriver()->EventServer.postEvent( - new NLMISC::CEventMouseWheel(-fX, fY, (NLMISC::TMouseButton)buttons, false, NULL)); -} -#endif // defined(NL_OS_MAC) - - #if defined(NL_OS_WINDOWS) typedef bool (*winProc)(NL3D::IDriver *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -164,6 +134,9 @@ bool CGraphicsViewport::winEvent(MSG *message, long *result) if (driver) { winProc proc = (winProc)driver->getWindowProc(); + + // TODO: shouldn't it return false like the others? + // see macEvent() and x11Event() below return proc(driver, message->hwnd, message->message, message->wParam, message->lParam); } } @@ -186,10 +159,12 @@ bool CGraphicsViewport::macEvent(EventHandlerCallRef caller, EventRef event) if (driver) { cocoaProc proc = (cocoaProc)driver->getWindowProc(); - return proc(driver, event); + proc(driver, event); } } + // return false to let Qt handle the event as well, + // else the widget would never get focus return false; } @@ -205,10 +180,13 @@ bool CGraphicsViewport::x11Event(XEvent *event) if (driver) { x11Proc proc = (x11Proc)driver->getWindowProc(); - return proc(driver, event); + proc(driver, event); } } + // return false to let Qt handle the event as well, + // else the widget would never get focus + // TODO: test me please, i have no linux at hand (rti) return false; } #endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h index 00b2c80d2..d810d8c01 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h @@ -80,10 +80,6 @@ private Q_SLOTS: protected: virtual void resizeEvent(QResizeEvent *resizeEvent); -#if defined(NL_OS_MAC) - virtual void wheelEvent(QWheelEvent *event); -#endif - #if defined(NL_OS_WINDOWS) virtual bool winEvent(MSG *message, long *result); #elif defined(NL_OS_MAC) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.cpp index fa077cfed..e1962cf5b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.cpp @@ -66,7 +66,7 @@ CMainWindow::CMainWindow(QWidget *parent) _isGraphicsInitialized(false), _isGraphicsEnabled(false), _isSoundInitialized(false), - _isSoundEnabled(false), + _isSoundEnabled(true), _GraphicsViewport(NULL), _lastDir("."), _mouseMode(NL3D::U3dMouseListener::edit3d) @@ -80,19 +80,6 @@ CMainWindow::CMainWindow(QWidget *parent) setDockNestingEnabled(true); - QSettings *settings = Core::ICore::instance()->settings(); - settings->beginGroup(Constants::OBJECT_VIEWER_SECTION); - - // setup Qt style and palette from config file - _originalPalette = QApplication::palette(); - - QApplication::setStyle(QStyleFactory::create(settings->value(Constants::QT_STYLE, "").toString())); - - if (settings->value(Constants::QT_PALETTE, true).toBool()) - QApplication::setPalette(QApplication::style()->standardPalette()); - else - QApplication::setPalette(_originalPalette); - _GraphicsViewport->init(); _isGraphicsInitialized = true; @@ -102,6 +89,7 @@ CMainWindow::CMainWindow(QWidget *parent) _isSoundInitialized = true; } + _undoStack = new QUndoStack(this); _SkeletonTreeModel = new CSkeletonTreeModel(this); createDialogs(); @@ -111,6 +99,9 @@ CMainWindow::CMainWindow(QWidget *parent) setWindowIcon(QIcon(":/images/nel.png")); + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::OBJECT_VIEWER_SECTION); + restoreState(settings->value("QtWindowState").toByteArray()); restoreGeometry(settings->value("QtWindowGeometry").toByteArray()); @@ -248,12 +239,6 @@ void CMainWindow::updateStatusBar() void CMainWindow::createActions() { - _openAction = new QAction(tr("&Open..."), this); - _openAction->setIcon(QIcon(Core::Constants::ICON_OPEN)); - _openAction->setShortcut(QKeySequence::Open); - _openAction->setStatusTip(tr("Open an existing file")); - connect(_openAction, SIGNAL(triggered()), this, SLOT(open())); - _setBackColorAction = _GraphicsViewport->createSetBackgroundColor(this); _setBackColorAction->setText(tr("Set &background color")); _setBackColorAction->setIcon(QIcon(Constants::ICON_BGCOLOR)); @@ -268,7 +253,7 @@ void CMainWindow::createActions() connect(_reloadTexturesAction, SIGNAL(triggered()), this, SLOT(reloadTextures())); _saveScreenshotAction = _GraphicsViewport->createSaveScreenshotAction(this); - _saveScreenshotAction->setText(tr("Save &Screenshot")); + _saveScreenshotAction->setText(tr("Save Screenshot")); _saveScreenshotAction->setStatusTip(tr("Make a screenshot of the current viewport and save")); } @@ -276,14 +261,7 @@ void CMainWindow::createMenus() { Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); - // register actions for file menu - menuManager->registerAction(_openAction, "ObjectViewer.File.Open"); - - // add actions in file menu - QMenu *fileMenu = menuManager->menu(Core::Constants::M_FILE); - QAction *exitAction = menuManager->action(Core::Constants::EXIT); - fileMenu->insertAction(exitAction, _openAction); - fileMenu->insertSeparator(exitAction); + _openAction = menuManager->action(Core::Constants::OPEN); // register actions for view menu menuManager->registerAction(_setBackColorAction, "ObjectViewer.View.SetBackgroundColor"); @@ -484,22 +462,6 @@ bool CMainWindow::loadFile(const QString &fileName, const QString &skelName) return true; } -void CMainWindow::cfcbQtStyle(NLMISC::CConfigFile::CVar &var) -{ - QApplication::setStyle(QStyleFactory::create(var.asString().c_str())); -} - -void CMainWindow::cfcbQtPalette(NLMISC::CConfigFile::CVar &var) -{ - if (var.asBool()) QApplication::setPalette(QApplication::style()->standardPalette()); - else QApplication::setPalette(_originalPalette); -} - -void CMainWindow::cfcbSoundEnabled(NLMISC::CConfigFile::CVar &var) -{ - _isSoundEnabled = var.asBool(); // update loop inits -} - void CMainWindow::updateRender() { if (isVisible()) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.h index 3a6411df2..5a392c191 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.h @@ -25,6 +25,7 @@ // Qt includes #include #include +#include // NeL includes #include @@ -71,15 +72,18 @@ public: { return _SkeletonTreeModel; } - QPalette getOriginalPalette() const + + QUndoStack *getUndoStack() const { - return _originalPalette; + return _undoStack; } -private Q_SLOTS: +public Q_SLOTS: void open(); void resetScene(); void reloadTextures(); + +private Q_SLOTS: void updateStatusBar(); void updateRender(); void setInterval(int value); @@ -96,10 +100,6 @@ private: bool loadFile(const QString &fileName, const QString &skelName); - void cfcbQtStyle(NLMISC::CConfigFile::CVar &var); - void cfcbQtPalette(NLMISC::CConfigFile::CVar &var); - void cfcbSoundEnabled(NLMISC::CConfigFile::CVar &var); - bool _isGraphicsInitialized, _isGraphicsEnabled; bool _isSoundInitialized, _isSoundEnabled; @@ -122,7 +122,6 @@ private: CCameraControl *_cameraControl; - QPalette _originalPalette; QString _lastDir; QTimer *_mainTimer; @@ -139,6 +138,7 @@ private: QAction *_resetSceneAction; QAction *_saveScreenshotAction; QLabel *_statusInfo; + QUndoStack *_undoStack; float _fps; uint _numTri; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/modules.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/modules.cpp index 76afed779..605f484f7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/modules.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/modules.cpp @@ -37,7 +37,7 @@ void Modules::init() void Modules::release() { - delete _mainWindow; +// delete _mainWindow; _mainWindow = NULL; delete _particleEditor; _particleEditor = NULL; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp index b48eb82cc..f82789e66 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp @@ -22,7 +22,7 @@ ObjectViewerPlugin::~ObjectViewerPlugin() } qDeleteAll(_autoReleaseObjects); _autoReleaseObjects.clear(); - //Modules::release(); + Modules::release(); } bool ObjectViewerPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) @@ -43,7 +43,7 @@ void ObjectViewerPlugin::extensionsInitialized() void ObjectViewerPlugin::shutdown() { - Modules::release(); +// Modules::release(); } void ObjectViewerPlugin::setNelContext(NLMISC::INelContext *nelContext) @@ -89,6 +89,16 @@ void ObjectViewerPlugin::addAutoReleasedObject(QObject *obj) _autoReleaseObjects.prepend(obj); } +void CObjectViewerContext::open() +{ + Modules::mainWin().open(); +} + +QUndoStack *CObjectViewerContext::undoStack() +{ + return Modules::mainWin().getUndoStack(); +} + QWidget *CObjectViewerContext::widget() { return &Modules::mainWin(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h index dae298fce..b5f9c2881 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h @@ -66,14 +66,21 @@ public: { return QLatin1String("ObjectViewer"); } + virtual QString trName() const { return tr("Object Viewer"); } + virtual QIcon icon() const { return QIcon(); } + + virtual QUndoStack *undoStack(); + + virtual void open(); + virtual QWidget *widget(); }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_editor.h index da191705f..e4d1605e3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_editor.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_editor.h @@ -214,7 +214,7 @@ public: { return _FontGen; } - + CSchemeManager *getSchemeManager () const { return _SchemeManager; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_system_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_system_page.cpp index b9c07db1a..072297437 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_system_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_system_page.cpp @@ -605,25 +605,21 @@ void CParticleSystemPage::setMaxSteps(uint32 value) void CParticleSystemPage::setUserParam1(float value) { _Node->getPSPointer()->setUserParam(0, value); - updateModifiedFlag(); } void CParticleSystemPage::setUserParam2(float value) { _Node->getPSPointer()->setUserParam(1, value); - updateModifiedFlag(); } void CParticleSystemPage::setUserParam3(float value) { _Node->getPSPointer()->setUserParam(2, value); - updateModifiedFlag(); } void CParticleSystemPage::setUserParam4(float value) { _Node->getPSPointer()->setUserParam(3, value); - updateModifiedFlag(); } void CParticleSystemPage::setMaxViewDist(float value) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_tree_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_tree_model.cpp index 155e6ad4c..77286ed32 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_tree_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_tree_model.cpp @@ -177,7 +177,7 @@ CParticleTreeModel::~CParticleTreeModel() int CParticleTreeModel::columnCount(const QModelIndex &parent) const { if (parent.isValid()) - return static_cast(parent.internalPointer())->columnCount(); + return static_cast(parent.internalPointer())->columnCount(); else return _rootItem->columnCount(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.cpp index 50698198b..858922af1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.cpp @@ -222,24 +222,27 @@ void CParticleWorkspaceDialog::touchPSState(CParticleTreeItem *item) void CParticleWorkspaceDialog::clickedItem(const QModelIndex & index) { - if (_currentItem != NULL) + if (_currentItem != 0) _treeModel->getOwnerNode(_currentItem)->getPSPointer()->setCurrentEditedElement(NULL); _currentItem = static_cast(index.internalPointer()); + if (_currentItem == 0) + return; + if (index.flags() != Qt::NoItemFlags) _PropertyDialog->setCurrentEditedElement(_currentItem); if ((_currentItem->itemType() == ItemType::Workspace) || (_currentItem->itemType() == ItemType::ParticleSystemNotLoaded)) - _currentItem = NULL; + _currentItem = 0; } void CParticleWorkspaceDialog::customContextMenu() { if (!Modules::psEdit().getParticleWorkspace()) return; clickedItem(_ui.treeView->currentIndex()); - if (_currentItem == NULL) return; + if (_currentItem == 0) return; QMenu *popurMenu = new QMenu(this); switch (_currentItem->itemType()) { diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.h index 01a2abb35..8348fae0c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.h @@ -25,10 +25,10 @@ namespace NL3D { - class CPSAttribMakerBase; +class CPSAttribMakerBase; } - -namespace NLQT + +namespace NLQT { class CSchemeManager @@ -50,10 +50,9 @@ public: void remove(NL3D::CPSAttribMakerBase *am); // rename a scheme, given a pointer on it void rename(NL3D::CPSAttribMakerBase *am, const std::string &newName); -protected: - typedef std::pair TSchemeInfo; +protected: typedef std::multimap TSchemeMap; - TSchemeMap _SchemeMap; + TSchemeMap _SchemeMap; }; } /* namespace NLQT */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_settings_page.cpp index 4c677f4bf..1bceeb80b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_settings_page.cpp @@ -56,6 +56,11 @@ QString SoundSettingsPage::trCategory() const return tr("Object Viewer"); } +QIcon SoundSettingsPage::categoryIcon() const +{ + return QIcon(); +} + QWidget *SoundSettingsPage::createPage(QWidget *parent) { m_page = new QWidget(parent); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_settings_page.h index c27a82e1f..0e5361f54 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_settings_page.h @@ -44,6 +44,7 @@ public: virtual QString trName() const; virtual QString category() const; virtual QString trCategory() const; + QIcon categoryIcon() const; virtual QWidget *createPage(QWidget *parent); virtual void apply(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/tune_timer_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/tune_timer_form.ui index f2f883263..8288747ce 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/tune_timer_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/tune_timer_form.ui @@ -6,14 +6,14 @@ 0 0 - 460 - 64 + 452 + 52 - 86 - 64 + 0 + 0 @@ -24,6 +24,12 @@ + + 3 + + + 3 + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/value_gradient_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/value_gradient_dialog.cpp index adf91c598..544ceec98 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/value_gradient_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/value_gradient_dialog.cpp @@ -1,18 +1,18 @@ -// Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // Projects include @@ -154,6 +154,9 @@ void CGradientDialog::valueDown() m_ui.listWidget->setCurrentRow(currentRow); } m_ui.listWidget->setCurrentRow(currentRow); + --currentRow; + QListWidgetItem *item = m_ui.listWidget->item(currentRow); + m_clientInterface->displayValue(currentRow, item); } void CGradientDialog::valueUp() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/value_gradient_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/value_gradient_dialog.h index 48da2f600..dc2b366d8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/value_gradient_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/value_gradient_dialog.h @@ -1,18 +1,18 @@ -// Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef VALUE_GRADIENT_DIALOG_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.cpp index f794e0b73..68a1f4b98 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.cpp @@ -59,6 +59,11 @@ QString VegetableSettingsPage::trCategory() const return tr("Object Viewer"); } +QIcon VegetableSettingsPage::categoryIcon() const +{ + return QIcon(); +} + QWidget *VegetableSettingsPage::createPage(QWidget *parent) { m_page = new QWidget(parent); @@ -81,6 +86,7 @@ QWidget *VegetableSettingsPage::createPage(QWidget *parent) connect(m_ui.coarseToolButton, SIGNAL(clicked()), this, SLOT(setCoarseMeshTexture())); connect(m_ui.addZoneToolButton, SIGNAL(clicked()), this, SLOT(addZone())); connect(m_ui.removeZoneToolButton, SIGNAL(clicked()), this, SLOT(removeZone())); + connect(m_ui.clearButton, SIGNAL(clicked()), m_ui.zonesListWidget, SLOT(clear())); return m_page; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.h index bf49e2d2c..b66d070ba 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.h @@ -43,6 +43,7 @@ public: virtual QString trName() const; virtual QString category() const; virtual QString trCategory() const; + QIcon categoryIcon() const; virtual QWidget *createPage(QWidget *parent); virtual void apply(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.ui index 0d4a41cf2..13deb2d4e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_settings_page.ui @@ -181,6 +181,17 @@ + + + + + + + + :/icons/ic_nel_reset_all.png:/icons/ic_nel_reset_all.png + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/README b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/README new file mode 100644 index 000000000..c5c895519 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/README @@ -0,0 +1,3 @@ +OVQT Translation Manager plugin +-------------------------------- +http://dev.ryzom.com/wiki/ryzom/OVQTTranslationPluginGSoc2011 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.cpp index 1bd91f667..01086f231 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.cpp @@ -77,7 +77,7 @@ ZonePainterMainWindow::ZonePainterMainWindow(QWidget *parent) : Core::ICore::instance()->mainWindow()->statusBar()->addPermanentWidget(m_statusInfo); - + m_undoStack = new QUndoStack(this); } void ZonePainterMainWindow::showEvent(QShowEvent *showEvent) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.h index d55eb39e5..0dbfd9948 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace NLQT { class QNLWidget; @@ -26,7 +27,7 @@ public: void loadConfig(); void saveConfig(); - + QUndoStack *getUndoStack() { return m_undoStack; } public Q_SLOTS: void setToolMode(int value); void setToolMode(); @@ -49,7 +50,7 @@ private: QAction *_toolSelectModeAction; QAction *_toolPickModeAction; QMenu *_toolModeMenu; - + QUndoStack *m_undoStack; //QAction *m_setBackColorAction; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.cpp index 7b8237ccb..9ccfb9053 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.cpp @@ -19,6 +19,8 @@ namespace Plugin { + NLMISC_SAFE_SINGLETON_IMPL(CZoneManager) + ZonePainterPlugin::~ZonePainterPlugin() { Q_FOREACH(QObject *obj, _autoReleaseObjects) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.h index aeae39ba6..2c1dff53e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.h @@ -7,10 +7,12 @@ #include "zone_painter_main_window.h" // NeL includes -#include "nel/misc/app_context.h" +#include +#include #include #include #include +#include // Qt includes #include @@ -29,16 +31,15 @@ class IPluginSpec; namespace Plugin { - class CZoneManager { + class CZoneManager + { + NLMISC_SAFE_SINGLETON_DECL(CZoneManager) public: - NL3D::CZone zone; - - std::string getZoneInfo() { - NL3D::CZone zone; - zone.getNumPatchs(); - - return ""; - } + //m_painterLandscape = static_cast + + private: + NL3D::CLandscapeModel *m_painterLandscape; + NL3D::CZone *m_currentZone; }; class ZonePainterPlugin : public QObject, public ExtensionSystem::IPlugin @@ -79,28 +80,38 @@ class CZonePainterContext: public Core::IContext { Q_OBJECT public: - CZonePainterContext(QObject *parent = 0): IContext(parent) - { - m_zonePainterMainWindow = new ZonePainterMainWindow(); - } - virtual ~CZonePainterContext() {} - - virtual QString id() const - { - return QLatin1String("ZonePainterContext"); - } - virtual QString trName() const - { - return tr("Zone Painter"); - } - virtual QIcon icon() const - { - return QIcon(); - } - virtual QWidget *widget() - { - return m_zonePainterMainWindow; - } + CZonePainterContext(QObject *parent = 0): IContext(parent) + { + m_zonePainterMainWindow = new ZonePainterMainWindow(); + } + virtual ~CZonePainterContext() {} + + virtual QString id() const + { + return QLatin1String("ZonePainterContext"); + } + virtual QString trName() const + { + return tr("Zone Painter"); + } + virtual QIcon icon() const + { + return QIcon(); + } + virtual QWidget *widget() + { + return m_zonePainterMainWindow; + } + + virtual QUndoStack *undoStack() + { + return m_zonePainterMainWindow->getUndoStack(); + } + virtual void open() + { + } + + ZonePainterMainWindow *m_zonePainterMainWindow; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_settings_page.cpp index 69c4e7525..e59f76da1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_settings_page.cpp @@ -53,6 +53,11 @@ QString CZonePainterSettingsPage::trCategory() const return tr("General"); } +QIcon CZonePainterSettingsPage::categoryIcon() const +{ + return QIcon(); +} + QWidget *CZonePainterSettingsPage::createPage(QWidget *parent) { _currentPage = new QWidget(parent); @@ -64,4 +69,4 @@ void CZonePainterSettingsPage::apply() { } -} /* namespace Plugin */ \ No newline at end of file +} /* namespace Plugin */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_settings_page.h index 8e4b3f3d6..d84b117eb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_settings_page.h @@ -43,6 +43,7 @@ public: virtual QString trName() const; virtual QString category() const; virtual QString trCategory() const; + QIcon categoryIcon() const; virtual QWidget *createPage(QWidget *parent); virtual void apply(); diff --git a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp index 4c6d25b3a..70bf51f81 100644 --- a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp +++ b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp @@ -62,7 +62,8 @@ namespace NLQT _CameraFocal(75), _CurrentInstance(""), _BloomEffect(false), _Scene(0), QWidget(parent) { - + setMouseTracking(true); + setFocusPolicy(Qt::StrongFocus); _objectViewerWidget = this; _isGraphicsEnabled = true; @@ -78,7 +79,7 @@ namespace NLQT CObjectViewerWidget::~CObjectViewerWidget() { - + release(); } void CObjectViewerWidget::showEvent ( QShowEvent * event ) @@ -261,7 +262,7 @@ namespace NLQT //updateAnimation(_AnimationDialog->getTime()); - + updateAnimatePS(); // 10. Update Camera (depends on entities) // ... @@ -718,6 +719,19 @@ namespace NLQT //CFile::deleteFile(filename); return icon; } + + void CObjectViewerWidget::updateAnimatePS(uint64 deltaTime) + { + static sint64 firstTime = NLMISC::CTime::getLocalTime(); + static sint64 lastTime = NLMISC::CTime::getLocalTime(); + if (deltaTime == 0) + { + deltaTime = NLMISC::CTime::getLocalTime() - lastTime; + } + lastTime += deltaTime; + float fdelta = 0.001f * (float) (lastTime - firstTime); + _Scene->animate ( fdelta); + } #if defined(NL_OS_WINDOWS) diff --git a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.h b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.h index 82bf26f92..15c9b0fa9 100644 --- a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.h +++ b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.h @@ -178,6 +178,10 @@ namespace NLQT void updateRender(); private: + + /// Update the animation time for Particle System animation. + /// @param deltaTime - set the manual animation time. + void updateAnimatePS(uint64 deltaTime = 0); static CObjectViewerWidget *_objectViewerWidget; diff --git a/code/nel/tools/3d/panoply_maker/panoply_maker.cpp b/code/nel/tools/3d/panoply_maker/panoply_maker.cpp index 9f51d86f7..6be9590c2 100644 --- a/code/nel/tools/3d/panoply_maker/panoply_maker.cpp +++ b/code/nel/tools/3d/panoply_maker/panoply_maker.cpp @@ -140,7 +140,7 @@ int main(int argc, char* argv[]) NLMISC::CPath::addSearchPath(NLMISC::CPath::standardizePath(additionnal_paths.asString(k)),true, false); } } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -149,7 +149,7 @@ int main(int argc, char* argv[]) { _Path_Input_TexBases = NLMISC::CPath::standardizePath(cf.getVar ("input_path_texbase").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -158,7 +158,7 @@ int main(int argc, char* argv[]) { _Path_Input_Masks = NLMISC::CPath::standardizePath(cf.getVar ("input_path_mask").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -167,7 +167,7 @@ int main(int argc, char* argv[]) { _Path_Output_MaksOptimized = NLMISC::CPath::standardizePath(cf.getVar ("output_path_mask_optimized").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -176,7 +176,7 @@ int main(int argc, char* argv[]) { _Path_Output_Cgi = NLMISC::CPath::standardizePath(cf.getVar ("output_path_cgi").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -185,12 +185,12 @@ int main(int argc, char* argv[]) { _Path_Output_Gtm = NLMISC::CPath::standardizePath(cf.getVar ("output_path_gtm").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } } - catch (std::exception &e) + catch (const std::exception &e) { nlwarning("Panoply building failed."); nlwarning(e.what()); @@ -256,7 +256,7 @@ int main(int argc, char* argv[]) NLMISC::CPath::addSearchPath(NLMISC::CPath::standardizePath(additionnal_paths.asString(k))); } } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -265,7 +265,7 @@ int main(int argc, char* argv[]) { bi.InputPath = NLMISC::CPath::standardizePath(cf.getVar ("input_path").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -274,7 +274,7 @@ int main(int argc, char* argv[]) { bi.OutputPath = NLMISC::CPath::standardizePath(cf.getVar ("output_path").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -283,7 +283,7 @@ int main(int argc, char* argv[]) { bi.HlsInfoPath = NLMISC::CPath::standardizePath(cf.getVar("hls_info_path").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { bi.HlsInfoPath = "hlsInfo/"; } @@ -293,7 +293,7 @@ int main(int argc, char* argv[]) { bi.CachePath = NLMISC::CPath::standardizePath(cf.getVar ("cache_path").asString()); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { } @@ -302,7 +302,7 @@ int main(int argc, char* argv[]) { bi.OutputFormat = "." + cf.getVar ("output_format").asString(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { bi.OutputFormat = ".tga"; } @@ -312,7 +312,7 @@ int main(int argc, char* argv[]) { bi.DefaultSeparator = cf.getVar ("default_separator").asString(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { bi.DefaultSeparator = '_'; } @@ -330,7 +330,7 @@ int main(int argc, char* argv[]) } } } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { bi.BitmapExtensions[0].resize(1); bi.BitmapExtensions[0] = bi.OutputFormat; @@ -340,14 +340,14 @@ int main(int argc, char* argv[]) { bi.LowDefShift = cf.getVar ("low_def_shift").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { // tranform 512*512 to 64*64 by default bi.LowDefShift= 3; } } - catch (std::exception &e) + catch (const std::exception &e) { nlwarning("Panoply building failed."); nlwarning(e.what()); @@ -361,7 +361,7 @@ int main(int argc, char* argv[]) { BuildColoredVersions(bi); } - catch (std::exception &e) + catch (const std::exception &e) { nlwarning("Something went wrong while building bitmap : %s", e.what()); return -1; @@ -389,7 +389,7 @@ static void validateCgiInfo() f.serialCont(temp); } - catch(std::exception &e) + catch(const std::exception &e) { nlwarning("Panoply building failed."); } @@ -491,7 +491,7 @@ static void BuildColoredVersions(const CBuildInfo &bi) //nlwarning(("No need to rebuild " + NLMISC::CFile::getFilename(files[k])).c_str()); } } - catch (std::exception &e) + catch (const std::exception &e) { nlwarning("Processing of %s failed : %s \n", files[k].c_str(), e.what()); } @@ -662,7 +662,7 @@ static void BuildColoredVersionForOneBitmap(const CBuildInfo &bi, const std::str return; } } - catch (NLMISC::Exception &) + catch (const NLMISC::Exception &) { nlwarning("File or format error with : %s. Processing next...", fileNameWithExtension.c_str()); return; @@ -743,7 +743,7 @@ static void BuildColoredVersionForOneBitmap(const CBuildInfo &bi, const std::str return; } } - catch (std::exception &e) + catch (const std::exception &e) { nlwarning("Error with : %s : %s. Aborting this bitmap processing", maskFileName.c_str(), e.what()); return; @@ -827,7 +827,7 @@ static void BuildColoredVersionForOneBitmap(const CBuildInfo &bi, const std::str nlwarning(("Couldn't open " + bi.OutputPath + outputFileName + bi.OutputFormat + " for writing").c_str()); } } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlwarning(("Couldn't write " + bi.OutputPath + outputFileName + bi.OutputFormat + " : " + e.what()).c_str()); } diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h index 11b8c8ff2..944807aca 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h @@ -578,13 +578,16 @@ class PaintPatchData : public LocalModData { LocalModData *Clone() { return new PaintPatchData(*this); } void SetFlag(DWORD f,BOOL on) - { - if ( on ) { + { + if ( on ) + { flags|=f; - } else { - flags&=~f; - } } + else + { + flags&=~f; + } + } DWORD GetFlag(DWORD f) { return flags&f; } EPTempData *TempData(PaintPatchMod *mod); diff --git a/code/nel/tools/3d/shapes_exporter/shapes_exporter.cpp b/code/nel/tools/3d/shapes_exporter/shapes_exporter.cpp index a9cff1fc1..ad8e8ec3f 100644 --- a/code/nel/tools/3d/shapes_exporter/shapes_exporter.cpp +++ b/code/nel/tools/3d/shapes_exporter/shapes_exporter.cpp @@ -99,7 +99,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) // load the config file cf.load(filename); } - catch(exception &e) + catch(const exception &e) { nlwarning("can't parse config file : %s", filename.c_str()); nlwarning(e.what()); @@ -111,7 +111,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.input_path = CPath::standardizePath(cf.getVar("input_path").asString()); } - catch (EUnknownVar &) + catch (const EUnknownVar &) { } @@ -120,7 +120,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.output_path = CPath::standardizePath(cf.getVar("output_path").asString()); } - catch (EUnknownVar &) + catch (const EUnknownVar &) { } @@ -129,7 +129,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.output_format = cf.getVar("output_format").asString(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.output_format = "jpg"; } @@ -141,7 +141,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) for (uint i=0; i < (uint)search_pathes.size(); ++i) CPath::addSearchPath(CPath::standardizePath(search_pathes.asString(i))); } - catch(EUnknownVar &) + catch(const EUnknownVar &) { } @@ -152,7 +152,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) for (uint i=0; i< (uint)recursive_search_pathes.size(); ++i) CPath::addSearchPath(CPath::standardizePath(recursive_search_pathes.asString(i)), true, false); } - catch(EUnknownVar &) + catch(const EUnknownVar &) { } @@ -171,7 +171,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) CPath::remapExtension(extensions_remapping.asString(i), extensions_remapping.asString(i+1), true); } } - catch (EUnknownVar &) + catch (const EUnknownVar &) { } @@ -180,7 +180,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.preview_format = cf.getVar("preview_format").asString(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.preview_format = "jpg"; } @@ -190,7 +190,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.preview_width = cf.getVar("preview_width").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.preview_width = 256; } @@ -200,7 +200,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.preview_height = cf.getVar("preview_height").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.preview_height = 256; } @@ -210,7 +210,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.preview_quality = (uint8)cf.getVar("preview_quality").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.preview_quality = 90; } @@ -223,7 +223,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) settings.output_background.G = (uint8)var.asInt(1); settings.output_background.B = (uint8)var.asInt(2); } - catch (EUnknownVar &) + catch (const EUnknownVar &) { settings.output_background = CRGBA::Black; } @@ -236,7 +236,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) settings.light_ambiant.G = (uint8)var.asInt(1); settings.light_ambiant.B = (uint8)var.asInt(2); } - catch (EUnknownVar &) + catch (const EUnknownVar &) { settings.light_ambiant = CRGBA::White; } @@ -249,7 +249,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) settings.light_diffuse.G = (uint8)var.asInt(1); settings.light_diffuse.B = (uint8)var.asInt(2); } - catch (EUnknownVar &) + catch (const EUnknownVar &) { settings.light_diffuse = CRGBA::White; } @@ -262,7 +262,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) settings.light_specular.G = (uint8)var.asInt(1); settings.light_specular.B = (uint8)var.asInt(2); } - catch (EUnknownVar &) + catch (const EUnknownVar &) { settings.light_specular = CRGBA::White; } @@ -273,7 +273,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) CConfigFile::CVar &var = cf.getVar("light_direction"); settings.light_direction = CVector(var.asFloat(0), var.asFloat(1), var.asFloat(2)); } - catch (EUnknownVar &) + catch (const EUnknownVar &) { settings.light_direction = CVector(0.f, 1.f, 0.f); } @@ -283,7 +283,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.output_steps_z = cf.getVar("output_steps_z").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.output_steps_z = 10; } @@ -293,7 +293,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.output_steps_x = cf.getVar("output_steps_x").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.output_steps_x = 10; } @@ -303,7 +303,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.output_width = cf.getVar("output_width").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.output_width = 256; } @@ -313,7 +313,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.output_height = cf.getVar("output_height").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.output_height = 256; } @@ -323,7 +323,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.output_antialiasing = (uint8)cf.getVar("output_antialiasing").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.output_antialiasing = 2; } @@ -333,7 +333,7 @@ bool ShapesExporter::parseConfigFile(const string &filename) { settings.output_quality = (uint8)cf.getVar("output_quality").asInt(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { settings.output_quality = 90; } diff --git a/code/nel/tools/3d/tga_2_dds/tga2dds.cpp b/code/nel/tools/3d/tga_2_dds/tga2dds.cpp index 4328c48fb..27e7b1603 100644 --- a/code/nel/tools/3d/tga_2_dds/tga2dds.cpp +++ b/code/nel/tools/3d/tga_2_dds/tga2dds.cpp @@ -629,7 +629,7 @@ int main(int argc, char **argv) picSrc.writePNG (output, 8); } } - catch(NLMISC::EWriteError &e) + catch(const NLMISC::EWriteError &e) { cerr<Name.c_str(), e.what()); } @@ -734,7 +734,7 @@ static void computeZoneIGBBox(const char *zoneName, CLightingBBox &result, TShap { ig.serial(igFile); } - catch (NLMISC::Exception &e) + catch (const NLMISC::Exception &e) { nlwarning("Error while reading an instance group file : %s \n reason : %s", pathName.c_str(), e.what()); return; @@ -803,7 +803,7 @@ static void computeBBoxFromVillage(const NLGEORGES::UFormElm *villageItem, computeIGBBox(group, currBBox, shapeMap); result.makeUnion(currBBox); } - catch(NLMISC::Exception &) + catch(const NLMISC::Exception &) { nlwarning ("Error while loading instance group %s\n", igName.c_str()); continue; @@ -909,7 +909,7 @@ static void computeIGBBoxFromContinent(NLMISC::CConfigFile ¶meter, nlwarning("Can't load continent form : %s", continentName.c_str()); } } - catch (NLMISC::EUnknownVar &e) + catch (const NLMISC::EUnknownVar &e) { nlinfo(e.what()); } diff --git a/code/nel/tools/3d/zone_dump/zone_dump.cpp b/code/nel/tools/3d/zone_dump/zone_dump.cpp index 9e37aa0b3..b03accdc4 100644 --- a/code/nel/tools/3d/zone_dump/zone_dump.cpp +++ b/code/nel/tools/3d/zone_dump/zone_dump.cpp @@ -211,7 +211,7 @@ int main(int argc, char* argv[]) } } } - catch (Exception& e) + catch (const Exception& e) { fprintf (stderr, "FATAL: %s", e.what()); } diff --git a/code/nel/tools/3d/zone_ig_lighter/zone_ig_lighter.cpp b/code/nel/tools/3d/zone_ig_lighter/zone_ig_lighter.cpp index bdf564a66..1c074fd77 100644 --- a/code/nel/tools/3d/zone_ig_lighter/zone_ig_lighter.cpp +++ b/code/nel/tools/3d/zone_ig_lighter/zone_ig_lighter.cpp @@ -241,7 +241,7 @@ int main(int argc, char* argv[]) landscape->TileBank.serial (inputFile); landscape->initTileBanks(); } - catch (Exception &e) + catch (const Exception &e) { // Error nlwarning ("ERROR error loading tile bank %s\n%s\n", bank_name.c_str(), e.what()); @@ -305,7 +305,7 @@ int main(int argc, char* argv[]) } } } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { nlinfo("No additionnal ig's to load"); } @@ -515,7 +515,7 @@ int main(int argc, char* argv[]) // Save the new ig outputFile.serial(output); } - catch (Exception& except) + catch (const Exception& except) { // Error message nlwarning ("ERROR writing %s: %s\n", argv[2], except.what()); @@ -533,7 +533,7 @@ int main(int argc, char* argv[]) nlwarning ("ERROR Abort: files are missing.\n"); } } - catch (Exception& except) + catch (const Exception& except) { // Error message nlwarning ("ERROR %s\n", except.what()); diff --git a/code/nel/tools/3d/zone_lighter/zone_lighter.cpp b/code/nel/tools/3d/zone_lighter/zone_lighter.cpp index 8608958e0..d00db9438 100644 --- a/code/nel/tools/3d/zone_lighter/zone_lighter.cpp +++ b/code/nel/tools/3d/zone_lighter/zone_lighter.cpp @@ -158,7 +158,7 @@ static void loadIGFromVillage(const NLGEORGES::UFormElm *villageItem, const std: { group->serial (inputFile); } - catch(NLMISC::Exception &) + catch(const NLMISC::Exception &) { nlwarning ("Error while loading instance group %s\n", igName.c_str()); continue; @@ -266,7 +266,7 @@ static void loadIGFromContinent(NLMISC::CConfigFile ¶meter, std::listTileBank.serial (inputFile); landscape->initTileBanks(); } - catch (Exception &e) + catch (const Exception &e) { // Error nlwarning ("ERROR error loading tile bank %s\n%s\n", bankName.c_str(), e.what()); @@ -581,7 +581,7 @@ int main(int argc, char* argv[]) } } } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { nlinfo("No additionnal ig's to load"); } @@ -835,7 +835,7 @@ int main(int argc, char* argv[]) // load it output.serial (zonelFile); } - catch (Exception& except) + catch (const Exception& except) { // Error message nlwarning ("ERROR reading %s: %s\n", argv[2], except.what()); @@ -860,7 +860,7 @@ int main(int argc, char* argv[]) { output.serial (outputFile); } - catch (Exception& except) + catch (const Exception& except) { nlwarning ("ERROR backuping %s: %s\n", bkupFile.c_str(), except.what()); } @@ -886,7 +886,7 @@ int main(int argc, char* argv[]) // Save it output.serial (outputFile); } - catch (Exception& except) + catch (const Exception& except) { // Error message nlwarning ("ERROR writing %s: %s\n", argv[2], except.what()); @@ -909,7 +909,7 @@ int main(int argc, char* argv[]) nlwarning ("ERROR Abort: files are missing.\n"); } } - catch (Exception& except) + catch (const Exception& except) { // Error message nlwarning ("ERROR %s\n", except.what()); diff --git a/code/nel/tools/3d/zone_welder/zone_welder.cpp b/code/nel/tools/3d/zone_welder/zone_welder.cpp index 9e0d94e37..e2b345e9e 100644 --- a/code/nel/tools/3d/zone_welder/zone_welder.cpp +++ b/code/nel/tools/3d/zone_welder/zone_welder.cpp @@ -270,7 +270,7 @@ void weldZones(const char *center) adjZonesName[i]="empty"; } } - catch(exception &e) + catch(const exception &e) { nlwarning ("ERROR %s\n", e.what ()); adjZoneFileFound[i] = false; diff --git a/code/nel/tools/3d/zviewer/zviewer.cpp b/code/nel/tools/3d/zviewer/zviewer.cpp index 6cd17e7df..da966b420 100644 --- a/code/nel/tools/3d/zviewer/zviewer.cpp +++ b/code/nel/tools/3d/zviewer/zviewer.cpp @@ -364,7 +364,7 @@ void displayZones() CIFile bankFile (ViewerCfg.BanksPath + "/" + ViewerCfg.Bank); Landscape->Landscape.TileBank.serial(bankFile); } - catch(Exception) + catch(const Exception &) { string tmp = string("Cant load bankfile ")+ViewerCfg.BanksPath + "/" + ViewerCfg.Bank; nlerror (tmp.c_str()); @@ -390,7 +390,7 @@ void displayZones() CIFile farbankFile(ViewerCfg.BanksPath + "/" + farBank); Landscape->Landscape.TileFarBank.serial(farbankFile); } - catch(Exception) + catch(const Exception &) { string tmp = string("Cant load bankfile ")+ViewerCfg.BanksPath + "/" + farBank; nlerror (tmp.c_str()); @@ -450,7 +450,7 @@ void displayZones() // Add it to collision manager. CollisionManager.addZone(zone.getZoneId()); } - catch(Exception &e) + catch(const Exception &e) { printf("%s\n", e.what ()); } @@ -472,7 +472,7 @@ void displayZones() // Add it to the scene. group->addToScene (*CNELU::Scene); } - catch(Exception &e) + catch(const Exception &e) { printf("%s\n", e.what ()); } @@ -940,7 +940,7 @@ void initViewerConfig(const char * configFileName) } } - catch (EConfigFile &e) + catch (const EConfigFile &e) { nlerror("Problem in config file : %s\n", e.what ()); } @@ -970,7 +970,7 @@ int main(int /* argc */, char ** /* argv */) initViewerConfig("zviewer.cfg"); // Init NELU - NL3D::CNELU::init(ViewerCfg.Width, ViewerCfg.Height, CViewport(), ViewerCfg.Depth, ViewerCfg.Windowed, NULL, false, false); + NL3D::CNELU::init(ViewerCfg.Width, ViewerCfg.Height, CViewport(), ViewerCfg.Depth, ViewerCfg.Windowed, EmptyWindow, false, false); NL3D::CNELU::Driver->setWindowTitle(ucstring("NeL ZViewer")); NL3D::CNELU::Camera->setTransformMode(ITransformable::DirectMatrix); @@ -985,7 +985,7 @@ int main(int /* argc */, char ** /* argv */) // release nelu NL3D::CNELU::release(); } - catch (Exception &e) + catch (const Exception &e) { nlerror("main trapped an exception: '%s'", e.what ()); } diff --git a/code/nel/tools/georges/georges2csv/georges2csv.cpp b/code/nel/tools/georges/georges2csv/georges2csv.cpp index b5785159a..e10d06bf5 100644 --- a/code/nel/tools/georges/georges2csv/georges2csv.cpp +++ b/code/nel/tools/georges/georges2csv/georges2csv.cpp @@ -838,7 +838,7 @@ void convertCsvFile( const string &file, bool generate, const string& sheetType ForceInsertParents = (fiparents->asInt() == 1); nlinfo( "Force insert parents mode: %s", ForceInsertParents ? "ON" : "OFF" ); } - catch ( EConfigFile& e ) + catch (const EConfigFile &e) { nlwarning( "Problem in directory mapping: %s", e.what() ); } diff --git a/code/nel/tools/misc/bnp_make/main.cpp b/code/nel/tools/misc/bnp_make/main.cpp index cf0332d2a..6f0c6a235 100644 --- a/code/nel/tools/misc/bnp_make/main.cpp +++ b/code/nel/tools/misc/bnp_make/main.cpp @@ -99,6 +99,7 @@ struct BNPHeader fclose(f); return false; } + for (uint32 i = 0; i < nNbFile; ++i) { uint8 nStringSize = (uint8)Files[i].Name.size(); @@ -424,13 +425,13 @@ int main (int nNbArg, char **ppArgs) } else { - nlwarning ("ERROR (bnp_make.exe) : can't set current directory to %s", ppArgs[2]); + nlwarning ("ERROR (bnp_make) : can't set current directory to %s", ppArgs[2]); return -1; } } else { - nlwarning ("ERROR (bnp_make.exe) : can't set current directory to %s", ppArgs[3]); + nlwarning ("ERROR (bnp_make) : can't set current directory to %s", ppArgs[3]); return -1; } } @@ -438,7 +439,7 @@ int main (int nNbArg, char **ppArgs) { if (chdir (ppArgs[2]) == -1) { - nlwarning ("ERROR (bnp_make.exe) : can't set current directory to %s", ppArgs[2]); + nlwarning ("ERROR (bnp_make) : can't set current directory to %s", ppArgs[2]); return -1; } //getcwd (sCurDir, MAX_PATH); @@ -475,7 +476,7 @@ int main (int nNbArg, char **ppArgs) } else { - nlwarning ("ERROR (bnp_make.exe) : can't set current directory to %s", path.c_str()); + nlwarning ("ERROR (bnp_make) : can't set current directory to %s", path.c_str()); return -1; } } @@ -521,7 +522,7 @@ int main (int nNbArg, char **ppArgs) } else { - nlwarning ("ERROR (bnp_make.exe) : can't set current directory to %s", path.c_str()); + nlwarning ("ERROR (bnp_make) : can't set current directory to %s", path.c_str()); return -1; } } diff --git a/code/nel/tools/misc/extract_filename/extract_filename.cpp b/code/nel/tools/misc/extract_filename/extract_filename.cpp index c8ca13452..39fead0e4 100644 --- a/code/nel/tools/misc/extract_filename/extract_filename.cpp +++ b/code/nel/tools/misc/extract_filename/extract_filename.cpp @@ -23,7 +23,7 @@ using namespace NLMISC; #ifdef NL_DEBUG #define INFO nlinfo #else // NL_DEBUG -# if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) +# if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10) # define INFO __noop # else # define INFO 0&& diff --git a/code/nel/tools/misc/lock/lock.cpp b/code/nel/tools/misc/lock/lock.cpp index efdda5d73..616095bb6 100644 --- a/code/nel/tools/misc/lock/lock.cpp +++ b/code/nel/tools/misc/lock/lock.cpp @@ -25,7 +25,7 @@ int main(int argc, char* argv[]) { if (argc <3) { - printf ("lock.exe [filein] [fleout]\n\t"); + printf ("lock [filein] [fleout]\n\t"); } else { diff --git a/code/nel/tools/nel_unit_test/ut_net_module.h b/code/nel/tools/nel_unit_test/ut_net_module.h index 871901f8d..15d526075 100644 --- a/code/nel/tools/nel_unit_test/ut_net_module.h +++ b/code/nel/tools/nel_unit_test/ut_net_module.h @@ -193,7 +193,7 @@ public: { invokeModuleOperation(proxy, msg, resp); } - catch(IModule::EInvokeFailed) + catch(const IModule::EInvokeFailed &) { ResponseReceived++; } diff --git a/code/nel/tools/pacs/build_ig_boxes/main.cpp b/code/nel/tools/pacs/build_ig_boxes/main.cpp index 046e5ee74..7e917d85e 100644 --- a/code/nel/tools/pacs/build_ig_boxes/main.cpp +++ b/code/nel/tools/pacs/build_ig_boxes/main.cpp @@ -112,7 +112,7 @@ void init() CPath::addSearchPath(cvPathes.asString(i)); } } - catch (EConfigFile &e) + catch (const EConfigFile &e) { printf ("Problem in config file : %s\n", e.what ()); } @@ -219,7 +219,7 @@ int main(int argc, char **argv) COFile output(Output); output.serialCont(Boxes); } - catch (Exception &e) + catch (const Exception &e) { fprintf (stderr,"main trapped an exception: '%s'\n", e.what ()); } diff --git a/code/nel/tools/pacs/build_indoor_rbank/main.cpp b/code/nel/tools/pacs/build_indoor_rbank/main.cpp index 1d459e2ee..b432f372a 100644 --- a/code/nel/tools/pacs/build_indoor_rbank/main.cpp +++ b/code/nel/tools/pacs/build_indoor_rbank/main.cpp @@ -146,7 +146,7 @@ void initConfig() for (i=0; i<(uint)meshes.size(); i++) Meshes.push_back(meshes.asString(i)); } - catch (EConfigFile &e) + catch (const EConfigFile &e) { printf ("Problem in config file : %s\n", e.what ()); } @@ -195,7 +195,7 @@ void makeGlobalRetriever(vector &translation) ninst.push_back(iid); } } - catch (Exception &e) + catch (const Exception &e) { nlwarning("WARNING: can't merge lr '%s.lr': %s", Meshes[i].c_str(), e.what()); } @@ -303,7 +303,7 @@ void createRetriever(vector &translation) // Save the lr file serialAndSave(lr, OutputPath+meshName+".lr"); } - catch (Exception &e) + catch (const Exception &e) { nlwarning("WARNING: can compute lr '%s.lr': %s", meshName.c_str(), e.what()); } diff --git a/code/nel/tools/pacs/build_rbank/build_rbank.cpp b/code/nel/tools/pacs/build_rbank/build_rbank.cpp index 0a8091a5f..295409508 100644 --- a/code/nel/tools/pacs/build_rbank/build_rbank.cpp +++ b/code/nel/tools/pacs/build_rbank/build_rbank.cpp @@ -215,7 +215,7 @@ void processAllPasses(string &zoneName) retriever.serial(outputRetriever); } } - catch(Exception &e) + catch(const Exception &e) { printf("%s\n", e.what ()); } @@ -264,7 +264,7 @@ void tessellateAndMoulineZone(string &zoneName) nlinfo("WARNING: IG list no found"); } } - catch (Exception &) { nlinfo("WARNING: IG list no found"); } + catch (const Exception &) { nlinfo("WARNING: IG list no found"); } for (i=0; iasString(i)); } } - catch (EConfigFile &e) + catch (const EConfigFile &e) { nlwarning("Problem in config file : %s\n", e.what ()); } @@ -383,7 +383,7 @@ int main(int argc, char **argv) if (Verbose) nlinfo("total computation time: %d days, %d hours, %d minutes and %d seconds", workDay, workHour, workMinute, workSecond); } - catch (Exception &e) + catch (const Exception &e) { nlwarning ("main trapped an exception: '%s'\n", e.what ()); } diff --git a/code/nel/tools/pacs/build_rbank/prim_checker.cpp b/code/nel/tools/pacs/build_rbank/prim_checker.cpp index 678972f91..5273db1da 100644 --- a/code/nel/tools/pacs/build_rbank/prim_checker.cpp +++ b/code/nel/tools/pacs/build_rbank/prim_checker.cpp @@ -171,7 +171,7 @@ bool CPrimChecker::build(const string &primitivesPath, const string &igLandPath, } } } - catch (Exception &e) + catch (const Exception &e) { nlwarning("%s", e.what()); } diff --git a/code/ryzom/client/client_default.cfg b/code/ryzom/client/client_default.cfg index ca6534931..c29ca9b93 100644 --- a/code/ryzom/client/client_default.cfg +++ b/code/ryzom/client/client_default.cfg @@ -385,21 +385,21 @@ SystemInfoColors = }; PrintfCommands = { - "52", "15", "55 55 0 255", "28", "uiChapterIV", "624", + "52", "15", "55 55 0 255", "28", "uiChapterV", "624", "428", "0 0 0 255", "18", "", "624", "378", "0 0 0 255", "14", "", "644", "278", "0 0 0 255", "18", "", "52", "17", "255 255 255 255", "28", - "uiChapterIV", "622", "430", "255 255 255 255", "18", "", + "uiChapterV", "622", "430", "255 255 255 255", "18", "", "622", "380", "255 255 255 255", "14", "", "642", "280", "255 255 255 255", "18", "" }; PrintfCommandsFreeTrial = { - "52", "15", "55 55 0 255", "28", "uiChapterIV", "624", + "52", "15", "55 55 0 255", "28", "uiChapterV", "624", "428", "0 0 0 255", "18", "", "624", "378", "0 0 0 255", "14", "", "644", "278", "0 0 0 255", "18", "", "52", "17", "255 255 255 255", "28", - "uiChapterIV", "622", "430", "255 255 255 255", "18", "", + "uiChapterV", "622", "430", "255 255 255 255", "18", "", "622", "380", "255 255 255 255", "14", "", "642", "280", "255 255 255 255", "18", "" }; diff --git a/code/ryzom/client/data/gamedev/adds/interfaces/color_palette.dds b/code/ryzom/client/data/gamedev/adds/interfaces/color_palette.dds new file mode 100644 index 0000000000000000000000000000000000000000..86be36532130712b2b61e01cce7cf98d795c495f GIT binary patch literal 22032 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 literal 0 HcmV?d00001 diff --git a/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.tga b/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.tga index 026fada234b5ef5fa55c2e33ddd992431b66b08e..bbeeab27b137f23de2ef17354622069d33f7c77c 100644 GIT binary patch delta 64023 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 QJgQhSOFZ*3G_lS91JJ_$N&o-= delta 46202 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 literal 0 HcmV?d00001 diff --git a/code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_blue_yubo.shape b/code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_blue_yubo.shape new file mode 100644 index 0000000000000000000000000000000000000000..c1c313e804defc0c6ffcd45ce65b752b1f559199 GIT binary patch literal 9730 zcmbtZ2~-r<(jHLau9*0qQC~z66;u>~0hyuuBH$7YB8Y;R2ne_mP&Q>B7gQ9~XhexT zG_IgQqu@3}cY{LIXd)V8q9lRD1((FQM$ICxs^|91b>TmG{~OOoEnnZdb?a6a9%jPm z;o~h-#*Y;UAHV2?nXk2>p1&(}@F0awLY*kE1glL;_|XM+L8Ao#H^NVTetr{(CX`f1 z_iz9Nz^C!k9^excy&y3uK6>P=m}mN=&-PcAETnfX3UzN7&a{?DSB|?j0k+x zLjGrI0sordgZtx$jp~y$E!t9!Dn|kqpOSS<9Y5^j|3?xX;L(J+(UD;>Nehe_$gBUx zkC!u57X8yM-YH4b;u7Y}ifyLm|L>E)!sbseN5xB0jrNgs z`a`)gv(K_cD^;sjE$OFy`?l>ZEWSiqX)(*lTUw#@?I5AMzYE#aFG%QJpq6Gma3R)( zYdL(-X4hMWx*tPizP|MHifvy_l#Ug(C)Nac9gqB#j|(dD&bX7I?zM*Slo4W@QyS^z zxtm8G^)<5VM#3}0|oaFU#{5F$k2ptlfh|em6 zVQEyn6jr)jt_|jg@mJ3Zm3g$M)n!S88(YhFqr_L%KfL^{U^ym3>g0b~z-Qqj$3Ji| zf@=@)kK`E)IZ^S%UyhHX${2sxXF)QLc2r#!`T9D>mq(eLKeJx@!g_Lh^i|Ifye9~o zRyvcGc6)_R!UJI-$snp>nVS1eP5c{ergFXZ-qZIeb|nsr77K;P@(rC9WRXJ0D((r% z;&J^~gIgP#99_wQ(d&gi-tQU424u;(;rX&trf?_DCksQbI1{%!9}1faz7rfTWRNxC zmE1#!-%)p$vtQR)Uo%@x8gDy_0fz?|@<*i;yKjyC7rf^-mlVBBICs;92(w+qJ#o8) z>o#d5G~pBecUV78;`q1oKhR8@sUeY(0q0 zZ%f71ft!WVcFDx~7vxpsx8QibQ)3J5M-MoXr@1H$>7doRY|JFK55wg34RP`OPoHfN zwgr2VgOw+R3!C=|U!Kb#yS5{*BHj;I@E>_})Rryb$bn6P+;=^awU>(V{KoqCj9$)9 z)~yvXFKbC|#yajFc% zu)f^P;T+!2hKYxS*3T??`}%aEa?Q}IR9>!+GH!EQ6P9w0-@A|-9&Tb~(oxRu+f-6# zy9eK2mwRyj%E=o!Jio`0Wn%EgLT-a~GO5k7!~9hRGvoP`XGNUtBu_H*R<#g!Y$s=U zltF&KB%iOmAZ$7RTHZ&TE#%LgTf`No@8u#_X43P)`yaVd#Pf|x(~^}zD}_tt`-I0y zz|;Oo^jRQceIIY($eqeMPCYKrFeW?G)IZ(E=7}4je*MOCq-^^@VcGEmhNK#-AAWRv zL-Yc%0qXD5%9G4{>nOMP{&wNfTbZW*S=!lG90m8^sUp`DW_0RS3e+drIe`m+3$(8f{`1+{T+OO87oBD@Ke^{RTUUqP0sf3j~R3fTXRjn3ru zJL|ZRn-2vk)7(ER)a?X(f3AADk~c17bFl{!wW$f_{>cL#-%nkUGda3*A6KNa6m5S? zH}y}!)CFP=++UTICwW|7$^BJxh--Jz+&=@Rt`zb9vQo9=V(Av)$~Rwf-&}+DoAwXZ zrxyAH>$9ZYQoeI>5!Ys9vZ;Tf{GJF0pubX&xezx_&2!!*Tu$dSQ~%7+B?{QT4=y>A z$j8~-ua|$~QtQqAgZX3sV*d9BZs6Rkf9DoP!2a_4p;8q+a^T!kf`livF2pO{d6z=i8dVB9GEEmm}0Lj`hFv?%pY8Tu-#n!V_07?-9>sf{=8<| zW;aRcpD{(g+|a%=h0ztzKQ;+cVXAvYTW$-l%%7XrcXMZd8mQm1W;_{j_+2SJx zh^c=*tZ&Z`?6glvw2mT|7urjmP8A!%4||#VC->T9zDtj5n$NUxBs$q!46eVd{dr=V zsef+$9K`z$mxL^`k?XNMAcing63N|BGK{x5-kpOWOIUzn{XcXGG#CB=@~VO8;x zGXE3Qh1~1VKU0d;jj%UNuLSC8wrO@AfdcMP9e^(~BN^z=To(-$jlJfq#2NZK#-^$_qPy3VVZtqFS zPwhRISz4Ih-va2r0bykv_Ftcf{!)%~SKDv@aMSxcr!k1H>0QI=En|tk^-$40pf|VT zUYcqCk1biuueCYFg(axB%gA(cuVMms?tEWS z$-mk4bpFJ`{n|r*c)xBBe8}ONecE9ac9Qb@>&~fe{1!N$PYq9k;;cxUF^@H&DWQ_` z`zvzWCb@oYdNm0O*u$6kg2ItSFz(le<#okcL%%3r^UU%WF2G`e4cOef(p4a;^^XI8FQ7FDLo5T4NXOlqq z6nD?A%=|e%zf8DaS*oG)hjgBFQIp8bpZuwx3b$%ka&-QXUK#iF?ELx8sf)O!SKFg> z{*Y}6Ej449`J=M$EJnqCD&K$ILVI%VWU)4anLke*r;6*xd9i}mP(G!AAXqR&$08T)w&#U(4PHzoIg+OT%;kpLiB&uo99p8^VuTtJI>+!S^dmK zsxPbJ&M@<*IbNARu?KR+FCjmiKij!6KlNN9>w`nUGFU=+J@y)DQd9HP~0WRaC2uV&=~w+umYz zMX3hoPslMVso3G9!Izmo?Sp!XH{t$p{_L4$B`vzTOM9Q0KT|z+3E^#yXmI{~o4Zx~ zbGxI#lbJtbKie)WhyKC&)6imvxU$1YPj>z^-+#vW(_DWm^QYU@Ny7U(rwVlbkjdpa z73}s(o z^6x*GKP0f~u7RCDmxoLi7auz=;QaZn^-$h7ptrD`nLmrZ$QA=CPY4k(f6f;=NkLt! zg(PPF+#I_?TmtJqg!$t-GF{qHF+r$h=1;Th>HPT~?)Nt2mk0Oj{=i4FIkC^+&di_C z*L#Z5a6Vs{Kf!TUlK=F_`VeORXkE7pu~0vpKcNA8!~oyi3O8o{G+RG9e}dA-2PirLtWtiMiTtN2WG5_Aph&TyZKeXPuoA(p)=);|G!a@ec4*>XUc!s z(9=O#Pk9ycN__M&ycgO(Je(-Z8&EDz5S?&8`oZ2&K^`iV`q@Y>{+0Zi13(iu;6D#9 z=U=hj3;FLM{^{m<6?^_cS&augu4hRLg=-bCR^I=`{E=TG^Tz$z{GQ!dQ;vMBalO1h zd%jcKiex^<%**vr>gVScqlWc_u9x>`>;J~1G?|~x?9ZNWb9RL*uHRse|6F}wf0_Tc znO8Xs-6O_a_TfHVY=vj0AM^cB3@qUzU%}G{$pqlH_4gKDT(3kL2=SZYz3`dV>Vx9_ zK!5HP_a~pfE$|Lo{DhZzWBpwwmGQ6URT!VR0)O+>@sWS-{6TPcV{Q7YZT-ym&*qPO z^^^YUJ~D6IpUn?>mv|d>U*md=PuTMz|IN0ZEU#ko2cGC3mX4^RgUOFQKk}EM2kn^ru07f+j=%k}IH2VjcdUo;gMW+OSk}0AI6=Oo_g4O8 zUPq9(?)ov`96#PSMMS>2_{b0Xd7qg7<6bfJ+29x6|2NA^e()i|9rp6C=5<8jf9<-D ze|f!*IAzb36!HhzIl!=EwApd_H`R zy&vWL=!g1CFV>&Q-?Sc|ErR-E{>uHJFAj1X2m8~%zew!;ArJYHsmM39JoIN%(<|Oz z9Vu`h=!(yV6dLPe-XFaRuOp-1H1f*+(X>8E5Pwd`5^}QCc>fBIt4;euoGsgU`Tb>i zbN(vTi#!`2^FUsCzhCS>mRI7l{foIM@v%Q~JCYMQx0Yae4!A@16h~0QxYFEdc$P z8*(UnF*>eC8zsg-9oOPIv@u2>YNL)hplt`}3+PAn{?tZk&*%=+Mmd1d2T~j5AVznj zHp;<_K7`sB8{^>r6>)DTz)%4CFb>WM^kZ(wp>$?+T#q(NjDb3?#dT<73^lb;#~jdh z1K|IchEd&v+9)-QuBA3gPe#Y@R?tR?@3o@i{6-t47o!iSHpa$h0|4FtAAm2_M^GE( zNJbw;ZIq)K{cUQa9K+~isg3d-M)#vO#>P0o06hOVfIk3z7$*dPeyk62D91B8o&jx? zcn;L@Oo7x!9czF#$_b3_MQz+?G646&^9KPY0?>~+BZq#h4{|6cF*=?BZIpNp)G>dI zhju7n3gBI;zejD9QyD#s+9<;rJ%ZXOr!jgYwNXYfdNj2$b~qpjFdZ-hFq7)DsEu+q zqtBr>${0p}pV}y689k2LDCaWzJZfWXjFSey^Tz`c0O-Rw=>YU&eUL+$$mne~r& z7oZqW0@w}MLm^NfauNWa{RB`7*h{gG`aT7@A8>%83?%x>0S5txC@Mjs57%LglN4W2 zAFjg~pHZ9uiN3>tBY>k6BI85u6vgKt@i{%f0H~m-p}s1R#{kDEszIXfG~f&X&xyb@ fqtE!6^Q&GJKH1}N-(UF6Bg*+Az}Eryc-4OZ+&M}y literal 0 HcmV?d00001 diff --git a/code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_green.shape b/code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_green.shape new file mode 100644 index 0000000000000000000000000000000000000000..4b2cf8e9298f73ad92f6e8ca8e4bba54cc6f31fb GIT binary patch literal 9584 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 ZdR4?^uOt0`<)M#9Y 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 literal 0 HcmV?d00001 diff --git a/code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_red.shape b/code/ryzom/client/data/gamedev/adds/shapes/Ge_gift_red.shape new file mode 100644 index 0000000000000000000000000000000000000000..6ab854bd5da8d640aa34d97f8b31bc2e130cf7c6 GIT binary patch literal 9582 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 hA~0uMGk#|Mu2)4(^gh`CH@VAFeR@JR8 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 literal 0 HcmV?d00001 diff --git a/code/ryzom/client/data/gamedev/adds/shapes/UL_Mission_Hall_Of_Fame.shape b/code/ryzom/client/data/gamedev/adds/shapes/UL_Mission_Hall_Of_Fame.shape new file mode 100644 index 0000000000000000000000000000000000000000..21773da12f65816544e1c46ac8348ab91d76051b GIT binary patch literal 74362 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 literal 0 HcmV?d00001 diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/actions.xml b/code/ryzom/client/data/gamedev/interfaces_v3/actions.xml index 3b0395826..06cbac804 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/actions.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/actions.xml @@ -27,6 +27,7 @@ + @@ -165,6 +166,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -262,6 +287,8 @@ + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/bot_chat_v4.xml b/code/ryzom/client/data/gamedev/interfaces_v3/bot_chat_v4.xml index 4efed8d2f..caf7394f8 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/bot_chat_v4.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/bot_chat_v4.xml @@ -4454,6 +4454,10 @@ + + + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/guild.xml b/code/ryzom/client/data/gamedev/interfaces_v3/guild.xml index 3ecd0f746..8bcf456e9 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/guild.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/guild.xml @@ -1088,7 +1088,8 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml b/code/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml index d3fe32848..4bdd0c761 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml @@ -16,6 +16,7 @@ + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/info_player.xml b/code/ryzom/client/data/gamedev/interfaces_v3/info_player.xml index f9d129789..cc76e5f80 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/info_player.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/info_player.xml @@ -640,6 +640,13 @@ posparent="tab1" group="content:rpjobs" hardtext="uiRpJobs" + onclick_r="" + params_r="" /> + - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -3277,7 +3391,7 @@ action="lua:game:onMissionJournalOpened()" /> - + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/inventory.xml b/code/ryzom/client/data/gamedev/interfaces_v3/inventory.xml index 8fbd69efe..b3817ce12 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/inventory.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/inventory.xml @@ -985,7 +985,31 @@ tooltip_posref="TR TL" tooltip_posref_alt="TL TR" /> - + + @@ -1290,6 +1314,143 @@ params="value=add(@UI:PHRASE:SELECT_MEMORY,-1)" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/keys.xml b/code/ryzom/client/data/gamedev/interfaces_v3/keys.xml index 5632f3c86..5cad940bd 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/keys.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/keys.xml @@ -26,6 +26,8 @@ + + @@ -82,6 +84,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/reset.xml b/code/ryzom/client/data/gamedev/interfaces_v3/reset.xml index 684d9e85a..6c920a76c 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/reset.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/reset.xml @@ -95,11 +95,233 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/taskbar.xml b/code/ryzom/client/data/gamedev/interfaces_v3/taskbar.xml index a828dc08b..5ad82b280 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/taskbar.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/taskbar.xml @@ -1004,7 +1004,10 @@ - + + - + diff --git a/code/ryzom/client/src/attached_fx.h b/code/ryzom/client/src/attached_fx.h index c58a9e92c..6cd8d2ef7 100644 --- a/code/ryzom/client/src/attached_fx.h +++ b/code/ryzom/client/src/attached_fx.h @@ -71,6 +71,8 @@ public: const NLMISC::CMatrix *StaticMatrix; // Useful if stick mode is "StaticMatrix" uint MaxNumAnimCount; // Number of frame on which the fx can overlap when it is being shutdown float TimeOut; + double StartTime; + float DelayBeforeStart; public: CBuildInfo() { @@ -80,6 +82,8 @@ public: StaticMatrix = NULL; MaxNumAnimCount = 0; TimeOut = FX_MANAGER_DEFAULT_TIMEOUT; + StartTime = 0.0; + DelayBeforeStart = 0.f; } }; CAttachedFX(); diff --git a/code/ryzom/client/src/bg_downloader_access.cpp b/code/ryzom/client/src/bg_downloader_access.cpp index df95c6454..699f01f3a 100644 --- a/code/ryzom/client/src/bg_downloader_access.cpp +++ b/code/ryzom/client/src/bg_downloader_access.cpp @@ -336,21 +336,21 @@ void CBGDownloaderAccess::CDownloadCoTask::run() } } } - catch(EDownloadException &e) + catch(const EDownloadException &e) { //shutdownDownloader(); Parent->_TaskResult = TaskResult_Error; Parent->_ErrorMsg.fromUtf8(e.what()); Parent->_DownloadThreadPriority = ThreadPriority_DownloaderError; } - catch(EDownloadTerminationRequested &e) + catch(const EDownloadTerminationRequested &e) { shutdownDownloader(); Parent->_TaskResult = TaskResult_Error; Parent->_ErrorMsg = ucstring(e.what()); Parent->_DownloadThreadPriority = ThreadPriority_DownloaderError; } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { shutdownDownloader(); Parent->_TaskResult = TaskResult_Error; @@ -358,7 +358,7 @@ void CBGDownloaderAccess::CDownloadCoTask::run() Parent->_ErrorMsg = CI18N::get("uiBGD_ProtocolError") + ucstring(" : ") + ucstring(e.what()); Parent->_DownloadThreadPriority = ThreadPriority_DownloaderError; } - catch (EWaitMessageTimeoutException &e) + catch (const EWaitMessageTimeoutException &e) { shutdownDownloader(); Parent->_TaskResult = TaskResult_Error; @@ -517,7 +517,7 @@ void CBGDownloaderAccess::CDownloadCoTask::restartDownloader() ok = true; break; } - catch (EWaitMessageTimeoutException &) + catch (const EWaitMessageTimeoutException &) { // no-op, just continue the loop for another try } diff --git a/code/ryzom/client/src/camera_recorder.cpp b/code/ryzom/client/src/camera_recorder.cpp index 9ef556b06..309eee039 100644 --- a/code/ryzom/client/src/camera_recorder.cpp +++ b/code/ryzom/client/src/camera_recorder.cpp @@ -239,7 +239,7 @@ class CAHSaveCameraRecord : public IActionHandler nlwarning("Couldn't compute camera recorder next filename"); } } - catch(EStream &e) + catch(const EStream &e) { nlwarning(e.what()); } @@ -283,7 +283,7 @@ NLMISC_COMMAND(loadCamRec, "Load a camera path record file (.cr)", "") f.serialCont(Track); State = Idle; } - catch(EStream &e) + catch(const EStream &e) { nlwarning(e.what()); } diff --git a/code/ryzom/client/src/cdb_branch.cpp b/code/ryzom/client/src/cdb_branch.cpp index 06501e940..60c6b63f4 100644 --- a/code/ryzom/client/src/cdb_branch.cpp +++ b/code/ryzom/client/src/cdb_branch.cpp @@ -87,7 +87,7 @@ extern const char *CDBBankNames[INVALID_CDB_BANK+1]; // reset all static data void CCDBNodeBranch::reset() { - for ( uint b=0; b!=INVALID_CDB_BANK; ++b ) + for ( uint b=0; binit( read.getRootNode (), progressCallBack, true ); } } - catch (Exception &e) + catch (const Exception &e) { // Output error nlwarning ("CFormLoader: Error while loading the form %s: %s", fileName.c_str(), e.what()); diff --git a/code/ryzom/client/src/character_cl.cpp b/code/ryzom/client/src/character_cl.cpp index 9a651e331..6130f2b60 100644 --- a/code/ryzom/client/src/character_cl.cpp +++ b/code/ryzom/client/src/character_cl.cpp @@ -4521,6 +4521,10 @@ void CCharacterCL::applyBehaviourFlyingHPs(const CBehaviourContext &bc, const MB else deltaHPColor = ClientCfg.SystemInfoParams["dg"].Color; } + else + { + deltaHPColor = CRGBA(127,127,127); + } } else { @@ -5874,6 +5878,27 @@ void CCharacterCL::updateAttachedFX() CMatrix alignMatrix; buildAlignMatrix(alignMatrix); + std::list::iterator itAttachedFxToStart = _AttachedFXListToStart.begin(); + while(itAttachedFxToStart != _AttachedFXListToStart.end()) + { + if ((*itAttachedFxToStart).DelayBeforeStart < (float)(TimeInSec - (*itAttachedFxToStart).StartTime)) + { + uint index = (*itAttachedFxToStart).MaxNumAnimCount; + (*itAttachedFxToStart).MaxNumAnimCount = 0; + CAttachedFX::TSmartPtr fx = new CAttachedFX; + fx->create(*this, (*itAttachedFxToStart), CAttachedFX::CTargeterInfo()); + if (!fx->FX.empty()) + { + _AuraFX[index] = fx; + } + itAttachedFxToStart = _AttachedFXListToStart.erase(itAttachedFxToStart); + } + else + { + ++itAttachedFxToStart; + } + } + // update tracks & pos for anim attachedfxs std::list::iterator itAttachedFx = _AttachedFXListForCurrentAnim.begin(); while(itAttachedFx != _AttachedFXListForCurrentAnim.end()) @@ -8312,7 +8337,7 @@ ADD_METHOD(void CCharacterCL::displayDebug(float x, float &y, float lineStep)) / TextContext->printfAt(x, y, "(Walk)Run Factor: %f", runFactor()); y += lineStep; // Display the current animation name(id)(offset)(nbloop) pour le channel MOVE. - TextContext->printfAt(x, y, "Current Animation: %s(%u)(%f)(%u loops)", animId(MOVE)==-1?"[NONE]":currentAnimationName().c_str(), animId(MOVE), animOffset(MOVE), _NbLoopAnim); + TextContext->printfAt(x, y, "Current Animation: %s(%u)(%lf)(%u loops)", animId(MOVE)==std::numeric_limits::max()?"[NONE]":currentAnimationName().c_str(), animId(MOVE), animOffset(MOVE), _NbLoopAnim); y += lineStep; // First Pos if(_First_Pos) @@ -8985,6 +9010,14 @@ void CCharacterCL::setAuraFX(uint index, const CAnimationFX *sheet) if (sheet == NULL) { + std::list::iterator itAttachedFxToStart = _AttachedFXListToStart.begin(); + while(itAttachedFxToStart != _AttachedFXListToStart.end()) + { + if ((*itAttachedFxToStart).MaxNumAnimCount == index) + itAttachedFxToStart = _AttachedFXListToStart.erase(itAttachedFxToStart); + else + ++itAttachedFxToStart; + } // if there's already an aura attached, and if it is not already shutting down if (_AuraFX[index] && _AuraFX[index]->TimeOutDate == 0.f) { @@ -8993,16 +9026,40 @@ void CCharacterCL::setAuraFX(uint index, const CAnimationFX *sheet) } else { + std::list::iterator itAttachedFxToStart = _AttachedFXListToStart.begin(); + while(itAttachedFxToStart != _AttachedFXListToStart.end()) + { + if ((*itAttachedFxToStart).MaxNumAnimCount == index) + return; + } // remove previous aura _AuraFX[index] = NULL; - CAttachedFX::TSmartPtr fx = new CAttachedFX; CAttachedFX::CBuildInfo bi; bi.Sheet = sheet; bi.TimeOut = 0.f; - fx->create(*this, bi, CAttachedFX::CTargeterInfo()); - if (!fx->FX.empty()) + + if (sheet->Sheet->PSName == "misc_caravan_teleportout.ps") { - _AuraFX[index] = fx; + bi.MaxNumAnimCount = index; + bi.StartTime = TimeInSec; + bi.DelayBeforeStart = 12.5f; + _AttachedFXListToStart.push_front(bi); + } + else if (sheet->Sheet->PSName == "misc_kami_teleportout.ps") + { + bi.MaxNumAnimCount = index; + bi.StartTime = TimeInSec; + bi.DelayBeforeStart = 11.5f; + _AttachedFXListToStart.push_front(bi); + } + else + { + CAttachedFX::TSmartPtr fx = new CAttachedFX; + fx->create(*this, bi, CAttachedFX::CTargeterInfo()); + if (!fx->FX.empty()) + { + _AuraFX[index] = fx; + } } } } diff --git a/code/ryzom/client/src/character_cl.h b/code/ryzom/client/src/character_cl.h index 1a0e864d0..a5d7ba880 100644 --- a/code/ryzom/client/src/character_cl.h +++ b/code/ryzom/client/src/character_cl.h @@ -675,6 +675,7 @@ protected: /// List of attached to remove as soon as possible (when there are no particles left) std::list _AttachedFXListToRemove; + std::list _AttachedFXListToStart; CAttachedFX::TSmartPtr _AuraFX[MaxNumAura]; // special case for aura CAttachedFX::TSmartPtr _LinkFX; // special case for link diff --git a/code/ryzom/client/src/client.cpp b/code/ryzom/client/src/client.cpp index 8eea73241..72fe1c0b1 100644 --- a/code/ryzom/client/src/client.cpp +++ b/code/ryzom/client/src/client.cpp @@ -85,7 +85,7 @@ using namespace NLNET; // We don't catch(...) because these exception are already trapped with the se_translation that generate the NeL message box #define RYZOM_TRY(_block) try { nlinfo(_block" of Ryzom..."); -#define RYZOM_CATCH(_block) nlinfo(_block" of Ryzom success"); } catch(EFatalError &) { return EXIT_FAILURE; } +#define RYZOM_CATCH(_block) nlinfo(_block" of Ryzom success"); } catch(const EFatalError &) { return EXIT_FAILURE; } ///////////// // GLOBALS // @@ -168,7 +168,7 @@ static bool connect() goto end; } } - catch(Exception &e) + catch(const Exception &e) { nlwarning("Can't connect to web server '%s': %s", server.c_str(), e.what()); goto end; diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index 8a73510e1..9b60a4c5f 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -1942,7 +1942,7 @@ void CClientConfig::init(const string &configFileName) // save the updated config file NLMISC::COFile configFile(configFileName, false, true, false); - configFile.serialBuffer((uint8*)contentUtf8.c_str(), contentUtf8.size()); + configFile.serialBuffer((uint8*)contentUtf8.c_str(), (uint)contentUtf8.size()); configFile.close(); // now we can continue loading and parsing the config file @@ -2017,7 +2017,7 @@ void CClientConfig::release () // Save the camera distance writeDouble("CameraDistance", ClientCfg.CameraDistance); } - catch (Exception &e) + catch (const Exception &e) { nlwarning ("Error while set config file variables : %s", e.what ()); } diff --git a/code/ryzom/client/src/client_chat_manager.cpp b/code/ryzom/client/src/client_chat_manager.cpp index 184c3fac3..fa4159b1f 100644 --- a/code/ryzom/client/src/client_chat_manager.cpp +++ b/code/ryzom/client/src/client_chat_manager.cpp @@ -963,7 +963,7 @@ void CClientChatManager::buildTellSentence(const ucstring &sender, const ucstrin else { // Does the char have a CSR title? - csr = CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender)) ? ucstring("(CSR) ") : ucstring(""); + if (CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender))) csr = ucstring("(CSR) "); } ucstring cur_time; @@ -1018,7 +1018,7 @@ void CClientChatManager::buildChatSentence(TDataSetIndex /* compressedSenderInde ucstring csr; // Does the char have a CSR title? - csr = CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender)) ? ucstring("(CSR) ") : ucstring(""); + if (CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender))) csr = ucstring("(CSR) "); if (UserEntity && senderName == UserEntity->getDisplayName()) { @@ -1199,6 +1199,11 @@ class CHandlerTell : public IActionHandler // display msg with good color // TDataSetIndex dsi; // not used .... PeopleInterraction.ChatInput.Tell.displayTellMessage(/*dsi, */finalMsg, receiver, prop.getRGBA()); + + ucstring s = CI18N::get("youTellPlayer"); + strFindReplace(s, "%name", receiver); + strFindReplace(finalMsg, CI18N::get("youTell"), s); + CInterfaceManager::getInstance()->log(finalMsg); } }; REGISTER_ACTION_HANDLER( CHandlerTell, "tell"); @@ -1262,6 +1267,12 @@ void CClientChatManager::updateChatModeAndButton(uint mode, uint32 dynamicChanne const bool teamActive = pIM->getDbProp("SERVER:GROUP:0:PRESENT")->getValueBool(); const bool guildActive = pIM->getDbProp("SERVER:GUILD:NAME")->getValueBool(); + if (m == CChatGroup::team && ! teamActive) + m = PeopleInterraction.TheUserChat.Filter.getTargetGroup(); + + if (m == CChatGroup::guild && ! guildActive) + m = PeopleInterraction.TheUserChat.Filter.getTargetGroup(); + if (pUserBut) { switch(m) diff --git a/code/ryzom/client/src/color_slot_manager.cpp b/code/ryzom/client/src/color_slot_manager.cpp index 996d256a5..f7c059171 100644 --- a/code/ryzom/client/src/color_slot_manager.cpp +++ b/code/ryzom/client/src/color_slot_manager.cpp @@ -323,7 +323,7 @@ bool CColorSlotManager::addSlotsFromConfigFile(NLMISC::CConfigFile &cf, uint &st { mask_extensions = &cf.getVar("mask_extensions"); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { return false; } @@ -343,7 +343,7 @@ bool CColorSlotManager::addSlotsFromConfigFile(NLMISC::CConfigFile &cf, uint &st _Slots[k + startSlot][l] = extensions.asString(l); } } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { _Slots.resize(startSlot); nlwarning(("CColorSlotManager::addSlotsFromConfigFile : invalid config file, variable not found :" + mask_extensions->asString(k) + "_color_id").c_str()); @@ -355,7 +355,7 @@ bool CColorSlotManager::addSlotsFromConfigFile(NLMISC::CConfigFile &cf, uint &st { _Separator = cf.getVar("default_separator").asString(); } - catch (NLMISC::EUnknownVar &) + catch (const NLMISC::EUnknownVar &) { _Separator = "_"; } diff --git a/code/ryzom/client/src/commands.cpp b/code/ryzom/client/src/commands.cpp index 0e27ff487..877f80429 100644 --- a/code/ryzom/client/src/commands.cpp +++ b/code/ryzom/client/src/commands.cpp @@ -1096,7 +1096,7 @@ NLMISC_COMMAND(execScript, "Execute a script file (.cmd)","") // read one byte iFile.serialBuffer ((uint8 *)buffer, 1); } - catch (EFile &) + catch (const EFile &) { *buffer = '\0'; eof = true; @@ -1271,6 +1271,30 @@ NLMISC_COMMAND(7,"talk in 7th dynamic chat channel"," ") { return talkInChan(7,args); } + + +NLMISC_COMMAND(setItemName, "set name of items, sbrick, etc.."," ") +{ + if (args.size() < 2) return false; + CSheetId id(args[0]); + ucstring name; + name.fromUtf8(args[1]); + ucstring desc; + ucstring desc2; + if (args.size() > 2) + desc.fromUtf8(args[2]); + if (args.size() > 2) + desc2.fromUtf8(args[3]); + + STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); + if (pSMC) + pSMC->replaceSBrickName(id, name, desc, desc2); + else + return false; + return true; +} + + ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// @@ -5113,7 +5137,7 @@ NLMISC_COMMAND(luaObject, "Dump the content of a lua object", " [max // make a reference to the table to be inspected (is this this a primitive type, just make a copy) luaState->executeScript(std::string(inspectedTable) + " = " + args[0]); } - catch(ELuaError &e) + catch(const ELuaError &e) { CLuaIHM::debugInfo(e.what()); return false; @@ -5383,7 +5407,7 @@ NLMISC_COMMAND(dumpPosAsPrim, "ld helper : add current position to pos.primitive stream.open(path); stream.serialBuffer((uint8 *) &srcFile[0], fileSize); } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlinfo(e.what()); srcFile.clear(); @@ -5431,7 +5455,7 @@ NLMISC_COMMAND(dumpPosAsPrim, "ld helper : add current position to pos.primitive stream.open(path); stream.serialBuffer((uint8 *) &srcFile[0], (uint)srcFile.size()); } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlinfo(e.what()); } diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 4fafcdd07..1750d253b 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -1011,7 +1011,7 @@ TInterfaceState globalMenu() if ( ! firewallTimeout ) NetMngr.update(); } - catch ( EBlockedByFirewall& ) + catch (const EBlockedByFirewall&) { if ( NetMngr.getConnectionState() == CNetManager::Disconnect ) { @@ -1811,13 +1811,13 @@ string getTarget(CCtrlBase * /* ctrl */, const string &targetName) if (!elem) { nlwarning(" : Element is NULL"); - return false; + return ""; } const CReflectedProperty *pRP = CReflectSystem ::getProperty(elem->getReflectedClassName(), rTI.PropertyName); if (pRP->Type == CReflectedProperty::String) return ((elem->*(pRP->GetMethod.GetString))()); - return string(""); + return ""; } // ------------------------------------------------------------------------------------------------ diff --git a/code/ryzom/client/src/continent.cpp b/code/ryzom/client/src/continent.cpp index dc1d0fdaf..eb5a4dbe6 100644 --- a/code/ryzom/client/src/continent.cpp +++ b/code/ryzom/client/src/continent.cpp @@ -473,7 +473,7 @@ void CContinent::select(const CVectorD &pos, NLMISC::IProgressCallback &progress // Set the texture for the coarse mesh manager Scene->setCoarseMeshManagerTexture (CPath::lookup(seasonname).c_str()); } - catch (Exception &e) + catch (const Exception &e) { nlwarning (e.what()); } @@ -509,7 +509,7 @@ void CContinent::select(const CVectorD &pos, NLMISC::IProgressCallback &progress { LandscapeIGManager.initIG (Scene, CPath::lookup(LandscapeIG).c_str(), Driver, Season, &progress); } - catch (Exception &e) + catch (const Exception &e) { nlwarning (e.what()); } @@ -641,7 +641,7 @@ void CContinent::select(const CVectorD &pos, NLMISC::IProgressCallback &progress BackgroundIG = UInstanceGroup::createInstanceGroup(BackgroundIGName); } } - catch (Exception &e) + catch (const Exception &e) { nlwarning (e.what()); } @@ -1266,7 +1266,7 @@ void CContinent::dumpVillagesLoadingZones(const std::string &filename) { outBitmap.writeTGA(outFile, 24, true); } - catch(EStream &) + catch(const EStream &) { } } @@ -1327,7 +1327,7 @@ void CContinent::dumpFogMap(CFogMapBuild::TMapType mapType, const std::string &f { outBitmap.writeTGA(outFile, 24); } - catch(EStream &) + catch(const EStream &) { } } diff --git a/code/ryzom/client/src/cursor_functions.cpp b/code/ryzom/client/src/cursor_functions.cpp index 437624a86..c212dbb0d 100644 --- a/code/ryzom/client/src/cursor_functions.cpp +++ b/code/ryzom/client/src/cursor_functions.cpp @@ -550,7 +550,9 @@ void checkUnderCursor() if (!instref.ContextText.empty()) { selectedInstanceURL = instref.ContextURL; - if(ContextCur.context("WEBIG", 0.f, ucstring(instref.ContextText))) + ucstring contextText; + contextText.fromUtf8(instref.ContextText); + if(ContextCur.context("WEBIG", 0.f, contextText)) return; } } diff --git a/code/ryzom/client/src/entity_cl.cpp b/code/ryzom/client/src/entity_cl.cpp index bc63d9d85..fbbe0c041 100644 --- a/code/ryzom/client/src/entity_cl.cpp +++ b/code/ryzom/client/src/entity_cl.cpp @@ -3064,7 +3064,8 @@ void CEntityCL::updateVisiblePostPos(const NLMISC::TTime &/* currentTimeInMs */, } } - if (!_StateFX.empty()) { + if (!_StateFX.empty()) + { // Build a matrix for the fx NLMISC::CMatrix mat; mat.identity(); @@ -3529,8 +3530,10 @@ CVector CEntityCL::dirToTarget() const //---------------------------------------------------------------------- void CEntityCL::setStateFx(const std::string &fxName) { - if (fxName != _StateFXName) { - if (!_StateFX.empty() && Scene) { + if (fxName != _StateFXName) + { + if (!_StateFX.empty() && Scene) + { Scene->deleteInstance(_StateFX); } @@ -3556,7 +3559,8 @@ void CEntityCL::setStateFx(const std::string &fxName) //---------------------------------------------------------------------- void CEntityCL::removeStateFx() { - if (!_StateFX.empty() && Scene) { + if (!_StateFX.empty() && Scene) + { Scene->deleteInstance(_StateFX); _StateFXName = ""; } diff --git a/code/ryzom/client/src/far_tp.cpp b/code/ryzom/client/src/far_tp.cpp index b6fceac51..fb23b5810 100644 --- a/code/ryzom/client/src/far_tp.cpp +++ b/code/ryzom/client/src/far_tp.cpp @@ -174,7 +174,7 @@ const std::string& CLoginStateMachine::toString(CLoginStateMachine::TEvent event outputF.close(); \ } \ } \ - catch ( Exception & ) \ + catch (const Exception &) \ {} \ _CurrentState = stateId; \ break; \ @@ -912,7 +912,7 @@ retryJoinEdit: outputF.close(); } } - catch ( Exception & ) + catch (const Exception &) {} // If the session is not a permanent session and has vanished, pop the position diff --git a/code/ryzom/client/src/fog_map.cpp b/code/ryzom/client/src/fog_map.cpp index bd1e47978..78cd7ecda 100644 --- a/code/ryzom/client/src/fog_map.cpp +++ b/code/ryzom/client/src/fog_map.cpp @@ -224,7 +224,7 @@ void CFogMap::load(NLMISC::CBitmap &bm, const std::string &filename) inputFile.close(); } } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlwarning(e.what()); inputFile.close(); diff --git a/code/ryzom/client/src/http_client.cpp b/code/ryzom/client/src/http_client.cpp index 6a10034cd..4c5f03d6d 100644 --- a/code/ryzom/client/src/http_client.cpp +++ b/code/ryzom/client/src/http_client.cpp @@ -57,7 +57,7 @@ bool CHttpClient::connect(std::string server) nldebug("Connected to web server '%s'", server.c_str()); } } - catch(Exception &e) + catch(const Exception &e) { nlwarning("Can't connect to web server '%s': %s", server.c_str(), e.what()); goto end; diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 7ae13500c..55d09c69e 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -1105,7 +1105,7 @@ void prelogInit() FPU_CHECKER_ONCE } - catch (Exception &e) + catch (const Exception &e) { ExitClientError (e.what()); } @@ -1264,7 +1264,7 @@ void postlogInit() { SoundMngr->init(&ProgressBar); } - catch(Exception &e) + catch(const Exception &e) { nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); // leak the alocated sound manager... @@ -1326,7 +1326,7 @@ void postlogInit() ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); CSBrickManager::getInstance()->init(); // Must be done after sheet loading - STRING_MANAGER::CStringManagerClient::specialWordsMemoryCompress(); // Must be done after brick manager init + //STRING_MANAGER::CStringManagerClient::specialWordsMemoryCompress(); // Must be done after brick manager init initLast = initCurrent; initCurrent = ryzomGetLocalTime(); @@ -1433,7 +1433,7 @@ void postlogInit() nlinfo ("PROFILE: %d seconds for postlogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000); } - catch (Exception &e) + catch (const Exception &e) { ExitClientError (e.what()); } diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index 9b37a1a53..2610b5882 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -187,7 +187,8 @@ struct CStatThread : public NLMISC::IRunnable { std::string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; std::string s; - for (int i = 0; i < 32; i++) { + for (int i = 0; i < 32; i++) + { s += chars[uint(frand(float(chars.size())))]; } return s; @@ -864,7 +865,7 @@ void initMainLoop() // load hlsBank Driver->loadHLSBank("characters.hlsbank"); } - catch(Exception &e) + catch(const Exception &e) { nlwarning("Can't load HLSBank: %s", e.what()); } diff --git a/code/ryzom/client/src/interface_v3/action_handler.cpp b/code/ryzom/client/src/interface_v3/action_handler.cpp index 529c7f1c2..242543531 100644 --- a/code/ryzom/client/src/interface_v3/action_handler.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler.cpp @@ -77,7 +77,7 @@ std::string IActionHandler::getParam (const string &Params, const string &ParamN std::string::size_type e = allparam.find('='); if (e == std::string::npos || e == 0) break; std::string::size_type p = allparam.find('|'); - string tmp = strlwr(allparam.substr(0,e)); + string tmp = NLMISC::toLower(allparam.substr(0,e)); skipBlankAtEnd(tmp); if (tmp == param) { @@ -103,7 +103,7 @@ void IActionHandler::getAllParams (const string &Params, vector< pairConsumable.ConsumptionTime)); - strFindReplace(itemText, "%overdose_timer", toString(pIS->Consumable.OverdoseTimer/60)); + strFindReplace(itemText, "%overdose_timer_min", toString(pIS->Consumable.OverdoseTimer/60)); + strFindReplace(itemText, "%overdose_timer_sec", toString(pIS->Consumable.OverdoseTimer % 60)); // Get Item Consumable infos CItemConsumableEffectHelper::getInstance()->getItemConsumableEffectText(pIS, itemText, item->getQuality()); } diff --git a/code/ryzom/client/src/interface_v3/action_handler_item.cpp b/code/ryzom/client/src/interface_v3/action_handler_item.cpp index f6e397c26..819b8c0d4 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_item.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_item.cpp @@ -1761,7 +1761,7 @@ class CHandlerItemMenuCheck : public IActionHandler if (pCS->getInventoryIndex()==INVENTORIES::bag) { bool isTextEditionActive = false; - static const string itemTextEditionPriv = ":DEV:SGM:EM:"; + static const string itemTextEditionPriv = ":DEV:SGM:GM:EM:"; if (!UserPrivileges.empty() && itemTextEditionPriv.find(UserPrivileges)!=std::string::npos) { isTextEditionActive = true; diff --git a/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp b/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp index 4c7c081f8..a24c49ad0 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp @@ -60,6 +60,7 @@ void launchPhraseComposition(bool creation); const std::string PhraseComposition="ui:interface:phrase_composition"; const std::string PhraseCompositionGroup="ui:interface:phrase_composition:header_opened"; const std::string PhraseMemoryCtrlBase= "ui:interface:gestionsets:shortcuts:s"; +const std::string PhraseMemoryAltCtrlBase= "ui:interface:gestionsets2:header_closed:shortcuts:s"; // ********************************************************************************************************** @@ -129,7 +130,11 @@ public: if(pCSDst && pCSDst->isSPhraseId() && pCSDst->isSPhraseIdMemory()) { // then will auto-memorize it in this slot - pPM->CompositionPhraseMemoryLineDest= pPM->getSelectedMemoryLineDB(); + if (pCSDst->isShortCut()) + pPM->CompositionPhraseMemoryLineDest= pPM->getSelectedMemoryLineDB(); + else + pPM->CompositionPhraseMemoryLineDest= 0; + pPM->CompositionPhraseMemorySlotDest= pCSDst->getIndexInDB(); } // else no auto memorize @@ -1110,7 +1115,11 @@ public: return; // Ok, the user try to cast a phrase slot. - sint32 memoryLine= pPM->getSelectedMemoryLineDB(); + sint32 memoryLine; + if (pCSDst->isShortCut()) + memoryLine = pPM->getSelectedMemoryLineDB(); + else + memoryLine = 0; if(memoryLine<0) return; @@ -1249,12 +1258,16 @@ public: { sint shortcut; fromString(Params, shortcut); - if (shortcut>=0 && shortcut <= RYZOM_MAX_SHORTCUT) + if (shortcut>=0 && shortcut <= 2*RYZOM_MAX_SHORTCUT) { CInterfaceManager *pIM= CInterfaceManager::getInstance(); // get the control - CInterfaceElement *elm= pIM->getElementFromId(PhraseMemoryCtrlBase + toString(shortcut) ); + CInterfaceElement *elm; + if (shortcut < RYZOM_MAX_SHORTCUT) + elm = pIM->getElementFromId(PhraseMemoryCtrlBase + toString(shortcut) ); + else + elm = pIM->getElementFromId(PhraseMemoryAltCtrlBase + toString(shortcut-RYZOM_MAX_SHORTCUT) ); CDBCtrlSheet *ctrl= dynamic_cast(elm); if(ctrl) { @@ -1491,7 +1504,11 @@ public: return; // Ok, the user try to cast a phrase slot. - sint32 memoryLine= pPM->getSelectedMemoryLineDB(); + sint32 memoryLine; + if (pCSDst->isShortCut()) + memoryLine = pPM->getSelectedMemoryLineDB(); + else + memoryLine = 0; if(memoryLine<0) return; diff --git a/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp b/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp index 76b60ade1..53a1258bc 100644 --- a/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp +++ b/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp @@ -1799,7 +1799,8 @@ void CActionPhraseFaber::updateItemResult() } /* Handle change of skill -> recompute success rate */ -void CActionPhraseFaber::CSkillObserver::onSkillChange() { +void CActionPhraseFaber::CSkillObserver::onSkillChange() +{ if (ActionPhraseFaber == NULL) ActionPhraseFaber = new CActionPhraseFaber; // Dont update if the plan has not yet been selected if(ActionPhraseFaber->_ExecuteFromItemPlanBrick==NULL) diff --git a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp index c09c2b16a..dcebe792d 100644 --- a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp +++ b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp @@ -1684,7 +1684,7 @@ void CBotChatPageTrade::setupFactionPointPrice(bool /* sellMode */, uint default // setup icon according to pvp clan CInterfaceManager *pIM= CInterfaceManager::getInstance(); - strlwr(factionName); + factionName = NLMISC::toLower(factionName); string factionIcon= pIM->getDefine(toString("faction_icon_%s", factionName.c_str())); CViewBitmap *vBmp= dynamic_cast(fpGroup->getView("unit_price:item_price:icone")); if(vBmp) vBmp->setTexture(factionIcon); diff --git a/code/ryzom/client/src/interface_v3/chat_filter.cpp b/code/ryzom/client/src/interface_v3/chat_filter.cpp index 8f5db8f20..fc2e6c9c3 100644 --- a/code/ryzom/client/src/interface_v3/chat_filter.cpp +++ b/code/ryzom/client/src/interface_v3/chat_filter.cpp @@ -313,7 +313,7 @@ void CChatTargetFilter::msgEntered(const ucstring &msg, CChatWindow *chatWindow) // the target must be a player, make a tell on him ChatMngr.tell(_TargetPlayer.toString(), msg); // direct output in the chat - chatWindow->displayLocalPlayerTell(msg); + chatWindow->displayLocalPlayerTell(_TargetPlayer.toString(), msg); } else { @@ -382,7 +382,7 @@ void CChatTargetFilter::setTargetGroup(CChatGroup::TGroupType groupType, uint32 case CChatGroup::say: entry+="SAY"; break; case CChatGroup::shout: entry+="SHOUT"; break; case CChatGroup::team: if(!teamActive) return; entry+="GROUP"; break; - case CChatGroup::guild: if(!guildActive) return; entry+="CLADE"; break; + case CChatGroup::guild: entry+="CLADE"; break; case CChatGroup::civilization: entry+="CIVILIZATION"; break; case CChatGroup::territory: entry+="TERRITORY"; break; case CChatGroup::universe: diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp index d58ccde77..6f13b1bed 100644 --- a/code/ryzom/client/src/interface_v3/chat_window.cpp +++ b/code/ryzom/client/src/interface_v3/chat_window.cpp @@ -199,7 +199,7 @@ bool CChatWindow::isVisible() const } //================================================================================= -void CChatWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CChatGroup::TGroupType /* gt */, uint32 /* dynamicChatDbIndex */, uint numBlinks /* = 0*/, bool *windowVisible /*= NULL*/) +void CChatWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CChatGroup::TGroupType gt, uint32 dynamicChatDbIndex, uint numBlinks /* = 0*/, bool *windowVisible /*= NULL*/) { if (!_Chat) { @@ -466,7 +466,7 @@ void CChatWindow::setHeaderColor(const std::string &n) } //================================================================================= -void CChatWindow::displayLocalPlayerTell(const ucstring &msg, uint numBlinks /*= 0*/) +void CChatWindow::displayLocalPlayerTell(const ucstring &receiver, const ucstring &msg, uint numBlinks /*= 0*/) { ucstring finalMsg; CInterfaceProperty prop; @@ -484,7 +484,12 @@ void CChatWindow::displayLocalPlayerTell(const ucstring &msg, uint numBlinks /*= prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); encodeColorTag(prop.getRGBA(), finalMsg, true); finalMsg += msg; + + ucstring s = CI18N::get("youTellPlayer"); + strFindReplace(s, "%name", receiver); + strFindReplace(finalMsg, CI18N::get("youTell"), s); displayMessage(finalMsg, prop.getRGBA(), CChatGroup::tell, 0, numBlinks); + CInterfaceManager::getInstance()->log(finalMsg); } void CChatWindow::encodeColorTag(const NLMISC::CRGBA &color, ucstring &text, bool append) @@ -797,14 +802,6 @@ CGroupContainer *CChatGroupWindow::createFreeTeller(const ucstring &winNameIn, c } } - // Create the free teller in all the desktops - uint8 nMode = pIM->getMode(); - pGC->setActive(false); - for (uint8 m = 0; m < MAX_NUM_MODES; ++m) - { - if (m != nMode) - pIM->updateGroupContainerImage(*pGC, m); - } // the group is only active on the current desktop pGC->setActive(true); } @@ -812,7 +809,7 @@ CGroupContainer *CChatGroupWindow::createFreeTeller(const ucstring &winNameIn, c if (!winColor.empty()) _FreeTellers[i]->setHeaderColor(winColor); - updateFreeTellerHeader(*_FreeTellers[i]); +// updateFreeTellerHeader(*_FreeTellers[i]); return _FreeTellers[i]; } diff --git a/code/ryzom/client/src/interface_v3/chat_window.h b/code/ryzom/client/src/interface_v3/chat_window.h index a18b950f6..5daf24c36 100644 --- a/code/ryzom/client/src/interface_v3/chat_window.h +++ b/code/ryzom/client/src/interface_v3/chat_window.h @@ -143,7 +143,7 @@ public: void setAHOnCloseButtonParams(const std::string &n); void setHeaderColor(const std::string &n); // - void displayLocalPlayerTell(const ucstring &msg, uint numBlinks = 0); + void displayLocalPlayerTell(const ucstring &receiver, const ucstring &msg, uint numBlinks = 0); /// Encode a color tag '@{RGBA}' in the text. If append is true, append at end of text, otherwise, replace the text static void encodeColorTag(const NLMISC::CRGBA &color, ucstring &text, bool append=true); diff --git a/code/ryzom/client/src/interface_v3/ctrl_base.cpp b/code/ryzom/client/src/interface_v3/ctrl_base.cpp index 85414ba6e..151d2be6f 100644 --- a/code/ryzom/client/src/interface_v3/ctrl_base.cpp +++ b/code/ryzom/client/src/interface_v3/ctrl_base.cpp @@ -93,7 +93,6 @@ bool CCtrlBase::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) if (prop) { _OnContextHelp= (const char*)prop; - NLMISC::strlwr(_OnContextHelp); } prop = (char*) xmlGetProp( cur, (xmlChar*)"on_tooltip_params" ); if (prop) diff --git a/code/ryzom/client/src/interface_v3/ctrl_base_button.cpp b/code/ryzom/client/src/interface_v3/ctrl_base_button.cpp index a25bbf56d..b2f03b98b 100644 --- a/code/ryzom/client/src/interface_v3/ctrl_base_button.cpp +++ b/code/ryzom/client/src/interface_v3/ctrl_base_button.cpp @@ -160,21 +160,18 @@ bool CCtrlBaseButton::parse (xmlNodePtr cur,CInterfaceGroup * parentGroup) prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_l" ); if (prop) { - string tmp = (const char *) prop; - _ListMenuLeft = strlwr(tmp); + _ListMenuLeft = NLMISC::toLower(std::string((const char *) prop)); } prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_r" ); if (prop) { - string tmp = (const char *) prop; - _ListMenuRight = strlwr(tmp); + _ListMenuRight = NLMISC::toLower(std::string((const char *) prop)); } // list menu on both clicks prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_b" ); if (prop) { - string tmp = (const char *) prop; - setListMenuBoth(strlwr(tmp)); + setListMenuBoth(NLMISC::toLower(std::string((const char *) prop))); } prop= (char*) xmlGetProp (cur, (xmlChar*)"frozen"); diff --git a/code/ryzom/client/src/interface_v3/ctrl_base_button.h b/code/ryzom/client/src/interface_v3/ctrl_base_button.h index c1d993aec..06a27b276 100644 --- a/code/ryzom/client/src/interface_v3/ctrl_base_button.h +++ b/code/ryzom/client/src/interface_v3/ctrl_base_button.h @@ -114,7 +114,7 @@ public: /// \name Handlers // @{ // Event part - void setActionOnLeftClick (const std::string &actionHandlerName) { _AHOnLeftClick = getAH(actionHandlerName, _AHLeftClickParams); } + void setActionOnLeftClick (const std::string &actionHandlerName) { _AHOnLeftClickString = actionHandlerName; _AHOnLeftClick = getAH(actionHandlerName, _AHLeftClickParams); } void setActionOnRightClick (const std::string &actionHandlerName) { _AHOnRightClick = getAH(actionHandlerName, _AHRightClickParams); } void setActionOnClockTick (const std::string &ahName) { _AHOnClockTick = getAH(ahName, _AHClockTickParams); } void setParamsOnLeftClick (const std::string ¶msHandlerName) { _AHLeftClickParams = paramsHandlerName; } @@ -203,6 +203,7 @@ protected: //@{ IActionHandler *_AHOnOver; CStringShared _AHOverParams; + std::string _AHOnLeftClickString; IActionHandler *_AHOnLeftClick; CStringShared _AHLeftClickParams; IActionHandler *_AHOnLeftDblClick; diff --git a/code/ryzom/client/src/interface_v3/ctrl_button.cpp b/code/ryzom/client/src/interface_v3/ctrl_button.cpp index 17d89e900..fd1ba049b 100644 --- a/code/ryzom/client/src/interface_v3/ctrl_button.cpp +++ b/code/ryzom/client/src/interface_v3/ctrl_button.cpp @@ -333,4 +333,16 @@ void CCtrlButton::fitTexture() setH(h); } - +// *************************************************************************** +bool CCtrlButton::getMouseOverShape(string &texName, uint8 &rot, CRGBA &col) +{ + if (_AHOnLeftClickString == "browse") + { + texName = "curs_pick.tga"; + rot= 0; + col = CRGBA::White; + return true; + } + + return false; +} diff --git a/code/ryzom/client/src/interface_v3/ctrl_button.h b/code/ryzom/client/src/interface_v3/ctrl_button.h index 3dcb0f896..ff769e6c4 100644 --- a/code/ryzom/client/src/interface_v3/ctrl_button.h +++ b/code/ryzom/client/src/interface_v3/ctrl_button.h @@ -50,6 +50,8 @@ public: virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); } + virtual bool getMouseOverShape(std::string &/* texName */, uint8 &/* rot */, NLMISC::CRGBA &/* col */); + // Display part virtual void draw(); diff --git a/code/ryzom/client/src/interface_v3/ctrl_text_button.cpp b/code/ryzom/client/src/interface_v3/ctrl_text_button.cpp index d2191a4eb..1e8c7c07b 100644 --- a/code/ryzom/client/src/interface_v3/ctrl_text_button.cpp +++ b/code/ryzom/client/src/interface_v3/ctrl_text_button.cpp @@ -86,8 +86,7 @@ bool CCtrlTextButton::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup) prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_normal" ); if (prop) { - string TxName = (const char *) prop; - TxName = strlwr(TxName); + string TxName = toLower(std::string((const char *) prop)); _TextureIdNormal[0].setTexture((TxName+"_l.tga").c_str()); _TextureIdNormal[1].setTexture((TxName+"_m.tga").c_str()); _TextureIdNormal[2].setTexture((TxName+"_r.tga").c_str()); @@ -96,8 +95,7 @@ bool CCtrlTextButton::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup) prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_pushed" ); if (prop) { - string TxName = (const char *) prop; - TxName = strlwr(TxName); + string TxName = toLower(std::string((const char *) prop)); _TextureIdPushed[0].setTexture((TxName+"_l.tga").c_str()); _TextureIdPushed[1].setTexture((TxName+"_m.tga").c_str()); _TextureIdPushed[2].setTexture((TxName+"_r.tga").c_str()); @@ -106,8 +104,7 @@ bool CCtrlTextButton::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup) prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_over" ); if (prop) { - string TxName = (const char *) prop; - TxName = strlwr(TxName); + string TxName = toLower(std::string((const char *) prop)); _TextureIdOver[0].setTexture((TxName+"_l.tga").c_str()); _TextureIdOver[1].setTexture((TxName+"_m.tga").c_str()); _TextureIdOver[2].setTexture((TxName+"_r.tga").c_str()); diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index e328816a9..42f438202 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -2095,13 +2095,13 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, armourCol); // decal layer because must drawn after Items/Brick in DXTC // NB: use OverColor, not Over2Color here. Because of hack in updateArmourColor() - rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOverColor)); + rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOverColor)); } else { // decal layer because must drawn after Items/Brick in DXTC - rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, _DispOverBmpId, fastMulRGB(curSheetColor, _IconOverColor)); - rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color)); + rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOverBmpId, fastMulRGB(curSheetColor, _IconOverColor)); + rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color)); } // Draw Quality. -1 for lookandfeel. Draw it with global color diff --git a/code/ryzom/client/src/interface_v3/group_editbox.cpp b/code/ryzom/client/src/interface_v3/group_editbox.cpp index b87d95f2d..5bc516f47 100644 --- a/code/ryzom/client/src/interface_v3/group_editbox.cpp +++ b/code/ryzom/client/src/interface_v3/group_editbox.cpp @@ -21,6 +21,7 @@ #include "group_editbox.h" #include "interface_manager.h" #include "input_handler_manager.h" +#include "nel/misc/command.h" #include "view_text.h" #include "game_share/xml_auto_ptr.h" #include "interface_options.h" @@ -56,6 +57,7 @@ CGroupEditBox::CGroupEditBox(const TCtorParam ¶m) : _MaxCharsSize(32768), _FirstVisibleChar(0), _LastVisibleChar(0), + _SelectingText(false), _ViewText(NULL), _MaxHistoric(0), _CurrentHistoricIndex(-1), @@ -354,16 +356,27 @@ void CGroupEditBox::paste() if (Driver->pasteTextFromClipboard(sString)) { // append string now - appendString(sString); + appendStringFromClipboard(sString); } } // ---------------------------------------------------------------------------- -void CGroupEditBox::appendString(const ucstring &str) +void CGroupEditBox::appendStringFromClipboard(const ucstring &str) { stopParentBlink(); makeTopWindow(); + writeString(str, true, false); + nlinfo ("Chat input was pasted from the clipboard"); + + triggerOnChangeAH(); + + _CursorAtPreviousLineEnd = false; +} + +// ---------------------------------------------------------------------------- +void CGroupEditBox::writeString(const ucstring &str, bool replace, bool atEnd) +{ sint length = (sint)str.length(); ucstring toAppend; @@ -500,13 +513,41 @@ void CGroupEditBox::appendString(const ucstring &str) length = _MaxNumChar - (sint)_InputString.length(); } ucstring toAdd = toAppend.substr(0, length); - _InputString = _InputString.substr(0, _CursorPos) + toAdd + _InputString.substr(_CursorPos); - _CursorPos += (sint32)toAdd.length(); - nlinfo ("Chat input was pasted from the clipboard"); + sint32 minPos; + sint32 maxPos; + if (_CurrSelection == this) + { + minPos = min(_CursorPos, _SelectCursorPos); + maxPos = max(_CursorPos, _SelectCursorPos); + } + else + { + minPos = _CursorPos; + maxPos = _CursorPos; + } - triggerOnChangeAH(); + nlinfo("%d, %d", minPos, maxPos); + if (replace) + { + _InputString = _InputString.substr(0, minPos) + toAdd + _InputString.substr(maxPos); + _CursorPos = minPos+(sint32)toAdd.length(); + } + else + { + if (atEnd) + { + _InputString = _InputString.substr(0, maxPos) + toAdd + _InputString.substr(maxPos); + _CursorPos = maxPos; + _SelectCursorPos = _CursorPos; - _CursorAtPreviousLineEnd = false; + } + else + { + _InputString = _InputString.substr(0, minPos) + toAdd + _InputString.substr(minPos); + _CursorPos = minPos+(sint32)toAdd.length(); + _SelectCursorPos = maxPos+(sint32)toAdd.length(); + } + } } // ---------------------------------------------------------------------------- @@ -672,7 +713,7 @@ void CGroupEditBox::handleEventChar(const CEventDescriptorKey &rEDK) // ---------------------------------------------------------------------------- void CGroupEditBox::handleEventString(const CEventDescriptorKey &rEDK) { - appendString(rEDK.getString()); + appendStringFromClipboard(rEDK.getString()); } // ---------------------------------------------------------------------------- @@ -862,6 +903,7 @@ bool CGroupEditBox::handleEvent (const CEventDescriptor& event) // if click, and not frozen, then get the focus if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown && !_Frozen) { + _SelectingText = true; stopParentBlink(); pIM->setCaptureKeyboard (this); // set the right cursor position @@ -872,9 +914,34 @@ bool CGroupEditBox::handleEvent (const CEventDescriptor& event) _CursorPos = newCurPos; _CursorPos -= (sint32)_Prompt.length(); _CursorPos = std::max(_CursorPos, sint32(0)); + _SelectCursorPos = _CursorPos; + _CurrSelection = NULL; return true; } + // if click, and not frozen, then get the focus + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mousemove && !_Frozen && _SelectingText) + { + // set the right cursor position + uint newCurPos; + bool cursorAtPreviousLineEnd; + _CurrSelection = this; + _ViewText->getCharacterIndexFromPosition(eventDesc.getX() - _ViewText->getXReal(), eventDesc.getY() - _ViewText->getYReal(), newCurPos, cursorAtPreviousLineEnd); + _SelectCursorPos = newCurPos; + _SelectCursorPos -= (sint32)_Prompt.length(); + _SelectCursorPos = std::max(_SelectCursorPos, sint32(0)); + return true; + } + + // if click, and not frozen, then get the focus + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup && !_Frozen) + { + _SelectingText = false; + if (_SelectCursorPos == _CursorPos) + _CurrSelection = NULL; + + return true; + } if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown) { diff --git a/code/ryzom/client/src/interface_v3/group_editbox.h b/code/ryzom/client/src/interface_v3/group_editbox.h index 3a067cf25..f2856709a 100644 --- a/code/ryzom/client/src/interface_v3/group_editbox.h +++ b/code/ryzom/client/src/interface_v3/group_editbox.h @@ -125,6 +125,8 @@ public: void copy(); // Paste the selection into buffer void paste(); + // Write the string into buffer + void writeString(const ucstring &str, bool replace = true, bool atEnd = true); // Expand the expression (true if there was a '/' at the start of the line) bool expand(); @@ -217,6 +219,7 @@ protected: // Text selection static sint32 _SelectCursorPos; static CGroupEditBox *_CurrSelection; // the edit box for which the selection is currently active, or NULL if there's none + bool _SelectingText; NLMISC::CRGBA _TextSelectColor; NLMISC::CRGBA _BackSelectColor; @@ -291,7 +294,7 @@ private: void handleEventString(const CEventDescriptorKey &event); void setup(); void triggerOnChangeAH(); - void appendString(const ucstring &str); + void appendStringFromClipboard(const ucstring &str); ucstring getSelection(); diff --git a/code/ryzom/client/src/interface_v3/group_html.cpp b/code/ryzom/client/src/interface_v3/group_html.cpp index 43ff1ca75..30c089aae 100644 --- a/code/ryzom/client/src/interface_v3/group_html.cpp +++ b/code/ryzom/client/src/interface_v3/group_html.cpp @@ -442,6 +442,9 @@ void CGroupHTML::addText (const char * buf, int len) { if (_Browsing) { + if (_IgnoreText) + return; + // Build a UTF8 string string inputString(buf, buf+len); // inputString.resize (len); @@ -525,6 +528,11 @@ void CGroupHTML::addLink (uint element_number, uint /* attribute_number */, HTCh // in ah: command we don't respect the uri standard so the HTAnchor_address doesn't work correctly _Link.push_back (suri); } + else if (suri[0] == '#') + { + // Direct url (hack for lua beginElement) + _Link.push_back (suri.substr(1)); + } else { HTAnchor * dest = HTAnchor_followMainLink((HTAnchor *) anchor); @@ -839,6 +847,14 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c } } break; + case HTML_DIV: + { + if (present[MY_HTML_DIV_NAME] && value[MY_HTML_DIV_NAME]) + { + _DivName = value[MY_HTML_DIV_NAME]; + } + } + break; case HTML_FONT: { bool found = false; @@ -855,8 +871,19 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c { _TextColor.push_back(_TextColor.empty() ? CRGBA::White : _TextColor.back()); } + + if (present[HTML_FONT_SIZE] && value[HTML_FONT_SIZE]) + { + uint fontsize; + fromString(value[HTML_FONT_SIZE], fontsize); + _FontSize.push_back(fontsize); + } + else + { + _FontSize.push_back(_FontSize.empty() ? TextFontSize : _FontSize.back()); + } } - break; + break; case HTML_BR: addString(ucstring ("\n")); break; @@ -1372,6 +1399,9 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c _ObjectAction = value[HTML_OBJECT_STANDBY]; _Object = true; + break; + case HTML_STYLE: + _IgnoreText = true; break; } } @@ -1388,6 +1418,7 @@ void CGroupHTML::endElement (uint element_number) { case HTML_FONT: popIfNotEmpty (_TextColor); + popIfNotEmpty (_FontSize); break; case HTML_A: popIfNotEmpty (_TextColor); @@ -1409,6 +1440,10 @@ void CGroupHTML::endElement (uint element_number) case HTML_PRE: popIfNotEmpty (_PRE); break; + case HTML_DIV: + _DivName = ""; + break; + case HTML_TABLE: popIfNotEmpty (_CellParams); popIfNotEmpty (_TR); @@ -1493,6 +1528,9 @@ void CGroupHTML::endElement (uint element_number) popIfNotEmpty (_UL); } break; + case HTML_STYLE: + _IgnoreText = false; + break; case HTML_OBJECT: if (_ObjectType=="application/ryzom-data") { @@ -1560,6 +1598,7 @@ CGroupHTML::CGroupHTML(const TCtorParam ¶m) // init _ParsingLua = false; + _IgnoreText = false; _BrowseNextTime = false; _PostNextTime = false; _Browsing = false; @@ -2224,8 +2263,9 @@ void CGroupHTML::addImage(const char *img, bool globalColor) else*/ getParagraph()->addChild(newImage); paragraphChange (); - } else { - + } + else + { // // 2/ if it doesn't work, try to load the image in cache // @@ -2506,6 +2546,7 @@ void CGroupHTML::clearContext() _Cells.clear(); _TR.clear(); _Forms.clear(); + _Groups.clear(); _CellParams.clear(); _Title = false; _TextArea = false; @@ -2584,6 +2625,12 @@ void CGroupHTML::addGroup (CInterfaceGroup *group, uint beginSpace) _Paragraph = NULL; } + if (!_DivName.empty()) + { + group->setName(_DivName); + _Groups.push_back(group); + } + group->setSizeRef(CInterfaceElement::width); // Compute begin space between paragraph and tables @@ -3337,6 +3384,175 @@ int CGroupHTML::luaRefresh(CLuaState &ls) return 0; } +// *************************************************************************** +int CGroupHTML::luaRemoveContent(CLuaState &ls) +{ + const char *funcName = "refresh"; + CLuaIHM::checkArgCount(ls, funcName, 0); + removeContent(); + return 0; +} + +// *************************************************************************** +int CGroupHTML::luaInsertText(CLuaState &ls) +{ + const char *funcName = "insertText"; + CLuaIHM::checkArgCount(ls, funcName, 3); + CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING); + CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING); + CLuaIHM::checkArgType(ls, funcName, 3, LUA_TBOOLEAN); + + string name = ls.toString(1); + + ucstring text; + text.fromUtf8(ls.toString(2)); + + if (!_Forms.empty()) + { + for (uint i=0; i<_Forms.back().Entries.size(); i++) + { + if (_Forms.back().Entries[i].TextArea && _Forms.back().Entries[i].Name == name) + { + // Get the edit box view + CInterfaceGroup *group = _Forms.back().Entries[i].TextArea->getGroup ("eb"); + if (group) + { + // Should be a CGroupEditBox + CGroupEditBox *editBox = dynamic_cast(group); + if (editBox) + editBox->writeString(text, false, ls.toBoolean(3)); + } + } + } + } + + return 0; +} + +// *************************************************************************** +int CGroupHTML::luaAddString(CLuaState &ls) +{ + const char *funcName = "addString"; + CLuaIHM::checkArgCount(ls, funcName, 1); + CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING); + addString(ucstring(ls.toString(1))); + return 0; +} + +// *************************************************************************** +int CGroupHTML::luaAddImage(CLuaState &ls) +{ + const char *funcName = "addImage"; + CLuaIHM::checkArgCount(ls, funcName, 2); + CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING); + CLuaIHM::checkArgType(ls, funcName, 2, LUA_TBOOLEAN); + if (!_Paragraph) + { + newParagraph(0); + paragraphChange(); + } + string url = getLink(); + if (!url.empty()) + { + string params = "name=" + getId() + "|url=" + getLink (); + addButton(CCtrlButton::PushButton, ls.toString(1), ls.toString(1), ls.toString(1), + "", ls.toBoolean(2), "browse", params.c_str(), ""); + } + else + { + addImage(ls.toString(1), ls.toBoolean(2)); + } + + + return 0; +} + +// *************************************************************************** +int CGroupHTML::luaBeginElement(CLuaState &ls) +{ + const char *funcName = "beginElement"; + CLuaIHM::checkArgCount(ls, funcName, 2); + CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); + CLuaIHM::checkArgType(ls, funcName, 2, LUA_TTABLE); + + uint element_number = (uint)ls.toNumber(1); + std::vector present; + std::vector value; + present.resize(30, false); + value.resize(30); + + CLuaObject params; + params.pop(ls); + uint max_idx = 0; + + + ENUM_LUA_TABLE(params, it) + { + if (!it.nextKey().isNumber()) + { + nlwarning("%s : bad key encountered with type %s, number expected.", funcName, it.nextKey().getTypename()); + continue; + } + if (!it.nextValue().isString()) + { + nlwarning("%s : bad value encountered with type %s for key %s, string expected.", funcName, it.nextValue().getTypename(), it.nextKey().toString().c_str()); + continue; + } + uint idx = (uint)it.nextKey().toNumber(); + + present.insert(present.begin() + (uint)it.nextKey().toNumber(), true); + + string str = it.nextValue().toString(); + size_t size = str.size() + 1; + char * buffer = new char[ size ]; + strncpy(buffer, str.c_str(), size ); + + value.insert(value.begin() + (uint)it.nextKey().toNumber(), buffer); + } + + beginElement(element_number, &present[0], &value[0]); + if (element_number == HTML_A) + addLink(element_number, 0, NULL, &present[0], &value[0]); + + return 0; +} + + +// *************************************************************************** +int CGroupHTML::luaEndElement(CLuaState &ls) +{ + const char *funcName = "endElement"; + CLuaIHM::checkArgCount(ls, funcName, 1); + CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); + + uint element_number = (uint)ls.toNumber(1); + endElement(element_number); + + return 0; +} + + +// *************************************************************************** +int CGroupHTML::luaShowDiv(CLuaState &ls) +{ + const char *funcName = "showDiv"; + CLuaIHM::checkArgCount(ls, funcName, 2); + CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING); + CLuaIHM::checkArgType(ls, funcName, 2, LUA_TBOOLEAN); + + if (!_Groups.empty()) { + for (uint i=0; i<_Groups.size(); i++) + { + CInterfaceGroup *group = _Groups[i]; + if (group->getName() == ls.toString(1)) + { + group->setActive(ls.toBoolean(2)); + } + } + } + return 0; +} + // *************************************************************************** void CGroupHTML::setURL(const std::string &url) { diff --git a/code/ryzom/client/src/interface_v3/group_html.h b/code/ryzom/client/src/interface_v3/group_html.h index b4f4ee00b..92cb81e6e 100644 --- a/code/ryzom/client/src/interface_v3/group_html.h +++ b/code/ryzom/client/src/interface_v3/group_html.h @@ -165,10 +165,24 @@ public: int luaBrowse(CLuaState &ls); int luaRefresh(CLuaState &ls); + int luaRemoveContent(CLuaState &ls); + int luaInsertText(CLuaState &ls); + int luaAddString(CLuaState &ls); + int luaAddImage(CLuaState &ls); + int luaBeginElement(CLuaState &ls); + int luaEndElement(CLuaState &ls); + int luaShowDiv(CLuaState &ls); REFLECT_EXPORT_START(CGroupHTML, CGroupScrollText) REFLECT_LUA_METHOD("browse", luaBrowse) REFLECT_LUA_METHOD("refresh", luaRefresh) + REFLECT_LUA_METHOD("removeContent", luaRemoveContent) + REFLECT_LUA_METHOD("insertText", luaInsertText) + REFLECT_LUA_METHOD("addString", luaAddString) + REFLECT_LUA_METHOD("addImage", luaAddImage) + REFLECT_LUA_METHOD("beginElement", luaBeginElement) + REFLECT_LUA_METHOD("endElement", luaEndElement) + REFLECT_LUA_METHOD("showDiv", luaShowDiv) REFLECT_STRING("url", getURL, setURL) REFLECT_FLOAT("timeout", getTimeout, setTimeout) REFLECT_EXPORT_END @@ -290,6 +304,7 @@ protected : // element has been found // True when the element has been encountered bool _ParsingLua; + bool _IgnoreText; // the script to execute std::string _LuaScript; @@ -303,6 +318,7 @@ protected : class CLibWWWData *_LibWWW; // Current paragraph + std::string _DivName; CGroupParagraph* _Paragraph; inline CGroupParagraph *getParagraph() { @@ -442,6 +458,7 @@ protected : std::vector Entries; }; std::vector _Forms; + std::vector _Groups; // Cells parameters class CCellParams diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.cpp b/code/ryzom/client/src/interface_v3/group_html_webig.cpp index ac866830b..7e1781289 100644 --- a/code/ryzom/client/src/interface_v3/group_html_webig.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_webig.cpp @@ -277,7 +277,7 @@ string CGroupHTMLWebIG::home () void CGroupHTMLWebIG::handle () { - Home = "http://atys.ryzom.com/start/index.php"; +// Home = "http://atys.ryzom.com/start/index.php"; CGroupHTML::handle (); } diff --git a/code/ryzom/client/src/interface_v3/group_map.cpp b/code/ryzom/client/src/interface_v3/group_map.cpp index 43021767c..51d07bb88 100644 --- a/code/ryzom/client/src/interface_v3/group_map.cpp +++ b/code/ryzom/client/src/interface_v3/group_map.cpp @@ -775,7 +775,7 @@ bool CGroupMap::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup) _Islands.push_back(island); } } - catch(NLMISC::EFile &e) + catch(const NLMISC::EFile &e) { nlwarning(e.what()); } diff --git a/code/ryzom/client/src/interface_v3/group_menu.cpp b/code/ryzom/client/src/interface_v3/group_menu.cpp index 93d2ee4bb..22ff2b07c 100644 --- a/code/ryzom/client/src/interface_v3/group_menu.cpp +++ b/code/ryzom/client/src/interface_v3/group_menu.cpp @@ -1156,7 +1156,7 @@ void CGroupSubMenu::addSeparatorAtIndex(uint index, const std::string &id) tmp.CheckBox = NULL; tmp.RightArrow = NULL; _Lines.insert(_Lines.begin() + index, tmp); - _SubMenus.insert(_SubMenus.begin() + index, NULL); + _SubMenus.insert(_SubMenus.begin() + index, (CGroupSubMenu*)NULL); _GroupMenu->invalidateCoords(); } @@ -1304,7 +1304,7 @@ CViewTextMenu* CGroupSubMenu::addLineAtIndex(uint index, const ucstring &name, _Lines.insert(_Lines.begin() + index, tmp); // Add an empty sub menu by default - _SubMenus.insert(_SubMenus.begin() + index, NULL); + _SubMenus.insert(_SubMenus.begin() + index, (CGroupSubMenu*)NULL); _GroupMenu->invalidateCoords(); diff --git a/code/ryzom/client/src/interface_v3/group_quick_help.cpp b/code/ryzom/client/src/interface_v3/group_quick_help.cpp index 9df6c343e..210c7110e 100644 --- a/code/ryzom/client/src/interface_v3/group_quick_help.cpp +++ b/code/ryzom/client/src/interface_v3/group_quick_help.cpp @@ -278,8 +278,11 @@ void CGroupQuickHelp::browse (const char *url) _IsQuickHelp = false; string completeURL = url; - completeURL = completeURL.substr(0, completeURL.size()-5); // Substract the ".html" - completeURL += "_" + ClientCfg.getHtmlLanguageCode() + ".html"; + if (completeURL.substr(completeURL.size()-5, 5) == ".html") + { + completeURL = completeURL.substr(0, completeURL.size()-5); // Substract the ".html" + completeURL += "_" + ClientCfg.getHtmlLanguageCode() + ".html"; + } CGroupHTML::browse (completeURL.c_str()); } diff --git a/code/ryzom/client/src/interface_v3/group_tab.cpp b/code/ryzom/client/src/interface_v3/group_tab.cpp index 33588cbb9..27e6aa3a4 100644 --- a/code/ryzom/client/src/interface_v3/group_tab.cpp +++ b/code/ryzom/client/src/interface_v3/group_tab.cpp @@ -155,7 +155,7 @@ void CGroupTab::addTab(CCtrlTabButton * tabB, sint index) { if(i==index) { - tabB->setId(string("tab") + count); + tabB->setId("tab" + NLMISC::toString(count)); tabB->setParentPos(lastTab); if(i==0) tabB->setParentPosRef(Hotspot_TL); @@ -168,7 +168,7 @@ void CGroupTab::addTab(CCtrlTabButton * tabB, sint index) count++; } - buttons[i]->setId(string("tab") + count); + buttons[i]->setId("tab" + NLMISC::toString(count)); buttons[i]->setParentPos(lastTab); if(i==0 && index!=0) buttons[i]->setParentPosRef(Hotspot_TL); @@ -297,7 +297,7 @@ void CGroupTab::removeTab(sint index) { if(i!=index) { - buttons[i]->setId(string("tab")+count); + buttons[i]->setId("tab"+NLMISC::toString(count)); buttons[i]->setParentPos(lastTab); if((i==0) || (index==0 && i==1)) buttons[i]->setParentPosRef(Hotspot_TL); diff --git a/code/ryzom/client/src/interface_v3/group_tree.h b/code/ryzom/client/src/interface_v3/group_tree.h index 556abab99..c2a299c01 100644 --- a/code/ryzom/client/src/interface_v3/group_tree.h +++ b/code/ryzom/client/src/interface_v3/group_tree.h @@ -106,7 +106,7 @@ public: void setOpened(bool opened) { Opened = opened; } bool getOpened() const { return Opened; } void setText(const ucstring &text) { Text = text; } - ucstring getText() const { return Text; } + const ucstring& getText() const { return Text; } sint32 getFontSize() const { return FontSize; } void setFontSize(sint32 value) { FontSize = value; } sint32 getYDecal() const { return YDecal; } diff --git a/code/ryzom/client/src/interface_v3/guild_manager.cpp b/code/ryzom/client/src/interface_v3/guild_manager.cpp index c9bb4ec01..6abd0c029 100644 --- a/code/ryzom/client/src/interface_v3/guild_manager.cpp +++ b/code/ryzom/client/src/interface_v3/guild_manager.cpp @@ -29,6 +29,7 @@ #include "group_html.h" #include "../init_main_loop.h" #include "inventory_manager.h" +#include "../client_chat_manager.h" #include "../connection.h" #include "../entity_cl.h" @@ -48,6 +49,7 @@ using namespace std; using namespace NLMISC; extern CPeopleInterraction PeopleInterraction; +extern CClientChatManager ChatMngr; NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListAscensor, std::string, "list_sheet_guild"); @@ -539,6 +541,10 @@ void CGuildManager::closeAllInterfaces() CGroupContainer *pGuildChat = dynamic_cast(pIM->getElementFromId(WIN_GUILD_CHAT)); if (pGuildChat != NULL) pGuildChat->setActive(false); + + if (PeopleInterraction.TheUserChat.Filter.getTargetGroup() == CChatGroup::guild) + ChatMngr.updateChatModeAndButton(CChatGroup::say); + } // *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/input_handler_manager.cpp b/code/ryzom/client/src/interface_v3/input_handler_manager.cpp index 1d755dd56..3ece9f125 100644 --- a/code/ryzom/client/src/interface_v3/input_handler_manager.cpp +++ b/code/ryzom/client/src/interface_v3/input_handler_manager.cpp @@ -518,7 +518,7 @@ bool CInputHandlerManager::readInputConfigFile(const std::string & fileName) root = read.getRootNode(); } - catch (Exception &e) + catch (const Exception &e) { // Output error root = NULL; diff --git a/code/ryzom/client/src/interface_v3/interface_element.cpp b/code/ryzom/client/src/interface_v3/interface_element.cpp index f937a34e9..6db901b10 100644 --- a/code/ryzom/client/src/interface_v3/interface_element.cpp +++ b/code/ryzom/client/src/interface_v3/interface_element.cpp @@ -1235,7 +1235,7 @@ CInterfaceElement *CInterfaceElement::clone() dupStream.fill(&datas[0], (uint32)datas.size()); dupStream.serialPolyPtr(begunThisCloneWarHas); } - catch(NLMISC::EStream &) + catch(const NLMISC::EStream &) { // no-op -> caller has to handle the failure because NULL will be returned } diff --git a/code/ryzom/client/src/interface_v3/interface_element.h b/code/ryzom/client/src/interface_v3/interface_element.h index c77fc41b6..24982cad2 100644 --- a/code/ryzom/client/src/interface_v3/interface_element.h +++ b/code/ryzom/client/src/interface_v3/interface_element.h @@ -250,6 +250,9 @@ public: /// Accessors : SET void setId (const std::string &newID) { _Id = newID; } + inline void setName(const std::string &name) { _Name = name; } + inline const std::string& getName() { return _Name; } + virtual void setIdRecurse(const std::string &newID); void setParent (CInterfaceGroup *pIG) { _Parent = pIG; } @@ -510,6 +513,8 @@ protected: ///the id of the element std::string _Id; + std::string _Name; + ///is the element active? bool _Active; diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 45514f3c5..c4e238141 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -524,12 +524,12 @@ void CInterfaceManager::initOutGame() ActionsContext.addActionsManager(&Actions, ""); ActionsContext.addActionsManager(&EditActions, RZ_CATEGORY_EDIT); - - if (ClientCfg.SelectCharacter != -1) return; - // Init LUA Scripting initLUA(); + if (ClientCfg.SelectCharacter != -1) + return; + { if (SoundMngr != NULL) { @@ -1659,7 +1659,7 @@ bool CInterfaceManager::loadConfig (const string &filename) } } } - catch(NLMISC::EStream &) + catch(const NLMISC::EStream &) { f.close(); string sFileNameBackup = sFileName+"backup"; @@ -1846,7 +1846,7 @@ bool CInterfaceManager::saveConfig (const string &filename) return false; } } - catch(NLMISC::EStream &) + catch(const NLMISC::EStream &) { f.close(); nlwarning("Config saving failed."); @@ -4790,7 +4790,7 @@ bool CInterfaceManager::saveKeys(const std::string &filename) nlwarning ("Can't open the file %s", filename.c_str()); } } - catch (Exception &e) + catch (const Exception &e) { nlwarning ("Error while writing the file %s : %s. Remove it.", filename.c_str(), e.what ()); CFile::deleteFile(filename); @@ -5754,7 +5754,7 @@ bool CInterfaceManager::executeLuaScript(const std::string &luaScript, bool smal else _LuaState->executeScript(luaScript); } - catch(ELuaError &e) + catch(const ELuaError &e) { std::string msg = e.luaWhat(); char filename[MAX_PATH]; @@ -6079,7 +6079,7 @@ void CInterfaceManager::createLocalBranch(const std::string &fileName, NLMISC::I ServerToLocalAutoCopySkillPoints.init("USER"); } } - catch (Exception &e) + catch (const Exception &e) { // Output error nlwarning ("CFormLoader: Error while loading the form %s: %s", fileName.c_str(), e.what()); diff --git a/code/ryzom/client/src/interface_v3/interface_options.cpp b/code/ryzom/client/src/interface_v3/interface_options.cpp index ae70f1460..0a8135f71 100644 --- a/code/ryzom/client/src/interface_v3/interface_options.cpp +++ b/code/ryzom/client/src/interface_v3/interface_options.cpp @@ -78,14 +78,14 @@ bool CInterfaceOptions::parse (xmlNodePtr cur) CXMLAutoPtr ptr, val; ptr = xmlGetProp (cur, (xmlChar*)"name"); val = xmlGetProp (cur, (xmlChar*)"value"); - if ((ptr == NULL) || (val == NULL)) + if (!ptr || !val) { nlinfo("param with no name or no value"); ok = false; } else { - string name = strlwr (string((const char*)ptr)); + string name = NLMISC::toLower(string((const char*)ptr)); string value = (string((const char*)val)); _ParamValue[name].init(value); } @@ -321,7 +321,7 @@ bool COptionsList::parse (xmlNodePtr cur) { CXMLAutoPtr ptr, val; val = xmlGetProp (cur, (xmlChar*)"value"); - if (val == NULL) + if (!val) { nlinfo("param with no name or no value"); ok = false; diff --git a/code/ryzom/client/src/interface_v3/interface_parser.cpp b/code/ryzom/client/src/interface_v3/interface_parser.cpp index 90f307316..56b95be88 100644 --- a/code/ryzom/client/src/interface_v3/interface_parser.cpp +++ b/code/ryzom/client/src/interface_v3/interface_parser.cpp @@ -685,7 +685,7 @@ bool CInterfaceParser::parseInterface (const std::vector & strings, i++; } } - catch (Exception &e) + catch (const Exception &e) { // Output error // todo hulud interface syntax error @@ -4721,7 +4721,7 @@ bool CInterfaceParser::loadLUA(const std::string &fileName, std::string &error) { _LuaState->executeFile(pathName); } - catch(ELuaError &e) + catch(const ELuaError &e) { nlwarning(e.luaWhat().c_str()); error= e.luaWhat(); diff --git a/code/ryzom/client/src/interface_v3/item_consumable_effect.cpp b/code/ryzom/client/src/interface_v3/item_consumable_effect.cpp index bbd664ad5..3c1e958f8 100644 --- a/code/ryzom/client/src/interface_v3/item_consumable_effect.cpp +++ b/code/ryzom/client/src/interface_v3/item_consumable_effect.cpp @@ -113,6 +113,33 @@ void CItemConsumableEffectHelper::getItemConsumableEffectText(const CItemSheet * effects += "\n"; } + if ( name == "SP_LIFE_AURA2" ) + { + + uint16 regenMod; + fromString(params[0].c_str(), regenMod); + uint32 bonus = regenMod * itemQuality; + uint32 duration; + fromString(params[1].c_str(), duration); + uint32 radius; + fromString(params[2].c_str(), radius); + uint32 targetDisableTime; + fromString(params[3].c_str(), targetDisableTime); + uint32 userDisableTime; + fromString(params[4].c_str(), userDisableTime); + + ucstring result = CI18N::get("uiItemConsumableEffectLifeAura"); + strFindReplace(result, "%modifier", toString(bonus)); + strFindReplace(result, "%minutes", toString(duration/60)); + strFindReplace(result, "%secondes", toString(duration%60)); + strFindReplace(result, "%radius", toString(radius)); + strFindReplace(result, "%targetDisableTime", "0"); + strFindReplace(result, "%userDisableTime", "0"); + + effects += result; + effects += "\n"; + } + if ( name == "SP_STAMINA_AURA" ) { @@ -139,6 +166,34 @@ void CItemConsumableEffectHelper::getItemConsumableEffectText(const CItemSheet * effects += "\n"; } + + if ( name == "SP_STAMINA_AURA2" ) + { + + uint16 regenMod; + fromString(params[0].c_str(), regenMod); + uint32 bonus = regenMod * itemQuality; + uint32 duration; + fromString(params[1].c_str(), duration); + uint32 radius; + fromString(params[2].c_str(), radius); + uint32 targetDisableTime; + fromString(params[3].c_str(), targetDisableTime); + uint32 userDisableTime; + fromString(params[4].c_str(), userDisableTime); + + ucstring result = CI18N::get("uiItemConsumableEffectStaminaAura"); + strFindReplace(result, "%modifier", toString(bonus)); + strFindReplace(result, "%minutes", toString(duration/60)); + strFindReplace(result, "%secondes", toString(duration%60)); + strFindReplace(result, "%radius", toString(radius)); + strFindReplace(result, "%targetDisableTime", "0"); + strFindReplace(result, "%userDisableTime", "0"); + + effects += result; + effects += "\n"; + } + if ( name == "SP_SAP_AURA" ) { @@ -165,6 +220,33 @@ void CItemConsumableEffectHelper::getItemConsumableEffectText(const CItemSheet * effects += "\n"; } + if ( name == "SP_SAP_AURA2" ) + { + + uint16 regenMod; + fromString(params[0].c_str(), regenMod); + uint32 bonus = regenMod * itemQuality; + uint32 duration; + fromString(params[1].c_str(), duration); + uint32 radius; + fromString(params[2].c_str(), radius); + uint32 targetDisableTime; + fromString(params[3].c_str(), targetDisableTime); + uint32 userDisableTime; + fromString(params[4].c_str(), userDisableTime); + + ucstring result = CI18N::get("uiItemConsumableEffectSapAura"); + strFindReplace(result, "%modifier", toString(bonus)); + strFindReplace(result, "%minutes", toString(duration/60)); + strFindReplace(result, "%secondes", toString(duration%60)); + strFindReplace(result, "%radius", toString(radius)); + strFindReplace(result, "%targetDisableTime", "0"); + strFindReplace(result, "%userDisableTime", "0"); + + effects += result; + effects += "\n"; + } + // skill modifier consumables //--------------------------- ucstring result(""); diff --git a/code/ryzom/client/src/interface_v3/lua_helper.cpp b/code/ryzom/client/src/interface_v3/lua_helper.cpp index 0ec99d5a4..9fa942d41 100644 --- a/code/ryzom/client/src/interface_v3/lua_helper.cpp +++ b/code/ryzom/client/src/interface_v3/lua_helper.cpp @@ -378,7 +378,7 @@ bool CLuaState::executeScriptNoThrow(const std::string &code, int numRet) { executeScript(code, numRet); } - catch (ELuaError &e) + catch (const ELuaError &e) { nlwarning(e.what()); return false; diff --git a/code/ryzom/client/src/interface_v3/lua_ihm.cpp b/code/ryzom/client/src/interface_v3/lua_ihm.cpp index 6fee6811a..15dd9872a 100644 --- a/code/ryzom/client/src/interface_v3/lua_ihm.cpp +++ b/code/ryzom/client/src/interface_v3/lua_ihm.cpp @@ -115,6 +115,7 @@ #include "game_share/scenario_entry_points.h" #include "game_share/bg_downloader_msg.h" #include "game_share/constants.h" +#include "game_share/visual_slot_manager.h" #ifdef LUA_NEVRAX_VERSION #include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger @@ -232,7 +233,7 @@ bool CLuaIHM::pop(CLuaState &ls, NLMISC::CRGBA &dest) #endif dest = luabind::object_cast(obj); } - catch(luabind::cast_failed &) + catch(const luabind::cast_failed &) { return false; } @@ -255,7 +256,7 @@ bool CLuaIHM::pop(CLuaState &ls,NLMISC::CVector2f &dest) #endif dest = luabind::object_cast(obj); } - catch(luabind::cast_failed &) + catch(const luabind::cast_failed &) { return false; } @@ -278,7 +279,7 @@ bool CLuaIHM::pop(CLuaState &ls, ucstring &dest) #endif dest = luabind::object_cast(obj); } - catch(luabind::cast_failed &) + catch(const luabind::cast_failed &) { return false; } @@ -1368,6 +1369,8 @@ void CLuaIHM::registerIHM(CLuaState &ls) ls.registerFunc("isPlayerNewbie", isPlayerNewbie); ls.registerFunc("isInRingMode", isInRingMode); ls.registerFunc("getUserRace", getUserRace); + ls.registerFunc("getSheet2idx", getSheet2idx); + // Through LUABind API lua_State *L= ls.getStatePointer(); @@ -3351,7 +3354,7 @@ bool CLuaIHM::popString(CLuaState &ls, std::string & dest) #endif dest = luabind::object_cast(obj); } - catch(luabind::cast_failed &) + catch(const luabind::cast_failed &) { return false; } @@ -3373,7 +3376,7 @@ bool CLuaIHM::popSINT32(CLuaState &ls, sint32 & dest) #endif dest = luabind::object_cast(obj); } - catch(luabind::cast_failed &) + catch(const luabind::cast_failed &) { return false; } @@ -4412,3 +4415,25 @@ int CLuaIHM::getUserRace(CLuaState &ls) return 1; } +// *************************************************************************** +int CLuaIHM::getSheet2idx(CLuaState &ls) +{ + CLuaIHM::checkArgCount(ls, "getSheet2idx", 2); + CLuaIHM::checkArgType(ls, "getSheet2idx", 1, LUA_TSTRING); + CLuaIHM::checkArgType(ls, "getSheet2idx", 2, LUA_TNUMBER); + + const std::string & sheedtName = ls.toString(1); + uint32 slotId = (uint32)ls.toNumber(2); + + NLMISC::CSheetId sheetId; + + if (sheetId.buildSheetId(sheedtName)) + { + uint32 idx = CVisualSlotManager::getInstance()->sheet2Index(sheetId, (SLOTTYPE::EVisualSlot)slotId); + ls.push((lua_Number)idx); + } + else + return 0; + return 1; +} + diff --git a/code/ryzom/client/src/interface_v3/lua_ihm.h b/code/ryzom/client/src/interface_v3/lua_ihm.h index f2a0e2628..6a11a5c91 100644 --- a/code/ryzom/client/src/interface_v3/lua_ihm.h +++ b/code/ryzom/client/src/interface_v3/lua_ihm.h @@ -351,6 +351,7 @@ private: static int isPlayerNewbie(CLuaState &ls); static int isInRingMode(CLuaState &ls); static int getUserRace(CLuaState &ls); + static int getSheet2idx(CLuaState &ls); // LUA functions exported for Dev only (debug) diff --git a/code/ryzom/client/src/interface_v3/lua_object.cpp b/code/ryzom/client/src/interface_v3/lua_object.cpp index 86b91af73..eb5f76c4f 100644 --- a/code/ryzom/client/src/interface_v3/lua_object.cpp +++ b/code/ryzom/client/src/interface_v3/lua_object.cpp @@ -613,7 +613,7 @@ void CLuaObject::dump(uint maxDepth /*= 20*/, std::set *alreadySee NLMISC::InfoLog->forceDisplayRaw((res[k] + "\n") .c_str()); } } - catch(std::exception &e) + catch(const std::exception &e) { CLuaIHM::dumpCallStack(); nlwarning(e.what()); diff --git a/code/ryzom/client/src/interface_v3/people_interraction.cpp b/code/ryzom/client/src/interface_v3/people_interraction.cpp index 3b5a4fb43..e98013f9a 100644 --- a/code/ryzom/client/src/interface_v3/people_interraction.cpp +++ b/code/ryzom/client/src/interface_v3/people_interraction.cpp @@ -999,7 +999,7 @@ class CHandlerChatGroupFilter : public IActionHandler } - rCTF.setTargetGroup(PeopleInterraction.TheUserChat.Filter.getTargetGroup()); + rCTF.setTargetGroup(PeopleInterraction.TheUserChat.Filter.getTargetGroup(), PeopleInterraction.TheUserChat.Filter.getTargetDynamicChannelDbIndex()); } else { @@ -1670,7 +1670,7 @@ bool CPeopleInterraction::saveUserChatsInfos(NLMISC::IStream &f) pCGW->saveFreeTeller(f); } } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlwarning("Error while saving user chat infos : %s", e.what()); return false; @@ -1691,7 +1691,7 @@ bool CPeopleInterraction::saveUserDynChatsInfos(NLMISC::IStream &f) saveFilteredDynChat(f, TheUserChat); } } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlwarning("Error while saving user dyn chat infos : %s", e.what()); return false; @@ -1756,7 +1756,7 @@ bool CPeopleInterraction::loadUserChatsInfos(NLMISC::IStream &f) if (pCGW) pCGW->loadFreeTeller(f); } } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlwarning("Error while loading user chat infos : %s", e.what()); return false; @@ -1786,7 +1786,7 @@ bool CPeopleInterraction::loadUserDynChatsInfos(NLMISC::IStream &f) setupUserDynChatFromSummary(fcs, TheUserChat); } } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlwarning("Error while loading user dyn chat infos : %s", e.what()); return false; @@ -1813,8 +1813,6 @@ void CPeopleInterraction::setupUserChatFromSummary(const CFilteredChatSummary &s //================================================================================================================= void CPeopleInterraction::setupUserDynChatFromSummary(const CFilteredDynChatSummary &summary, CFilteredChat &dest) { - // User Dest - dest.Filter.setTargetGroup(summary.Target, 0, false); // src for (uint8 i = 0; i < CChatGroup::MaxDynChanPerPlayer; i++) { @@ -2279,7 +2277,8 @@ public: CPeopleList::TSortOrder order = (CPeopleList::TSortOrder)(pIM->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32()); order = (CPeopleList::TSortOrder)(order + 1); - if (order == CPeopleList::END_SORT_ORDER) { + if (order == CPeopleList::END_SORT_ORDER) + { order = CPeopleList::START_SORT_ORDER; } @@ -2656,8 +2655,10 @@ class CHandlerChatTargetSelected : public IActionHandler } else { - for (uint i = 0; i < CChatGroup::MaxDynChanPerPlayer; i++) { - if (nlstricmp(sParams, "dyn"+toString("%d", i)) == 0) { + for (uint i = 0; i < CChatGroup::MaxDynChanPerPlayer; i++) + { + if (nlstricmp(sParams, "dyn"+toString("%d", i)) == 0) + { cf.setTargetGroup(CChatGroup::dyn_chat, i); } } @@ -2666,12 +2667,12 @@ class CHandlerChatTargetSelected : public IActionHandler // Case of user chat in grouped chat window if (cw == PeopleInterraction.ChatGroup.Window) { - PeopleInterraction.TheUserChat.Filter.setTargetGroup(cf.getTargetGroup()); + PeopleInterraction.TheUserChat.Filter.setTargetGroup(cf.getTargetGroup(), cf.getTargetDynamicChannelDbIndex()); CInterfaceManager::getInstance()->runActionHandler("chat_group_filter", NULL, "user"); } if (cw == PeopleInterraction.TheUserChat.Window) { - PeopleInterraction.TheUserChat.Filter.setTargetGroup(cf.getTargetGroup()); + PeopleInterraction.TheUserChat.Filter.setTargetGroup(cf.getTargetGroup(), cf.getTargetDynamicChannelDbIndex()); CInterfaceManager::getInstance()->runActionHandler("user_chat_active", NULL, ""); } diff --git a/code/ryzom/client/src/interface_v3/people_list.cpp b/code/ryzom/client/src/interface_v3/people_list.cpp index 66ce8a2a8..ac4764e15 100644 --- a/code/ryzom/client/src/interface_v3/people_list.cpp +++ b/code/ryzom/client/src/interface_v3/people_list.cpp @@ -207,12 +207,14 @@ bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b) ucstring name_b = toUpper(b.getName()); // We want order: online/alpha, offworld/alpha, offline/alpha - if (a.Online == b.Online) { + if (a.Online == b.Online) + { return (name_a < name_b); } else { // Compare online status - switch (a.Online) { + switch (a.Online) + { case ccs_online: // a is > if a is online return true; @@ -244,7 +246,8 @@ void CPeopleList::sortEx(TSortOrder order) _BaseContainer->detachContainer(_Peoples[k].Container); } - switch (order) { + switch (order) + { default: case sort_index: std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByContactId); @@ -441,7 +444,7 @@ void CPeopleList::setContactId(uint index, uint32 contactId) } //================================================================== -void CPeopleList::displayLocalPlayerTell(uint index,const ucstring &msg,uint numBlinks /*=0*/) +void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, const ucstring &msg,uint numBlinks /*=0*/) { if (_ContactType == CPeopleListDesc::Ignore) { @@ -475,7 +478,12 @@ void CPeopleList::displayLocalPlayerTell(uint index,const ucstring &msg,uint num // display msg with good color CInterfaceProperty prop; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); + + ucstring s = CI18N::get("youTellPlayer"); + strFindReplace(s, "%name", receiver); + strFindReplace(finalMsg, CI18N::get("youTell"), s); gl->addChild(getChatTextMngr().createMsgText(finalMsg, prop.getRGBA())); + CInterfaceManager::getInstance()->log(finalMsg); // if the group is closed, make it blink if (!gc->isOpen()) @@ -924,7 +932,7 @@ class CHandlerContactEntry : public IActionHandler uint index; if (PeopleInterraction.getPeopleFromContainerID(str, peopleList, index)) { - peopleList->displayLocalPlayerTell(index, text); + peopleList->displayLocalPlayerTell(str2, index, text); } } else @@ -948,6 +956,11 @@ class CHandlerContactEntry : public IActionHandler CChatWindow::encodeColorTag(prop.getRGBA(), final, true); final += text; pWin->displayTellMessage(final, prop.getRGBA(), pWin->getFreeTellerName(str)); + + ucstring s = CI18N::get("youTellPlayer"); + strFindReplace(s, "%name", pWin->getFreeTellerName(str)); + strFindReplace(final, CI18N::get("youTell"), s); + CInterfaceManager::getInstance()->log(final); } } diff --git a/code/ryzom/client/src/interface_v3/people_list.h b/code/ryzom/client/src/interface_v3/people_list.h index 0ab0f3508..a3748c01a 100644 --- a/code/ryzom/client/src/interface_v3/people_list.h +++ b/code/ryzom/client/src/interface_v3/people_list.h @@ -111,7 +111,7 @@ public: * If the window is closed, it causes it to blink (and also the parent window) */ void displayMessage(uint index, const ucstring &msg, NLMISC::CRGBA col, uint numBlinks = 0); - void displayLocalPlayerTell(uint index, const ucstring &msg, uint numBlinks = 0); + void displayLocalPlayerTell(const ucstring &receiver, uint index, const ucstring &msg, uint numBlinks = 0); // Is the given people window visible ? bool isPeopleChatVisible(uint index) const; // reset remove everything from the interface diff --git a/code/ryzom/client/src/interface_v3/player_trade.cpp b/code/ryzom/client/src/interface_v3/player_trade.cpp index 671d0047a..7307110d9 100644 --- a/code/ryzom/client/src/interface_v3/player_trade.cpp +++ b/code/ryzom/client/src/interface_v3/player_trade.cpp @@ -78,9 +78,9 @@ void CPlayerTrade::restoreItem(CDBCtrlSheet *exchangeSlot) // *** If not an AMMO, try to 'auto-stack', as server does bool canAutoStack= false; - uint32 autoStackSheetId; - sint32 autoStackQuality; - sint32 autoStackMaxQuantity; + uint32 autoStackSheetId = 0; + sint32 autoStackQuality = 0; + sint32 autoStackMaxQuantity = 0; const CItemSheet *itemSheet= exchangeSlot->asItemSheet(); // NB: cannot auto stack ammo because their full props (dammage etc...) are not sent to client if(itemSheet) diff --git a/code/ryzom/client/src/interface_v3/sphrase_manager.cpp b/code/ryzom/client/src/interface_v3/sphrase_manager.cpp index 8058e41da..dc12a391f 100644 --- a/code/ryzom/client/src/interface_v3/sphrase_manager.cpp +++ b/code/ryzom/client/src/interface_v3/sphrase_manager.cpp @@ -57,6 +57,7 @@ const std::string PhraseMemoryViewNextAction= "ui:interface:gestionsets:shortcu const std::string PhraseMemoryViewCycleAction= "ui:interface:gestionsets:shortcuts:view_cycle_action"; const std::string PhraseMemoryViewSlotBase= "ui:interface:gestionsets:shortcuts:s"; const std::string PhraseMemoryCtrlBase= "ui:interface:gestionsets:shortcuts:s"; +const std::string PhraseMemoryAltCtrlBase= "ui:interface:gestionsets2:header_closed:shortcuts:s"; const std::string PhraseMemoryPhraseMenu= "ui:interface:cm_memory_phrase"; const std::string PhraseMemoryPhraseAction= "cast_phrase_or_create_new"; @@ -118,11 +119,16 @@ void CSPhraseManager::initInGame() _BookDbLeaves[i]= node; } _MemoryDbLeaves.resize(PHRASE_MAX_MEMORY_SLOT, NULL); + _MemoryAltDbLeaves.resize(PHRASE_MAX_MEMORY_SLOT, NULL); + for(i=0;igetDbProp(PHRASE_DB_MEMORY + ":" + toString(i) + ":PHRASE"); node->setValue32(0); _MemoryDbLeaves[i]= node; + CCDBNodeLeaf *node_alt= pIM->getDbProp(PHRASE_DB_MEMORY_ALT + ":" + toString(i) + ":PHRASE"); + node_alt->setValue32(0); + _MemoryAltDbLeaves[i]= node_alt; } // Progression Db leaves @@ -510,6 +516,19 @@ void CSPhraseManager::updateMemoryDBAll() _MemoryDbLeaves[i]->setValue32(slot.Id); } } + + if(_SelectedMemoryDB != -1 && (sint32)_Memories.size() > 0) + { + // Always update alt gestionsets + for(uint i=0;isetValue32(0); + else + _MemoryAltDbLeaves[i]->setValue32(slotAlt.Id); + } + } } // *************************************************************************** @@ -530,6 +549,15 @@ void CSPhraseManager::updateMemoryDBSlot(uint32 memorySlot) else _MemoryDbLeaves[memorySlot]->setValue32(slot.Id); } + + if (_SelectedMemoryDB == 0) + { + CMemorySlot &slotAlt= _Memories[0].Slot[memorySlot]; + if(!slotAlt.isPhrase()) + _MemoryAltDbLeaves[memorySlot]->setValue32(0); + else + _MemoryAltDbLeaves[memorySlot]->setValue32(slotAlt.Id); + } } // *************************************************************************** @@ -873,6 +901,7 @@ void CSPhraseManager::reset() _LastProgressionNumDbFill[i]= 0; } _MemoryDbLeaves.clear(); + _MemoryAltDbLeaves.clear(); _NextExecuteLeaf= NULL; _NextExecuteIsCyclicLeaf= NULL; @@ -2645,7 +2674,13 @@ static sint getRightHandEnchantValue() void CSPhraseManager::updateMemoryCtrlRegenTickRange(uint memorySlot, CDBCtrlSheet *ctrl) { // - uint memoryLine= getSelectedMemoryLineDB(); + sint32 memoryLine; + if (ctrl->isShortCut()) + memoryLine = getSelectedMemoryLineDB(); + else + memoryLine = 0; + if (memoryLine < 0) + return; sint32 phraseId= getMemorizedPhrase(memoryLine, memorySlot); // if(phraseId) @@ -2780,8 +2815,12 @@ void CSPhraseManager::updateMemoryCtrlState(uint memorySlot, CDBCtrlSheet *ctrl, CSBrickManager *pBM = CSBrickManager::getInstance(); CSkillManager *pSM = CSkillManager::getInstance(); + uint memoryLine; // get the slot info - uint memoryLine= getSelectedMemoryLineDB(); + if (ctrl->isShortCut()) // No memoryLine defined + memoryLine= getSelectedMemoryLineDB(); + else + memoryLine= 0; bool newIsMacro= isMemorizedMacro(memoryLine, memorySlot); sint32 macroId= getMemorizedMacro(memoryLine, memorySlot); sint32 phraseId= getMemorizedPhrase(memoryLine, memorySlot); @@ -3004,6 +3043,9 @@ void CSPhraseManager::updateAllMemoryCtrlState() // update the valid state. updateMemoryCtrlState(i, ctrl, itemSkill); } + CDBCtrlSheet *ctrlAlt= dynamic_cast(pIM->getElementFromId(PhraseMemoryAltCtrlBase + toString(i)) ); + if(ctrlAlt) + updateMemoryCtrlState(i, ctrlAlt, itemSkill); } TTicks endTime = CTime::getPerformanceTime(); //nldebug("***** %d ms for CSPhraseManager::updateAllMemoryCtrlState", (int) (1000 * CTime::ticksToSecond(endTime - startTime))); @@ -3030,26 +3072,49 @@ CDBCtrlSheet *CSPhraseManager::getMemorySlotCtrl(uint memorySlot) return dynamic_cast(pIM->getElementFromId(PhraseMemoryCtrlBase + toString(memorySlot))); } +// *************************************************************************** +CDBCtrlSheet *CSPhraseManager::getMemoryAltSlotCtrl(uint memorySlot) +{ + if(memorySlot>=PHRASE_MAX_MEMORY_SLOT) + return NULL; + + // Get the ctrl + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + return dynamic_cast(pIM->getElementFromId(PhraseMemoryAltCtrlBase + toString(memorySlot))); +} + // *************************************************************************** void CSPhraseManager::updateMemoryCtrlState(uint memorySlot) { CDBCtrlSheet *ctrl= getMemorySlotCtrl(memorySlot); + CDBCtrlSheet *ctrlAlt= getMemoryAltSlotCtrl(memorySlot); if(ctrl) { // update the valid state. updateMemoryCtrlState(memorySlot, ctrl, getRightHandItemSkill()); } + if(ctrlAlt) + { + // update the valid state. + updateMemoryCtrlState(memorySlot, ctrlAlt, getRightHandItemSkill()); + } } // *************************************************************************** void CSPhraseManager::updateMemoryCtrlRegenTickRange(uint memorySlot) { CDBCtrlSheet *ctrl= getMemorySlotCtrl(memorySlot); + CDBCtrlSheet *ctrlAlt= getMemoryAltSlotCtrl(memorySlot); if(ctrl) { // update the valid state. updateMemoryCtrlRegenTickRange(memorySlot, ctrl); } + if(ctrlAlt) + { + // update the valid state. + updateMemoryCtrlRegenTickRange(memorySlot, ctrlAlt); + } } // *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/sphrase_manager.h b/code/ryzom/client/src/interface_v3/sphrase_manager.h index 0a934f4e2..bf40dcc35 100644 --- a/code/ryzom/client/src/interface_v3/sphrase_manager.h +++ b/code/ryzom/client/src/interface_v3/sphrase_manager.h @@ -34,6 +34,7 @@ const std::string PHRASE_DB_BOOK="UI:PHRASE:BOOK"; const std::string PHRASE_DB_PROGRESSION[2]= {"UI:PHRASE:PROGRESS_ACTIONS", "UI:PHRASE:PROGRESS_UPGRADES"}; const std::string PHRASE_DB_MEMORY="UI:PHRASE:MEMORY"; +const std::string PHRASE_DB_MEMORY_ALT="UI:PHRASE:MEMORY_ALT"; const std::string PHRASE_DB_EXECUTE_NEXT="UI:PHRASE:EXECUTE_NEXT:PHRASE"; const std::string PHRASE_DB_EXECUTE_NEXT_IS_CYCLIC="UI:PHRASE:EXECUTE_NEXT:ISCYCLIC"; const std::string PHRASE_DB_BOTCHAT="LOCAL:TRADING"; @@ -458,6 +459,7 @@ private: // Shortcut To Phrases Leaves std::vector _BookDbLeaves; std::vector _MemoryDbLeaves; + std::vector _MemoryAltDbLeaves; CCDBNodeLeaf *_NextExecuteLeaf; CCDBNodeLeaf *_NextExecuteIsCyclicLeaf; @@ -698,6 +700,7 @@ private: void updateMemoryCtrlRegenTickRange(uint memorySlot); CDBCtrlSheet *getMemorySlotCtrl(uint memorySlot); + CDBCtrlSheet *getMemoryAltSlotCtrl(uint memorySlot); CTickRange getRegenTickRange(const CSPhraseCom &phrase) const; diff --git a/code/ryzom/client/src/interface_v3/yubo_chat.cpp b/code/ryzom/client/src/interface_v3/yubo_chat.cpp index d24ae8bea..55bc17922 100644 --- a/code/ryzom/client/src/interface_v3/yubo_chat.cpp +++ b/code/ryzom/client/src/interface_v3/yubo_chat.cpp @@ -59,7 +59,7 @@ void CYuboChat::connect(const string &url, const std::string &login, const std:: return; } } - catch(Exception &e) + catch(const Exception &e) { addStringReceived(toString("ERROR: exception with server %s: %s", _URL.c_str(), e.what())); } @@ -78,7 +78,7 @@ void CYuboChat::disconnect() { _Sock.disconnect(); } - catch(Exception &e) + catch(const Exception &e) { addStringReceived(toString("ERROR: exception with server %s: %s", _URL.c_str(), e.what())); } @@ -265,7 +265,7 @@ void CYuboChat::sendInternal(const ucstring &msg) size= (uint32)toSend.size()-off; } } - catch(Exception &e) + catch(const Exception &e) { addStringReceived(toString("ERROR: exception with server %s: %s", _URL.c_str(), e.what())); } diff --git a/code/ryzom/client/src/libwww.cpp b/code/ryzom/client/src/libwww.cpp index dc5c151bd..c4695840d 100644 --- a/code/ryzom/client/src/libwww.cpp +++ b/code/ryzom/client/src/libwww.cpp @@ -218,6 +218,14 @@ HTAttr p_attr[] = HTML_ATTR(P,QUICK_HELP_CONDITION), HTML_ATTR(P,QUICK_HELP_EVENTS), HTML_ATTR(P,QUICK_HELP_LINK), + HTML_ATTR(P,NAME), + { 0 } +}; + + +HTAttr div_attr[] = +{ + HTML_ATTR(DIV,NAME), { 0 } }; @@ -684,6 +692,8 @@ void initLibWWW() HTML_DTD->tags[HTML_A].number_of_attributes = sizeof(a_attr) / sizeof(HTAttr) - 1; //HTML_DTD->tags[HTML_I].attributes = a_attr; HTML_DTD->tags[HTML_I].number_of_attributes = 0; + HTML_DTD->tags[HTML_DIV].attributes = div_attr; + HTML_DTD->tags[HTML_DIV].number_of_attributes = sizeof(div_attr) / sizeof(HTAttr) - 1; // Set a request timeout // HTHost_setEventTimeout (30000); diff --git a/code/ryzom/client/src/libwww.h b/code/ryzom/client/src/libwww.h index f3f681268..5c686e39b 100644 --- a/code/ryzom/client/src/libwww.h +++ b/code/ryzom/client/src/libwww.h @@ -201,8 +201,15 @@ enum HTML_ATTR(P,QUICK_HELP_CONDITION) = 0, HTML_ATTR(P,QUICK_HELP_EVENTS), HTML_ATTR(P,QUICK_HELP_LINK), + HTML_ATTR(P,NAME), }; +enum +{ + HTML_ATTR(DIV,NAME) = 0, +}; + + #undef HTML_ATTR // *************************************************************************** diff --git a/code/ryzom/client/src/light_cycle_manager.cpp b/code/ryzom/client/src/light_cycle_manager.cpp index cb34c0dd0..4b0488dd5 100644 --- a/code/ryzom/client/src/light_cycle_manager.cpp +++ b/code/ryzom/client/src/light_cycle_manager.cpp @@ -442,7 +442,7 @@ bool CLightCycleManager::isInDayInterval(float startHour, float endHour, float d float CLightCycleManager::getLightLevel(float hour) const { H_AUTO_USE(RZ_LightCycleManager) - float lightValue; + float lightValue = 0.f; if (isInDayInterval(_Desc.NightTransitionStartHour, _Desc.NightTransitionEndHour, _Desc.NumHours, hour, lightValue)) return lightValue; if (isInDayInterval(_Desc.DawnTransitionStartHour, _Desc.DawnTransitionEndHour, _Desc.NumHours, hour, lightValue)) diff --git a/code/ryzom/client/src/lod_character_user_manager.cpp b/code/ryzom/client/src/lod_character_user_manager.cpp index 871f6fc30..5ba9d4a46 100644 --- a/code/ryzom/client/src/lod_character_user_manager.cpp +++ b/code/ryzom/client/src/lod_character_user_manager.cpp @@ -69,7 +69,7 @@ bool CLodCharacterUserManager::addLodShapeBank(const std::string &filename) // load and add the file to the main scene Scene->loadCLodShapeBank(filename); } - catch(Exception &e) + catch(const Exception &e) { nlwarning(e.what()); return false; diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 6f06d1b5f..d1dee738d 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -1721,15 +1721,15 @@ class CAHReboot : public IActionHandler } LoginSM.pushEvent(CLoginStateMachine::ev_reboot); } - catch (NLMISC::EDiskFullError &) + catch (const NLMISC::EDiskFullError &) { im->messageBoxWithHelp(CI18N::get("uiPatchDiskFull"), "ui:login"); } - catch (NLMISC::EWriteError &) + catch (const NLMISC::EWriteError &) { im->messageBoxWithHelp(CI18N::get("uiPatchWriteError"), "ui:login"); } - catch (std::exception &e) + catch (const std::exception &e) { im->messageBoxWithHelp(ucstring(e.what()), "ui:login", "login_quit"); } diff --git a/code/ryzom/client/src/login_patch.cpp b/code/ryzom/client/src/login_patch.cpp index fa0ef7f57..762cee9c7 100644 --- a/code/ryzom/client/src/login_patch.cpp +++ b/code/ryzom/client/src/login_patch.cpp @@ -386,7 +386,7 @@ void CPatchManager::readClientVersionAndDescFile() DescFilename = "unknown"; ValidDescFile = true; } - catch(Exception &) + catch(const Exception &) { nlwarning("EXCEPTION CATCH: readClientVersionAndDescFile() failed - not important"); // Not important that there is no desc file @@ -1203,7 +1203,7 @@ void CPatchManager::getServerFile (const std::string &name, bool bZipped, const downloadSuccess = true; } - catch (EPatchDownloadException& e) + catch (const EPatchDownloadException& e) { //nlwarning("EXCEPTION CATCH: getServerFile() failed - try to find an alternative: %i: %s",UsedServer,PatchServers[UsedServer].DisplayedServerPath.c_str()); @@ -2492,7 +2492,7 @@ void CCheckThread::run () CheckOk = true; Ended = true; } - catch (NLMISC::EDiskFullError) + catch (const NLMISC::EDiskFullError &) { // more explicit message for this common error case nlwarning("EXCEPTION CATCH: disk full"); @@ -2501,7 +2501,7 @@ void CCheckThread::run () CheckOk = false; Ended = true; } - catch (Exception &e) + catch (const Exception &e) { nlwarning("EXCEPTION CATCH: CCheckThread::run() failed"); ucstring sTranslate = CI18N::get("uiCheckEndWithErr") + " " + e.what(); @@ -2622,7 +2622,7 @@ void CPatchThread::run() } } - catch (NLMISC::EDiskFullError) + catch (const NLMISC::EDiskFullError &) { // more explicit message for this common error case nlwarning("EXCEPTION CATCH: CPatchThread::run() Disk Full"); @@ -2630,7 +2630,7 @@ void CPatchThread::run() sTranslate = CI18N::get("uiPatchDiskFull"); bErr = true; } - catch(Exception &e) + catch(const Exception &e) { nlwarning("EXCEPTION CATCH: CPatchThread::run() failed"); pPM->setState(true, ucstring(e.what())); @@ -2803,7 +2803,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) // else -> file comes from a previous download (with .tmp extension, and is up to date) // the remaining code will just rename it with good name and exit } - catch (NLMISC::EWriteError) + catch (const NLMISC::EWriteError &) { // this is a local error, rethrow ... throw; @@ -2814,7 +2814,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) pPM->getServerFile(lzmaFile, false, "", &progress); } } - catch (NLMISC::EWriteError) + catch (const NLMISC::EWriteError &) { // this is a local error, rethrow ... throw; @@ -2837,7 +2837,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) break; } } - catch (NLMISC::EWriteError) + catch (const NLMISC::EWriteError&) { throw; } @@ -2880,7 +2880,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) // remove the subfolder name PatchName = NLMISC::CFile::getFilename(PatchName); } - catch (NLMISC::EWriteError) + catch (const NLMISC::EWriteError &) { throw; } @@ -3027,7 +3027,7 @@ void CPatchThread::xDeltaPatch(const string &patch, const string &src, const str } - // Launching xdelta.exe + // Launching xdelta /* STARTUPINFO si; PROCESS_INFORMATION pi; @@ -3139,7 +3139,7 @@ void CScanDataThread::run () CheckOk = true; Ended = true; } - catch (Exception &e) + catch (const Exception &e) { nlwarning("EXCEPTION CATCH: CScanDataThread::run() failed"); ucstring sTranslate = CI18N::get("uiCheckEndWithErr") + " " + e.what(); diff --git a/code/ryzom/client/src/login_progress_post_thread.cpp b/code/ryzom/client/src/login_progress_post_thread.cpp index 1c38fdd88..ad39de60d 100644 --- a/code/ryzom/client/src/login_progress_post_thread.cpp +++ b/code/ryzom/client/src/login_progress_post_thread.cpp @@ -220,7 +220,7 @@ public: if (StopWanted) break; } } - catch (std::exception &e) + catch (const std::exception &e) { nlwarning(e.what()); } diff --git a/code/ryzom/client/src/lua_ide_dll_nevrax/include/cj60/CJOutlookBar.h b/code/ryzom/client/src/lua_ide_dll_nevrax/include/cj60/CJOutlookBar.h index 0e1434c3b..69eed259a 100644 --- a/code/ryzom/client/src/lua_ide_dll_nevrax/include/cj60/CJOutlookBar.h +++ b/code/ryzom/client/src/lua_ide_dll_nevrax/include/cj60/CJOutlookBar.h @@ -76,10 +76,12 @@ protected: public: CContentItems( UINT nID, CString str ) : - m_nImageID( nID ), m_csText( str ) { + m_nImageID( nID ), m_csText( str ) + { } - void operator = ( CContentItems& pItems ) { + void operator = ( CContentItems& pItems ) + { m_nImageID = pItems.m_nImageID; m_csText = pItems.m_csText; } diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index f8ff5ae89..81a63ae60 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -700,9 +700,6 @@ void updateFromClientCfg() //--------------------------------------------------- if (Landscape) { -#ifdef NL_OS_MAC - Landscape->enableVegetable(false); -#else if (ClientCfg.MicroVeget != LastClientCfg.MicroVeget) { if(ClientCfg.MicroVeget) @@ -722,7 +719,6 @@ void updateFromClientCfg() Landscape->enableVegetable(false); } } -#endif } //--------------------------------------------------- @@ -854,7 +850,7 @@ void updateFromClientCfg() { SoundMngr->init(NULL); } - catch(Exception &e) + catch(const Exception &e) { nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); SoundMngr = 0; @@ -3781,7 +3777,7 @@ void updateMovieShooting() { MovieShooter.replayMovie(Driver, TextContext); } - catch (Exception &e) + catch (const Exception &e) { Driver->systemMessageBox(e.what(), "MovieShooter"); } @@ -3819,7 +3815,7 @@ void updateMovieShooting() // Save the movie. MovieShooter.saveMovie(Driver, TextContext, theDir.c_str(), ClientCfg.MovieShooterFramePeriod, ClientCfg.MovieShooterBlend, ClientCfg.MovieShooterPrefix.c_str()); } - catch (Exception &e) + catch (const Exception &e) { Driver->systemMessageBox(e.what(), "MovieShooter"); } diff --git a/code/ryzom/client/src/motion/user_controls.cpp b/code/ryzom/client/src/motion/user_controls.cpp index 8b20ae026..7ce5523b2 100644 --- a/code/ryzom/client/src/motion/user_controls.cpp +++ b/code/ryzom/client/src/motion/user_controls.cpp @@ -619,6 +619,7 @@ void CUserControls::commonMove() // MOUSE WHEEL // CEventsListener::TWheelState wheelState = EventsListener.getWheelState(); // Done all the time, to reset the state View.changeCameraDist((wheelState == CEventsListener::foreward), (wheelState == CEventsListener::backward)); + View.changeCameraDist(Actions.valide("camera_foreward"), Actions.valide("camera_backward")); // Camera Up/Down. View.changeCameraHeight(Actions.valide("camera_up"), Actions.valide("camera_down")); ////////////////// diff --git a/code/ryzom/client/src/net_manager.cpp b/code/ryzom/client/src/net_manager.cpp index 608eae45b..29a5a0e37 100644 --- a/code/ryzom/client/src/net_manager.cpp +++ b/code/ryzom/client/src/net_manager.cpp @@ -168,7 +168,7 @@ void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse) IngameDbMngr.setInitPacketReceived(); nlinfo( "DB_INIT:PLR done (%u bytes)", impulse.getPos()-p ); } - catch (Exception &e) + catch (const Exception &e) { BOMB( NLMISC::toString( "Problem while decoding a DB_INIT:PLR msg, skipped: %s", e.what() ), return ); } @@ -185,7 +185,7 @@ void impulseDatabaseUpdatePlayer(NLMISC::CBitMemStream &impulse) // read delta IngameDbMngr.readDelta( serverTick, impulse, CDBPlayer ); // unlike on the server, here there is only one unified CCDBSynchronized object } - catch (Exception &e) + catch (const Exception &e) { BOMB( NLMISC::toString( "Problem while decoding a DB_UPDATE_PLR msg, skipped: %s", e.what() ), return ); @@ -218,7 +218,7 @@ void impulseDatabaseUpdateBank(NLMISC::CBitMemStream &impulse) updateInventoryFromStream( impulse, (INVENTORIES::CInventoryCategoryForGuild*)NULL, false ); } } - catch (Exception &e) + catch (const Exception &e) { BOMB( NLMISC::toString( "Problem while decoding a DB_GROUP:UPDATE_BANK %s msg, skipped: %s", CDBBankNames[bank], e.what() ), return ); } @@ -248,7 +248,7 @@ void impulseDatabaseInitBank(NLMISC::CBitMemStream &impulse) updateInventoryFromStream( impulse, (INVENTORIES::CInventoryCategoryForGuild*)NULL, false ); } } - catch (Exception &e) + catch (const Exception &e) { BOMB( NLMISC::toString( "Problem while decoding a DB_GROUP:INIT_BANK %s msg, skipped: %s", CDBBankNames[bank], e.what() ), return ); } @@ -272,7 +272,7 @@ void impulseDatabaseResetBank(NLMISC::CBitMemStream &impulse) IngameDbMngr.getNodePtr()->resetBank( serverTick, (TCDBBank)bank ); nldebug( "CDB: DB_GROUP:RESET_BANK %s", CDBBankNames[bank] ); } - catch (Exception &e) + catch (const Exception &e) { BOMB( NLMISC::toString( "Problem while decoding a DB_GROUP:RESET_BANK %s msg, skipped: %s", CDBBankNames[bank], e.what() ), return ); } @@ -286,7 +286,7 @@ static void readPrivileges(NLMISC::CBitMemStream &impulse) { impulse.serial(UserPrivileges); } - catch(EStreamOverflow &) + catch(const EStreamOverflow &) { nlwarning("User privileges not serialised, assuming none"); UserPrivileges = ""; @@ -345,7 +345,7 @@ void copyKeySet(const std::string &srcPath, const std::string &destPath) COFile ofile(destPath); ofile.serialBuffer((uint8 *) &srcStr[0], (uint)srcStr.size()); } - catch(EStream &) + catch(const EStream &) { nlwarning("Couldn't copy %s to %s to create new character keyset", srcPath.c_str(), destPath.c_str()); } @@ -805,27 +805,35 @@ void CInterfaceChatDisplayer::displayChat(TDataSetIndex compressedSenderIndex, c else { ucstring::size_type index = finalString.find(ucstring("")); - if (index != ucstring::npos) { + if (index != ucstring::npos) + { bubbleWanted = false; finalString = finalString.substr(index+6,finalString.size()); ucstring::size_type index2 = finalString.find(ucstring(" ")); ucstring playerName; - if (index2 < (finalString.size()-3)) { + if (index2 < (finalString.size()-3)) + { playerName = finalString.substr(0,index2); finalString = finalString.substr(index2+1,finalString.size()); } if (!senderName.empty()) { CEntityCL *senderEntity = EntitiesMngr.getEntityByName (CEntityCL::removeTitleAndShardFromName(senderName), true, true); - if (senderEntity) { - if (senderEntity->Type != CEntityCL::Player) { - if (playerName.empty()) { + if (senderEntity) + { + if (senderEntity->Type != CEntityCL::Player) + { + if (playerName.empty()) + { senderEntity->removeStateFx(); senderEntity->setStateFx(finalString.toString()); nlinfo("empty"); - } else { + } + else + { CEntityCL *destEntity = EntitiesMngr.getEntityByName (CEntityCL::removeTitleAndShardFromName(playerName), false, true); - if (destEntity) { + if (destEntity) + { destEntity->removeStateFx(); destEntity->setStateFx(finalString.toString()); nlinfo("no empty"); @@ -895,6 +903,7 @@ void CInterfaceChatDisplayer::displayTell(/*TDataSetIndex senderIndex, */const u colorizeSender(finalString, senderPart, prop.getRGBA()); PeopleInterraction.ChatInput.Tell.displayTellMessage(/*senderIndex, */finalString, goodSenderName, prop.getRGBA(), 2, &windowVisible); + CInterfaceManager::getInstance()->log(finalString); // Open the free teller window CChatGroupWindow *pCGW = PeopleInterraction.getChatGroupWindow(); @@ -1559,7 +1568,7 @@ void impulseTPCommon2(NLMISC::CBitMemStream &impulse, bool hasSeason) } } - catch (EStream &) + catch (const EStream &) { tpReason = ucstring("TP Reason"); tpCancelText = ucstring("Cancel TP"); // for test @@ -2227,7 +2236,7 @@ void impulseCounter(NLMISC::CBitMemStream &impulse) } } } - catch (Exception &e) + catch (const Exception &e) { nlwarning ("Problem while decoding a COUTNER msg, skipped: %s", e.what()); } @@ -2812,7 +2821,7 @@ void updateInventoryFromStream (NLMISC::CBitMemStream &impulse, const CInventory CInventoryManager::getInstance()->sortBag(); } - catch ( Exception &e ) + catch (const Exception &e) { nlwarning ("Problem while decoding a DB_UPD_INV msg, skipped: %s", e.what()); } @@ -3216,9 +3225,13 @@ private: // get the content string (should have been received!) ucstring contentStr; + ucstring titleStr; if(!pSMC->getDynString(_TextId[ContentType], contentStr)) return; + if(!pSMC->getDynString(_TextId[TitleType], titleStr)) + return; + // if the string start with a @{Wxxxx} code, remove it and get the wanted window size sint w = 256; // default size to 256 !! bool is_webig = false; @@ -3273,23 +3286,36 @@ private: if (is_webig) { - CGroupHTML *groupHtml = dynamic_cast(pIM->getElementFromId("ui:interface:webig:content:html")); + CGroupHTML *groupHtml; + string group = titleStr.toString(); + // + group = group.substr(9, group.size()-10); + nlinfo("group = %s", group.c_str()); + groupHtml = dynamic_cast(pIM->getElementFromId("ui:interface:"+group+":content:html")); + if (!groupHtml) + { + groupHtml = dynamic_cast(pIM->getElementFromId("ui:interface:webig:content:html")); + group = "webig"; + } + if (groupHtml) { - - CGroupContainer *pGC = dynamic_cast(pIM->getElementFromId("ui:interface:webig")); - - if (contentStr.empty()) + CGroupContainer *pGC = dynamic_cast(pIM->getElementFromId("ui:interface:"+group)); + if (pGC) { - pGC->setActive(false); - } - else - { - pGC->setActive(true); - string url = contentStr.toString(); - addWebIGParams(url); - groupHtml->browse(url.c_str()); - pIM->setTopWindow(pGC); + if (contentStr.empty()) + { + pGC->setActive(false); + } + else + { + if (group == "webig") + pGC->setActive(true); + string url = contentStr.toString(); + addWebIGParams(url); + groupHtml->browse(url.c_str()); + pIM->setTopWindow(pGC); + } } } } diff --git a/code/ryzom/client/src/network_connection.cpp b/code/ryzom/client/src/network_connection.cpp index fe1216b64..f633126e5 100644 --- a/code/ryzom/client/src/network_connection.cpp +++ b/code/ryzom/client/src/network_connection.cpp @@ -141,7 +141,7 @@ void initReceiveLog() ReceiveLogger.displayNL( "LogReceive is on" ); // only when enabled } } - catch ( EConfigFile& ) + catch (const EConfigFile&) {} } @@ -616,7 +616,7 @@ bool CNetworkConnection::connect(string &result) nlinfo ("Can't copy, same path '%s'", arg1.c_str()); } } - catch (Exception &) + catch (const Exception &) { nlwarning ("Can't copy '%s' '%s', try the next file", arg1.c_str(), dstPath.c_str()); } @@ -624,7 +624,7 @@ bool CNetworkConnection::connect(string &result) break; } } - catch (Exception &e) + catch (const Exception &e) { nlwarning (e.what ()); } @@ -635,7 +635,7 @@ bool CNetworkConnection::connect(string &result) } } } - catch (Exception &) + catch (const Exception &) { nlinfo ("There's no shards.cfg, or bad file format, can't copy common files"); } @@ -654,7 +654,7 @@ bool CNetworkConnection::connect(string &result) // _Connection.connect (CInetAddress(_FrontendAddress)); } - catch (ESocket &e) + catch (const ESocket &e) { result = toString ("FS refused the connection (%s)", e.what()); return false; @@ -847,7 +847,7 @@ bool CNetworkConnection::update() } while (stateBroke);// && _TotalMessages<5); } - catch (ESocket &) + catch (const ESocket &) { _ConnectionState = Disconnect; } @@ -968,7 +968,7 @@ void CNetworkConnection::sendSystemLogin() //sendUDP (&(_Connection), message.buffer(), length); _Connection.send( message.buffer(), length ); } - catch ( ESocket& e ) + catch (const ESocket &e) { #ifdef NL_OS_WINDOWS // An exception (10004: Blocking operation interrupted) may occur if a firewall such as Kerio is @@ -1123,7 +1123,7 @@ void CNetworkConnection::receiveSystemSync(CBitMemStream &msgin) if(xmlInvalid) xmlInvalid = (checkMsgXml != _AltMsgXmlMD5 || checkDatabaseXml != _AltDatabaseXmlMD5); } - catch (NLMISC::Exception&) + catch (const NLMISC::Exception&) { } @@ -1720,7 +1720,7 @@ void CNetworkConnection::decodeVisualProperties( CBitMemStream& msgin ) } } } - catch ( EStreamOverflow& ) + catch (const EStreamOverflow&) { // End of stream (saves useless bits) } @@ -2708,7 +2708,7 @@ void CNetworkConnection::send(TGameCycle cycle) sendNormalMessage(); } } - catch (ESocket &/*e*/) + catch (const ESocket &/*e*/) { _ConnectionState = Disconnect; disconnect(); // won't send disconnection message as state is already Disconnect @@ -2732,7 +2732,7 @@ void CNetworkConnection::send() sendNormalMessage(); } } - catch (ESocket &/*e*/) + catch (const ESocket &/*e*/) { _ConnectionState = Disconnect; } diff --git a/code/ryzom/client/src/pacs_client.cpp b/code/ryzom/client/src/pacs_client.cpp index 16147f0f9..4dc7d7535 100644 --- a/code/ryzom/client/src/pacs_client.cpp +++ b/code/ryzom/client/src/pacs_client.cpp @@ -243,7 +243,7 @@ void initPrimitiveBlocks() { addPacsPrim(primFile); } - catch (NLMISC::Exception &) + catch (const NLMISC::Exception &) { nlwarning("Error while loading %s", primFile.c_str()); } diff --git a/code/ryzom/client/src/permanent_ban.cpp b/code/ryzom/client/src/permanent_ban.cpp index 032a5ffaa..ba1ce4188 100644 --- a/code/ryzom/client/src/permanent_ban.cpp +++ b/code/ryzom/client/src/permanent_ban.cpp @@ -87,7 +87,7 @@ static void setPermanentBanFileMarker(const std::string &path, bool on) SetFileAttributes(path.c_str(), FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM); #endif } - catch(EStream &e) + catch(const EStream &e) { nlinfo(e.what()); } diff --git a/code/ryzom/client/src/prim_file.cpp b/code/ryzom/client/src/prim_file.cpp index c9839956e..e1959aabd 100644 --- a/code/ryzom/client/src/prim_file.cpp +++ b/code/ryzom/client/src/prim_file.cpp @@ -167,7 +167,7 @@ void CPrimFileMgr::load (sint primFileIndex) } } - catch (Exception &e) + catch (const Exception &e) { // Error nlwarning ("Error while reading the prim file (%s) : %s", pathName.c_str(), e.what ()); diff --git a/code/ryzom/client/src/r2/displayer_visual_entity.cpp b/code/ryzom/client/src/r2/displayer_visual_entity.cpp index f8f6bfd9d..20f84c90f 100644 --- a/code/ryzom/client/src/r2/displayer_visual_entity.cpp +++ b/code/ryzom/client/src/r2/displayer_visual_entity.cpp @@ -986,7 +986,7 @@ void CDisplayerVisualEntity::updateName() } std::string firstPart = ""; if(actNb>0) - firstPart = CI18N::get("uiR2EDDefaultActTitle").toString() + " " + actNb; + firstPart = CI18N::get("uiR2EDDefaultActTitle").toString() + " " + NLMISC::toString(actNb); if (act->isString("Name")) actName = act->toString("Name"); diff --git a/code/ryzom/client/src/r2/dmc/com_lua_module.cpp b/code/ryzom/client/src/r2/dmc/com_lua_module.cpp index b4f6de3a4..69223a2ae 100644 --- a/code/ryzom/client/src/r2/dmc/com_lua_module.cpp +++ b/code/ryzom/client/src/r2/dmc/com_lua_module.cpp @@ -1359,7 +1359,7 @@ CObject* CComLuaModule::loadFromBuffer(const std::string& data, const std::strin } } } - catch(ELuaError &e) + catch(const ELuaError &e) { nlwarning("%s", e.what()); } diff --git a/code/ryzom/client/src/r2/editor.cpp b/code/ryzom/client/src/r2/editor.cpp index a068af182..0de8bc626 100644 --- a/code/ryzom/client/src/r2/editor.cpp +++ b/code/ryzom/client/src/r2/editor.cpp @@ -1706,7 +1706,7 @@ void CEditor::waitScenarioScreen() if ( ! firewallTimeout ) NetMngr.update(); } - catch ( EBlockedByFirewall& ) + catch (const EBlockedByFirewall&) { if ( NetMngr.getConnectionState() == CNetManager::Disconnect ) { @@ -4414,11 +4414,11 @@ bool CEditor::doLuaScript(const char *filename, const char *fileDescText) CLuaStackChecker ls(&getLua()); return true; } - catch(NLMISC::EStream &e) + catch(const NLMISC::EStream &e) { nlwarning("Error while loading R2 %s (file = %s) : %s", fileDescText, filename, e.what()); } - catch(ELuaError &e) + catch(const ELuaError &e) { //char filename[MAX_PATH]; std::string msg = e.what(); @@ -5038,7 +5038,7 @@ void CEditor::onErase(CObject *root, bool &foundInBase, std::string &nameInParen { (*inst).getLuaProjection()["User"].setValue("Erased", true); } - catch (ELuaNotATable &e) + catch (const ELuaNotATable &e) { nlwarning(e.what()); } diff --git a/code/ryzom/client/src/r2/island_collision.cpp b/code/ryzom/client/src/r2/island_collision.cpp index eecddb642..b096a4255 100644 --- a/code/ryzom/client/src/r2/island_collision.cpp +++ b/code/ryzom/client/src/r2/island_collision.cpp @@ -419,7 +419,7 @@ CPackedWorld *CIslandCollision::reloadPackedIsland(const CScenarioEntryPoints::C _PackedIslandName = islandDesc.Island; _IslandDesc = islandDesc; } - catch (Exception &) + catch (const Exception &) { _PackedIslandLoadingFailure = true; } @@ -432,7 +432,7 @@ CPackedWorld *CIslandCollision::reloadPackedIsland(const CScenarioEntryPoints::C f.serialCheck((uint32) 'MHSI'); f.serial(_HeightMap); } - catch(Exception &e) + catch(const Exception &e) { nlwarning(e.what()); _HeightMap.clear(); @@ -572,7 +572,7 @@ void CIslandCollision::loadEntryPoints() { sep.loadCompleteIslands(); } - catch (NLMISC::EStream &e) + catch (const NLMISC::EStream &e) { _EntryPointsLoadingFailure = true; nlwarning(e.what()); diff --git a/code/ryzom/client/src/r2/tool_select_move.cpp b/code/ryzom/client/src/r2/tool_select_move.cpp index 1ad9fd797..6bbbe75ee 100644 --- a/code/ryzom/client/src/r2/tool_select_move.cpp +++ b/code/ryzom/client/src/r2/tool_select_move.cpp @@ -369,7 +369,7 @@ void CToolSelectMove::commitAction(CInstance &instance) pos.setValue("y", _FinalPos.y); pos.setValue("z", _FinalPos.z); } - catch(ELuaNotATable &) + catch(const ELuaNotATable &) { nlwarning("Error while setting position of copied object"); } diff --git a/code/ryzom/client/src/session_browser_impl.cpp b/code/ryzom/client/src/session_browser_impl.cpp index 4f39db901..c5ddb8f47 100644 --- a/code/ryzom/client/src/session_browser_impl.cpp +++ b/code/ryzom/client/src/session_browser_impl.cpp @@ -427,7 +427,7 @@ void CSessionBrowserImpl::fill(const std::vector &session // call into lua callRingAccessPointMethod("onSessionListReceived", 1, 0); } - catch(ELuaError &) + catch(const ELuaError &) { // no-op (error msg already printed at exception launch) } @@ -454,7 +454,7 @@ void CSessionBrowserImpl::playerRatingFill(bool scenarioRated, uint32 rateFun, u // call into lua callScenarioScoresMethod("onScenarioScoresReceived", 1, 0); } - catch(ELuaError &) + catch(const ELuaError &) { // no-op (error msg already printed at exception launch) } @@ -482,7 +482,7 @@ void CSessionBrowserImpl::averageScoresFill(bool scenarioRated, uint32 rateFun, // call into lua callScenarioScoresMethod("onAverageScoresReceived", 1, 0); } - catch(ELuaError &) + catch(const ELuaError &) { // no-op (error msg already printed at exception launch) } @@ -573,7 +573,7 @@ void CSessionBrowserImpl::on_scenarioAverageScores(NLNET::TSockId /* from */, bo // call into lua callScenarioScoresMethod("onScenarioAverageScoresReceived", 1, 0); } - catch(ELuaError &) + catch(const ELuaError &) { // no-op (error msg already printed at exception launch) } @@ -647,7 +647,7 @@ void CSessionBrowserImpl::charsFill(const std::vector &chars // call into lua callRingCharTrackingMethod("onCharsListReceived", 1, 0); } - catch(ELuaError &) + catch(const ELuaError &) { // no-op (error msg already printed at exception launch) } @@ -706,7 +706,7 @@ void CSessionBrowserImpl::ringStatsFill() pSM->tryToUnblockTitleFromRingRatings( _LastAuthorRating, _LastAMRating, _LastMasterlessRating ); } } - catch(ELuaError &) + catch(const ELuaError &) { // no-op (error msg already printed at exception launch) } diff --git a/code/ryzom/client/src/sky.cpp b/code/ryzom/client/src/sky.cpp index 560cf7313..aedee24ce 100644 --- a/code/ryzom/client/src/sky.cpp +++ b/code/ryzom/client/src/sky.cpp @@ -305,7 +305,7 @@ CBitmap *buildSharedBitmap(const std::string &filename, // dump bitmap fisrt line return builtBitmaps.back(); } - catch(EStream &) + catch(const EStream &) { return NULL; } diff --git a/code/ryzom/client/src/sound_manager.cpp b/code/ryzom/client/src/sound_manager.cpp index 762eeb298..fb4b3708f 100644 --- a/code/ryzom/client/src/sound_manager.cpp +++ b/code/ryzom/client/src/sound_manager.cpp @@ -512,7 +512,7 @@ void CSoundManager::init(IProgressCallback *progressCallBack) _AudioMixer->enableBackgroundMusicTimeConstraint(ClientCfg.EnableBackgroundMusicTimeConstraint); /* } - catch( Exception& e ) + catch(const Exception &e) { nlwarning( "Error: %s", e.what() ); } @@ -1732,7 +1732,7 @@ void CSoundManager::updateEventAndGameMusicVolume() materials.push_back( cvMaterials.asInt(i) ); } } - catch (EConfigFile &e) + catch (const EConfigFile &e) { nlerror("Problem in the file %s : %s", fileName,e.what ()); } @@ -1786,7 +1786,7 @@ void CSoundManager::updateEventAndGameMusicVolume() } _Sounds.insert( make_pair( make_pair(moveType,soft), sounds) ); } - catch (EConfigFile &e) + catch (const EConfigFile &e) { nlwarning("Problem in the sounds by material config file : %s", e.what ()); } diff --git a/code/ryzom/client/src/stdpch.h b/code/ryzom/client/src/stdpch.h index fdb16ef93..48c1a3c06 100644 --- a/code/ryzom/client/src/stdpch.h +++ b/code/ryzom/client/src/stdpch.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/code/ryzom/client/src/string_manager_client.cpp b/code/ryzom/client/src/string_manager_client.cpp index e46895368..40886d518 100644 --- a/code/ryzom/client/src/string_manager_client.cpp +++ b/code/ryzom/client/src/string_manager_client.cpp @@ -175,7 +175,7 @@ namespace STRING_MANAGER _CacheLoaded = true; } - catch(NLMISC::Exception &e) + catch(const NLMISC::Exception &e) { nlinfo("SM : loadCache failed, exception : %s", e.what()); nlinfo("SM : cache deactivated"); @@ -620,7 +620,7 @@ restartLoop: { dynInfo.Message.serial(param.StringId); } - catch(Exception &) + catch(const Exception &) { param.StringId = EmptyStringId; } @@ -631,7 +631,7 @@ restartLoop: { dynInfo.Message.serial(param.Integer); } - catch(Exception &) + catch(const Exception &) { param.Integer= 0; } @@ -642,7 +642,7 @@ restartLoop: { dynInfo.Message.serial(param.Time); } - catch(Exception &) + catch(const Exception &) { param.Time= 0; } @@ -653,7 +653,7 @@ restartLoop: { dynInfo.Message.serial(param.Money); } - catch(Exception &) + catch(const Exception &) { param.Money= 0; } @@ -664,7 +664,7 @@ restartLoop: { dynInfo.Message.serial(param.DynStringId); } - catch(Exception &) + catch(const Exception &) { param.DynStringId= EmptyDynStringId; } @@ -1206,15 +1206,15 @@ void CStringManagerClient::initI18NSpecialWords(const std::string &languageCode) continue; // Get the women name index if possible. - uint womenNameColIndex; + uint womenNameColIndex = std::numeric_limits::max(); if( !ws.findCol(womenNameColIdent, womenNameColIndex) ) womenNameColIndex= std::numeric_limits::max(); // Get the description index if possible. - uint descColIndex; + uint descColIndex = std::numeric_limits::max(); if( !ws.findCol(descColIdent, descColIndex) ) descColIndex= std::numeric_limits::max(); - uint descColIndex2; + uint descColIndex2 = std::numeric_limits::max(); if( !ws.findCol(descColIdent2, descColIndex2) ) descColIndex2= std::numeric_limits::max(); @@ -1225,9 +1225,8 @@ void CStringManagerClient::initI18NSpecialWords(const std::string &languageCode) const ucstring &key= ws.getData(j, keyColIndex); const ucstring &name= ws.getData(j, nameColIndex); // Append to the I18N. - string keyStr= key.toString(); // avoid case problems - strlwr(keyStr); + string keyStr= NLMISC::toLower(key.toString()); // append the special key extension. keyStr+= keyExtenstion; @@ -1424,6 +1423,9 @@ const ucchar * CStringManagerClient::getSpecialWord(const std::string &label, bo map::iterator it = _SpecItem_TempMap.find(lwrLabel); if (it != _SpecItem_TempMap.end()) { + if( UseFemaleTitles && women ) + if (!it->second.WomenName.empty()) + return it->second.WomenName.c_str(); return it->second.Name.c_str(); } } @@ -1641,8 +1643,6 @@ const ucchar *CStringManagerClient::getSquadLocalizedDescription(NLMISC::CSheetI // *************************************************************************** void CStringManagerClient::replaceSBrickName(NLMISC::CSheetId id, const ucstring &name, const ucstring &desc, const ucstring &desc2) { - nlassert(!_SpecItem_MemoryCompressed); - std::string label= id.toString(); if (label.empty()) { @@ -1654,14 +1654,57 @@ void CStringManagerClient::replaceSBrickName(NLMISC::CSheetId id, const ucstrin lwrLabel= label; strlwr(lwrLabel); - map::iterator it(_SpecItem_TempMap.find(lwrLabel)); - if (it == _SpecItem_TempMap.end()) - return; + if (_SpecItem_MemoryCompressed) + { + ucchar *strName = (ucchar *)name.c_str(); + ucchar *strDesc = (ucchar *)desc.c_str(); + ucchar *strDesc2 = (ucchar *)desc2.c_str(); + CItemLight tmp; + tmp.Label = (char*)lwrLabel.c_str(); + vector::iterator it = lower_bound(_SpecItems.begin(), _SpecItems.end(), tmp, CItemLightComp()); - // Then replace - it->second.Name= name; - it->second.Desc= desc; - it->second.Desc2= desc2; + if (it != _SpecItems.end()) + { + if (strcmp(it->Label, lwrLabel.c_str()) == 0) + { + it->Name = strName; + it->Desc = strDesc; + it->Desc2 = strDesc2; + } + else + { + it->Label = tmp.Label; + it->Name = strName; + it->Desc = strDesc; + it->Desc2 = strDesc2; + } + } + else + { + tmp.Name = strName; + tmp.Desc = strDesc; + tmp.Desc2 = strDesc2; + _SpecItems.push_back(tmp); + } + } + else + { + map::iterator it(_SpecItem_TempMap.find(lwrLabel)); + if (it != _SpecItem_TempMap.end()) + { + it->second.Name= name; + it->second.Desc= desc; + it->second.Desc2= desc2; + } + else + { + CItem newItem; + newItem.Name = name; + newItem.Desc = desc; + newItem.Desc2 = desc2; + _SpecItem_TempMap.insert(pair(lwrLabel,newItem)); + } + } } diff --git a/code/ryzom/client/src/user_entity.cpp b/code/ryzom/client/src/user_entity.cpp index a5c016f34..64a493d2e 100644 --- a/code/ryzom/client/src/user_entity.cpp +++ b/code/ryzom/client/src/user_entity.cpp @@ -361,7 +361,8 @@ bool CUserEntity::build(const CEntitySheet *sheet) // virtual CInterfaceManager *pIM = CInterfaceManager::getInstance(); { CCDBNodeLeaf *node = pIM->getDbProp("SERVER:USER:IS_INVISIBLE", false); - if (node) { + if (node) + { ICDBNode::CTextId textId; node->addObserver(&_InvisibleObs, textId); } diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml index be7ce1beb..1e4f9d723 100644 --- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml +++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml @@ -688,12 +688,15 @@ + + + @@ -835,11 +838,20 @@ + + + + + + + + + @@ -852,6 +864,7 @@ + @@ -1007,6 +1020,7 @@ + @@ -1019,6 +1033,7 @@ + @@ -1093,6 +1108,8 @@ + + @@ -1106,6 +1123,9 @@ + + + @@ -1115,7 +1135,9 @@ - + + + @@ -1124,24 +1146,34 @@ + + + + - + + + - + + + - + + + @@ -1150,20 +1182,27 @@ + + + - + + + - + + + @@ -1173,7 +1212,9 @@ - + + + @@ -1182,7 +1223,9 @@ - + + + @@ -1190,7 +1233,9 @@ - + + + @@ -1198,26 +1243,35 @@ - + + + - + + + - + + + + + + @@ -1250,13 +1304,18 @@ + + + - + + + diff --git a/code/ryzom/common/src/game_share/action_nature.cpp b/code/ryzom/common/src/game_share/action_nature.cpp index 04d8fc132..456cfcbc1 100644 --- a/code/ryzom/common/src/game_share/action_nature.cpp +++ b/code/ryzom/common/src/game_share/action_nature.cpp @@ -38,6 +38,7 @@ namespace ACTNATURE NL_STRING_CONVERSION_TABLE_ENTRY(DODGE) NL_STRING_CONVERSION_TABLE_ENTRY(PARRY) NL_STRING_CONVERSION_TABLE_ENTRY(SHIELD_USE) + NL_STRING_CONVERSION_TABLE_ENTRY(RECHARGE) NL_END_STRING_CONVERSION_TABLE(TActionNature, ActionNatureConversion, UNKNOWN) diff --git a/code/ryzom/common/src/game_share/action_nature.h b/code/ryzom/common/src/game_share/action_nature.h index 36494b1ff..333656101 100644 --- a/code/ryzom/common/src/game_share/action_nature.h +++ b/code/ryzom/common/src/game_share/action_nature.h @@ -35,6 +35,7 @@ namespace ACTNATURE DODGE, PARRY, SHIELD_USE, + RECHARGE, NEUTRAL, //only for multi effect on spell,progression consider it as OFFENSIVE_MAGIC diff --git a/code/ryzom/common/src/game_share/character_sync_itf.h b/code/ryzom/common/src/game_share/character_sync_itf.h index 728104322..459659732 100644 --- a/code/ryzom/common/src/game_share/character_sync_itf.h +++ b/code/ryzom/common/src/game_share/character_sync_itf.h @@ -21,9 +21,7 @@ #ifndef CHARACTER_SYNC_ITF #define CHARACTER_SYNC_ITF #include "nel/misc/types_nl.h" -#if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) -# include -#endif +#include #include "nel/misc/hierarchical_timer.h" #include "nel/misc/string_conversion.h" #include "nel/net/message.h" @@ -1139,12 +1137,12 @@ namespace CHARSYNC } // - ucstring getFullName() const + const ucstring& getFullName() const { return _FullName; } - void setFullName(ucstring value) + void setFullName(const ucstring &value) { _FullName = value; diff --git a/code/ryzom/common/src/game_share/magic_fx.h b/code/ryzom/common/src/game_share/magic_fx.h index df1d927ad..1d1df3bc4 100644 --- a/code/ryzom/common/src/game_share/magic_fx.h +++ b/code/ryzom/common/src/game_share/magic_fx.h @@ -133,6 +133,9 @@ namespace MAGICFX WaterWall = 11, ThornWall = 12, LightningWall = 13, + OtherFireWall = 14, + TeleportKami = 15, // No effect aura + TeleportKara = 16, // No effect aura }; } diff --git a/code/ryzom/common/src/game_share/mirror.cpp b/code/ryzom/common/src/game_share/mirror.cpp index 31304614b..1e025a30d 100644 --- a/code/ryzom/common/src/game_share/mirror.cpp +++ b/code/ryzom/common/src/game_share/mirror.cpp @@ -634,7 +634,7 @@ void CMirror::receiveTracker( bool entitiesOrProp, NLNET::CMessage& msgin ) ++nbSent; } } - catch( EMirror& ) + catch(const EMirror& ) { nlwarning( "MIRROR:ROWMGT:ATE> Invalid dataset name %s for adding tracker", name.c_str() ); } @@ -752,7 +752,7 @@ void CMirror::receiveAcknowledgeAddEntityTracker( NLNET::CMessage& msgin, TSe } } - catch( EMirror& ) + catch(const EMirror& ) { nlwarning( "MIRROR: Invalid dataset name %s for receiving ack of addEntityTracker", datasetname.c_str() ); } @@ -1043,7 +1043,7 @@ void cbAllMirrorsOnline( NLNET::CMessage& msgin, const std::string &/* serviceNa msgin.serial( versionStr ); hasVersion = true; } - catch ( EStreamOverflow& ) + catch (const EStreamOverflow&) {} if ( (! hasVersion) || (MirrorVersion != versionStr) ) nlerror( "Mirror version mismatch! This service: %s; Local MS: %s", MirrorVersion.c_str(), versionStr.c_str() ); @@ -1174,7 +1174,7 @@ void CMirror::receiveServiceHasMirrorReady( const std::string& serviceName, TSer } } } - catch ( EStreamOverflow& ) + catch (const EStreamOverflow&) { nlwarning( "Received SMIRU from old version service %s-%hu", serviceName.c_str(), serviceId.get() ); } @@ -2484,7 +2484,7 @@ NLMISC_CATEGORISED_COMMAND(mirror, displayMirrorRow, "Display the contents of th return true; } } - catch ( EMirror& ) + catch (const EMirror&) { log.displayNL( "Dataset not found" ); return true; @@ -2682,7 +2682,7 @@ NLMISC_CATEGORISED_COMMAND(mirror, displayMirrorEntities, "Display all of part o } } } - catch ( EMirror& ) + catch (const EMirror&) { log.displayNL( "Dataset not found" ); } @@ -2727,7 +2727,7 @@ NLMISC_COMMAND( lookForMirrorValue, "Look for values with criteria (Value can be } MirrorInstance->getDataSet( args[0] ).lookForValue( log, propName, anyValue, valueSearchedStr, onlyEntityType, onlyCreatorId, onlyDynamicId, false, true, false, true ); } - catch ( EMirror& ) + catch (const EMirror&) { log.displayNL( "Dataset not found" ); } @@ -2747,7 +2747,7 @@ NLMISC_CATEGORISED_COMMAND(mirror, displayMirrorTrackers, "Display the trackers { MirrorInstance->getDataSet( args[0] ).displayTrackers( log ); } - catch ( EMirror& ) + catch (const EMirror&) { log.displayNL( "Dataset not found" ); } @@ -2794,7 +2794,7 @@ NLMISC_CATEGORISED_COMMAND(mirror, rescanExistingEntities, "Scan the entities to CMirroredDataSet& dataset = MirrorInstance->getDataSet( args[0] ); MirrorInstance->rescanExistingEntities( dataset, log, true ); } - catch ( EMirror& ) + catch (const EMirror&) { log.displayNL( "Dataset not found" ); } @@ -2815,7 +2815,7 @@ NLMISC_CATEGORISED_COMMAND(mirror, displayUnknownOnlineEntities, "Scan the entit CMirroredDataSet& dataset = MirrorInstance->getDataSet( args[0] ); MirrorInstance->rescanExistingEntities( dataset, log, false ); } - catch ( EMirror& ) + catch (const EMirror&) { log.displayNL( "Dataset not found" ); } @@ -2844,7 +2844,7 @@ NLMISC_CATEGORISED_COMMAND(mirror, monitorMirrorEntity, "Set/unset an entity for else log.displayNL( "Invalid entity index provided" ); } - catch ( EMirror& ) + catch (const EMirror&) { log.displayNL( "Dataset not found" ); } @@ -2867,7 +2867,7 @@ NLMISC_CATEGORISED_DYNVARIABLE(mirror, sint32, MainNbEntities, "Number of online { *pointer = MirrorInstance->getDataSet( "fe_temp" ).getNbOnlineEntities(); } - catch ( EMirror& ) + catch (const EMirror&) { *pointer = -2; // silent } @@ -2888,7 +2888,7 @@ NLMISC_CATEGORISED_DYNVARIABLE(mirror, sint32, LocalEntities, "Number of online { *pointer = MirrorInstance->getDataSet( "fe_temp" ).getNbOwnedEntities(); } - catch ( EMirror& ) + catch (const EMirror&) { *pointer = -2; // silent } diff --git a/code/ryzom/common/src/game_share/mirror_prop_value.h b/code/ryzom/common/src/game_share/mirror_prop_value.h index 553c73b96..08e96761d 100644 --- a/code/ryzom/common/src/game_share/mirror_prop_value.h +++ b/code/ryzom/common/src/game_share/mirror_prop_value.h @@ -1022,14 +1022,14 @@ struct _CMirrorPropValueListIterator CMirrorPropValueList *_ParentList; TSharedListRow _Index; - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - // typedef typename std::forward_iterator_tag iterator_category; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + // typedef typename std::forward_iterator_tag iterator_category; }; @@ -1050,15 +1050,14 @@ struct _CCMirrorPropValueListIterator CMirrorPropValueList *_ParentList; TSharedListRow _Index; - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - // typedef typename std::forward_iterator_tag iterator_category; - + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + // typedef typename std::forward_iterator_tag iterator_category; }; @@ -1232,7 +1231,7 @@ class CMirrorPropValueList { public: - typedef CPropLocationUnpacked CPropLocationClass; + typedef CPropLocationUnpacked CPropLocationClass; typedef uint32 size_type; typedef _CMirrorPropValueListIterator iterator; diff --git a/code/ryzom/common/src/game_share/msg_ais_egs_gen.h b/code/ryzom/common/src/game_share/msg_ais_egs_gen.h index 99de7c001..d7bfc39e7 100644 --- a/code/ryzom/common/src/game_share/msg_ais_egs_gen.h +++ b/code/ryzom/common/src/game_share/msg_ais_egs_gen.h @@ -21,9 +21,7 @@ #ifndef MSG_AIS_EGS_GEN #define MSG_AIS_EGS_GEN #include "nel/misc/types_nl.h" -#if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) -# include -#endif +#include #include "nel/misc/hierarchical_timer.h" #include "nel/misc/string_conversion.h" #include "nel/net/message.h" diff --git a/code/ryzom/common/src/game_share/object.cpp b/code/ryzom/common/src/game_share/object.cpp index d15497ce4..908cc6e2a 100644 --- a/code/ryzom/common/src/game_share/object.cpp +++ b/code/ryzom/common/src/game_share/object.cpp @@ -1288,7 +1288,8 @@ void CObjectTable::clear() CHECK_TABLE_INTEGRITY TContainer::iterator first(_Value.begin()); TContainer::iterator last(_Value.end()); - for (; first != last ;++first) { + for (; first != last ;++first) + { delete first->second; } _Value.clear(); @@ -3044,7 +3045,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data, -- (serializer->Level); } uint endLength = stream.getPos(); - if (serializer->Log) { + if (serializer->Log) + { if (className.empty()) { nldebug("R2NET: (%u) Table sent %u bytes",serializer->Level, endLength - initLength); diff --git a/code/ryzom/common/src/game_share/object.h b/code/ryzom/common/src/game_share/object.h index 0f74d70fa..f4b292e2e 100644 --- a/code/ryzom/common/src/game_share/object.h +++ b/code/ryzom/common/src/game_share/object.h @@ -206,9 +206,8 @@ protected: uint32 _Validation; }; -/*inline std::ostream& operator<<( std::ostream& os, - const CObject& c ) { - +/*inline std::ostream& operator<<( std::ostream& os, const CObject& c ) +{ c.serialize(os); return os; }*/ diff --git a/code/ryzom/common/src/game_share/r2_modules_itf.h b/code/ryzom/common/src/game_share/r2_modules_itf.h index e8626cafd..d44f0ea5a 100644 --- a/code/ryzom/common/src/game_share/r2_modules_itf.h +++ b/code/ryzom/common/src/game_share/r2_modules_itf.h @@ -21,9 +21,7 @@ #ifndef R2_MODULES_ITF #define R2_MODULES_ITF #include "nel/misc/types_nl.h" -#if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) -# include -#endif +#include #include "nel/misc/hierarchical_timer.h" #include "nel/misc/string_conversion.h" #include "nel/net/message.h" diff --git a/code/ryzom/common/src/game_share/r2_share_itf.h b/code/ryzom/common/src/game_share/r2_share_itf.h index 0d2956089..4e2abdf10 100644 --- a/code/ryzom/common/src/game_share/r2_share_itf.h +++ b/code/ryzom/common/src/game_share/r2_share_itf.h @@ -21,9 +21,7 @@ #ifndef R2_SHARE_ITF #define R2_SHARE_ITF #include "nel/misc/types_nl.h" -#if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) -# include -#endif +#include #include "nel/misc/hierarchical_timer.h" #include "nel/misc/string_conversion.h" #include "nel/net/message.h" diff --git a/code/ryzom/common/src/game_share/time_weather_season/weather_predict.cpp b/code/ryzom/common/src/game_share/time_weather_season/weather_predict.cpp index 144b06036..6570e2600 100644 --- a/code/ryzom/common/src/game_share/time_weather_season/weather_predict.cpp +++ b/code/ryzom/common/src/game_share/time_weather_season/weather_predict.cpp @@ -580,7 +580,7 @@ void CPredictWeather::generateWeatherStats(const std::string &fileName, const CW outputFile.serial(output[n]); } } - catch (NLMISC::EStream &e) + catch (const NLMISC::EStream &e) { nlwarning(e.what()); } diff --git a/code/ryzom/server/data_shard/client_commands_privileges.txt b/code/ryzom/server/data_shard/client_commands_privileges.txt index 0ab0e8e9f..c61537dfa 100644 --- a/code/ryzom/server/data_shard/client_commands_privileges.txt +++ b/code/ryzom/server/data_shard/client_commands_privileges.txt @@ -15,10 +15,10 @@ addSkillPoints :DEV:SGM:GM:EM: // Add skill points of given type (Fight=0, M addXPToSkill :DEV:SGM:GM:EM: // Gain experience in the given skill: [] broadcast :DEV:SGM:GM:EM:VG: // Broadcast a message: [repeat= or during=