merge edubart-otclient

This commit is contained in:
Renato 2021-04-30 00:20:36 -03:00
commit 6327d87e16
41 changed files with 359 additions and 375 deletions

View file

@ -28,7 +28,7 @@ jobs:
fail-fast: false
max-parallel: 8
matrix:
name: [ubuntu-gcc, ubuntu-clang, macos-clang, windows-msvc]
name: [ubuntu-gcc, macos-clang, windows-msvc]
buildtype: [Debug, Release]
luajit: [on, off]
include:
@ -38,23 +38,15 @@ jobs:
cc: cl.exe
triplet: x64-windows
packages: >
boost-iostreams boost-asio boost-system boost-variant boost-lockfree luajit glew
boost-filesystem boost-uuid physfs openal-soft libogg libvorbis zlib opengl
boost-iostreams boost-asio boost-system boost-variant boost-lockfree boost-filesystem boost-uuid
glew luajit libogg libvorbis openal-soft opengl openssl physfs zlib
- name: ubuntu-gcc
os: ubuntu
cxx: g++
cc: gcc
triplet: x64-linux
packages: >
boost-iostreams boost-asio boost-system boost-variant boost-lockfree luajit glew
boost-filesystem boost-uuid physfs openal-soft libogg libvorbis zlib opengl
- name: ubuntu-clang
os: ubuntu
cxx: clang++
cc: clang
triplet: x64-linux
packages: >
boost-iostreams boost-asio boost-system boost-variant boost-lockfree luajit glew
boost-iostreams boost-asio boost-system boost-variant boost-lockfree glew
boost-filesystem boost-uuid physfs openal-soft libogg libvorbis zlib opengl
- name: macos-clang
os: macos
@ -62,8 +54,11 @@ jobs:
cc: clang
triplet: x64-osx
packages: >
boost-iostreams boost-asio boost-system boost-variant boost-lockfree luajit glew
boost-filesystem boost-uuid physfs openal-soft libogg libvorbis zlib opengl
boost-iostreams boost-asio boost-system boost-variant boost-lockfree glew
boost-filesystem boost-uuid libogg libvorbis zlib opengl
exclude:
- name: windows-msvc
luajit: off
steps:
- uses: actions/checkout@v2
@ -77,35 +72,35 @@ jobs:
# Using 'latest' branch, the latest CMake is installed.
uses: lukka/get-cmake@latest
- name: Ubuntu - install luajit
run: |
sudo apt-get install libluajit-5.1-dev
- name: Ubuntu - install opengl lua5.1 luajit
# vcpkg has lua 5.3+
run: sudo apt-get install libglew-dev liblua5.1-0-dev libluajit-5.1-dev
if: contains( matrix.os, 'ubuntu')
- name: MacOS - install luajit pkgconfig
run: brew install luajit pkgconfig
- name: MacOS - install physfs pkgconfig lua5.1 luajit xquartz
run: brew install physfs pkgconfig lua@5.1 luajit xquartz
if: contains( matrix.os, 'macos')
- uses: lukka/set-shell-env@v1
with:
CXX: ${{ matrix.cxx }}
CC: ${{ matrix.cc }}
- name: Set Environment vars
run: |
echo "CXX=${{ matrix.cxx }}" >> $GITHUB_ENV
echo "CC=${{ matrix.cc }}" >> $GITHUB_ENV
- name: Run vcpkg
uses: lukka/run-vcpkg@v2
uses: lukka/run-vcpkg@v7.1
with:
vcpkgArguments: ${{ matrix.packages }}
vcpkgDirectory: ${{ runner.workspace }}/vcpkg/
vcpkgTriplet: ${{ matrix.triplet }}
vcpkgGitCommitId: 7db401cb1ef1fc559ec9f9ce814d064c328fd767
vcpkgGitCommitId: 9a49e3df7f729655318c59b9985c9c18ad0c99d6
- name: Build with CMake
uses: lukka/run-cmake@v2
uses: lukka/run-cmake@v3
with:
useVcpkgToolchainFile: true
buildDirectory: ${{ runner.workspace }}/build
cmakeBuildType: ${{ matrix.buildtype }}
cmakeAppendedArgs: -DUSE_LUAJIT=${{ matrix.luajit }}
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
cmakeAppendedArgs: '-G Ninja -DCMAKE_BUILD_TYPE="${{ matrix.buildtype }}" -DLUAJIT="${{ matrix.luajit }}"'
useVcpkgToolchainFile: true
- name: dir
run: find $RUNNER_WORKSPACE
@ -130,4 +125,4 @@ jobs:
with:
name: otclient-${{ matrix.name }}-${{ matrix.buildtype }}-luajit=${{ matrix.luajit }}-${{ github.sha }}
path: ${{ runner.workspace }}/build/*.dll
if: contains( matrix.os, 'windows')
if: contains( matrix.os, 'windows')

View file

@ -1,38 +0,0 @@
language: cpp
compiler:
- gcc
before_script:
- |-
set -o errexit
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
git-core \
libboost-all-dev \
libglew-dev \
liblua5.1-0-dev \
libncurses5-dev \
libopenal-dev \
libssl-dev \
libvorbis-dev \
mercurial \
zlib1g-dev
hg clone -r stable-3.0 http://hg.icculus.org/icculus/physfs/
mkdir -p physfs/build
pushd physfs/build
cmake ..
make -j$(nproc)
sudo make install
popd
script: |
cmake . -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
notifications:
irc:
channels:
- "irc.freenode.org#otclient"
on_success: change
skip_join: true

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.1)
project(otclient)
set(VERSION "1.0.0")
@ -23,13 +23,24 @@ set(executable_SOURCES
src/main.cpp
)
# add executable icon for win32 platforms
if(WIN32)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
COMMAND ${CMAKE_RC_COMPILER}
-I${CMAKE_CURRENT_SOURCE_DIR}/src
-i${CMAKE_CURRENT_SOURCE_DIR}/src/otcicon.rc
-o ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o)
if(MSVC)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
COMMAND ${CMAKE_RC_COMPILER}
-I${CMAKE_CURRENT_SOURCE_DIR}/src
-fo${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
${CMAKE_CURRENT_SOURCE_DIR}/src/otcicon.rc
)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
else()
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
COMMAND ${CMAKE_RC_COMPILER}
-I${CMAKE_CURRENT_SOURCE_DIR}/src
-i${CMAKE_CURRENT_SOURCE_DIR}/src/otcicon.rc
-o ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
)
endif()
set(executable_SOURCES ${executable_SOURCES} otcicon.o)
endif()
@ -37,8 +48,16 @@ add_definitions(-D"VERSION=\\"${VERSION}\\"")
# add client executable
add_executable(${PROJECT_NAME} ${framework_SOURCES} ${client_SOURCES} ${executable_SOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD_REQUIRED ON)
target_link_libraries(${PROJECT_NAME} ${framework_LIBRARIES})
if(APPLE AND USE_STATIC_LIBS)
target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework IOKit")
endif()
if(USE_PCH)
include(cotire)
cotire(${PROJECT_NAME})

View file

@ -1,42 +1,46 @@
# OTCLient "1.0"
![#6ff791](https://via.placeholder.com/15/6ff791/000000?text=+) `Tested on Tibia 10.98`
### Based on [edubart/otclient](https://github.com/edubart/otclient) Rev: 2.728
### Features
- Tile/Light/Creature Render Optimized
- Adaptive/Event-based Rendering (g_map.schedulePainting)
- New Light System
- Render Scale System (FAKE ONE)
- Idle Animation Support
- Highlight Mouse Target
- Crosshair
- Floor Shadowing
- Anti-Aliasing Option
- Floating Effects Option
- Adjusted Path Finding
- Module Controller System ([Code example](https://github.com/mehah/otclient/blob/cache-for-all/modules/game_minimap/minimap.lua))
- Optimized Terminal
- Refactored Walk System
- Refactored Battle Module by [@andersonfaaria](https://github.com/andersonfaaria)
- Health&Mana Circle by [@EgzoT](https://github.com/EgzoT), [@GustavoBlaze](https://github.com/GustavoBlaze), [@Tekadon58](https://github.com/Tekadon58) ([GITHUB Project](https://github.com/EgzoT/-OTClient-Mod-health_and_mana_circle))
- Tibia Theme 1.2 by Zews ([Forum Thread](https://otland.net/threads/otc-tibia-theme-v1-2.230988/))
- Some bugs fixed contained in [edubart/otclient](https://github.com/edubart/otclient)
- Custom Feature Definitions in [features.h](https://github.com/mehah/otclient/blob/cache-for-all/src/client/features.h)
### What I don't intend to do
- Floor Fading
- Optimize UI
- Compatibility with other protocols
![#6ff791](https://via.placeholder.com/15/6ff791/000000?text=+) `Tested on Tibia 10.98`
### Based on [edubart/otclient](https://github.com/edubart/otclient) Rev: 2.744
### Features
- Tile/Light/Creature Render Optimized
- Adaptive/Event-based Rendering (g_map.schedulePainting)
- New Light System
- Render Scale System (FAKE ONE)
- Idle Animation Support
- Highlight Mouse Target
- Crosshair
- Floor Shadowing
- Anti-Aliasing Option
- Floating Effects Option
- Adjusted Path Finding
- Module Controller System ([Code example](https://github.com/mehah/otclient/blob/cache-for-all/modules/game_minimap/minimap.lua))
- Optimized Terminal
- Refactored Walk System
- Refactored Battle Module by [@andersonfaaria](https://github.com/andersonfaaria)
- Health&Mana Circle by [@EgzoT](https://github.com/EgzoT), [@GustavoBlaze](https://github.com/GustavoBlaze), [@Tekadon58](https://github.com/Tekadon58) ([GITHUB Project](https://github.com/EgzoT/-OTClient-Mod-health_and_mana_circle))
- Tibia Theme 1.2 by Zews ([Forum Thread](https://otland.net/threads/otc-tibia-theme-v1-2.230988/))
- Some bugs fixed contained in [edubart/otclient](https://github.com/edubart/otclient)
- Custom Feature Definitions in [features.h](https://github.com/mehah/otclient/blob/cache-for-all/src/client/features.h)
### What I don't intend to do
- Floor Fading
- Optimize UI
- Compatibility with other protocols
<h2>
```diff
- Want to help? Just open a PR.
```
```diff
- Want to help? Just open a PR.
```
</h2>
[![Build Status](https://secure.travis-ci.org/edubart/otclient.svg?branch=master)](http://travis-ci.org/edubart/otclient) [![Join the chat at https://gitter.im/edubart/otclient](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/edubart/otclient?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Open Source Helpers](https://www.codetriage.com/edubart/otclient/badges/users.svg)](https://www.codetriage.com/edubart/otclient)
[![Build Status](https://github.com/edubart/otclient/actions/workflows/build-vcpkg.yml/badge.svg)](https://github.com/edubart/otclient/actions/workflows/build-vcpkg.yml) [![Join the chat at https://gitter.im/edubart/otclient](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/edubart/otclient?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Open Source Helpers](https://www.codetriage.com/edubart/otclient/badges/users.svg)](https://www.codetriage.com/edubart/otclient)
### What is otclient?
@ -53,7 +57,8 @@ or connect to one listed on [otservlist](https://otservlist.org/).#
### Where do I download?
Compiled for Windows can be found here (but can be outdated):
* [Windows Builds](http://otland.net/threads/otclient-builds-windows.217977/)
- [Windows Builds](http://otland.net/threads/otclient-builds-windows.217977/)
**NOTE:** You will need to download spr/dat files on your own and place them in `data/things/VERSION/` (i.e: `data/things/1098/Tibia.spr`)
@ -70,9 +75,10 @@ client, instead otclient was designed to be a combination of a framework and tib
### Compiling
In short, if you need to compile OTClient, follow these tutorials:
* [Compiling on Windows](https://github.com/edubart/otclient/wiki/Compiling-on-Windows)
* [Compiling on Linux](https://github.com/edubart/otclient/wiki/Compiling-on-Linux)
* [Compiling on OS X](https://github.com/edubart/otclient/wiki/Compiling-on-Mac-OS-X)
- [Compiling on Windows](https://github.com/edubart/otclient/wiki/Compiling-on-Windows)
- [Compiling on Linux](https://github.com/edubart/otclient/wiki/Compiling-on-Linux)
- [Compiling on OS X](https://github.com/edubart/otclient/wiki/Compiling-on-Mac-OS-X)
### Build and run with Docker

View file

@ -1,5 +1,8 @@
local musicFilename = "/sounds/startup"
local musicChannel = g_sounds.getChannel(1)
local musicChannel = nil
if g_sounds then
musicChannel = g_sounds.getChannel(SoundChannels.Music)
end
function setMusic(filename)
musicFilename = filename
@ -27,12 +30,14 @@ end
function startup()
-- Play startup music (The Silver Tree, by Mattias Westlund)
musicChannel:enqueue(musicFilename, 3)
connect(g_game, { onGameStart = function() musicChannel:stop(3) end })
connect(g_game, { onGameEnd = function()
g_sounds.stopAll()
musicChannel:enqueue(musicFilename, 3)
end })
if musicChannel then
musicChannel:enqueue(musicFilename, 3)
connect(g_game, { onGameStart = function() musicChannel:stop(3) end })
connect(g_game, { onGameEnd = function()
g_sounds.stopAll()
musicChannel:enqueue(musicFilename, 3)
end })
end
-- Check for startup errors
local errtitle = nil
@ -57,7 +62,9 @@ function init()
onExit = exit })
g_window.setMinimumSize({ width = 600, height = 480 })
g_sounds.preload(musicFilename)
if musicChannel then
g_sounds.preload(musicFilename)
end
-- initialize in fullscreen mode on mobile devices
if g_window.getPlatformType() == "X11-EGL" then

View file

@ -114,8 +114,8 @@ function init()
graphicsPanel = g_ui.loadUI('graphics')
optionsTabBar:addTab(tr('Graphics'), graphicsPanel, '/images/optionstab/graphics')
audioPanel = g_ui.loadUI('audio')
optionsTabBar:addTab(tr('Audio'), audioPanel, '/images/optionstab/audio')
soundPanel = g_ui.loadUI('audio')
optionsTabBar:addTab(tr('Audio'), soundPanel, '/images/optionstab/audio')
optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle)
audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end)
@ -229,17 +229,23 @@ function setOption(key, value, force)
elseif key == 'fullscreen' then
g_window.setFullscreen(value)
elseif key == 'enableAudio' then
g_sounds.setAudioEnabled(value)
if g_sounds then
g_sounds.setAudioEnabled(value)
end
if value then
audioButton:setIcon('/images/topbuttons/audio')
else
audioButton:setIcon('/images/topbuttons/audio_mute')
end
elseif key == 'enableMusicSound' then
g_sounds.getChannel(SoundChannels.Music):setEnabled(value)
if g_sounds then
g_sounds.getChannel(SoundChannels.Music):setEnabled(value)
end
elseif key == 'musicSoundVolume' then
g_sounds.getChannel(SoundChannels.Music):setGain(value/100)
audioPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value))
if g_sounds then
g_sounds.getChannel(SoundChannels.Music):setGain(value/100)
end
soundPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value))
elseif key == 'showLeftPanel' then
modules.game_interface.getLeftPanel():setOn(value)
elseif key == 'backgroundFrameRate' then

View file

@ -553,6 +553,8 @@ function addTabText(text, speaktype, tab, creatureName)
label:setColor(speaktype.color)
consoleTabBar:blinkTab(tab)
label.highlightInfo = {}
-- Overlay for consoleBuffer which shows highlighted words only
if speaktype.npcChat and (g_game.getCharacterName() ~= creatureName or g_game.getCharacterName() == 'Account Manager') then
@ -582,6 +584,10 @@ function addTabText(text, speaktype, tab, creatureName)
local dataBlock = { _start = highlightData[(i-1)*3+1], _end = highlightData[(i-1)*3+2], words = highlightData[(i-1)*3+3] }
local lastBlockEnd = (highlightData[(i-2)*3+2] or 1)
for i = dataBlock._start, dataBlock._end do
label.highlightInfo[i] = dataBlock.words
end
for letter = lastBlockEnd, dataBlock._start-1 do
local tmpChar = string.byte(drawText:sub(letter, letter))
local fillChar = (tmpChar == 10 or tmpChar == 32) and string.char(tmpChar) or string.char(127)
@ -609,7 +615,14 @@ function addTabText(text, speaktype, tab, creatureName)
processMessageMenu(mousePos, mouseButton, nil, nil, nil, tab)
end
label.onMouseRelease = function(self, mousePos, mouseButton)
processMessageMenu(mousePos, mouseButton, creatureName, text, self, tab)
if mouseButton == MouseLeftButton then
local position = label:getTextPos(mousePos)
if position and label.highlightInfo[position] then
sendMessage(label.highlightInfo[position], npcTab)
end
elseif mouseButton == MouseRightButton then
processMessageMenu(mousePos, mouseButton, creatureName, text, self, tab)
end
end
label.onMousePress = function(self, mousePos, button)
if button == MouseLeftButton then clearSelection(consoleBuffer) end

View file

@ -1,8 +1,3 @@
# CMAKE_CURRENT_LIST_DIR cmake 2.6 compatibility
if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6)
get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
endif(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6)
# client options
add_definitions(-DCLIENT)
option(BOT_PROTECTION "Enable bot protection" ON)
@ -110,5 +105,7 @@ set(client_SOURCES ${client_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/position.h
)
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os")
if(NOT MSVC)
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os")
endif()

View file

@ -72,7 +72,7 @@ protected:
private:
stdext::dynamic_storage<uint8> m_attribs;
std::unordered_map<Position, CreatureTypePtr, PositionHasher> m_creatures;
std::unordered_map<Position, CreatureTypePtr, Position::Hasher> m_creatures;
friend class CreatureManager;
};
@ -137,7 +137,7 @@ protected:
private:
std::vector<CreatureTypePtr> m_creatures;
std::unordered_map<Position, SpawnPtr, PositionHasher> m_spawns;
std::unordered_map<Position, SpawnPtr, Position::Hasher> m_spawns;
stdext::boolean<false> m_loaded, m_spawnLoaded;
CreatureTypePtr m_nullCreature;
};

View file

@ -85,9 +85,9 @@ typedef std::list<TownPtr> TownList;
typedef std::list<ItemPtr> ItemList;
typedef std::list<TilePtr> TileList;
typedef std::vector<ItemPtr> ItemVector;
typedef std::unordered_map<Position, TilePtr, PositionHasher> TileMap;
typedef std::unordered_map<Position, CreatureTypePtr, PositionHasher> CreatureMap;
typedef std::unordered_map<Position, SpawnPtr, PositionHasher> SpawnMap;
typedef std::unordered_map<Position, TilePtr, Position::Hasher> TileMap;
typedef std::unordered_map<Position, CreatureTypePtr, Position::Hasher> CreatureMap;
typedef std::unordered_map<Position, SpawnPtr, Position::Hasher> SpawnMap;
// net
class ProtocolLogin;

View file

@ -597,6 +597,7 @@ void Client::registerLuaFunctions()
g_lua.registerClass<Missile, Thing>();
g_lua.bindClassStaticFunction<Missile>("create", [] { return MissilePtr(new Missile); });
g_lua.bindClassMemberFunction<Missile>("setId", &Missile::setId);
g_lua.bindClassMemberFunction<Missile>("setPath", &Missile::setPath);
g_lua.registerClass<StaticText, Thing>();
g_lua.bindClassStaticFunction<StaticText>("create", [] { return StaticTextPtr(new StaticText); });

View file

@ -808,19 +808,20 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
// as described in http://en.wikipedia.org/wiki/A*_search_algorithm
struct Node {
Node(const Position& pos) : cost(0), totalCost(0), pos(pos), prev(nullptr), dir(Otc::InvalidDirection) {}
using Pair = std::pair<Node *, float>;
Node(const Position& pos) : cost(0), totalCost(0), pos(pos), prev(nullptr), dir(Otc::InvalidDirection) { }
float cost;
float totalCost;
Position pos;
Node* prev;
Otc::Direction dir;
};
struct LessNode : std::binary_function<std::pair<Node*, float>, std::pair<Node*, float>, bool> {
bool operator()(std::pair<Node*, float> a, std::pair<Node*, float> b) const
{
return b.second < a.second;
}
struct Compare {
bool operator() (const Pair &a, const Pair &b) const {
return b.second < a.second;
}
};
};
std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> ret;
@ -852,8 +853,8 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
}
}
std::unordered_map<Position, Node*, PositionHasher> nodes;
std::priority_queue<std::pair<Node*, float>, std::deque<std::pair<Node*, float>>, LessNode> searchList;
std::unordered_map<Position, Node*, Position::Hasher> nodes;
std::priority_queue<Node::Pair, std::deque<Node::Pair>, Node::Compare> searchList;
Node* currentNode = new Node(startPos);
currentNode->pos = startPos;
@ -946,7 +947,7 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
neighborNode->cost = cost;
neighborNode->totalCost = neighborNode->cost + neighborPos.distance(goalPos);
neighborNode->dir = walkDir;
searchList.push(std::make_pair(neighborNode, neighborNode->totalCost));
searchList.emplace(neighborNode, neighborNode->totalCost);
}
}

View file

@ -258,7 +258,7 @@ private:
std::unordered_map<uint, TileBlock> m_tileBlocks[Otc::MAX_Z + 1];
std::unordered_map<uint32, CreaturePtr> m_knownCreatures;
std::unordered_map<Position, std::string, PositionHasher> m_waypoints;
std::unordered_map<Position, std::string, Position::Hasher> m_waypoints;
std::map<uint32, Color> m_zoneColors;

View file

@ -289,13 +289,14 @@ public:
int32 x;
int32 y;
uint8 z;
};
struct PositionHasher : std::unary_function<Position, std::size_t> {
std::size_t operator()(const Position& pos) const
// NOTE: This does not increase the size of the struct.
struct Hasher
{
return (pos.x * 8192 + pos.y) * 16 + pos.z;
}
std::size_t operator() (const Position& pos) const {
return (((pos.x * 8192) + pos.y) * 16) + pos.z;
}
};
};
inline std::ostream& operator<<(std::ostream& out, const Position& pos)

View file

@ -5,11 +5,6 @@
# FRAMEWORK_XML
# FRAMEWORK_SQL
# CMAKE_CURRENT_LIST_DIR cmake 2.6 compatibility
if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6)
get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
endif(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6)
# add framework cmake modules
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake;${CMAKE_MODULE_PATH}")
@ -133,41 +128,44 @@ set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/platform.h
)
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os")
if(NOT MSVC)
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os")
endif()
# some build options
option(LUAJIT "Use lua jit" OFF)
option(USE_STATIC_LIBS "Don't use shared libraries (dlls)" ON)
if(NOT APPLE)
option(CRASH_HANDLER "Generate crash reports" ON)
option(USE_STATIC_LIBS "Don't use shared libraries (dlls)" ON)
option(USE_LIBCPP "Use the new libc++ library instead of stdc++" OFF)
option(USE_LTO "Use link time optimizations" OFF)
else()
set(CRASH_HANDLER OFF)
set(USE_STATIC_LIBS OFF)
set(USE_LIBCPP ON)
endif()
set(BUILD_COMMIT "devel" CACHE "Git commit string (intended for releases)" STRING)
set(BUILD_REVISION "0" CACHE "Git revision string (intended for releases)" STRING)
set(BUILD_COMMIT "devel" CACHE STRING "Git commit string (intended for releases)")
set(BUILD_REVISION "0" CACHE STRING "Git revision string (intended for releases)")
# default build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif()
include(FindCXX11)
set(COMPILER_CXX_EXTRA_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-unused-result -pipe")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
if (WIN32 AND MSVC)
set(COMPILER_CXX_EXTRA_FLAGS "/bigobj")
set(CMAKE_CXX_FLAGS_DEBUG "/Od /DEBUG:FULL")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/O12 /DEBUG:FASTLINK")
set(CMAKE_CXX_FLAGS_RELEASE "/Ot")
endif()
# gcc compile flags
set(WARNS_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-unused-result")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNS_FLAGS} ${ARCH_FLAGS} ${CPP2011_FLAGS} -pipe")
set(CMAKE_CXX_FLAGS_COMPILESPEED "-O0")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
set(CMAKE_CXX_FLAGS_PERFORMANCE "-Ofast -march=native")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_CXX_EXTRA_FLAGS} ${ARCH_FLAGS} ${CPP2011_FLAGS}")
if(USE_LTO)
if(USE_LTO AND NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwhole-program -flto")
if(WIN32)
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-O1,--gc-sections,--sort-common,--relax")
@ -274,7 +272,10 @@ if(USE_LIBCPP)
endif()
if(WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthreads")
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthreads")
endif()
set(framework_DEFINITIONS ${framework_DEFINITIONS} -D_WIN32_WINNT=0x0501 -DWIN32)
#set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,--large-address-aware") # strip all debug information
set(SYSTEM_LIBRARIES "")
@ -294,15 +295,16 @@ if(FRAMEWORK_THREAD_SAFE)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DTHREAD_SAFE)
endif()
set(OpenGL_GL_PREFERENCE "GLVND")
if(FRAMEWORK_GRAPHICS)
set(OPENGLES "OFF" CACHE "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)" STRING)
set(OPENGLES "OFF" CACHE STRING "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)")
if(OPENGLES STREQUAL "2.0")
find_package(OpenGLES2 REQUIRED)
find_package(EGL REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=2)
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES2_INCLUDE_DIR})
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY})
ELSEif(OPENGLES STREQUAL "1.0")
elseif(OPENGLES STREQUAL "1.0")
find_package(OpenGLES1 REQUIRED)
find_package(EGL REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=1)

View file

@ -1,26 +0,0 @@
if(__FIND_CXX11_CMAKE__)
return()
endif()
set(__FIND_CXX11_CMAKE__ TRUE)
include(CheckCXXCompilerFlag)
enable_language(CXX)
check_cxx_compiler_flag("-std=c++11" COMPILER_KNOWS_CXX11)
if(COMPILER_KNOWS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Tested on Mac OS X 10.8.2 with XCode 4.6 Command Line Tools
# Clang requires this to find the correct c++11 headers
check_cxx_compiler_flag("-stdlib=libc++" COMPILER_KNOWS_STDLIB)
if(APPLE AND COMPILER_KNOWS_STDLIB)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
else()
check_cxx_compiler_flag("-std=c++0x" COMPILER_KNOWS_CXX0X)
if(COMPILER_KNOWS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(FATAL_ERROR "Your C++ compiler does not support C++11.")
endif()
endif()

View file

@ -13,4 +13,4 @@ ELSE()
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMP DEFAULT_MSG GMP_LIBRARY GMP_INCLUDE_DIR)
MARK_AS_ADVANCED(GMP_LIBRARY GMP_INCLUDE_DIR)
MARK_AS_ADVANCED(GMP_LIBRARY GMP_INCLUDE_DIR)

View file

@ -4,10 +4,10 @@
# LUA_LIBRARY - the lua library
# LUA_LIBRARIES - the lua library and it's dependencies
FIND_PATH(LUA_INCLUDE_DIR NAMES lua.h PATH_SUFFIXES lua51 lua5.1 lua)
FIND_PATH(LUA_INCLUDE_DIR NAMES lua.h PATH_SUFFIXES lua51 lua5-1 lua5.1 lua)
FIND_LIBRARY(LUA_LIBRARY NAMES)
SET(_LUA_STATIC_LIBS liblua51.a liblua5.1.a liblua-5.1.a liblua.a )
SET(_LUA_SHARED_LIBS liblua51.dll.a liblua5.1.dll.a liblua-5.1.dll.a liblua.dll.a lua51.dll lua5.1 lua-5.1 lua)
SET(_LUA_STATIC_LIBS liblua51.a liblua5.1.a liblua-5.1.a liblua.a)
SET(_LUA_SHARED_LIBS lua51 lua5.1 lua-5.1 lua)
IF(USE_STATIC_LIBS)
FIND_LIBRARY(LUA_LIBRARY NAMES ${_LUA_STATIC_LIBS} ${_LUA_SHARED_LIBS})
ELSE()
@ -15,4 +15,4 @@ ELSE()
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua DEFAULT_MSG LUA_LIBRARY LUA_INCLUDE_DIR)
MARK_AS_ADVANCED(LUA_LIBRARY LUA_INCLUDE_DIR)
MARK_AS_ADVANCED(LUA_LIBRARY LUA_INCLUDE_DIR)

View file

@ -2,11 +2,10 @@
# LUAJIT_FOUND - system has lua
# LUAJIT_INCLUDE_DIR - the lua include directory
# LUAJIT_LIBRARY - the lua library
# LUAJIT_LIBRARIES - the lua library and it's dependencies
FIND_PATH(LUAJIT_INCLUDE_DIR NAMES lua.h PATH_SUFFIXES luajit-2.0)
SET(_LUAJIT_STATIC_LIBS libluajit51.a libluajit5.1.a libluajit-5.1.a libluajit.a)
SET(_LUAJIT_SHARED_LIBS libluajit51.dll.a libluajit5.1.dll.a libluajit-5.1.dll.a libluajit.dll.a luajit51 luajit5.1 luajit-5.1 luajit)
FIND_PATH(LUAJIT_INCLUDE_DIR NAMES luajit.h PATH_SUFFIXES luajit luajit-2.0 luajit-2.1)
SET(_LUAJIT_STATIC_LIBS libluajit-5.1.a libluajit.a liblua51.a)
SET(_LUAJIT_SHARED_LIBS luajit-5.1 luajit lua51)
IF(USE_STATIC_LIBS)
FIND_LIBRARY(LUAJIT_LIBRARY NAMES ${_LUAJIT_STATIC_LIBS} ${_LUAJIT_SHARED_LIBS})
ELSE()
@ -14,4 +13,4 @@ ELSE()
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT DEFAULT_MSG LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR)
MARK_AS_ADVANCED(LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR)
MARK_AS_ADVANCED(LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR)

View file

@ -12,5 +12,5 @@ ELSE()
FIND_LIBRARY(OGG_LIBRARY NAMES ${_OGG_SHARED_LIBS} ${_OGG_STATIC_LIBS})
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OGG DEFAULT_MSG OGG_LIBRARY OGG_INCLUDE_DIR)
MARK_AS_ADVANCED(OGG_LIBRARY OGG_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ogg DEFAULT_MSG OGG_LIBRARY OGG_INCLUDE_DIR)
MARK_AS_ADVANCED(OGG_LIBRARY OGG_INCLUDE_DIR)

View file

@ -13,5 +13,5 @@ ELSE()
FIND_LIBRARY(OPENAL_LIBRARY NAMES ${_OPENAL_SHARED_LIBS} ${_OPENAL_STATIC_LIBS} PATHS ${OPENAL_APPLE_PATHS})
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENAL DEFAULT_MSG OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenAL DEFAULT_MSG OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
MARK_AS_ADVANCED(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)

View file

@ -3,11 +3,11 @@
# OPENSSL_INCLUDE_DIR - the OpenSSL include directory
# OPENSSL_LIBRARY - the OpenSSL library
FIND_PATH(OPENSSL_INCLUDE_DIR NAMES openssl/ssl.h PATH_SUFFIXES openssl-1.0)
SET(_OPENSSL_STATIC_LIBS libssl.a)
SET(_OPENSSL_SHARED_LIBS libssl.dll.a ssl)
SET(_OPENSSL_CRYPTO_STATIC_LIBS libcrypto.a)
SET(_OPENSSL_CRYPTO_SHARED_LIBS libcrypto.dll.a crypto)
FIND_PATH(OPENSSL_INCLUDE_DIR NAMES openssl/ssl.h PATH_SUFFIXES include openssl-1.0)
SET(_OPENSSL_STATIC_LIBS libssl.a ssl.a)
SET(_OPENSSL_SHARED_LIBS libssl ssl)
SET(_OPENSSL_CRYPTO_STATIC_LIBS libcrypto.a crypto.a)
SET(_OPENSSL_CRYPTO_SHARED_LIBS libcrypto crypto)
IF(USE_STATIC_LIBS)
FIND_LIBRARY(OPENSSL_LIBRARY NAMES ${_OPENSSL_STATIC_LIBS} ${_OPENSSL_SHARED_LIBS} PATH_SUFFIXES openssl-1.0)
FIND_LIBRARY(OPENSSL_CRYPTO_LIBRARY NAMES ${_OPENSSL_CRYPTO_STATIC_LIBS} ${_OPENSSL_CRYPTO_SHARED_LIBS} PATH_SUFFIXES openssl-1.0)
@ -17,5 +17,5 @@ ELSE()
ENDIF()
SET(OPENSSL_LIBRARIES ${OPENSSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENSSL DEFAULT_MSG OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenSSL DEFAULT_MSG OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIR)
MARK_AS_ADVANCED(OPENSSL_LIBRARIES OPENSSL_LIBRARY OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR)

View file

@ -12,5 +12,5 @@ ELSE()
FIND_LIBRARY(PHYSFS_LIBRARY NAMES ${_PHYSFS_SHARED_LIBS} ${_PHYSFS_STATIC_LIBS})
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PHYSFS DEFAULT_MSG PHYSFS_LIBRARY PHYSFS_INCLUDE_DIR)
MARK_AS_ADVANCED(PHYSFS_LIBRARY PHYSFS_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PhysFS DEFAULT_MSG PHYSFS_LIBRARY PHYSFS_INCLUDE_DIR)
MARK_AS_ADVANCED(PHYSFS_LIBRARY PHYSFS_INCLUDE_DIR)

View file

@ -12,5 +12,5 @@ ELSE()
FIND_LIBRARY(VORBIS_LIBRARY NAMES ${_VORBIS_SHARED_LIBS} ${_VORBIS_STATIC_LIBS})
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(VORBIS DEFAULT_MSG VORBIS_LIBRARY VORBIS_INCLUDE_DIR)
MARK_AS_ADVANCED(VORBIS_LIBRARY VORBIS_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Vorbis DEFAULT_MSG VORBIS_LIBRARY VORBIS_INCLUDE_DIR)
MARK_AS_ADVANCED(VORBIS_LIBRARY VORBIS_INCLUDE_DIR)

View file

@ -12,5 +12,5 @@ ELSE()
FIND_LIBRARY(VORBISFILE_LIBRARY NAMES ${_VORBISFILE_SHARED_LIBS} ${_VORBISFILE_STATIC_LIBS})
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(VORBISFILE DEFAULT_MSG VORBISFILE_LIBRARY VORBISFILE_INCLUDE_DIR)
MARK_AS_ADVANCED(VORBISFILE_LIBRARY VORBISFILE_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(VorbisFile DEFAULT_MSG VORBISFILE_LIBRARY VORBISFILE_INCLUDE_DIR)
MARK_AS_ADVANCED(VORBISFILE_LIBRARY VORBISFILE_INCLUDE_DIR)

View file

@ -25,8 +25,8 @@
#include "stdext/compiler.h"
#define DEG_TO_RAD (acos(-1)/180.0)
#define RAD_TO_DEC (180.0/acos(-1))
#define DEG_TO_RAD (std::acos(-1.f)/180.f)
#define RAD_TO_DEC (180.f/std::acos(-1.f))
#ifndef BUILD_COMMIT
#define BUILD_COMMIT "devel"
@ -52,8 +52,9 @@
namespace Fw
{
static constexpr float pi = 3.14159265;
static constexpr float MIN_ALPHA = 0.003f;
static const float pi = 3.14159265f;
static const float MIN_ALPHA = 0.003f;
enum Key : unsigned char {
KeyUnknown = 0,
KeyEscape = 1,

View file

@ -54,7 +54,7 @@ ConfigPtr ConfigManager::getSettings()
ConfigPtr ConfigManager::get(const std::string& file)
{
for(const ConfigPtr config : m_configs) {
for(const ConfigPtr& config : m_configs) {
if(config->getFileName() == file) {
return config;
}

View file

@ -43,7 +43,7 @@ private:
std::deque<EventPtr> m_eventList;
int m_pollEventsSize;
stdext::boolean<false> m_disabled;
std::priority_queue<ScheduledEventPtr, std::deque<ScheduledEventPtr>, lessScheduledEvent> m_scheduledEventList;
std::priority_queue<ScheduledEventPtr, std::deque<ScheduledEventPtr>, ScheduledEvent::Compare> m_scheduledEventList;
};
extern EventDispatcher g_dispatcher;

View file

@ -34,6 +34,12 @@
Logger g_logger;
namespace
{
const std::string s_logPrefixes[] = { "", "", "WARNING: ", "ERROR: ", "FATAL ERROR: " };
bool s_ignoreLogs = false;
}
void Logger::log(Fw::LogLevel level, const std::string& message)
{
std::lock_guard<std::recursive_mutex> lock(m_mutex);
@ -43,13 +49,10 @@ void Logger::log(Fw::LogLevel level, const std::string& message)
return;
#endif
static bool ignoreLogs = false;
if(ignoreLogs)
if(s_ignoreLogs)
return;
const static std::string logPrefixes[] = { "", "", "WARNING: ", "ERROR: ", "FATAL ERROR: " };
std::string outmsg = logPrefixes[level] + message;
std::string outmsg = s_logPrefixes[level] + message;
/*
#if !defined(NDEBUG) && !defined(WIN32)
@ -91,7 +94,7 @@ void Logger::log(Fw::LogLevel level, const std::string& message)
#ifdef FW_GRAPHICS
g_window.displayFatalError(message);
#endif
ignoreLogs = true;
s_ignoreLogs = true;
exit(-1);
}
}
@ -122,8 +125,7 @@ void Logger::fireOldMessages()
std::lock_guard<std::recursive_mutex> lock(m_mutex);
if(m_onLog) {
auto backup = m_logMessages;
for(const LogMessage& logMessage : backup) {
for(const LogMessage& logMessage : m_logMessages) {
m_onLog(logMessage.level, logMessage.message, logMessage.when);
}
}

View file

@ -59,7 +59,7 @@ public:
void setOnLog(const OnLogCallback& onLog) { m_onLog = onLog; }
private:
std::list<LogMessage> m_logMessages;
std::deque<LogMessage> m_logMessages;
OnLogCallback m_onLog;
std::ofstream m_outFile;
std::recursive_mutex m_mutex;

View file

@ -40,6 +40,12 @@ public:
int cyclesExecuted() { return m_cyclesExecuted; }
int maxCycles() { return m_maxCycles; }
struct Compare {
bool operator() (const ScheduledEventPtr &a, const ScheduledEventPtr &b) const {
return b->ticks() < a->ticks();
}
};
private:
ticks_t m_ticks;
int m_delay;
@ -47,10 +53,4 @@ private:
int m_cyclesExecuted;
};
struct lessScheduledEvent : std::binary_function<ScheduledEventPtr, ScheduledEventPtr&, bool> {
bool operator()(const ScheduledEventPtr& a, const ScheduledEventPtr& b) {
return b->ticks() < a->ticks();
}
};
#endif

View file

@ -27,6 +27,14 @@
#include <framework/otml/otml.h>
namespace
{
// for performance reasons we use statics vectors that are allocated on demand
CoordsBuffer s_coordsBuffer;
std::vector<Point> s_glyphsPositions(1);
std::vector<int> s_lineWidths(1);
}
void BitmapFont::load(const OTMLNodePtr& fontNode)
{
OTMLNodePtr textureNode = fontNode->at("texture");
@ -35,11 +43,12 @@ void BitmapFont::load(const OTMLNodePtr& fontNode)
m_glyphHeight = fontNode->valueAt<int>("height");
m_yOffset = fontNode->valueAt("y-offset", 0);
m_firstGlyph = fontNode->valueAt("first-glyph", 32);
m_glyphSpacing = fontNode->valueAt("spacing", Size(0));
m_glyphSpacing = fontNode->valueAt("spacing", Size(0, 0));
int spaceWidth = fontNode->valueAt("space-width", glyphSize.width());
// load font texture
m_texture = g_textures.getTexture(textureFile);
Size textureSize = m_texture->getSize();
if(OTMLNodePtr node = fontNode->get("fixed-glyph-width")) {
for(int glyph = m_firstGlyph; glyph < 256; ++glyph)
@ -68,7 +77,7 @@ void BitmapFont::load(const OTMLNodePtr& fontNode)
// calculate glyphs texture coords
int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
int numHorizontalGlyphs = textureSize.width() / glyphSize.width();
for(int glyph = m_firstGlyph; glyph < 256; ++glyph) {
m_glyphsTextureCoords[glyph].setRect(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
@ -86,11 +95,9 @@ void BitmapFont::drawText(const std::string& text, const Point& startPos)
void BitmapFont::drawText(const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align)
{
static CoordsBuffer coordsBuffer;
coordsBuffer.clear();
calculateDrawTextCoords(coordsBuffer, text, screenCoords, align);
g_painter->drawTextureCoords(coordsBuffer, m_texture);
s_coordsBuffer.clear();
calculateDrawTextCoords(s_coordsBuffer, text, screenCoords, align);
g_painter->drawTextureCoords(s_coordsBuffer, m_texture);
}
void BitmapFont::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align)
@ -103,7 +110,7 @@ void BitmapFont::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::
// map glyphs positions
Size textBoxSize;
const std::vector<Point>& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
const auto& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
for(int i = 0; i < textLenght; ++i) {
int glyph = static_cast<uchar>(text[i]);
@ -170,54 +177,51 @@ void BitmapFont::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::
}
const std::vector<Point>& BitmapFont::calculateGlyphsPositions(const std::string& text,
Fw::AlignmentFlag align,
Size* textBoxSize)
Fw::AlignmentFlag align,
Size* textBoxSize)
{
// for performance reasons we use statics vectors that are allocated on demand
static std::vector<Point> glyphsPositions(1);
static std::vector<int> lineWidths(1);
int textLength = text.length();
int maxLineWidth = 0;
int lines = 0;
int glyph;
int i;
// return if there is no text
if(textLength == 0) {
if(textBoxSize)
textBoxSize->resize(0, m_glyphHeight);
return glyphsPositions;
return s_glyphsPositions;
}
// resize glyphsPositions vector when needed
if(textLength > static_cast<int>(glyphsPositions.size()))
glyphsPositions.resize(textLength);
// resize s_glyphsPositions vector when needed
if(textLength > (int)s_glyphsPositions.size())
s_glyphsPositions.resize(textLength);
// calculate lines width
if((align & Fw::AlignRight || align & Fw::AlignHorizontalCenter) || textBoxSize) {
lineWidths[0] = 0;
for(i = 0; i < textLength; ++i) {
glyph = static_cast<uchar>(text[i]);
s_lineWidths[0] = 0;
for(int i = 0; i < textLength; ++i) {
glyph = (uchar)text[i];
if(glyph == static_cast<uchar>('\n')) {
lines++;
if(lines + 1 > static_cast<int>(lineWidths.size()))
lineWidths.resize(lines + 1);
lineWidths[lines] = 0;
// resize s_lineWidths vector when needed
if(lines+1 > (int)s_lineWidths.size())
s_lineWidths.resize(lines+1);
s_lineWidths[lines] = 0;
} else if(glyph >= 32) {
lineWidths[lines] += m_glyphsSize[glyph].width();
if((i + 1 != textLength && text[i + 1] != '\n')) // only add space if letter is not the last or before a \n.
lineWidths[lines] += m_glyphSpacing.width();
maxLineWidth = std::max<int>(maxLineWidth, lineWidths[lines]);
s_lineWidths[lines] += m_glyphsSize[glyph].width();
// only add space if letter is not the last or before a \n
if((i+1 != textLength && text[i+1] != '\n'))
s_lineWidths[lines] += m_glyphSpacing.width();
maxLineWidth = std::max<int>(maxLineWidth, s_lineWidths[lines]);
}
}
}
Point virtualPos(0, m_yOffset);
lines = 0;
for(i = 0; i < textLength; ++i) {
glyph = static_cast<uchar>(text[i]);
for(int i = 0; i < textLength; ++i) {
glyph = (uchar)text[i];
// new line or first glyph
if(glyph == static_cast<uchar>('\n') || i == 0) {
@ -228,16 +232,16 @@ const std::vector<Point>& BitmapFont::calculateGlyphsPositions(const std::string
// calculate start x pos
if(align & Fw::AlignRight) {
virtualPos.x = (maxLineWidth - lineWidths[lines]);
virtualPos.x = (maxLineWidth - s_lineWidths[lines]);
} else if(align & Fw::AlignHorizontalCenter) {
virtualPos.x = (maxLineWidth - lineWidths[lines]) / 2;
virtualPos.x = (maxLineWidth - s_lineWidths[lines]) / 2;
} else { // AlignLeft
virtualPos.x = 0;
}
}
// store current glyph topLeft
glyphsPositions[i] = virtualPos;
s_glyphsPositions[i] = virtualPos;
// render only if the glyph is valid
if(glyph >= 32 && glyph != static_cast<uchar>('\n')) {
@ -250,7 +254,7 @@ const std::vector<Point>& BitmapFont::calculateGlyphsPositions(const std::string
textBoxSize->setHeight(virtualPos.y + m_glyphHeight);
}
return glyphsPositions;
return s_glyphsPositions;
}
Size BitmapFont::calculateTextRectSize(const std::string& text)
@ -265,8 +269,9 @@ void BitmapFont::calculateGlyphsWidthsAutomatically(const ImagePtr& image, const
if(!image)
return;
int numHorizontalGlyphs = image->getSize().width() / glyphSize.width();
auto texturePixels = image->getPixels();
Size imageSize = image->getSize();
int numHorizontalGlyphs = imageSize.width() / glyphSize.width();
const auto& texturePixels = image->getPixels();
// small AI to auto calculate pixels widths
for(int glyph = m_firstGlyph; glyph < 256; ++glyph) {
@ -279,7 +284,7 @@ void BitmapFont::calculateGlyphsWidthsAutomatically(const ImagePtr& image, const
int filledPixels = 0;
// check if all vertical pixels are alpha
for(int y = glyphCoords.top(); y <= glyphCoords.bottom(); ++y) {
if(texturePixels[(y * image->getSize().width() * 4) + (x * 4) + 3] != 0)
if(texturePixels[(y * imageSize.width() * 4) + (x*4) + 3] != 0)
filledPixels++;
}
if(filledPixels > 0)
@ -293,51 +298,54 @@ void BitmapFont::calculateGlyphsWidthsAutomatically(const ImagePtr& image, const
std::string BitmapFont::wrapText(const std::string& text, int maxWidth)
{
std::string outText;
std::string line;
std::vector<std::string> words;
std::vector<std::string> wordsSplit = stdext::split(text);
// break huge words into small ones
for(const auto& word : wordsSplit) {
for(const auto& word: wordsSplit) {
int wordWidth = calculateTextRectSize(word).width();
if(wordWidth > maxWidth) {
std::string newWord;
for(uint j = 0; j < word.length(); ++j) {
std::string candidate = newWord + word[j];
if(j != word.length() - 1)
candidate += "-";
candidate += '-';
int candidateWidth = calculateTextRectSize(candidate).width();
if(candidateWidth > maxWidth) {
newWord += "-";
newWord += '-';
words.push_back(newWord);
newWord = "";
newWord.clear();
}
newWord += word[j];
}
words.push_back(newWord);
} else
} else {
words.push_back(word);
}
}
// compose lines
for(const auto& word : words) {
std::string candidate = line + word;
int candidateWidth = calculateTextRectSize(candidate).width();
std::string line(words[0]);
for(ulong i = 1; i < words.size(); ++i)
{
const auto& word = words[i];
if(candidateWidth > maxWidth) {
if(!line.empty())
outText += line.substr(0, line.length() - 1) + "\n";
line = "";
line.push_back(' ');
ulong lineSize = line.size();
line.append(word);
if(calculateTextRectSize(line).width() > maxWidth)
{
line.resize(lineSize);
line.back() = '\n';
outText.append(line);
line.assign(word);
}
line += word + " ";
}
outText += line;
outText = outText.substr(0, outText.length() - 1);
outText.append(line);
return outText;
}

View file

@ -55,7 +55,7 @@ public:
std::string wrapText(const std::string& text, int maxWidth);
std::string getName() { return m_name; }
const std::string& getName() { return m_name; }
int getGlyphHeight() { return m_glyphHeight; }
const Rect* getGlyphsTextureCoords() { return m_glyphsTextureCoords; }
const Size* getGlyphsSize() { return m_glyphsSize; }
@ -79,4 +79,3 @@ private:
#endif

View file

@ -77,7 +77,7 @@ void GravityAffector::load(const OTMLNodePtr& node)
ParticleAffector::load(node);
m_angle = 270 * DEG_TO_RAD;
m_gravity = 9.8;
m_gravity = 9.8f;
for(const OTMLNodePtr& childNode : node->children()) {
if(childNode->tag() == "angle")
@ -132,5 +132,5 @@ void AttractionAffector::updateParticle(const ParticlePtr& particle, float elaps
direction = PointF(-1, -1);
PointF pVelocity = particle->getVelocity() + (d / d.length() * m_acceleration * elapsedTime) * direction;
particle->setVelocity(pVelocity - pVelocity * m_reduction/100.0 * elapsedTime);
particle->setVelocity(pVelocity - pVelocity * m_reduction/100.f * elapsedTime);
}

View file

@ -144,29 +144,35 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
void Protocol::generateXteaKey()
{
std::mt19937 eng(std::time(nullptr));
std::uniform_int_distribution<uint32> unif(0, 0xFFFFFFFF);
m_xteaKey[0] = unif(eng);
m_xteaKey[1] = unif(eng);
m_xteaKey[2] = unif(eng);
m_xteaKey[3] = unif(eng);
std::random_device rd;
std::uniform_int_distribution<uint32> unif;
std::generate(m_xteaKey.begin(), m_xteaKey.end(), [&]() { return unif(rd); });
}
void Protocol::setXteaKey(uint32 a, uint32 b, uint32 c, uint32 d)
namespace {
constexpr uint32_t delta = 0x9E3779B9;
template<typename Round>
void apply_rounds(uint8_t* data, size_t length, Round round)
{
m_xteaKey[0] = a;
m_xteaKey[1] = b;
m_xteaKey[2] = c;
m_xteaKey[3] = d;
for (auto j = 0u; j < length; j += 8) {
uint32_t left = data[j+0] | data[j+1] << 8u | data[j+2] << 16u | data[j+3] << 24u,
right = data[j+4] | data[j+5] << 8u | data[j+6] << 16u | data[j+7] << 24u;
round(left, right);
data[j] = static_cast<uint8_t>(left);
data[j+1] = static_cast<uint8_t>(left >> 8u);
data[j+2] = static_cast<uint8_t>(left >> 16u);
data[j+3] = static_cast<uint8_t>(left >> 24u);
data[j+4] = static_cast<uint8_t>(right);
data[j+5] = static_cast<uint8_t>(right >> 8u);
data[j+6] = static_cast<uint8_t>(right >> 16u);
data[j+7] = static_cast<uint8_t>(right >> 24u);
}
}
std::vector<uint32> Protocol::getXteaKey()
{
std::vector<uint32> xteaKey;
xteaKey.resize(4);
for(int i = 0; i < 4; ++i)
xteaKey[i] = m_xteaKey[i];
return xteaKey;
}
bool Protocol::xteaDecrypt(const InputMessagePtr& inputMessage)
@ -177,22 +183,12 @@ bool Protocol::xteaDecrypt(const InputMessagePtr& inputMessage)
return false;
}
uint32 *buffer = (uint32*)(inputMessage->getReadBuffer());
int readPos = 0;
while(readPos < encryptedSize/4) {
uint32 v0 = buffer[readPos], v1 = buffer[readPos + 1];
uint32 delta = 0x61C88647;
uint32 sum = 0xC6EF3720;
for(int32 i = 0; i < 32; i++) {
v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + m_xteaKey[sum>>11 & 3]);
sum += delta;
v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + m_xteaKey[sum & 3]);
}
buffer[readPos] = v0; buffer[readPos + 1] = v1;
readPos = readPos + 2;
}
for (uint32_t i = 0, sum = delta << 5, next_sum = sum - delta; i < 32; ++i, sum = next_sum, next_sum -= delta) {
apply_rounds(inputMessage->getReadBuffer(), encryptedSize, [&](uint32_t& left, uint32_t& right) {
right -= ((left << 4 ^ left >> 5) + left) ^ (sum + m_xteaKey[(sum >> 11) & 3]);
left -= ((right << 4 ^ right >> 5) + right) ^ (next_sum + m_xteaKey[next_sum & 3]);
});
};
uint16 decryptedSize = inputMessage->getU16() + 2;
int sizeDelta = decryptedSize - encryptedSize;
@ -217,21 +213,12 @@ void Protocol::xteaEncrypt(const OutputMessagePtr& outputMessage)
encryptedSize += n;
}
int readPos = 0;
uint32 *buffer = (uint32*)(outputMessage->getDataBuffer() - 2);
while(readPos < encryptedSize / 4) {
uint32 v0 = buffer[readPos], v1 = buffer[readPos + 1];
uint32 delta = 0x61C88647;
uint32 sum = 0;
for(int32 i = 0; i < 32; i++) {
v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + m_xteaKey[sum & 3]);
sum -= delta;
v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + m_xteaKey[sum>>11 & 3]);
}
buffer[readPos] = v0; buffer[readPos + 1] = v1;
readPos = readPos + 2;
}
for (uint32_t i = 0, sum = 0, next_sum = sum + delta; i < 32; ++i, sum = next_sum, next_sum += delta) {
apply_rounds(outputMessage->getDataBuffer() - 2, encryptedSize, [&](uint32_t& left, uint32_t& right) {
left += ((right << 4 ^ right >> 5) + right) ^ (sum + m_xteaKey[sum & 3]);
right += ((left << 4 ^ left >> 5) + left) ^ (next_sum + m_xteaKey[(next_sum >> 11) & 3]);
});
};
}
void Protocol::onConnect()

View file

@ -48,8 +48,8 @@ public:
void setConnection(const ConnectionPtr& connection) { m_connection = connection; }
void generateXteaKey();
void setXteaKey(uint32 a, uint32 b, uint32 c, uint32 d);
std::vector<uint32> getXteaKey();
void setXteaKey(uint32 a, uint32 b, uint32 c, uint32 d) { m_xteaKey = {a, b, c, d}; }
std::vector<uint32> getXteaKey() { return {m_xteaKey.begin(), m_xteaKey.end()}; }
void enableXteaEncryption() { m_xteaEncryptionEnabled = true; }
void enableChecksum() { m_checksumEnabled = true; }
@ -64,7 +64,7 @@ protected:
virtual void onRecv(const InputMessagePtr& inputMessage);
virtual void onError(const boost::system::error_code& err);
uint32 m_xteaKey[4];
std::array<uint32, 4> m_xteaKey;
private:
void internalRecvHeader(uint8* buffer, uint16 size);

View file

@ -27,8 +27,13 @@
#define AL_LIBTYPE_STATIC
#if defined(__APPLE__)
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
class SoundManager;
class SoundSource;

View file

@ -50,18 +50,16 @@ std::string date_time_string(const char* format/* = "%b %d %Y %H:%M:%S"*/)
char date[100];
std::time_t tnow;
std::time(&tnow);
std::tm *ts = std::localtime(&tnow);
std::tm* ts = std::localtime(&tnow);
std::strftime(date, 100, format, ts);
return std::string(date);
}
std::string dec_to_hex(uint64_t num)
{
std::string str;
std::ostringstream o;
o << std::hex << num;
str = o.str();
return str;
return o.str();
}
uint64_t hex_to_dec(const std::string& str)
@ -74,7 +72,7 @@ uint64_t hex_to_dec(const std::string& str)
bool is_valid_utf8(const std::string& src)
{
const unsigned char *bytes = (const unsigned char *)src.c_str();
const unsigned char* bytes = (const unsigned char*)src.c_str();
while(*bytes) {
if( (// ASCII
// use bytes[0] <= 0x7F to allow ASCII control characters
@ -146,7 +144,7 @@ bool is_valid_utf8(const std::string& src)
std::string utf8_to_latin1(const std::string& src)
{
std::string out;
for(uint i=0;i<src.length();) {
for(uint i = 0; i < src.length();) {
uchar c = src[i++];
if((c >= 32 && c < 128) || c == 0x0d || c == 0x0a || c == 0x09)
out += c;
@ -273,7 +271,7 @@ void replace_all(std::string& str, const std::string& search, const std::string&
std::vector<std::string> split(const std::string& str, const std::string& separators)
{
std::vector<std::string> splitted;
boost::split(splitted, str, boost::is_any_of(std::string(separators)));
boost::split(splitted, str, boost::is_any_of(separators));
return splitted;
}

View file

@ -63,11 +63,12 @@ std::string utf16_to_latin1(const std::wstring& src);
std::wstring latin1_to_utf16(const std::string& src);
#endif
// always returns at least one element in vector
std::vector<std::string> split(const std::string& str, const std::string& separators = " ");
template<typename T> std::vector<T> split(const std::string& str, const std::string& separators = " ") {
std::vector<std::string> splitted = split(str, separators);
std::vector<T> results(splitted.size());
for(uint i=0;i<splitted.size();++i)
for(uint i = 0; i < splitted.size(); ++i)
results[i] = safe_cast<T>(splitted[i]);
return results;
}

View file

@ -142,7 +142,7 @@ void UITextEdit::update(bool focusCursor)
// map glyphs positions
Size textBoxSize;
const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
const auto& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
const Rect* glyphsTextureCoords = m_font->getGlyphsTextureCoords();
const Size* glyphsSize = m_font->getGlyphsSize();
int glyph;

View file

@ -42,7 +42,7 @@ public:
void setCursorVisible(bool enable) { m_cursorVisible = enable; }
void setChangeCursorImage(bool enable) { m_changeCursorImage = enable; }
void setTextHidden(bool hidden);
void setValidCharacters(const std::string validCharacters) { m_validCharacters = validCharacters; }
void setValidCharacters(const std::string& validCharacters) { m_validCharacters = validCharacters; }
void setShiftNavigation(bool enable) { m_shiftNavigation = enable; }
void setMultiline(bool enable) { m_multiline = enable; }
void setMaxLength(uint maxLength) { m_maxLength = maxLength; }