56 Commits

Author SHA1 Message Date
divinity76
dab86e6109 Make OutputMessage::addRawString available in Lua (#1218) 2024-09-14 17:26:54 +02:00
vfjpl
e6861d79c9 Use float literals where applicable (#1210) 2023-08-14 04:47:12 +02:00
diath
52475761cd Save the minimap on a per server basis
Co-authored-by: Xagul <eixim@hotmail.com>
2022-12-10 10:52:03 +01:00
diath
a3fdf073b9 Use lambdas instead of std::bind (#1200) 2022-11-26 19:15:38 +01:00
Marcin Michalski
77f05b9476 Run CI on ubuntu 20.04 (#1199) 2022-11-26 01:50:42 +01:00
Marcin Michalski
0e5de3383e Prevent luaL_newlib macro redefinition (#1198) 2022-11-26 01:28:21 +01:00
Marcin Michalski
4a39d49fc1 Update workflow actions (#1197)
* Update workflow actions

* Update actions/checkout to v3
2022-11-26 01:06:57 +01:00
Marcin Michalski
725c200c9f Update vcpkg (#1196) 2022-11-26 00:12:00 +01:00
diath
da4bb92c33 Fix UIWidget::propagateOnMouseMove repeatedly adding the mouse receiver to the list (#1195) 2022-11-25 18:03:51 +01:00
diath
77c844d006 Fix building with newest Boost.Asio (#1194) 2022-11-25 18:00:45 +01:00
Marcin Michalski
fc39ee4adb Correctly include vcpkg LuaJIT in Visual Studio (#1174) 2022-05-26 13:45:13 +02:00
Kacper
b098210c6a move big functions from .h to .cpp 2022-05-26 13:40:01 +02:00
Marcin Michalski
f0d7963883 Fix compilation with GMP 2022-04-28 14:09:08 +02:00
Marcin Michalski
836ea2bdc6 Update vcpkg 2022-04-28 14:09:08 +02:00
Marcin Michalski
45afb65b90 Remove client stats module (#1170) 2022-01-26 20:13:18 +01:00
diath
d3e12b5d44 Make UIWidget::resizeToText() respect widget padding and text offset like text-auto-resize does (#1167) 2021-11-24 20:10:13 +01:00
Marcin Michalski
3092b5b2d5 Update physfs repo in Dockerfile (#1165) 2021-11-15 23:13:41 +01:00
diath
e73f6df221 Fix process hang on fatal errors (#1163) 2021-09-29 21:03:12 +02:00
diath
9eb13494f9 Fix ghost item border when dropping non-item objects (#1164) 2021-09-29 21:03:01 +02:00
vfjpl
1d614e294c Fix std::istream::streampos deprecation warning (#1154) 2021-08-25 19:24:08 +02:00
Marcin Michalski
e0d5b7d7fd Update vcpkg & switch back to ubuntu 18.04 in workflow (#1161) 2021-08-22 01:21:17 +02:00
Marcin Michalski
10100342b9 Fix opening "https://"-prefixed links on Windows (#1160) 2021-08-22 00:51:18 +02:00
Marcin Michalski
302748b2f3 Fix opening URLs on macOS (#1159) 2021-08-22 00:48:34 +02:00
Marcin Michalski
f173b03dbd Map option to alt and command to meta keys on macOS (#1158) 2021-08-22 00:38:58 +02:00
vfjpl
89dc0f87eb Fix stamina minutes check in the skills window (#1155) 2021-07-22 00:02:27 +02:00
vfjpl
9ce2cab9ae Fix uninitialized oldMaxMana variable in Player::setMana (#1152) 2021-06-16 23:25:43 +02:00
TheSumm
1e29b5cb01 Remove unused source file 2021-06-12 19:40:21 +02:00
Samuel
8eb01df240 Fix vcpkg compiling (#1153) 2021-06-12 18:07:18 +02:00
diath
6cd5eb3e22 Add clickable NPC keywords (#1148) 2021-04-29 18:06:48 +02:00
Ranieri Althoff
5cc9319a94 Optimize XTEA encryption (#1143)
https://dev.to/rsa/making-an-algorithm-15x-faster-without-parallelism-38k5
2021-04-02 21:48:58 +02:00
vfjpl
3600a9b40b Fix Lua errors when the client is built without the sound framework (#1142) 2021-04-02 21:35:34 +02:00
diath
b37623cd86 Fix the use of deprecated C++ functions (#1138) 2021-04-01 00:38:36 +02:00
vfjpl
67b7dbfcfe Keep log messages in a deque instead of a list and remove unnecessary copy
Co-authored-by: Kacper Piwiński <kacper.piwinski@arex.pl>
2021-04-01 00:38:02 +02:00
vfjpl
7752add8aa Use float literals where applicable (#1140)
Use float literals to perform more calculation in float instead of performing implicit conversion to double and back to float.

Co-authored-by: Kacper Piwiński <kacper.piwinski@arex.pl>
2021-04-01 00:06:50 +02:00
diath
7c528be73e Cleanup CMake project (#1137)
* Updated the minimum required standard from C++11 to C++14 (https://en.wikipedia.org/wiki/C%2B%2B14).
* Fixed -g0 and -Os flags being passed to luafunctions.cpp when building with MSVC.
* Fixed case mismatch in FIND_PACKAGE_HANDLE_STANDARD_ARGS argument in a number of CMake files.
2021-03-31 07:30:09 +02:00
vfjpl
4d055913dc Clean up BitmapFont code (#1129) 2021-03-30 17:03:02 +02:00
Marcin Michalski
4edb1eb3ad Fix adding executable icon on windows with non-msvc compiler (#1136) 2021-03-30 08:58:32 +02:00
Marcin Michalski
69e44a3722 Fix & enable by default static linking on macOS (#1133) 2021-03-29 17:22:04 +02:00
Marcin Michalski
ba706fc5c3 Remove travis (#1135)
Replaced by GitHub workflows.
2021-03-29 16:58:38 +02:00
Marcin Michalski
975d138a57 Run windows workflow with luajit only (#1134) 2021-03-29 16:54:02 +02:00
Marcin Michalski
c4530a6d17 Bump minimum required CMake version to 3.1 (#1131)
* Removed Ubuntu Clang workflow
* Removed FindCXX.cmake (in favor of native feature)
* Added support for building Windows binaries with CMake when using MSVC
* Cleaned up a number of Find*.cmake modules
2021-03-27 01:04:59 +01:00
Marcin Michalski
b6399a8ad9 Update workflow (#1130) 2021-03-26 14:37:02 +01:00
Kamil Chojnowski
9c9b85ac5e Fix UITextEdit::setTextHidden ignoring the hidden param and always setting the member variable to true 2021-03-14 21:12:59 +01:00
Martin Nylind
872abf05f4 Add Missile:setPath to Lua interface (#1125)
Add Missile:setPath(fromPos, toPos) method to Lua interface.
2021-02-10 05:40:39 +01:00
peonso
d07e7fcce7 Correct messageModsMap for version 10.41 (#1119) 2021-01-04 17:33:04 +01:00
vfjpl
f521737b26 Return Tile walking creatures and things by const ref instead of copy (#1117) 2020-11-23 17:26:15 +01:00
reyhammer
18dd9c2d2d Fix TPoint::distanceFrom() calling TPoint::getLength() instead of TPoint::length() (#1116) 2020-11-23 15:59:50 +01:00
vfjpl
72cc4b2fb0 Fix out-of-bounds access in Platform::getCPUName (#1115) 2020-11-22 22:08:37 +01:00
vfjpl
c6d0fc0f71 Fix laggy diagonal movement (#1108) 2020-10-07 03:14:00 +02:00
vfjpl
b3d947d4c3 Use std::deque for queues (#1112) 2020-10-07 03:12:04 +02:00
bakasuradbl
83959e5e23 Fix window position when entering fullscreen mode on Windows platform (#1099) 2020-10-05 19:59:36 +02:00
Source61
70400bc83e Add optional format string for stdext::date_time_string() (#1110) 2020-09-15 18:58:47 +02:00
vfjpl
9c1f519f8a resourcemanager:[bug fix] directoryExists method should resolvePath before checking (#1102) 2020-08-29 17:35:42 +02:00
diath
88d0ea34bf Fix UITabBar and UIMoveableTabBar bricking when removing first tabs in (#1101) collapsed view
Co-authored-by: Xagul <eixim@hotmail.com>
2020-08-26 09:54:56 +02:00
diath
b3aaa10646 Remove stdext::packed_vector (#1106)
Co-authored-by: Kacper Piwiński <cosiekvfj@o2.pl>
2020-08-26 09:54:05 +02:00
diath
59059321a6 Fix an issue with pathfinding not respecting the PathFindAllowCreatures flag properly (#1090) 2020-06-13 09:00:01 +02:00
89 changed files with 719 additions and 974 deletions

View File

@@ -10,12 +10,14 @@ on:
- v*
paths:
- .github/workflows/**
- cmake/**
- src/**
- CMakeLists.txt
pull_request:
paths:
- .github/workflows/**
- cmake/**
- src/**
- CMakeLists.txt
@@ -23,50 +25,48 @@ on:
jobs:
job:
name: ${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.buildtype }}-luajit=${{ matrix.luajit }}
runs-on: ${{ matrix.os }}-latest
runs-on: ${{ matrix.os }}-${{ matrix.os-version }}
strategy:
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:
- name: windows-msvc
os: windows
os-version: latest
cxx: cl.exe
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
os-version: 20.04
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
os-version: latest
cxx: clang++
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
- uses: actions/checkout@v3
with:
submodules: true
@@ -77,57 +77,57 @@ 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
with:
vcpkgArguments: ${{ matrix.packages }}
vcpkgDirectory: ${{ runner.workspace }}/vcpkg/
vcpkgTriplet: ${{ matrix.triplet }}
vcpkgGitCommitId: 7db401cb1ef1fc559ec9f9ce814d064c328fd767
vcpkgGitCommitId: 6f7ffeb18f99796233b958aaaf14ec7bd4fb64b2
- 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
shell: bash
- name: Upload artifact binary
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: otclient-${{ matrix.name }}-${{ matrix.buildtype }}-luajit=${{ matrix.luajit }}-${{ github.sha }}
path: ${{ runner.workspace }}/build/otclient
if: "! contains( matrix.os, 'windows')"
- name: Upload artifact binary (exe)
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: otclient-${{ matrix.name }}-${{ matrix.buildtype }}-luajit=${{ matrix.luajit }}-${{ github.sha }}
path: ${{ runner.workspace }}/build/otclient.exe
if: contains( matrix.os, 'windows')
- name: Upload artifact binary (dlls)
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
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

@@ -17,12 +17,11 @@ RUN apt-get update; \
libopenal-dev \
libssl-dev \
libvorbis-dev \
mercurial \
zlib1g-dev; \
apt-get clean && apt-get autoclean
WORKDIR /
RUN hg clone -r stable-3.0 http://hg.icculus.org/icculus/physfs/
RUN git clone --branch release-3.0.2 --depth 1 https://github.com/icculus/physfs.git
WORKDIR /physfs/build/
RUN cmake ..
RUN make -j$(nproc)

View File

@@ -1,4 +1,4 @@
[![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?

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

@@ -19,4 +19,3 @@ Module
- client_terminal
- client_modulemanager
- client_serverlist
- client_stats

View File

@@ -109,8 +109,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)
@@ -190,17 +190,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

@@ -1,131 +0,0 @@
UUID = nil
HOST = 'otclient.herokuapp.com'
PORT = 80
FIRST_REPORT_DELAY = 15
REPORT_DELAY = 60
sendReportEvent = nil
firstReportEvent = nil
function initUUID()
UUID = g_settings.getString('report-uuid')
if not UUID or #UUID ~= 36 then
UUID = g_crypt.genUUID()
g_settings.set('report-uuid', UUID)
end
end
function init()
connect(g_game, { onGameStart = onGameStart,
onGameEnd = onGameEnd })
initUUID()
end
function terminate()
disconnect(g_game, { onGameStart = onGameStart,
onGameEnd = onGameEnd })
removeEvent(firstReportEvent)
removeEvent(sendReportEvent)
end
function configure(host, port, delay)
if not host then return end
HOST = host
PORT = port or PORT
REPORT_DELAY = delay or REPORT_DELAY
end
function sendReport()
if not HOST then return end
local protocolHttp = ProtocolHttp.create()
protocolHttp.onConnect = onConnect
protocolHttp.onRecv = onRecv
protocolHttp.onError = onError
protocolHttp:connect(HOST, PORT)
end
function onGameStart()
if not HOST then return end
removeEvent(firstReportEvent)
removeEvent(sendReportEvent)
firstReportEvent = addEvent(sendReport, FIRST_REPORT_DELAY*1000)
sendReportEvent = cycleEvent(sendReport, REPORT_DELAY*1000)
end
function onGameEnd()
removeEvent(firstReportEvent)
removeEvent(sendReportEvent)
end
function onConnect(protocol)
if not g_game.isOnline() then
protocol:disconnect()
return
end
local post = ''
post = post .. 'uid=' .. urlencode(UUID)
post = post .. '&report_delay=' .. REPORT_DELAY
post = post .. '&os=' .. urlencode(g_app.getOs())
post = post .. '&graphics_vendor=' .. urlencode(g_graphics.getVendor())
post = post .. '&graphics_renderer=' .. urlencode(g_graphics.getRenderer())
post = post .. '&graphics_version=' .. urlencode(g_graphics.getVersion())
post = post .. '&painter_engine=' .. urlencode(g_graphics.getPainterEngine())
post = post .. '&fps=' .. urlencode(g_app.getBackgroundPaneFps())
post = post .. '&max_fps=' .. urlencode(g_app.getBackgroundPaneMaxFps())
post = post .. '&fullscreen=' .. urlencode(tostring(g_window.isFullscreen()))
post = post .. '&window_width=' .. urlencode(g_window.getWidth())
post = post .. '&window_height=' .. urlencode(g_window.getHeight())
post = post .. '&player_name=' .. urlencode(g_game.getCharacterName())
post = post .. '&world_name=' .. urlencode(g_game.getWorldName())
post = post .. '&otserv_host=' .. urlencode(G.host)
post = post .. '&otserv_port=' .. G.port
post = post .. '&otserv_protocol=' .. urlencode(g_game.getProtocolVersion())
post = post .. '&otserv_client=' .. urlencode(g_game.getClientVersion())
post = post .. '&build_version=' .. urlencode(g_app.getVersion())
post = post .. '&build_revision=' .. urlencode(g_app.getBuildRevision())
post = post .. '&build_commit=' .. urlencode(g_app.getBuildCommit())
post = post .. '&build_date=' .. urlencode(g_app.getBuildDate())
post = post .. '&display_width=' .. g_window.getDisplayWidth()
post = post .. '&display_height=' .. g_window.getDisplayHeight()
post = post .. '&cpu=' .. urlencode(g_platform.getCPUName())
post = post .. '&mem=' .. g_platform.getTotalSystemMemory()
post = post .. '&os_name=' .. urlencode(g_platform.getOSName())
post = post .. getAdditionalData()
local message = ''
message = message .. "POST /report HTTP/1.1\r\n"
message = message .. "Host: " .. HOST .. "\r\n"
message = message .. "Accept: */*\r\n"
message = message .. "Connection: close\r\n"
message = message .. "Content-Type: application/x-www-form-urlencoded\r\n"
message = message .. "Content-Length: " .. post:len() .. "\r\n\r\n"
message = message .. post
protocol:send(message)
protocol:recv()
end
function getAdditionalData()
return ''
end
function onRecv(protocol, message)
if string.find(message, 'HTTP/1.1 200 OK') then
--pinfo('Stats sent to server successfully!')
end
protocol:disconnect()
end
function onError(protocol, message, code)
pdebug('Could not send statistics: ' .. message)
end
function urlencode(str)
local encodeChar=function(chr)
return string.format("%%%X",string.byte(chr))
end
local output, t = string.gsub(str,"[^%w]",encodeChar)
return output
end

View File

@@ -1,9 +0,0 @@
Module
name: client_stats
description: Sends client statistics to a server
author: baxnie
website: https://github.com/edubart/otclient
sandboxed: true
scripts: [ stats ]
@onLoad: init()
@onUnload: terminate()

View File

@@ -334,9 +334,12 @@ function UIMoveableTabBar:removeTab(tab)
end
if self.currentTab == tab then
self:selectPrevTab()
if #self.tabs == 1 then
self.currentTab = nil
elseif index == #self.tabs then
self:selectPrevTab()
else
self:selectNextTab()
end
end
table.remove(tabTable, index)

View File

@@ -77,7 +77,13 @@ function UITabBar:removeTab(tab)
local index = table.find(self.tabs, tab)
if index == nil then return end
if self.currentTab == tab then
self:selectPrevTab()
if #self.tabs == 1 then
self.currentTab = nil
elseif index == #self.tabs then
self:selectPrevTab()
else
self:selectNextTab()
end
end
table.remove(self.tabs, index)
tab:destroy()

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

@@ -20,6 +20,7 @@ function UIItem:onDragLeave(droppedWidget, mousePos)
end
function UIItem:onDrop(widget, mousePos)
self:setBorderWidth(0)
if not self:canAcceptDrop(widget, mousePos) then
return false
@@ -47,7 +48,6 @@ function UIItem:onDrop(widget, mousePos)
g_game.move(item, toPos, 1)
end
self:setBorderWidth(0)
return true
end

View File

@@ -103,12 +103,12 @@ function loadMap(clean)
end
if otmm then
local minimapFile = '/minimap.otmm'
local minimapFile = '/minimap_'.. G.host ..'.otmm'
if g_resources.fileExists(minimapFile) then
g_minimap.loadOtmm(minimapFile)
end
else
local minimapFile = '/minimap_' .. clientVersion .. '.otcm'
local minimapFile = '/minimap_' .. clientVersion .. '_'.. G.host ..'.otcm'
if g_resources.fileExists(minimapFile) then
g_map.loadOtcm(minimapFile)
end
@@ -119,10 +119,10 @@ end
function saveMap()
local clientVersion = g_game.getClientVersion()
if otmm then
local minimapFile = '/minimap.otmm'
local minimapFile = '/minimap_'.. G.host ..'.otmm'
g_minimap.saveOtmm(minimapFile)
else
local minimapFile = '/minimap_' .. clientVersion .. '.otcm'
local minimapFile = '/minimap_' .. clientVersion .. '_'.. G.host ..'.otcm'
g_map.saveOtcm(minimapFile)
end
minimapWidget:save()

View File

@@ -1,5 +1,5 @@
skillsWindow = nil
skillsButton = nil
local skillsWindow = nil
local skillsButton = nil
function init()
connect(LocalPlayer, {
@@ -350,11 +350,11 @@ function onStaminaChange(localPlayer, stamina)
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. '\n' ..
tr("You will not gain 50%% more experience because you aren't premium player, now you receive only 1x experience points")
setSkillPercent('stamina', percent, text, '#89F013')
elseif stamina > 2400 and g_game.getClientVersion() < 1038 then
elseif stamina >= 2400 and g_game.getClientVersion() < 1038 then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. '\n' ..
tr("If you are premium player, you will gain 50%% more experience")
setSkillPercent('stamina', percent, text, 'green')
elseif stamina <= 2400 and stamina > 840 then
elseif stamina < 2400 and stamina > 840 then
setSkillPercent('stamina', percent, tr("You have %s hours and %s minutes left", hours, minutes), 'orange')
elseif stamina <= 840 and stamina > 0 then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. "\n" ..

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)
@@ -109,5 +104,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

@@ -53,7 +53,7 @@ void AnimatedText::drawText(const Point& dest, const Rect& visibleRect)
if(visibleRect.contains(rect)) {
//TODO: cache into a framebuffer
float t0 = tf / 1.2;
float t0 = tf / 1.2f;
if(t > t0) {
Color color = m_color;
color.setAlpha((float)(1 - (t - t0) / (tf - t0)));
@@ -92,7 +92,7 @@ bool AnimatedText::merge(const AnimatedTextPtr& other)
if(other->getCachedText().getFont() != m_cachedText.getFont())
return false;
if(m_animationTimer.ticksElapsed() > Otc::ANIMATED_TEXT_DURATION / 2.5)
if(m_animationTimer.ticksElapsed() > Otc::ANIMATED_TEXT_DURATION / 2.5f)
return false;
try {

View File

@@ -78,7 +78,7 @@ void Container::onAddItem(const ItemPtr& item, int slot)
ItemPtr Container::findItemById(uint itemId, int subType)
{
for(const ItemPtr item : m_items)
for(const ItemPtr& item : m_items)
if(item->getId() == itemId && (subType == -1 || item->getSubType() == subType))
return item;
return nullptr;

View File

@@ -483,14 +483,14 @@ void Creature::onDeath()
callLuaField("onDeath");
}
void Creature::updateWalkAnimation(int totalPixelsWalked)
void Creature::updateWalkAnimation(int totalPixelsWalked, int stepDuration)
{
// update outfit animation
if(m_outfit.getCategory() != ThingCategoryCreature)
return;
int footAnimPhases = getAnimationPhases() - 1;
int footDelay = getStepDuration(true) / 3;
int footDelay = stepDuration / 3;
// Since mount is a different outfit we need to get the mount animation phases
if(m_outfit.getMount() != 0) {
ThingType *type = g_things.rawGetThingType(m_outfit.getMount(), m_outfit.getCategory());
@@ -579,20 +579,20 @@ void Creature::nextWalkUpdate()
m_walkUpdateEvent = g_dispatcher.scheduleEvent([self] {
self->m_walkUpdateEvent = nullptr;
self->nextWalkUpdate();
}, getStepDuration() / 32);
}, getStepDuration(true) / Otc::TILE_PIXELS);
}
}
void Creature::updateWalk()
{
float walkTicksPerPixel = getStepDuration(true) / 32;
int totalPixelsWalked = std::min<int>(m_walkTimer.ticksElapsed() / walkTicksPerPixel, 32.0f);
int stepDuration = getStepDuration(true);
int totalPixelsWalked = stepDuration ? std::min<int>((m_walkTimer.ticksElapsed() * Otc::TILE_PIXELS) / stepDuration, Otc::TILE_PIXELS) : 0;
// needed for paralyze effect
m_walkedPixels = std::max<int>(m_walkedPixels, totalPixelsWalked);
// update walk animation and offsets
updateWalkAnimation(totalPixelsWalked);
updateWalkAnimation(totalPixelsWalked, stepDuration);
updateWalkOffset(m_walkedPixels);
updateWalkingTile();

View File

@@ -135,7 +135,7 @@ public:
virtual void onDeath();
protected:
virtual void updateWalkAnimation(int totalPixelsWalked);
virtual void updateWalkAnimation(int totalPixelsWalked, int stepDuration);
virtual void updateWalkOffset(int totalPixelsWalked);
void updateWalkingTile();
virtual void nextWalkUpdate();

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

@@ -59,7 +59,7 @@ LocalPlayer::LocalPlayer()
void LocalPlayer::lockWalk(int millis)
{
m_walkLockExpiration = std::max<int>(m_walkLockExpiration, (ticks_t) g_clock.millis() + millis);
m_walkLockExpiration = std::max<ticks_t>(m_walkLockExpiration, g_clock.millis() + millis);
}
bool LocalPlayer::canWalk(Otc::Direction)
@@ -102,8 +102,9 @@ void LocalPlayer::walk(const Position& oldPos, const Position& newPos)
if(newPos == m_lastPrewalkDestination) {
updateWalk();
// was to another direction, replace the walk
} else
} else {
Creature::walk(oldPos, newPos);
}
}
// no prewalk was going on, this must be an server side automated walk
else {
@@ -259,23 +260,23 @@ void LocalPlayer::updateWalkOffset(int totalPixelsWalked)
m_walkOffset.x = totalPixelsWalked;
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
m_walkOffset.x = -totalPixelsWalked;
} else
} else {
Creature::updateWalkOffset(totalPixelsWalked);
}
}
void LocalPlayer::updateWalk()
{
int stepDuration = getStepDuration();
float walkTicksPerPixel = getStepDuration(true) / 32.0f;
int totalPixelsWalked = std::min<int>(m_walkTimer.ticksElapsed() / walkTicksPerPixel, 32.0f);
int stepDuration = getStepDuration(true);
int totalPixelsWalked = stepDuration ? std::min<int>((m_walkTimer.ticksElapsed() * Otc::TILE_PIXELS) / stepDuration, Otc::TILE_PIXELS) : 0;
// update walk animation and offsets
updateWalkAnimation(totalPixelsWalked);
updateWalkAnimation(totalPixelsWalked, stepDuration);
updateWalkOffset(totalPixelsWalked);
updateWalkingTile();
// terminate walk only when client and server side walk are completed
if(m_walking && !m_preWalking && m_walkTimer.ticksElapsed() >= stepDuration)
if(m_walking && !m_preWalking && m_walkTimer.ticksElapsed() >= getStepDuration())
terminateWalk();
}
@@ -426,7 +427,7 @@ void LocalPlayer::setMana(double mana, double maxMana)
{
if(m_mana != mana || m_maxMana != maxMana) {
double oldMana = m_mana;
double oldMaxMana;
double oldMaxMana = m_maxMana;
m_mana = mana;
m_maxMana = maxMana;

View File

@@ -85,7 +85,7 @@ public:
double getStamina() { return m_stamina; }
double getRegenerationTime() { return m_regenerationTime; }
double getOfflineTrainingTime() { return m_offlineTrainingTime; }
std::vector<int> getSpells() { return m_spells; }
const std::vector<int>& getSpells() { return m_spells; }
ItemPtr getInventoryItem(Otc::InventorySlot inventory) { return m_inventoryItems[inventory]; }
int getBlessings() { return m_blessings; }

View File

@@ -596,6 +596,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

@@ -134,7 +134,7 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
if(prevAnimatedText) {
Point offset = prevAnimatedText->getOffset();
float t = prevAnimatedText->getTimer().ticksElapsed();
if(t < Otc::ANIMATED_TEXT_DURATION / 4.0) { // didnt move 12 pixels
if(t < Otc::ANIMATED_TEXT_DURATION / 4.f) { // didnt move 12 pixels
int y = 12 - 48 * t / (float)Otc::ANIMATED_TEXT_DURATION;
offset += Point(0, y);
}
@@ -718,18 +718,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 {
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;
@@ -751,7 +753,7 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
// check the goal pos is walkable
if(g_map.isAwareOfPosition(goalPos)) {
const TilePtr goalTile = getTile(goalPos);
if(!goalTile || !goalTile->isWalkable()) {
if(!goalTile || !goalTile->isWalkable((flags & Otc::PathFindAllowCreatures))) {
return ret;
}
}
@@ -762,8 +764,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::vector<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;
@@ -799,7 +801,7 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
wasSeen = true;
if(const TilePtr& tile = getTile(neighborPos)) {
hasCreature = tile->hasCreature();
isNotWalkable = !tile->isWalkable();
isNotWalkable = !tile->isWalkable((flags & Otc::PathFindAllowCreatures));
isNotPathable = !tile->isPathable();
speed = tile->getGroundSpeed();
}
@@ -856,7 +858,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

@@ -253,7 +253,7 @@ private:
std::vector<AnimatedTextPtr> m_animatedTexts;
std::vector<StaticTextPtr> m_staticTexts;
std::vector<MapViewPtr> m_mapViews;
std::unordered_map<Position, std::string, PositionHasher> m_waypoints;
std::unordered_map<Position, std::string, Position::Hasher> m_waypoints;
uint8 m_animationFlags;
uint32 m_zoneFlags;

View File

@@ -37,38 +37,38 @@ Color Outfit::getColor(int color)
float loc1 = 0, loc2 = 0, loc3 = 0;
if(color % HSI_H_STEPS != 0) {
loc1 = color % HSI_H_STEPS * 1.0/18.0;
loc1 = color % HSI_H_STEPS * 1.f/18.f;
loc2 = 1;
loc3 = 1;
switch(int(color / HSI_H_STEPS)) {
case 0:
loc2 = 0.25;
loc3 = 1.00;
loc2 = 0.25f;
loc3 = 1.f;
break;
case 1:
loc2 = 0.25;
loc3 = 0.75;
loc2 = 0.25f;
loc3 = 0.75f;
break;
case 2:
loc2 = 0.50;
loc3 = 0.75;
loc2 = 0.5f;
loc3 = 0.75f;
break;
case 3:
loc2 = 0.667;
loc3 = 0.75;
loc2 = 0.667f;
loc3 = 0.75f;
break;
case 4:
loc2 = 1.00;
loc3 = 1.00;
loc2 = 1.f;
loc3 = 1.f;
break;
case 5:
loc2 = 1.00;
loc3 = 0.75;
loc2 = 1.f;
loc3 = 0.75f;
break;
case 6:
loc2 = 1.00;
loc3 = 0.50;
loc2 = 1.f;
loc3 = 0.5f;
break;
}
}
@@ -88,27 +88,27 @@ Color Outfit::getColor(int color)
float red = 0, green = 0, blue = 0;
if(loc1 < 1.0/6.0) {
if(loc1 < 1.f/6.f) {
red = loc3;
blue = loc3 * (1 - loc2);
green = blue + (loc3 - blue) * 6 * loc1;
}
else if(loc1 < 2.0/6.0) {
else if(loc1 < 2.f/6.f) {
green = loc3;
blue = loc3 * (1 - loc2);
red = green - (loc3 - blue) * (6 * loc1 - 1);
}
else if(loc1 < 3.0/6.0) {
else if(loc1 < 3.f/6.f) {
green = loc3;
red = loc3 * (1 - loc2);
blue = red + (loc3 - red) * (6 * loc1 - 2);
}
else if(loc1 < 4.0/6.0) {
else if(loc1 < 4.f/6.f) {
blue = loc3;
red = loc3 * (1 - loc2);
green = blue - (loc3 - red) * (6 * loc1 - 3);
}
else if(loc1 < 5.0/6.0) {
else if(loc1 < 5.f/6.f) {
blue = loc3;
green = loc3 * (1 - loc2);
red = green + (loc3 - green) * (6 * loc1 - 4);

View File

@@ -131,7 +131,7 @@ public:
return positions;
}
static double getAngleFromPositions(const Position& fromPos, const Position& toPos) {
static float getAngleFromPositions(const Position& fromPos, const Position& toPos) {
// Returns angle in radians from 0 to 2Pi. -1 means positions are equal.
int dx = toPos.x - fromPos.x;
int dy = toPos.y - fromPos.y;
@@ -145,7 +145,7 @@ public:
return angle;
}
double getAngleFromPosition(const Position& position) const {
float getAngleFromPosition(const Position& position) const {
return getAngleFromPositions(*this, position);
}
@@ -154,21 +154,21 @@ public:
{
float angle = getAngleFromPositions(fromPos, toPos) * RAD_TO_DEC;
if(angle >= 360 - 22.5 || angle < 0 + 22.5)
if(angle >= 360 - 22.5f || angle < 0 + 22.5f)
return Otc::East;
else if(angle >= 45 - 22.5 && angle < 45 + 22.5)
else if(angle >= 45 - 22.5f && angle < 45 + 22.5f)
return Otc::NorthEast;
else if(angle >= 90 - 22.5 && angle < 90 + 22.5)
else if(angle >= 90 - 22.5f && angle < 90 + 22.5f)
return Otc::North;
else if(angle >= 135 - 22.5 && angle < 135 + 22.5)
else if(angle >= 135 - 22.5f && angle < 135 + 22.5f)
return Otc::NorthWest;
else if(angle >= 180 - 22.5 && angle < 180 + 22.5)
else if(angle >= 180 - 22.5f && angle < 180 + 22.5f)
return Otc::West;
else if(angle >= 225 - 22.5 && angle < 225 + 22.5)
else if(angle >= 225 - 22.5f && angle < 225 + 22.5f)
return Otc::SouthWest;
else if(angle >= 270 - 22.5 && angle < 270 + 22.5)
else if(angle >= 270 - 22.5f && angle < 270 + 22.5f)
return Otc::South;
else if(angle >= 315 - 22.5 && angle < 315 + 22.5)
else if(angle >= 315 - 22.5f && angle < 315 + 22.5f)
return Otc::SouthEast;
else
return Otc::InvalidDirection;
@@ -243,12 +243,14 @@ public:
int x;
int y;
short z;
};
struct PositionHasher : std::unary_function<Position, std::size_t> {
std::size_t operator()(const Position& pos) const {
return (((pos.x * 8192) + pos.y) * 16) + pos.z;
}
// NOTE: This does not increase the size of the struct.
struct Hasher
{
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

@@ -77,6 +77,49 @@ void buildMessageModesMap(int version) {
messageModesMap[Otc::MessageTutorialHint] = 40;
messageModesMap[Otc::MessageThankyou] = 41;
messageModesMap[Otc::MessageMarket] = 42;
} else if(version >= 1041) {
messageModesMap[Otc::MessageNone] = 0;
messageModesMap[Otc::MessageSay] = 1;
messageModesMap[Otc::MessageWhisper] = 2;
messageModesMap[Otc::MessageYell] = 3;
messageModesMap[Otc::MessagePrivateFrom] = 4;
messageModesMap[Otc::MessagePrivateTo] = 5;
messageModesMap[Otc::MessageChannelManagement] = 6;
messageModesMap[Otc::MessageChannel] = 7;
messageModesMap[Otc::MessageChannelHighlight] = 8;
messageModesMap[Otc::MessageSpell] = 9;
messageModesMap[Otc::MessageNpcFromStartBlock] = 10;
messageModesMap[Otc::MessageNpcFrom] = 11;
messageModesMap[Otc::MessageNpcTo] = 12;
messageModesMap[Otc::MessageGamemasterBroadcast] = 13;
messageModesMap[Otc::MessageGamemasterChannel] = 14;
messageModesMap[Otc::MessageGamemasterPrivateFrom] = 15;
messageModesMap[Otc::MessageGamemasterPrivateTo] = 16;
messageModesMap[Otc::MessageLogin] = 17;
messageModesMap[Otc::MessageWarning] = 18; // Admin
messageModesMap[Otc::MessageGame] = 19;
messageModesMap[Otc::MessageFailure] = 20;
messageModesMap[Otc::MessageLook] = 21;
messageModesMap[Otc::MessageDamageDealed] = 22;
messageModesMap[Otc::MessageDamageReceived] = 23;
messageModesMap[Otc::MessageHeal] = 24;
messageModesMap[Otc::MessageExp] = 25;
messageModesMap[Otc::MessageDamageOthers] = 26;
messageModesMap[Otc::MessageHealOthers] = 27;
messageModesMap[Otc::MessageExpOthers] = 28;
messageModesMap[Otc::MessageStatus] = 29;
messageModesMap[Otc::MessageLoot] = 30;
messageModesMap[Otc::MessageTradeNpc] = 31;
messageModesMap[Otc::MessageGuild] = 32;
messageModesMap[Otc::MessagePartyManagement] = 33;
messageModesMap[Otc::MessageParty] = 34;
messageModesMap[Otc::MessageBarkLow] = 35;
messageModesMap[Otc::MessageBarkLoud] = 36;
messageModesMap[Otc::MessageReport] = 37;
messageModesMap[Otc::MessageHotkeyUse] = 38;
messageModesMap[Otc::MessageTutorialHint] = 49;
messageModesMap[Otc::MessageThankyou] = 40;
messageModesMap[Otc::MessageMarket] = 41;
} else if(version >= 1036) {
for(int i = Otc::MessageNone; i <= Otc::MessageBeyondLast; ++i) {
if(i >= Otc::MessageNpcTo)

View File

@@ -1,67 +0,0 @@
/*
* Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef DATMANAGER_H
#define DATMANAGER_H
#include <framework/global.h>
#include <framework/core/declarations.h>
#include "thingtype.h"
//@bindsingleton g_thingsType
class ThingsType
{
public:
enum Categories {
Item = 0,
Creature,
Effect,
Missile,
LastCategory
};
bool load(const std::string& file);
void unload();
bool parseThingType(const FileStreamPtr& fin, ThingType& thingType);
ThingType *getEmptyThingType() { return &m_emptyThingType; }
ThingType *getThingType(uint16 id, Categories category);
uint32 getSignature() { return m_signature; }
bool isLoaded() { return m_loaded; }
uint16 getFirstItemId() { return 100; }
uint16 getMaxItemid() { return m_things[Item].size() + 99; }
bool isValidItemId(int id) { return id >= getFirstItemId() && id <= getMaxItemid(); }
private:
uint32 m_signature;
stdext::boolean<false> m_loaded;
ThingTypeList m_things[LastCategory];
static ThingType m_emptyThingType;
};
extern ThingsType g_thingsType;
#endif

View File

@@ -550,7 +550,7 @@ bool Tile::isClickable()
bool Tile::isEmpty()
{
return m_things.size() == 0;
return m_things.empty();
}
bool Tile::isDrawable()

View File

@@ -88,8 +88,8 @@ public:
int getDrawElevation() { return m_drawElevation; }
std::vector<ItemPtr> getItems();
std::vector<CreaturePtr> getCreatures();
std::vector<CreaturePtr> getWalkingCreatures() { return m_walkingCreatures; }
std::vector<ThingPtr> getThings() { return m_things; }
const std::vector<CreaturePtr>& getWalkingCreatures() { return m_walkingCreatures; }
const std::vector<ThingPtr>& getThings() { return m_things; }
ItemPtr getGround();
int getGroundSpeed();
uint8 getMinimapColorByte();
@@ -132,9 +132,9 @@ public:
private:
void checkTranslucentLight();
stdext::packed_vector<CreaturePtr> m_walkingCreatures;
stdext::packed_vector<EffectPtr> m_effects; // leave this outside m_things because it has no stackpos.
stdext::packed_vector<ThingPtr> m_things;
std::vector<CreaturePtr> m_walkingCreatures;
std::vector<EffectPtr> m_effects; // leave this outside m_things because it has no stackpos.
std::vector<ThingPtr> m_things;
Position m_position;
uint8 m_drawElevation;
uint8 m_minimapColor;

View File

@@ -43,36 +43,36 @@ void UIProgressRect::drawSelf(Fw::DrawPane drawPane)
// 0% - 12.5% (12.5)
// triangle from top center, to top right (var x)
if(m_percent < 12.5) {
Point var = Point(std::max<int>(m_percent - 0.0, 0.0) * (drawRect.right() - drawRect.horizontalCenter()) / 12.5, 0);
if(m_percent < 12.5f) {
Point var = Point(std::max<int>(m_percent - 0.f, 0.f) * (drawRect.right() - drawRect.horizontalCenter()) / 12.5f, 0);
g_painter->drawFilledTriangle(drawRect.center(), drawRect.topRight() + Point(1,0), drawRect.topCenter() + var);
}
// 12.5% - 37.5% (25)
// triangle from top right to bottom right (var y)
if(m_percent < 37.5) {
Point var = Point(0, std::max<int>(m_percent - 12.5, 0.0) * (drawRect.bottom() - drawRect.top()) / 25.0);
if(m_percent < 37.5f) {
Point var = Point(0, std::max<int>(m_percent - 12.5f, 0.f) * (drawRect.bottom() - drawRect.top()) / 25.f);
g_painter->drawFilledTriangle(drawRect.center(), drawRect.bottomRight() + Point(1,1), drawRect.topRight() + var + Point(1,0));
}
// 37.5% - 62.5% (25)
// triangle from bottom right to bottom left (var x)
if(m_percent < 62.5) {
Point var = Point(std::max<int>(m_percent - 37.5, 0.0) * (drawRect.right() - drawRect.left()) / 25.0, 0);
if(m_percent < 62.5f) {
Point var = Point(std::max<int>(m_percent - 37.5f, 0.f) * (drawRect.right() - drawRect.left()) / 25.f, 0);
g_painter->drawFilledTriangle(drawRect.center(), drawRect.bottomLeft() + Point(0,1), drawRect.bottomRight() - var + Point(1,1));
}
// 62.5% - 87.5% (25)
// triangle from bottom left to top left
if(m_percent < 87.5) {
Point var = Point(0, std::max<int>(m_percent - 62.5, 0.0) * (drawRect.bottom() - drawRect.top()) / 25.0);
if(m_percent < 87.5f) {
Point var = Point(0, std::max<int>(m_percent - 62.5f, 0.f) * (drawRect.bottom() - drawRect.top()) / 25.f);
g_painter->drawFilledTriangle(drawRect.center(), drawRect.topLeft(), drawRect.bottomLeft() - var + Point(0,1));
}
// 87.5% - 100% (12.5)
// triangle from top left to top center
if(m_percent < 100) {
Point var = Point(std::max<int>(m_percent - 87.5, 0.0) * (drawRect.horizontalCenter() - drawRect.left()) / 12.5, 0);
Point var = Point(std::max<int>(m_percent - 87.5f, 0.f) * (drawRect.horizontalCenter() - drawRect.left()) / 12.5f, 0);
g_painter->drawFilledTriangle(drawRect.center(), drawRect.topCenter(), drawRect.topLeft() + var);
}
@@ -84,7 +84,7 @@ void UIProgressRect::drawSelf(Fw::DrawPane drawPane)
void UIProgressRect::setPercent(float percent)
{
m_percent = stdext::clamp<float>((double)percent, 0.0, 100.0);
m_percent = stdext::clamp<float>(percent, 0.f, 100.f);
}
void UIProgressRect::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)

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}")
@@ -49,7 +44,6 @@ set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/stdext/net.h
${CMAKE_CURRENT_LIST_DIR}/stdext/packed_any.h
${CMAKE_CURRENT_LIST_DIR}/stdext/packed_storage.h
${CMAKE_CURRENT_LIST_DIR}/stdext/packed_vector.h
${CMAKE_CURRENT_LIST_DIR}/stdext/shared_object.h
${CMAKE_CURRENT_LIST_DIR}/stdext/shared_ptr.h
${CMAKE_CURRENT_LIST_DIR}/stdext/stdext.h
@@ -134,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")
@@ -275,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 "")
@@ -295,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,7 +52,7 @@
namespace Fw
{
static const float pi = 3.14159265;
static const float pi = 3.14159265f;
static const float MIN_ALPHA = 0.003f;
enum Key : unsigned char {
KeyUnknown = 0,

View File

@@ -46,7 +46,9 @@ void exitSignalHandler(int sig)
case SIGINT:
if(!signaled && !g_app.isStopping() && !g_app.isTerminated()) {
signaled = true;
g_dispatcher.addEvent(std::bind(&Application::close, &g_app));
g_dispatcher.addEvent([] () {
g_app.close();
});
}
break;
}

View File

@@ -38,7 +38,9 @@ void AsyncDispatcher::terminate()
void AsyncDispatcher::spawn_thread()
{
m_running = true;
m_threads.emplace_back(std::bind(&AsyncDispatcher::exec_loop, this));
m_threads.emplace_back([this] () {
exec_loop();
});
}
void AsyncDispatcher::stop()

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

@@ -74,7 +74,7 @@ void EventDispatcher::poll()
event->execute();
}
m_pollEventsSize = m_eventList.size();
loops++;
}
}
@@ -116,4 +116,3 @@ EventPtr EventDispatcher::addEvent(const std::function<void()>& callback, bool p
m_eventList.push_back(event);
return event;
}

View File

@@ -40,10 +40,10 @@ public:
ScheduledEventPtr cycleEvent(const std::function<void()>& callback, int delay);
private:
std::list<EventPtr> m_eventList;
std::deque<EventPtr> m_eventList;
int m_pollEventsSize;
stdext::boolean<false> m_disabled;
std::priority_queue<ScheduledEventPtr, std::vector<ScheduledEventPtr>, lessScheduledEvent> m_scheduledEventList;
std::priority_queue<ScheduledEventPtr, std::deque<ScheduledEventPtr>, ScheduledEvent::Compare> m_scheduledEventList;
};
extern EventDispatcher g_dispatcher;

View File

@@ -45,9 +45,15 @@ void GraphicalApplication::init(std::vector<std::string>& args)
// setup platform window
g_window.init();
g_window.hide();
g_window.setOnResize(std::bind(&GraphicalApplication::resize, this, std::placeholders::_1));
g_window.setOnInputEvent(std::bind(&GraphicalApplication::inputEvent, this, std::placeholders::_1));
g_window.setOnClose(std::bind(&GraphicalApplication::close, this));
g_window.setOnResize([this] (auto size) {
resize(size);
});
g_window.setOnInputEvent([this] (const auto &event) {
inputEvent(event);
});
g_window.setOnClose([this] () {
close();
});
g_mouse.init();

View File

@@ -25,6 +25,7 @@
//#include <boost/regex.hpp>
#include <framework/core/resourcemanager.h>
#include <framework/core/asyncdispatcher.h>
#ifdef FW_GRAPHICS
#include <framework/platform/platformwindow.h>
@@ -34,6 +35,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 +50,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 +95,11 @@ void Logger::log(Fw::LogLevel level, const std::string& message)
#ifdef FW_GRAPHICS
g_window.displayFatalError(message);
#endif
ignoreLogs = true;
s_ignoreLogs = true;
// NOTE: Threads must finish before the process can exit.
g_asyncDispatcher.terminate();
exit(-1);
}
}
@@ -122,8 +130,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

@@ -156,14 +156,13 @@ void ResourceManager::searchAndAddPackages(const std::string& packagesDir, const
bool ResourceManager::fileExists(const std::string& fileName)
{
const std::string path = resolvePath(fileName);
return (PHYSFS_exists(path.c_str()) && !directoryExists(path));
return (PHYSFS_exists(resolvePath(fileName).c_str()) && !directoryExists(fileName));
}
bool ResourceManager::directoryExists(const std::string& directoryName)
{
PHYSFS_Stat stat = {};
if (!PHYSFS_stat(directoryName.c_str(), &stat)) {
if (!PHYSFS_stat(resolvePath(directoryName).c_str(), &stat)) {
return false;
}

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,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 = (uchar)text[i];
@@ -171,52 +178,49 @@ void BitmapFont::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::
const std::vector<Point>& BitmapFont::calculateGlyphsPositions(const std::string& text,
Fw::AlignmentFlag align,
Size *textBoxSize)
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;
textBoxSize->resize(0, m_glyphHeight);
return s_glyphsPositions;
}
// resize glyphsPositions vector when needed
if(textLength > (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) {
s_lineWidths[0] = 0;
for(int i = 0; i < textLength; ++i) {
glyph = (uchar)text[i];
if(glyph == (uchar)'\n') {
lines++;
if(lines+1 > (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) {
for(int i = 0; i < textLength; ++i) {
glyph = (uchar)text[i];
// new line or first glyph
@@ -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 != (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,11 +269,12 @@ 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) {
for(int glyph = m_firstGlyph; glyph < 256; ++glyph) {
Rect glyphCoords(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
glyphSize.width(),
@@ -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) {
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

@@ -158,6 +158,7 @@ static lua_Unsigned luaL_checkunsigned (lua_State *L, int arg) {
#define LUAMOD_API LUALIB_API
#define LUA_BIT32LIBNAME "bit32"
#undef luaL_newlib
#define luaL_newlib(x, y) luaL_register(x, LUA_BIT32LIBNAME, y)
/* ----- avoid a 'symbol redefined' warning below ----- */

View File

@@ -818,6 +818,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<OutputMessage>("addU32", &OutputMessage::addU32);
g_lua.bindClassMemberFunction<OutputMessage>("addU64", &OutputMessage::addU64);
g_lua.bindClassMemberFunction<OutputMessage>("addString", &OutputMessage::addString);
g_lua.bindClassMemberFunction<OutputMessage>("addRawString", &OutputMessage::addRawString);
g_lua.bindClassMemberFunction<OutputMessage>("addPaddingBytes", &OutputMessage::addPaddingBytes);
g_lua.bindClassMemberFunction<OutputMessage>("encryptRsa", &OutputMessage::encryptRsa);
g_lua.bindClassMemberFunction<OutputMessage>("getMessageSize", &OutputMessage::getMessageSize);

View File

@@ -98,20 +98,28 @@ void Connection::connect(const std::string& host, uint16 port, const std::functi
m_connectCallback = connectCallback;
asio::ip::tcp::resolver::query query(host, stdext::unsafe_cast<std::string>(port));
m_resolver.async_resolve(query, std::bind(&Connection::onResolve, asConnection(), std::placeholders::_1, std::placeholders::_2));
m_resolver.async_resolve(query, [connection = asConnection()] (auto error, auto iterator) {
connection->onResolve(error, iterator);
});
m_readTimer.cancel();
m_readTimer.expires_from_now(boost::posix_time::seconds(static_cast<uint32>(READ_TIMEOUT)));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
m_readTimer.async_wait([connection = asConnection()] (auto error) {
connection->onTimeout(error);
});
}
void Connection::internal_connect(asio::ip::basic_resolver<asio::ip::tcp>::iterator endpointIterator)
{
m_socket.async_connect(*endpointIterator, std::bind(&Connection::onConnect, asConnection(), std::placeholders::_1));
m_socket.async_connect(*endpointIterator, [connection = asConnection()] (auto error) {
connection->onConnect(error);
});
m_readTimer.cancel();
m_readTimer.expires_from_now(boost::posix_time::seconds(static_cast<uint32>(READ_TIMEOUT)));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
m_readTimer.async_wait([connection = asConnection()] (auto error) {
connection->onTimeout(error);
});
}
void Connection::write(uint8* buffer, size_t size)
@@ -129,7 +137,9 @@ void Connection::write(uint8* buffer, size_t size)
m_delayedWriteTimer.cancel();
m_delayedWriteTimer.expires_from_now(boost::posix_time::milliseconds(0));
m_delayedWriteTimer.async_wait(std::bind(&Connection::onCanWrite, asConnection(), std::placeholders::_1));
m_delayedWriteTimer.async_wait([connection = asConnection()] (auto error) {
connection->onCanWrite(error);
});
}
std::ostream os(m_outputStream.get());
@@ -145,13 +155,15 @@ void Connection::internal_write()
std::shared_ptr<asio::streambuf> outputStream = m_outputStream;
m_outputStream = nullptr;
asio::async_write(m_socket,
*outputStream,
std::bind(&Connection::onWrite, asConnection(), std::placeholders::_1, std::placeholders::_2, outputStream));
asio::async_write(m_socket, *outputStream, [connection = asConnection(), outputStream] (auto error, auto size) {
connection->onWrite(error, size, outputStream);
});
m_writeTimer.cancel();
m_writeTimer.expires_from_now(boost::posix_time::seconds(static_cast<uint32>(WRITE_TIMEOUT)));
m_writeTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
m_writeTimer.async_wait([connection = asConnection()] (auto error) {
connection->onTimeout(error);
});
}
void Connection::read(uint16 bytes, const RecvCallback& callback)
@@ -161,13 +173,15 @@ void Connection::read(uint16 bytes, const RecvCallback& callback)
m_recvCallback = callback;
asio::async_read(m_socket,
asio::buffer(m_inputStream.prepare(bytes)),
std::bind(&Connection::onRecv, asConnection(), std::placeholders::_1, std::placeholders::_2));
asio::async_read(m_socket, asio::mutable_buffer(m_inputStream.prepare(bytes)), [connection = asConnection()] (auto error, auto size) {
connection->onRecv(error, size);
});
m_readTimer.cancel();
m_readTimer.expires_from_now(boost::posix_time::seconds(static_cast<uint32>(READ_TIMEOUT)));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
m_readTimer.async_wait([connection = asConnection()] (auto error) {
connection->onTimeout(error);
});
}
void Connection::read_until(const std::string& what, const RecvCallback& callback)
@@ -177,14 +191,15 @@ void Connection::read_until(const std::string& what, const RecvCallback& callbac
m_recvCallback = callback;
asio::async_read_until(m_socket,
m_inputStream,
what,
std::bind(&Connection::onRecv, asConnection(), std::placeholders::_1, std::placeholders::_2));
asio::async_read_until(m_socket, m_inputStream, what, [connection = asConnection()] (auto error, auto size) {
connection->onRecv(error, size);
});
m_readTimer.cancel();
m_readTimer.expires_from_now(boost::posix_time::seconds(static_cast<uint32>(READ_TIMEOUT)));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
m_readTimer.async_wait([connection = asConnection()] (auto error) {
connection->onTimeout(error);
});
}
void Connection::read_some(const RecvCallback& callback)
@@ -194,12 +209,15 @@ void Connection::read_some(const RecvCallback& callback)
m_recvCallback = callback;
m_socket.async_read_some(asio::buffer(m_inputStream.prepare(RECV_BUFFER_SIZE)),
std::bind(&Connection::onRecv, asConnection(), std::placeholders::_1, std::placeholders::_2));
m_socket.async_read_some(asio::mutable_buffer(m_inputStream.prepare(RECV_BUFFER_SIZE)), [connection = asConnection()] (auto buffer, auto size) {
connection->onRecv(buffer, size);
});
m_readTimer.cancel();
m_readTimer.expires_from_now(boost::posix_time::seconds(static_cast<uint32>(READ_TIMEOUT)));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
m_readTimer.async_wait([connection = asConnection()] (auto error) {
connection->onTimeout(error);
});
}
void Connection::onResolve(const boost::system::error_code& error, asio::ip::basic_resolver<asio::ip::tcp>::iterator endpointIterator)

View File

@@ -89,6 +89,17 @@ void OutputMessage::addString(const std::string& buffer)
m_messageSize += len;
}
void OutputMessage::addRawString(const std::string& buffer)
{
int len = buffer.length();
if (len > MAX_STRING_LENGTH)
throw stdext::exception(stdext::format("string length > %d", MAX_STRING_LENGTH));
checkWrite(len);
memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), len);
m_writePos += len;
m_messageSize += len;
}
void OutputMessage::addPaddingBytes(int bytes, uint8 byte)
{
if(bytes <= 0)

View File

@@ -48,6 +48,7 @@ public:
void addU32(uint32 value);
void addU64(uint64 value);
void addString(const std::string& buffer);
void addRawString(const std::string& buffer);
void addPaddingBytes(int bytes, uint8 byte = 0);
void encryptRsa();

View File

@@ -43,8 +43,12 @@ Protocol::~Protocol()
void Protocol::connect(const std::string& host, uint16 port)
{
m_connection = ConnectionPtr(new Connection);
m_connection->setErrorCallback(std::bind(&Protocol::onError, asProtocol(), std::placeholders::_1));
m_connection->connect(host, port, std::bind(&Protocol::onConnect, asProtocol()));
m_connection->setErrorCallback([proto = asProtocol()] (auto error) {
proto->onError(error);
});
m_connection->connect(host, port, [proto = asProtocol()] () {
proto->onConnect();
});
}
void Protocol::disconnect()
@@ -104,7 +108,9 @@ void Protocol::recv()
// read the first 2 bytes which contain the message size
if(m_connection)
m_connection->read(2, std::bind(&Protocol::internalRecvHeader, asProtocol(), std::placeholders::_1, std::placeholders::_2));
m_connection->read(2, [proto = asProtocol()] (auto buffer, auto size) {
proto->internalRecvHeader(buffer, size);
});
}
void Protocol::internalRecvHeader(uint8* buffer, uint16 size)
@@ -115,7 +121,9 @@ void Protocol::internalRecvHeader(uint8* buffer, uint16 size)
// read remaining message data
if(m_connection)
m_connection->read(remainingSize, std::bind(&Protocol::internalRecvData, asProtocol(), std::placeholders::_1, std::placeholders::_2));
m_connection->read(remainingSize, [proto = asProtocol()] (auto buffer, auto size) {
proto->internalRecvData(buffer, size);
});
}
void Protocol::internalRecvData(uint8* buffer, uint16 size)
@@ -144,29 +152,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 +191,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 +221,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

@@ -39,8 +39,12 @@ ProtocolHttp::~ProtocolHttp()
void ProtocolHttp::connect(const std::string& host, uint16 port)
{
m_connection = ConnectionPtr(new Connection);
m_connection->setErrorCallback(std::bind(&ProtocolHttp::onError, asProtocolHttp(), std::placeholders::_1));
m_connection->connect(host, port, std::bind(&ProtocolHttp::onConnect, asProtocolHttp()));
m_connection->setErrorCallback([proto = asProtocolHttp()] (auto error) {
proto->onError(error);
});
m_connection->connect(host, port, [proto = asProtocolHttp()] () {
proto->onConnect();
});
}
void ProtocolHttp::disconnect()
@@ -60,7 +64,9 @@ void ProtocolHttp::send(const std::string& message)
void ProtocolHttp::recv()
{
if(m_connection)
m_connection->read_until("\r\n\r\n", std::bind(&ProtocolHttp::onRecv, asProtocolHttp(), std::placeholders::_1, std::placeholders::_2));
m_connection->read_until("\r\n\r\n", [proto = asProtocolHttp()] (auto buffer, auto size) {
proto->onRecv(buffer, size);
});
}
void ProtocolHttp::onConnect()

View File

@@ -119,9 +119,14 @@ ticks_t Platform::getFileModificationTime(std::string file)
void Platform::openUrl(std::string url)
{
if(url.find("http://") == std::string::npos)
if(url.find("http://") == std::string::npos && url.find("https://") == std::string::npos)
url.insert(0, "http://");
#if defined(__APPLE__)
system(stdext::format("open %s", url).c_str());
#else
system(stdext::format("xdg-open %s", url).c_str());
#endif
}
std::string Platform::getCPUName()
@@ -130,12 +135,13 @@ std::string Platform::getCPUName()
std::ifstream in("/proc/cpuinfo");
while(getline(in, line)) {
auto strs = stdext::split(line, ":");
std::string first = strs[0];
std::string second = strs[1];
stdext::trim(first);
stdext::trim(second);
if(strs.size() == 2 && first == "model name")
return second;
if(strs.size() == 2) {
stdext::trim(strs[0]);
if(strs[0] == "model name") {
stdext::trim(strs[1]);
return strs[1];
}
}
}
return std::string();
}
@@ -146,12 +152,13 @@ double Platform::getTotalSystemMemory()
std::ifstream in("/proc/meminfo");
while(getline(in, line)) {
auto strs = stdext::split(line, ":");
std::string first = strs[0];
std::string second = strs[1];
stdext::trim(first);
stdext::trim(second);
if(strs.size() == 2 && first == "MemTotal")
return stdext::unsafe_cast<double>(second.substr(0, second.length() - 3)) * 1000.0;
if(strs.size() == 2) {
stdext::trim(strs[0]);
if(strs[0] == "MemTotal") {
stdext::trim(strs[1]);
return stdext::unsafe_cast<double>(strs[1].substr(0, strs[1].length() - 3)) * 1000;
}
}
}
return 0;
}
@@ -161,8 +168,7 @@ std::string Platform::getOSName()
std::string line;
std::ifstream in("/etc/issue");
if(getline(in, line)) {
std::size_t end = line.find('\\');
std::string res = line.substr(0, end);
auto res = line.substr(0, line.find('\\'));
stdext::trim(res);
return res;
}

View File

@@ -148,7 +148,7 @@ ticks_t Platform::getFileModificationTime(std::string file)
void Platform::openUrl(std::string url)
{
if(url.find("http://") == std::string::npos)
if(url.find("http://") == std::string::npos && url.find("https://") == std::string::npos)
url.insert(0, "http://");
ShellExecuteW(NULL, L"open", stdext::utf8_to_utf16(url).c_str(), NULL, NULL, SW_SHOWNORMAL);
}

View File

@@ -852,10 +852,19 @@ void WIN32Window::setFullscreen(bool fullscreen)
wpPrev.length = sizeof(wpPrev);
if(fullscreen) {
Size size = getDisplaySize();
MONITORINFO mi;
HMONITOR m = MonitorFromWindow(m_window, MONITOR_DEFAULTTONEAREST);
mi.cbSize = sizeof(mi);
GetMonitorInfoW(m, &mi);
uint x = mi.rcMonitor.left;
uint y = mi.rcMonitor.top;
uint width = mi.rcMonitor.right - mi.rcMonitor.left;
uint height = mi.rcMonitor.bottom - mi.rcMonitor.top;
GetWindowPlacement(m_window, &wpPrev);
SetWindowLong(m_window, GWL_STYLE, (dwStyle & ~WS_OVERLAPPEDWINDOW) | WS_POPUP | WS_EX_TOPMOST);
SetWindowPos(m_window, HWND_TOPMOST, 0, 0, size.width(), size.height(), SWP_FRAMECHANGED);
SetWindowPos(m_window, HWND_TOPMOST, x, y, width, height, SWP_FRAMECHANGED);
} else {
SetWindowLong(m_window, GWL_STYLE, (dwStyle & ~(WS_POPUP | WS_EX_TOPMOST)) | WS_OVERLAPPEDWINDOW);
SetWindowPlacement(m_window, &wpPrev);

View File

@@ -88,6 +88,11 @@ X11Window::X11Window()
m_keyMap[XK_Meta_R] = Fw::KeyMeta;
m_keyMap[XK_Menu] = Fw::KeyMenu;
#if defined(__APPLE__)
m_keyMap[65406] = Fw::KeyAlt;// Option
m_keyMap[65511] = Fw::KeyMeta;// Command
#endif
// ascii characters
m_keyMap[XK_space] = Fw::KeySpace;
m_keyMap[XK_exclam] = Fw::KeyExclamation;

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

@@ -1,161 +0,0 @@
/*
* Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef STDEXT_PACKEDVECTOR_H
#define STDEXT_PACKEDVECTOR_H
#include <algorithm>
namespace stdext {
// disable memory alignment
#pragma pack(push,1)
template<class T, class U = uint8_t>
class packed_vector
{
public:
typedef U size_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
packed_vector() : m_size(0), m_data(nullptr) { }
packed_vector(size_type size) : m_size(size), m_data(new T[size]) { }
packed_vector(size_type size, const T& value) : m_size(size), m_data(new T[size]) { std::fill(begin(), end(), value); }
template <class InputIterator>
packed_vector(InputIterator first, InputIterator last) : m_size(last - first), m_data(new T[m_size]) { std::copy(first, last, m_data); }
packed_vector(const packed_vector<T>& other) : m_size(other.m_size), m_data(new T[other.m_size]) { std::copy(other.begin(), other.end(), m_data); }
~packed_vector() { delete[] m_data; }
packed_vector<T,U>& operator=(packed_vector<T,U> other) { other.swap(*this); return *this; }
iterator begin() { return m_data; }
const_iterator begin() const { return m_data; }
const_iterator cbegin() const { return m_data; }
iterator end() { return m_data + m_size; }
const_iterator end() const { return m_data + m_size; }
const_iterator cend() const { return m_data + m_size; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
size_type size() const { return m_size; }
bool empty() const { return m_size == 0; }
T& operator[](size_type i) { return m_data[i]; }
const T& operator[](size_type i) const { return m_data[i]; }
T& at(size_type i) { return m_data[i]; }
const T& at(size_type i) const { return m_data[i]; }
T& front() { return m_data[0]; }
const T& front() const { return m_data[0]; }
T& back() { return m_data[m_size-1]; }
const T& back() const { return m_data[m_size-1]; }
T *data() { return m_data; }
const T *data() const { return m_data; }
void clear() {
if(m_data) {
delete[] m_data;
m_data = nullptr;
}
m_size = 0;
}
void resize(size_type size) {
clear();
if(size > 0) {
m_data = new T[size];
m_size = size;
}
}
void push_back(const T& x) {
T *tmp = new T[m_size+1];
std::copy(m_data, m_data + m_size, tmp);
tmp[m_size] = x;
delete[] m_data;
m_data = tmp;
m_size++;
}
void pop_back() {
if(m_size == 1) {
clear();
return;
}
T *tmp = new T[m_size-1];
std::copy(m_data, m_data + m_size - 1, tmp);
delete[] m_data;
m_data = tmp;
m_size--;
}
iterator insert(const_iterator position, const T& x) {
T *tmp = new T[m_size+1];
size_type i = position - m_data;
std::copy(m_data, m_data + i, tmp);
tmp[i] = x;
std::copy(m_data + i, m_data + m_size, tmp + i + 1);
delete[] m_data;
m_data = tmp;
m_size++;
return tmp + i;
}
iterator erase(const_iterator position) {
T *tmp = new T[m_size-1];
size_type i = position - m_data;
std::copy(m_data, m_data + i, tmp);
std::copy(m_data + i + 1, m_data + m_size, tmp + i);
delete[] m_data;
m_data = tmp;
m_size--;
return tmp + i;
}
void swap(packed_vector<T,U>& other) { std::swap(m_size, other.m_size); std::swap(m_data, other.m_data); }
operator std::vector<T>() const { return std::vector<T>(begin(), end()); }
private:
size_type m_size;
T* m_data;
};
// restore memory alignment
#pragma pack(pop)
}
namespace std {
template<class T, class U> void swap(stdext::packed_vector<T,U>& lhs, stdext::packed_vector<T,U>& rhs) { lhs.swap(rhs); }
}
#endif

View File

@@ -35,7 +35,6 @@
#include "math.h"
#include "packed_any.h"
#include "packed_storage.h"
#include "packed_vector.h"
#include "shared_object.h"
#include "string.h"
#include "time.h"

View File

@@ -45,23 +45,21 @@ std::string resolve_path(const std::string& filePath, std::string sourcePath)
return sourcePath + filePath;
}
std::string date_time_string()
std::string date_time_string(const char* format/* = "%b %d %Y %H:%M:%S"*/)
{
char date[32];
char date[100];
std::time_t tnow;
std::time(&tnow);
std::tm *ts = std::localtime(&tnow);
std::strftime(date, 32, "%b %d %Y %H:%M:%S", ts);
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

@@ -38,7 +38,7 @@ template<typename T> T from_string(const std::string& str, T def = T()) { return
/// Resolve a file path by combining sourcePath with filePath
std::string resolve_path(const std::string& filePath, std::string sourcePath);
/// Get current date and time in a std::string
std::string date_time_string();
std::string date_time_string(const char* format = "%b %d %Y %H:%M:%S");
std::string dec_to_hex(uint64_t num);
uint64_t hex_to_dec(const std::string& str);
@@ -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

@@ -36,8 +36,8 @@ void microsleep(size_t us);
struct timer {
public:
timer() { restart(); }
float elapsed_seconds() { return (float)((stdext::micros() - m_start)/1000000.0); }
ticks_t elapsed_millis() { return (stdext::micros() - m_start)/1000; }
float elapsed_seconds() { return (stdext::micros() - m_start) / 1000000.f; }
ticks_t elapsed_millis() { return (stdext::micros() - m_start) / 1000; }
ticks_t elapsed_micros() { return stdext::micros() - m_start; }
void restart() { m_start = stdext::micros(); }
private:
@@ -47,4 +47,3 @@ private:
}
#endif

View File

@@ -142,9 +142,9 @@ void UITextEdit::update(bool focusCursor)
// map glyphs positions
Size textBoxSize;
const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
const Rect *glyphsTextureCoords = m_font->getGlyphsTextureCoords();
const Size *glyphsSize = m_font->getGlyphsSize();
const auto& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
const Rect* glyphsTextureCoords = m_font->getGlyphsTextureCoords();
const Size* glyphsSize = m_font->getGlyphsSize();
int glyph;
// update rect size
@@ -369,7 +369,7 @@ void UITextEdit::setSelection(int start, int end)
void UITextEdit::setTextHidden(bool hidden)
{
m_textHidden = true;
m_textHidden = hidden;
update(true);
}

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; }

View File

@@ -65,7 +65,7 @@ void UIWidget::draw(const Rect& visibleRect, Fw::DrawPane drawPane)
if(m_rotation != 0.0f) {
g_painter->pushTransformMatrix();
g_painter->rotate(m_rect.center(), m_rotation * (Fw::pi / 180.0));
g_painter->rotate(m_rect.center(), m_rotation * (Fw::pi / 180.f));
}
drawSelf(drawPane);
@@ -1717,9 +1717,9 @@ bool UIWidget::propagateOnMouseMove(const Point& mousePos, const Point& mouseMov
if(child->isExplicitlyVisible() && child->isExplicitlyEnabled() && child->containsPoint(mousePos))
child->propagateOnMouseMove(mousePos, mouseMoved, widgetList);
widgetList.push_back(static_self_cast<UIWidget>());
}
}
widgetList.push_back(static_self_cast<UIWidget>());
return true;
}

View File

@@ -489,7 +489,7 @@ protected:
BitmapFontPtr m_font;
public:
void resizeToText() { setSize(getTextSize()); }
void resizeToText();
void clearText() { setText(""); }
void setText(std::string text, bool dontFireLuaCall = false);

View File

@@ -56,6 +56,15 @@ void UIWidget::updateText()
m_textMustRecache = true;
}
void UIWidget::resizeToText()
{
auto textSize = getTextSize();
textSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom);
textSize += m_textOffset.toSize();
setSize(textSize);
}
void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode)
{
for(const OTMLNodePtr& node : styleNode->children()) {

View File

@@ -21,30 +21,108 @@
*/
#include "color.h"
#include <iomanip>
// NOTE: AABBGGRR order
const Color Color::alpha = 0x00000000U;
const Color Color::white = 0xffffffff;
const Color Color::black = 0xff000000;
const Color Color::red = 0xff0000ff;
const Color Color::darkRed = 0xff000080;
const Color Color::green = 0xff00ff00;
const Color Color::darkGreen = 0xff008000;
const Color Color::blue = 0xffff0000;
const Color Color::darkBlue = 0xff800000;
const Color Color::pink = 0xffff00ff;
const Color Color::darkPink = 0xff800080;
const Color Color::yellow = 0xff00ffff;
const Color Color::darkYellow = 0xff008080;
const Color Color::teal = 0xffffff00;
const Color Color::darkTeal = 0xff808000;
const Color Color::gray = 0xffa0a0a0;
const Color Color::darkGray = 0xff808080;
const Color Color::lightGray = 0xffc0c0c0;
const Color Color::orange = 0xff008cff;
const Color Color::white = 0xffffffffU;
const Color Color::black = 0xff000000U;
const Color Color::red = 0xff0000ffU;
const Color Color::darkRed = 0xff000080U;
const Color Color::green = 0xff00ff00U;
const Color Color::darkGreen = 0xff008000U;
const Color Color::blue = 0xffff0000U;
const Color Color::darkBlue = 0xff800000U;
const Color Color::pink = 0xffff00ffU;
const Color Color::darkPink = 0xff800080U;
const Color Color::yellow = 0xff00ffffU;
const Color Color::darkYellow = 0xff008080U;
const Color Color::teal = 0xffffff00U;
const Color Color::darkTeal = 0xff808000U;
const Color Color::gray = 0xffa0a0a0U;
const Color Color::darkGray = 0xff808080U;
const Color Color::lightGray = 0xffc0c0c0U;
const Color Color::orange = 0xff008cffU;
Color::Color(const std::string& coltext)
{
std::stringstream ss(coltext);
ss >> *this;
}
std::ostream& operator<<(std::ostream& out, const Color& color)
{
return out << '#'
<< std::hex << std::setfill('0')
<< std::setw(2) << (int)color.r()
<< std::setw(2) << (int)color.g()
<< std::setw(2) << (int)color.b()
<< std::setw(2) << (int)color.a()
<< std::dec << std::setfill(' ');
}
std::istream& operator>>(std::istream& in, Color& color)
{
std::string tmp;
if(in.peek() == '#') {
in.ignore() >> tmp;
if(tmp.length() == 6 || tmp.length() == 8) {
color.setRed((uint8)stdext::hex_to_dec(tmp.substr(0, 2)));
color.setGreen((uint8)stdext::hex_to_dec(tmp.substr(2, 2)));
color.setBlue((uint8)stdext::hex_to_dec(tmp.substr(4, 2)));
if(tmp.length() == 8)
color.setAlpha((uint8)stdext::hex_to_dec(tmp.substr(6, 2)));
else
color.setAlpha(255);
} else {
in.seekg(-tmp.length()-1, std::ios_base::cur);
}
} else {
in >> tmp;
if(tmp == "alpha") {
color = Color::alpha;
} else if(tmp == "black") {
color = Color::black;
} else if(tmp == "white") {
color = Color::white;
} else if(tmp == "red") {
color = Color::red;
} else if(tmp == "darkRed") {
color = Color::darkRed;
} else if(tmp == "green") {
color = Color::green;
} else if(tmp == "darkGreen") {
color = Color::darkGreen;
} else if(tmp == "blue") {
color = Color::blue;
} else if(tmp == "darkBlue") {
color = Color::darkBlue;
} else if(tmp == "pink") {
color = Color::pink;
} else if(tmp == "darkPink") {
color = Color::darkPink;
} else if(tmp == "yellow") {
color = Color::yellow;
} else if(tmp == "darkYellow") {
color = Color::darkYellow;
} else if(tmp == "teal") {
color = Color::teal;
} else if(tmp == "darkTeal") {
color = Color::darkTeal;
} else if(tmp == "gray") {
color = Color::gray;
} else if(tmp == "darkGray") {
color = Color::darkGray;
} else if(tmp == "lightGray") {
color = Color::lightGray;
} else if(tmp == "orange") {
color = Color::orange;
} else {
in.seekg(-tmp.length(), std::ios_base::cur);
}
}
return in;
}

View File

@@ -27,7 +27,6 @@
#include "../stdext/cast.h"
#include "../stdext/string.h"
#include "../const.h"
#include <iomanip>
class Color
{
@@ -124,83 +123,7 @@ private:
float m_a;
};
inline std::ostream& operator<<(std::ostream& out, const Color& color)
{
using namespace std;
out << "#" << hex << setfill('0')
<< setw(2) << (int)color.r()
<< setw(2) << (int)color.g()
<< setw(2) << (int)color.b()
<< setw(2) << (int)color.a();
out << dec << setfill(' ');
return out;
}
inline std::istream& operator>>(std::istream& in, Color& color)
{
using namespace std;
std::string tmp;
if(in.get() == '#') {
in >> tmp;
if(tmp.length() == 6 || tmp.length() == 8) {
color.setRed((uint8)stdext::hex_to_dec(tmp.substr(0, 2)));
color.setGreen((uint8)stdext::hex_to_dec(tmp.substr(2, 2)));
color.setBlue((uint8)stdext::hex_to_dec(tmp.substr(4, 2)));
if(tmp.length() == 8)
color.setAlpha((uint8)stdext::hex_to_dec(tmp.substr(6, 2)));
else
color.setAlpha(255);
} else
in.seekg(-(std::istream::streampos)tmp.length()-1, ios_base::cur);
} else {
in.unget();
in >> tmp;
if(tmp == "alpha") {
color = Color::alpha;
} else if(tmp == "black") {
color = Color::black;
} else if(tmp == "white") {
color = Color::white;
} else if(tmp == "red") {
color = Color::red;
} else if(tmp == "darkRed") {
color = Color::darkRed;
} else if(tmp == "green") {
color = Color::green;
} else if(tmp == "darkGreen") {
color = Color::darkGreen;
} else if(tmp == "blue") {
color = Color::blue;
} else if(tmp == "darkBlue") {
color = Color::darkBlue;
} else if(tmp == "pink") {
color = Color::pink;
} else if(tmp == "darkPink") {
color = Color::darkPink;
} else if(tmp == "yellow") {
color = Color::yellow;
} else if(tmp == "darkYellow") {
color = Color::darkYellow;
} else if(tmp == "teal") {
color = Color::teal;
} else if(tmp == "darkTeal") {
color = Color::darkTeal;
} else if(tmp == "gray") {
color = Color::gray;
} else if(tmp == "darkGray") {
color = Color::darkGray;
} else if(tmp == "lightGray") {
color = Color::lightGray;
} else if(tmp == "orange") {
color = Color::orange;
} else {
in.seekg(-tmp.length(), ios_base::cur);
}
}
return in;
}
std::ostream& operator<<(std::ostream& out, const Color& color);
std::istream& operator>>(std::istream& in, Color& color);
#endif

View File

@@ -267,7 +267,7 @@ void Crypt::rsaSetPrivateKey(const std::string& p, const std::string& q, const s
mpz_set_str(m_d, d.c_str(), 10);
// n = p * q
mpz_mul(n, p, q);
mpz_mul(m_n, m_p, m_q);
#else
#if OPENSSL_VERSION_NUMBER < 0x10100005L
BN_dec2bn(&m_rsa->p, p.c_str());

View File

@@ -77,7 +77,7 @@ public:
T manhattanLength() const { return std::abs(x) + std::abs(y); }
float distanceFrom(const TPoint<T>& other) const {
return TPoint<T>(x - other.x, y - other.y).getLength();
return TPoint<T>(x - other.x, y - other.y).length();
}
T x, y;

View File

@@ -89,7 +89,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<AdditionalIncludeDirectories>$(VcpkgRoot)include\luajit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\luajit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
@@ -101,7 +101,7 @@
<PreprocessorDefinitions>$(PREPROCESSOR_DEFS);_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnableEnhancedInstructionSet>AdvancedVectorExtensions</EnableEnhancedInstructionSet>
<AdditionalIncludeDirectories>$(VcpkgRoot)include\luajit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\luajit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -115,7 +115,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<AdditionalIncludeDirectories>$(VcpkgRoot)include\luajit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\luajit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
@@ -134,7 +134,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<AdditionalIncludeDirectories>$(VcpkgRoot)include\luajit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\luajit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -323,7 +323,6 @@
<ClInclude Include="..\src\client\spritemanager.h" />
<ClInclude Include="..\src\client\statictext.h" />
<ClInclude Include="..\src\client\thing.h" />
<ClInclude Include="..\src\client\thingstype.h" />
<ClInclude Include="..\src\client\thingtype.h" />
<ClInclude Include="..\src\client\thingtypemanager.h" />
<ClInclude Include="..\src\client\tile.h" />
@@ -436,7 +435,6 @@
<ClInclude Include="..\src\framework\stdext\net.h" />
<ClInclude Include="..\src\framework\stdext\packed_any.h" />
<ClInclude Include="..\src\framework\stdext\packed_storage.h" />
<ClInclude Include="..\src\framework\stdext\packed_vector.h" />
<ClInclude Include="..\src\framework\stdext\shared_object.h" />
<ClInclude Include="..\src\framework\stdext\shared_ptr.h" />
<ClInclude Include="..\src\framework\stdext\stdext.h" />
@@ -474,4 +472,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@@ -833,9 +833,6 @@
<ClInclude Include="..\src\framework\stdext\packed_storage.h">
<Filter>Header Files\framework\stdext</Filter>
</ClInclude>
<ClInclude Include="..\src\framework\stdext\packed_vector.h">
<Filter>Header Files\framework\stdext</Filter>
</ClInclude>
<ClInclude Include="..\src\framework\stdext\shared_object.h">
<Filter>Header Files\framework\stdext</Filter>
</ClInclude>
@@ -1013,9 +1010,6 @@
<ClInclude Include="..\src\client\thing.h">
<Filter>Header Files\client</Filter>
</ClInclude>
<ClInclude Include="..\src\client\thingstype.h">
<Filter>Header Files\client</Filter>
</ClInclude>
<ClInclude Include="..\src\client\thingtype.h">
<Filter>Header Files\client</Filter>
</ClInclude>