67 Commits

Author SHA1 Message Date
17c61c5950 load AABB into model
All checks were successful
Linux arm64 / Build (push) Successful in 4m37s
2024-03-23 18:07:53 +01:00
864a15e4c8 Squashed commit of the following:
All checks were successful
Linux arm64 / Build (push) Successful in 4m45s
commit c1ded40cc4
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 21 17:24:05 2024 +0100

    improve network test

commit 285bf880ee
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 21 17:14:43 2024 +0100

    fix warning

commit 06ff76607d
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 21 15:45:33 2024 +0100

    add bots

commit 19229bbe8a
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 21 14:55:57 2024 +0100

    fix warnings

commit 2b0930a734
Author: Morph01 <thibaut6969delastreet@gmail.com>
Date:   Tue Mar 19 10:43:55 2024 +0100

    hud of blitz (#16)

    Résoudre partiellement #12

    Co-authored-by: Persson-dev <sim16.prib@gmail.com>
    Co-authored-by: Morph01 <145839520+Morph01@users.noreply.github.com>
    Co-authored-by: Simon Pribylski <sim16.prib@gmail.com>
    Reviewed-on: #16

commit 84b6acad4c
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Mar 19 10:15:54 2024 +0100

    less spooky light

commit 9f94d51fc4
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 14 16:36:15 2024 +0100

    Ajout de tests d'intégration (#17)

    Le paquet fournissant OpenGL a été temporairement remplacé par glew

    Reviewed-on: #17
    Co-authored-by: Persson-dev <sim16.prib@gmail.com>
    Co-committed-by: Persson-dev <sim16.prib@gmail.com>

commit 9951256881
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Wed Mar 13 20:19:37 2024 +0100

    action: install libsdl via apt

commit 4a02054648
Author: Morph01 <145839520+Morph01@users.noreply.github.com>
Date:   Wed Mar 13 13:53:20 2024 +0100

    compression tests

commit 19c39312bf
Author: Morph01 <145839520+Morph01@users.noreply.github.com>
Date:   Wed Mar 13 13:51:57 2024 +0100

    setup action

commit d5014b1e8a
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Mar 12 10:26:47 2024 +0100

    Revert "extend Vec3"

    This reverts commit dccfa9c936.

commit dccfa9c936
Author: = <=>
Date:   Tue Mar 12 10:01:00 2024 +0100

    extend Vec3
Merge branch 'main' into physics
2024-03-22 19:33:45 +01:00
7efd8218ea moved functions in Maths.h
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-03-22 19:28:46 +01:00
08db7f84b9 add missing include
All checks were successful
Linux arm64 / Build (push) Successful in 5m7s
2024-03-22 19:16:48 +01:00
7119dea783 merge 'main' branch
commit c1ded40cc4
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 21 17:24:05 2024 +0100

    improve network test

commit 285bf880ee
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 21 17:14:43 2024 +0100

    fix warning

commit 06ff76607d
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 21 15:45:33 2024 +0100

    add bots

commit 19229bbe8a
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 21 14:55:57 2024 +0100

    fix warnings

commit 2b0930a734
Author: Morph01 <thibaut6969delastreet@gmail.com>
Date:   Tue Mar 19 10:43:55 2024 +0100

    hud of blitz (#16)

    Résoudre partiellement #12

    Co-authored-by: Persson-dev <sim16.prib@gmail.com>
    Co-authored-by: Morph01 <145839520+Morph01@users.noreply.github.com>
    Co-authored-by: Simon Pribylski <sim16.prib@gmail.com>
    Reviewed-on: #16

commit 84b6acad4c
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Mar 19 10:15:54 2024 +0100

    less spooky light

commit 9f94d51fc4
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 14 16:36:15 2024 +0100

    Ajout de tests d'intégration (#17)

    Le paquet fournissant OpenGL a été temporairement remplacé par glew

    Reviewed-on: #17
    Co-authored-by: Persson-dev <sim16.prib@gmail.com>
    Co-committed-by: Persson-dev <sim16.prib@gmail.com>

commit 9951256881
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Wed Mar 13 20:19:37 2024 +0100

    action: install libsdl via apt

commit 4a02054648
Author: Morph01 <145839520+Morph01@users.noreply.github.com>
Date:   Wed Mar 13 13:53:20 2024 +0100

    compression tests

commit 19c39312bf
Author: Morph01 <145839520+Morph01@users.noreply.github.com>
Date:   Wed Mar 13 13:51:57 2024 +0100

    setup action

commit d5014b1e8a
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Mar 12 10:26:47 2024 +0100

    Revert "extend Vec3"

    This reverts commit dccfa9c936.

commit dccfa9c936
Author: = <=>
Date:   Tue Mar 12 10:01:00 2024 +0100

    extend Vec3
2024-03-22 19:15:01 +01:00
6e998fc368 change tests
All checks were successful
Linux arm64 / Build (push) Successful in 4m29s
2024-03-22 16:41:52 +01:00
441131a2f5 rename Intersects to distance 2024-03-22 16:14:56 +01:00
c875fa1dee more template
All checks were successful
Linux arm64 / Build (push) Successful in 4m46s
2024-03-22 15:50:32 +01:00
5e4b318d67 inline Reduce_<> functions
All checks were successful
Linux arm64 / Build (push) Successful in 4m34s
2024-03-22 15:26:07 +01:00
076fa7badc fix compilation error
Some checks failed
Linux arm64 / Build (push) Failing after 4m22s
2024-03-22 15:18:39 +01:00
1091abd034 fix some compilation errors
Some checks failed
Linux arm64 / Build (push) Failing after 2m14s
2024-03-22 14:58:26 +01:00
dd9ea3ece8 update intersects, document changes
Some checks failed
Linux arm64 / Build (push) Failing after 2m12s
2024-03-22 12:02:39 +01:00
6226161e31 fix compilation error, add min/max functions for Vec3d
Some checks failed
Linux arm64 / Build (push) Failing after 2m23s
2024-03-22 09:22:06 +01:00
6b32e8878e fix min/max functions
Some checks failed
Linux arm64 / Build (push) Failing after 2m18s
2024-03-22 09:18:34 +01:00
c1ded40cc4 improve network test
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-03-21 17:24:05 +01:00
285bf880ee fix warning
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-03-21 17:20:36 +01:00
06ff76607d add bots
Some checks failed
Linux arm64 / Build (push) Failing after 3m31s
2024-03-21 15:45:33 +01:00
19229bbe8a fix warnings
Some checks failed
Linux arm64 / Build (push) Failing after 11m53s
2024-03-21 14:55:57 +01:00
438bc4a968 remove unused variable
Some checks failed
Linux arm64 / Build (push) Failing after 4m32s
2024-03-21 14:39:18 +01:00
9aa546881a better shoot logging
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-03-21 14:35:41 +01:00
4db03f2b83 working shoot
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-03-21 14:32:03 +01:00
0119d36b5c should work
All checks were successful
Linux arm64 / Build (push) Successful in 5m5s
2024-03-19 13:01:17 +01:00
249d7534a4 Squashed commit of the following:
All checks were successful
Linux arm64 / Build (push) Successful in 4m20s
commit 2b0930a734
Author: Morph01 <thibaut6969delastreet@gmail.com>
Date:   Tue Mar 19 10:43:55 2024 +0100

    hud of blitz (#16)

    Résoudre partiellement #12

    Co-authored-by: Persson-dev <sim16.prib@gmail.com>
    Co-authored-by: Morph01 <145839520+Morph01@users.noreply.github.com>
    Co-authored-by: Simon Pribylski <sim16.prib@gmail.com>
    Reviewed-on: #16

commit 84b6acad4c
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Mar 19 10:15:54 2024 +0100

    less spooky light

commit 9f94d51fc4
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Thu Mar 14 16:36:15 2024 +0100

    Ajout de tests d'intégration (#17)

    Le paquet fournissant OpenGL a été temporairement remplacé par glew

    Reviewed-on: #17
    Co-authored-by: Persson-dev <sim16.prib@gmail.com>
    Co-committed-by: Persson-dev <sim16.prib@gmail.com>

commit 9951256881
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Wed Mar 13 20:19:37 2024 +0100

    action: install libsdl via apt

commit 4a02054648
Author: Morph01 <145839520+Morph01@users.noreply.github.com>
Date:   Wed Mar 13 13:53:20 2024 +0100

    compression tests

commit 19c39312bf
Author: Morph01 <145839520+Morph01@users.noreply.github.com>
Date:   Wed Mar 13 13:51:57 2024 +0100

    setup action

commit d5014b1e8a
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Mar 12 10:26:47 2024 +0100

    Revert "extend Vec3"

    This reverts commit dccfa9c936.

commit dccfa9c936
Author: = <=>
Date:   Tue Mar 12 10:01:00 2024 +0100

    extend Vec3
2024-03-19 12:16:23 +01:00
=
abe89d2089 remove debug prints 2024-03-19 12:10:32 +01:00
f070b28d8b revert c_cpp_properties 2024-03-19 12:03:12 +01:00
=
a7f734d22e fix Intersects, add tests 2024-03-19 11:56:29 +01:00
2b0930a734 hud of blitz (#16)
All checks were successful
Linux arm64 / Build (push) Successful in 4m33s
Résoudre partiellement #12

Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-authored-by: Morph01 <145839520+Morph01@users.noreply.github.com>
Co-authored-by: Simon Pribylski <sim16.prib@gmail.com>
Reviewed-on: #16
2024-03-19 10:43:55 +01:00
=
abbc4419fa update intersects function 2024-03-19 10:36:43 +01:00
84b6acad4c less spooky light
All checks were successful
Linux arm64 / Build (push) Successful in 4m23s
2024-03-19 10:15:54 +01:00
9f94d51fc4 Ajout de tests d'intégration (#17)
All checks were successful
Linux arm64 / Build (push) Successful in 4m28s
Le paquet fournissant OpenGL a été temporairement remplacé par glew

Reviewed-on: #17
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
2024-03-14 16:36:15 +01:00
9951256881 action: install libsdl via apt
Some checks failed
Linux arm64 / Build (push) Failing after 54m19s
2024-03-13 20:19:37 +01:00
Morph01
4a02054648 compression tests
Some checks failed
Linux arm64 / Build (push) Failing after 57m27s
2024-03-13 13:53:20 +01:00
Morph01
19c39312bf setup action 2024-03-13 13:51:57 +01:00
86e47601d7 idk 2024-03-12 11:31:04 +01:00
d5014b1e8a Revert "extend Vec3"
This reverts commit dccfa9c936.
2024-03-12 10:26:47 +01:00
=
a3b6d2488f extend Vec3, implement AABB intersection 2024-03-12 10:25:27 +01:00
=
dccfa9c936 extend Vec3 2024-03-12 10:01:00 +01:00
e39fc8aa70 Star Wars (#14)
Reviewed-on: #14
2024-03-12 08:55:49 +01:00
d42f67724d fix error 2024-03-12 08:32:53 +01:00
71bc4dd249 add keybindings (#13)
Co-authored-by: Morph01 <thibaut6969delastreet@gmail.com>
Reviewed-on: #13
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
2024-03-09 18:37:54 +01:00
2cb5074140 better server logs 2024-03-09 11:01:30 +01:00
269ac16d28 more precise logging 2024-03-08 22:59:50 +01:00
b7926d7a98 pretty log 2024-03-08 22:57:38 +01:00
52da1cf19b explicit server in logs 2024-03-07 23:10:37 +01:00
2da89c8dab xmake: remove global include 2024-03-07 21:12:41 +01:00
88cb433ecf xmake: relative paths 2024-03-07 21:03:23 +01:00
d96b01074e split xmake targets 2024-03-07 20:50:14 +01:00
a1effa05cd remove github ci 2024-03-07 20:14:12 +01:00
7b58117f36 fix warnings 2024-03-07 20:13:05 +01:00
bf8a6458a0 valgrind full info 2024-03-05 12:30:09 +01:00
18ddede8c0 add shoot 2024-03-05 12:29:39 +01:00
d3467418c7 Merge branch 'main' of github.com:Persson-dev/Blitz 2024-03-05 09:01:15 +01:00
d98939cb31 remove useless add_requires 2024-03-05 08:39:24 +01:00
0d039caa0e Merge branch 'weirdshoot' 2024-03-05 08:38:34 +01:00
848f12e58b Vecxuc wrong type 2024-02-27 12:15:35 +01:00
ce249359c6 non copyable classes 2024-02-26 11:27:16 +01:00
9591836074 add valgrind test 2024-01-30 09:14:07 +01:00
7305051062 fix memory warnings 2024-01-30 08:53:26 +01:00
617e1fa95e branchless 2024-01-28 19:09:30 +01:00
73b4539e8d add gun animation 2024-01-28 18:30:16 +01:00
de3ff4326a CooldownTimer to template 2024-01-28 18:29:55 +01:00
51f046f44e fix compile error 2024-01-27 20:12:14 +01:00
3b5208aeba clamp horizonal movement vector norm to 1 (fix diagonal movement speed increase) 2024-01-27 20:10:10 +01:00
a40cd1cd61 change smoothing time const names 2024-01-27 19:11:04 +01:00
1ccf525dd6 fix wrong filter equation 2024-01-27 19:08:56 +01:00
b345d6eb49 fixed-alpha movement smoothing 2024-01-27 17:54:26 +01:00
a7dbf69a4a oooo? 2024-01-27 17:48:37 +01:00
102 changed files with 1674 additions and 411 deletions

View File

@@ -0,0 +1,38 @@
name: Linux arm64
run-name: Build And Test
on: [push]
jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Install deps
run : |
apt update
apt install -y libsdl2-dev libassimp-dev libglew-dev
- name: Check out repository code
uses: actions/checkout@v3
- name: Prepare XMake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: latest
actions-cache-folder: '.xmake-cache'
actions-cache-key: 'ubuntu'
- name: Packages cache
uses: actions/cache@v4
with:
path: ~/.xmake
key: 'ubuntu-packages'
- name: XMake config
run: xmake f -p linux -y --root
- name: Build
run: xmake --root
- name: Test
run: xmake test --root

View File

@@ -1,32 +0,0 @@
name: macOS
on:
pull_request:
push:
branches: main
jobs:
build:
strategy:
fail-fast: false
runs-on: macos-latest
concurrency:
group: ${{ github.ref }}-${{ github.base_ref }}-${{ github.head_ref }}-macOS
cancel-in-progress: true
steps:
- uses: actions/checkout@v1
- uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: branch@master
- name: Prepare XMake
run: xmake f -p macosx -y
- name: Build
run: xmake
- name: Test
run: xmake test

View File

@@ -1,42 +0,0 @@
name: Windows
on:
pull_request:
push:
branches: main
jobs:
build:
strategy:
fail-fast: false
matrix:
arch: [x64, x86]
vs_runtime: [MT, MD]
runs-on: windows-latest
concurrency:
group: ${{ github.ref }}-${{ github.base_ref }}-${{ github.head_ref }}-Windows-${{ matrix.arch }}-${{ matrix.vs_runtime }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v1
- uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: branch@master
- name: Configure Pagefile
uses: al-cheb/configure-pagefile-action@v1.2
with:
minimum-size: 8GB
maximum-size: 32GB
disk-root: "D:"
- name: Prepare XMake
run: xmake f -p windows -a ${{ matrix.arch }} --vs_runtime=${{ matrix.vs_runtime }} -y
- name: Build
run: xmake
- name: Test
run: xmake test

View File

@@ -1,11 +1,13 @@
{
"configurations": [
{
"name": "Blitz",
"cppStandard": "c++17",
"includePath": ["include"],
"compileCommands": ".vscode/compile_commands.json"
}
],
"version": 4
"configurations": [
{
"name": "Blitz",
"cppStandard": "c++17",
"includePath": [
"include"
],
"compileCommands": ".vscode/compile_commands.json"
}
],
"version": 4
}

BIN
assets/cube.glb Normal file

Binary file not shown.

BIN
assets/fingergun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

BIN
assets/jp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -10,6 +10,7 @@
#include <cstring>
#include <string>
#include <vector>
#include <cstdint>
namespace blitz {
@@ -180,6 +181,10 @@ class DataBuffer {
std::memcpy(newBuffer, data(), GetSize());
return newBuffer;
}
bool operator==(const DataBuffer& other) const{
return m_Buffer == other.m_Buffer;
}
};
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);

View File

@@ -0,0 +1,15 @@
#pragma once
namespace blitz {
class NonCopyable {
public:
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
protected:
NonCopyable() {}
~NonCopyable() {}
};
} // namespace blitz

View File

@@ -28,8 +28,8 @@ class Game {
return m_Players;
}
void AddPlayer(PlayerID player, const std::string& name);
void RemovePlayer(PlayerID player);
virtual void AddPlayer(PlayerID player, const std::string& name);
virtual void RemovePlayer(PlayerID player);
};

View File

@@ -0,0 +1,15 @@
#pragma once
#include "blitz/maths/Vector.h"
namespace blitz {
namespace game {
class PlayerInputListener {
public:
virtual void OnLocalPlayerJump() {}
virtual void OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) {}
};
} // namespace game
} // namespace blitz

View File

@@ -1,7 +1,7 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/common/Vector.h"
#include "blitz/maths/Vector.h"
#include <cstdint>
#include <string>

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/common/Vector.h"
#include "blitz/maths/Vector.h"
#include <cmath>
namespace blitz {
@@ -55,6 +55,100 @@ T Distance(const Vec3<T>& vect, const Vec3<T>& other) {
return Length(vect - other);
}
// it seems that `std::{min, max}`'s behavior conflicts with that of `cmath`'s `f{min, max}[f]`
// Why? Like I fucking know dude
template <typename T>
T ReduceMin(const Vec3<T>& vect) {
return std::min(std::min(vect.x, vect.y), vect.z);
}
template <typename T>
T ReduceMax(const Vec3<T>& vect) {
return std::max(std::max(vect.x, vect.y), vect.z);
}
/**
* @brief returns the (signed) minimal coordinate of the vector
*
* @param v
* @return constexpr T
*/
template <>
inline float ReduceMin<float>(const Vec3f& v) {
return std::fminf(std::fminf(v.x, v.y), v.z);
}
/**
* @brief returns the (signed) maximal coordinate of the vector
*
* @param v
* @return constexpr T
*/
template <>
inline float ReduceMax<float>(const Vec3f& v) {
return std::fmaxf(std::fmaxf(v.x, v.y), v.z);
}
/**
* @brief returns the (signed) minimal coordinate of the vector
*
* @param v
* @return constexpr T
*/
template <>
inline double ReduceMin<double>(const Vec3d& v) {
return std::fmin(std::fmin(v.x, v.y), v.z);
}
/**
* @brief returns the (signed) maximal coordinate of the vector
*
* @param v
* @return constexpr T
*/
template <>
inline double ReduceMax<double>(const Vec3d& v) {
return std::fmax(std::fmax(v.x, v.y), v.z);
}
/**
* @brief returns the coordinate-wise minimum of the given vectors,
* where a coordinate in the returned vector is NAN iff any of the two compared ones are NAN
*
* @tparam T
* @param self
* @param other
* @return constexpr Vec3f
*/
template <typename T>
constexpr Vec3<T> Min(const Vec3<T>& self, const Vec3<T>& other) {
return {
std::min(self.x, other.x),
std::min(self.y, other.y),
std::min(self.z, other.z),
};
}
/**
* @brief returns the coordinate-wise maximum of the given vectors,
* where a coordinate in the returned vector is NAN iff any of the two compared ones are NAN
*
* @tparam T
* @param self
* @param other
* @return constexpr Vec3f
*/
template <typename T>
constexpr Vec3<T> Max(const Vec3<T>& self, const Vec3<T>& other) {
return {
std::max(self.x, other.x),
std::max(self.y, other.y),
std::max(self.z, other.z),
};
}
//////////////////////////////////////////////////////////////////
// Matricies //
//////////////////////////////////////////////////////////////////
@@ -125,6 +219,8 @@ Mat4f Inverse(const Mat4f& mat);
Mat4f Translate(const Vec3f& translation);
Mat4f Scale(const Vec3f& axisFactor);
Mat4f RotateX(float angle);
Mat4f RotateY(float angle);
Mat4f RotateZ(float angle);

View File

@@ -0,0 +1,30 @@
#pragma once
#include "blitz/maths/Vector.h"
namespace blitz {
namespace maths {
struct Ray {
Vec3f origin;
Vec3f direction;
};
struct AABB {
Vec3f from;
Vec3f to;
};
inline AABB operator+(const AABB& aabb, const Vec3f& offset) {
AABB result = aabb;
result.from += offset;
result.to += offset;
return result;
}
float Distance(const Ray& ray, const AABB& aabb);
bool Intersects(const Ray& ray, const AABB& aabb);
} // namespace maths
} // namespace blitz

View File

@@ -1,5 +1,7 @@
#pragma once
#include <algorithm>
#include <cmath>
#include <cstddef>
namespace blitz {
@@ -81,19 +83,19 @@ struct Vec4 {
using Vec2uc = Vec2<unsigned int>;
using Vec2uc = Vec2<unsigned char>;
using Vec2i = Vec2<int>;
using Vec2u = Vec2<unsigned int>;
using Vec2f = Vec2<float>;
using Vec2d = Vec2<double>;
using Vec3uc = Vec3<unsigned int>;
using Vec3uc = Vec3<unsigned char>;
using Vec3i = Vec3<int>;
using Vec3u = Vec3<unsigned int>;
using Vec3f = Vec3<float>;
using Vec3d = Vec3<double>;
using Vec4uc = Vec4<unsigned int>;
using Vec4uc = Vec4<unsigned char>;
using Vec4i = Vec4<int>;
using Vec4u = Vec4<unsigned int>;
using Vec4f = Vec4<float>;
@@ -178,7 +180,7 @@ Vec3<T>& operator+=(Vec3<T>& vect, const Vec3<T>& other) {
template <typename T>
constexpr Vec3<T> operator-(const Vec3<T>& vect, const Vec3<T>& other) {
return vect + (-other);
return {vect.x - other.x, vect.y - other.y, vect.z - other.z};
}
template <typename T>
@@ -197,6 +199,40 @@ constexpr Vec3<T> operator*(T mult, const Vec3<T>& vect) {
return vect * mult;
}
template <typename T>
constexpr Vec3<T> operator*=(const Vec3<T>& vect, T mult) {
vect = vect * mult;
return vect;
}
template <typename T>
constexpr Vec3<T> operator*=(T mult, const Vec3<T>& vect) {
vect = vect * mult;
return vect;
}
template <typename T>
constexpr Vec3<T> operator*(const Vec3<T>& vect, const Vec3<T>& other) {
return {vect.x * other.x, vect.y * other.y, vect.z * other.z};
}
template <typename T>
Vec3<T>& operator*=(Vec3<T>& vect, const Vec3<T>& other) {
vect = vect * other;
return vect;
}
template <typename T>
constexpr Vec3<T> operator/(const Vec3<T>& vect, const Vec3<T>& other) {
return {vect.x / other.x, vect.y / other.y, vect.z / other.z};
}
template <typename T>
Vec3<T>& operator/=(Vec3<T>& vect, const Vec3<T>& other) {
vect = vect / other;
return vect;
}
@@ -279,11 +315,11 @@ struct Mat4 {
}
T at(std::size_t row, std::size_t column) const {
return operator[](row* MATRIX_SIZE + column);
return operator[](row * MATRIX_SIZE + column);
}
T& at(std::size_t row, std::size_t column) {
return operator[](row* MATRIX_SIZE + column);
return operator[](row * MATRIX_SIZE + column);
}
};

View File

@@ -1,5 +0,0 @@
#pragma once
#define REMOVE_COPY(className) \
className(const className&) = delete; \
className& operator=(const className&) = delete

View File

@@ -0,0 +1,25 @@
#pragma once
#include "blitz/maths/Vector.h"
#include <string>
namespace blitz {
namespace utils {
namespace TextColor {
const static Vec3uc AQUA = {0, 255, 255};
const static Vec3uc BLUE = {0, 0, 255};
const static Vec3uc GREEN = {0, 255, 0};
const static Vec3uc PURPLE = {255, 0, 255};
const static Vec3uc RED = {255, 0, 0};
const static Vec3uc WHITE = {255, 255, 255};
const static Vec3uc YELLOW = {255, 255, 0};
} // namespace TextColor
std::string GetTextColor(Vec3uc color);
std::string GetTextColorReset();
} // namespace utils
} // namespace blitz

View File

@@ -70,26 +70,36 @@ class Timer {
};
// utililty class to trigger update at regular period of time with a cooldown
template <typename T>
class CooldownTimer {
private:
std::uint64_t m_Cooldown; // in millis
std::uint64_t m_CooldownTime;
T m_Cooldown;
T m_CooldownTime;
public:
CooldownTimer() : m_Cooldown(0), m_CooldownTime(0) {}
CooldownTimer(std::uint64_t cooldown) : m_Cooldown(0), m_CooldownTime(cooldown) {}
CooldownTimer(T cooldown) : m_Cooldown(0), m_CooldownTime(cooldown) {}
bool Update(std::uint64_t delta);
bool Update(T delta) {
if (m_Cooldown > 0) {
m_Cooldown = std::max<T>(static_cast<T>(0), static_cast<T>(m_Cooldown - delta));
}
return m_Cooldown == 0;
}
void ApplyCooldown();
void ApplyCooldown() {
m_Cooldown = m_CooldownTime;
}
void Reset();
void Reset() {
m_Cooldown = 0;
}
void SetCooldown(std::uint64_t newCooldown) {
void SetCooldown(T newCooldown) {
m_CooldownTime = newCooldown;
}
std::uint64_t GetCooldown() const {
T GetCooldown() const {
return m_CooldownTime;
}
};

View File

@@ -16,7 +16,7 @@ namespace network {
* \class Connexion
* \brief Represents a network connexion
*/
class Connexion : public protocol::PacketHandler {
class Connexion : public protocol::PacketHandler, private NonCopyable {
protected:
protocol::PacketDispatcher m_Dispatcher;
@@ -72,11 +72,6 @@ class Connexion : public protocol::PacketHandler {
* \param packet The protocol::Packet to send
*/
void SendPacket(const protocol::Packet* packet);
/**
* \brief Disables Connexion copy
*/
REMOVE_COPY(Connexion);
};
} // namespace network

View File

@@ -21,7 +21,7 @@ namespace network {
* \note This class is meant to be created only once in your program. \n
* The easiest thing to do is to create an instance of this class at the top of your **main.cpp**.
*/
class NetworkInitializer {
class NetworkInitializer : private NonCopyable {
public:
/**
* \brief Creates the networking context
@@ -31,8 +31,6 @@ class NetworkInitializer {
* \brief Destroys the networking context
*/
~NetworkInitializer();
REMOVE_COPY(NetworkInitializer);
};
} // namespace network

View File

@@ -14,7 +14,7 @@ namespace network {
* \class TCPListener
* \brief Cross platform abstraction of a TCP socket server
*/
class TCPListener {
class TCPListener : private NonCopyable {
private:
SocketHandle m_Handle;
std::uint16_t m_Port;
@@ -79,11 +79,6 @@ class TCPListener {
int GetMaximumConnections() const {
return m_MaxConnections;
}
/**
* \brief Disables TCPListener copy
*/
REMOVE_COPY(TCPListener);
};
} // namespace network

View File

@@ -1,7 +1,7 @@
#pragma once
#include "blitz/common/DataBuffer.h"
#include "blitz/misc/ClassEntity.h"
#include "blitz/common/NonCopyable.h"
#ifdef _WIN32
#include <winsock2.h>
@@ -40,7 +40,7 @@ typedef int SocketHandle;
* \class TCPSocket
* \brief Cross platform abstraction of a TCP socket
*/
class TCPSocket {
class TCPSocket : private NonCopyable {
public:
/**
* \enum Status
@@ -153,11 +153,6 @@ class TCPSocket {
*/
std::size_t Receive(DataBuffer& buffer, std::size_t amount);
/**
* \brief Disable TCPSocket copy, as it disconnects when destroyed
*/
REMOVE_COPY(TCPSocket);
friend class TCPListener;
};

View File

@@ -29,6 +29,7 @@ class PacketHandler {
virtual void HandlePacket(const PlayerListPacket* packet) {}
virtual void HandlePacket(const PlayerLoginPacket* packet) {}
virtual void HandlePacket(const PlayerPositionAndRotationPacket* packet) {}
virtual void HandlePacket(const PlayerShootPacket* packet) {}
virtual void HandlePacket(const ServerTpsPacket* packet) {}
};

View File

@@ -7,4 +7,5 @@
#include "packets/PlayerListPacket.h"
#include "packets/PlayerLoginPacket.h"
#include "packets/PlayerPositionAndRotationPacket.h"
#include "packets/PlayerShootPacket.h"
#include "packets/ServerTpsPacket.h"

View File

@@ -12,6 +12,7 @@ class PlayerLeavePacket;
class PlayerListPacket;
class PlayerLoginPacket;
class PlayerPositionAndRotationPacket;
class PlayerShootPacket;
class ServerTpsPacket;
} // namespace protocol

View File

@@ -35,6 +35,7 @@ enum class PacketType : std::uint8_t {
Disconnect, /**< Corresponds to DisconnectPacket */
Chat, /**< Corresponds to ChatPacket */
PlayerPositionAndRotation, /**< Corresponds to PlayerPositionAndRotationPacket */
PlayerShoot, /**< Corresponds to PlayerShootPacket */
PACKET_COUNT
};

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/common/Vector.h"
#include "blitz/maths/Vector.h"
#include "blitz/protocol/Protocol.h"
#include <vector>

View File

@@ -1,7 +1,7 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/common/Vector.h"
#include "blitz/maths/Vector.h"
#include "blitz/protocol/Protocol.h"
namespace blitz {

View File

@@ -0,0 +1,47 @@
#pragma once
#include "blitz/game/Player.h"
#include "blitz/protocol/Protocol.h"
namespace blitz {
namespace protocol {
class PlayerShootPacket : public Packet {
private:
game::PlayerID m_Player; // only used when sent to client
Vec3f m_Position;
float m_Yaw, m_Pitch;
public:
PlayerShootPacket() {}
PlayerShootPacket(Vec3f position, float yaw, float pitch, game::PlayerID player = 0) :
m_Player(player), m_Position(position), m_Yaw(yaw), m_Pitch(pitch) {}
virtual ~PlayerShootPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const Vec3f& GetPosition() const {
return m_Position;
}
float GetYaw() const {
return m_Yaw;
}
float GetPitch() const {
return m_Pitch;
}
game::PlayerID GetPlayer() const {
return m_Player;
}
virtual PacketType GetType() const {
return PacketType::PlayerShoot;
}
};
} // namespace protocol
} // namespace blitz

View File

@@ -1,6 +1,7 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/game/Listeners.h"
#include "blitz/misc/ObjectNotifier.h"
#include "blitz/misc/Time.h"
#include "blitz/protocol/packets/ChatPacket.h"
@@ -25,11 +26,12 @@ class Server;
class GuiListener {
public:
virtual void OnTextChatReceived(const protocol::ColoredText& text) {}
virtual void OnSpectatorChange(const game::PlayerID player) {}
virtual void OnSpectatorChange(game::PlayerID player) {}
virtual void OnPlayerShoot(game::PlayerID player, const Vec3f& position, float yaw, float pitch) {}
};
// Singleton
class Client : public utils::ObjectNotifier<GuiListener> {
class Client : public utils::ObjectNotifier<GuiListener>, public game::PlayerInputListener {
private:
std::unique_ptr<server::Server> m_Server;
std::unique_ptr<client::ClientConnexion> m_Connexion;
@@ -55,6 +57,8 @@ class Client : public utils::ObjectNotifier<GuiListener> {
void SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch);
virtual void OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) override;
game::PlayerID GetPlayerID() const;
client::ClientGame* GetGame() {
@@ -65,6 +69,12 @@ class Client : public utils::ObjectNotifier<GuiListener> {
return &m_Config;
}
bool IsAdmin() const;
server::Server* GetServer() {
return m_Server.get();
}
private:
void Reset();

View File

@@ -5,11 +5,24 @@
namespace blitz {
enum KeyAction {
kaAvancer = 0,
kaReculer,
kaDroite,
kaGauche,
kaMax,
};
typedef std::array<int, kaMax> Keybinds;
class BlitzConfig {
private:
std::array<char, 256> m_Pseudo;
bool m_VSync;
bool m_DisplayFps;
KeyAction m_CurrentAction;
Keybinds m_Keybinds{};
public:
BlitzConfig();
@@ -35,6 +48,10 @@ class BlitzConfig {
m_DisplayFps = display;
}
Keybinds& GetKeys() {
return m_Keybinds;
}
private:
void LoadConfig();
void LoadDefaultConfig();

View File

@@ -1,7 +1,14 @@
#pragma once
#include "blitz/common/Smoothing.h"
#include "blitz/game/Listeners.h"
#include "blitz/misc/ObjectNotifier.h"
#include "blitz/misc/Time.h"
namespace blitz {
class Client;
namespace game {
class Player;
@@ -10,21 +17,23 @@ class Player;
namespace input {
class PlayerController {
class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener> {
private:
game::Player* m_Player;
game::Player* m_Player;
Client* m_Client;
utils::CooldownTimer<float> m_ShootTimer{1.0f};
EMASmoother m_DxSmoother;
/// maximum x-axis velocity
float m_MaxDx;
EMASmoother m_DySmoother;
/// current (target) x-axis velocity
float m_Dx;
EMASmoother m_DySmoother;
/// maximum (target) y-axis velocity
float m_MaxDy;
/// current (target) y-axis velocity
float m_Dy;
/// current z-axis velocity
float m_Dz;
/// maximum x-axis velocity
float m_MaxDx;
/// maximum (target) y-axis velocity
float m_MaxDy;
/// maximum z-axis velocity (velocity at initial keypress)
float m_MaxDz;
/// individual gravitational force
@@ -33,7 +42,7 @@ class PlayerController {
bool m_OnGround;
public:
PlayerController();
PlayerController(Client* client);
void Update(float delta);

View File

@@ -23,6 +23,7 @@ class ClientGame : public game::Game, public protocol::PacketHandler {
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet) override;
virtual void HandlePacket(const protocol::PlayerListPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerShootPacket* packet) override;
private:
void RegisterHandlers();

View File

@@ -15,6 +15,9 @@ class GameChatGui : public GuiWidget, GuiListener {
std::vector<protocol::ColoredText> m_Lines;
std::vector<protocol::ColoredText> m_TempLines;
bool m_FocusRequested = false;
int HistoryPos; // -1: new line, 0..History.Size-1 browsing history.
bool ScrollToBottom = false;
bool AutoScroll = true;
float m_ChatDisplay = 0;

25
include/client/gui/Hud.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#include "GuiWidget.h"
#include "client/Client.h"
namespace blitz {
class Client;
namespace gui {
class Hud : public GuiWidget {
private:
/* data */
void Draw(const char* title, bool* p_open);
unsigned int m_GunTexture;
unsigned int m_JP;
public:
Hud(GuiWidget* parent, Client* client);
virtual void Render() override;
};
} // namespace gui
} // namespace blitz

View File

@@ -1,6 +1,10 @@
#pragma once
#include "GuiWidget.h"
#include "blitz/misc/Time.h"
#include "client/config/BlitzConfig.h"
#include <array>
#include <string>
namespace blitz {
@@ -12,6 +16,10 @@ class OptionsMenu : public GuiWidget {
private:
bool m_ShowFPS;
bool m_VSync;
bool m_IsKeyPopupOpen;
bool m_KeyPopupShouldClose;
utils::Timer m_Timer{100};
KeyAction m_CurrentAction;
public:
OptionsMenu(GuiWidget* parent, Client* client);
@@ -19,6 +27,11 @@ class OptionsMenu : public GuiWidget {
virtual void Render() override;
void OnKeyEvent(int key);
private:
std::string GetKeyActionCodeName(KeyAction);
void HotkeyBindingButton();
void HotkeyBindingPopUp();
};
} // namespace gui

View File

@@ -0,0 +1,16 @@
#pragma once
#include "GuiWidget.h"
namespace blitz {
namespace gui {
class ServerGui : public GuiWidget {
public:
ServerGui(GuiWidget* parent, Client* client);
virtual void Render() override;
};
} // namespace gui
} // namespace blitz

View File

@@ -0,0 +1,44 @@
#pragma once
#include "blitz/maths/Vector.h"
#include "client/render/loader/ModelLoader.h"
#include <memory>
#include <vector>
namespace blitz {
namespace shader {
class BulletShader;
} // namespace shader
namespace render {
class Camera;
struct Trail {
Mat4f m_Transform;
float m_Decay;
};
class BulletRenderer {
private:
std::vector<Trail> m_Trails;
ModelLoader::Model m_BulletModel;
std::unique_ptr<shader::BulletShader> m_Shader;
unsigned int m_Vbo;
const Camera& m_Camera;
public:
BulletRenderer(const Camera& cam);
~BulletRenderer();
void AddBullet(const Vec3f& origin, float yaw, float pitch);
void Update(float delta);
void Render();
};
} // namespace render
} // namespace blitz

View File

@@ -1,7 +1,7 @@
#pragma once
#include "blitz/common/Vector.h"
#include "blitz/game/Player.h"
#include "blitz/maths/Vector.h"
#include <cstdint>
namespace blitz {
@@ -19,6 +19,8 @@ class Camera {
void Update(float delta);
static float GetPlayerEyeHeight();
void SetAttachedPlayer(game::Player* a_Player) {
m_Player = a_Player;
}

View File

@@ -2,6 +2,7 @@
#include "client/Client.h"
#include "client/display/PlayerController.h"
#include "client/render/BulletRenderer.h"
#include "client/render/Camera.h"
#include "client/render/loader/GLLoader.h"
#include "client/render/loader/ModelLoader.h"
@@ -19,7 +20,7 @@ class GunShader;
namespace render {
class MainRenderer : public GuiListener {
class MainRenderer : public GuiListener, public game::PlayerInputListener {
private:
Client* m_Client;
ModelLoader::Model m_PlayerModel;
@@ -30,13 +31,17 @@ class MainRenderer : public GuiListener {
std::unique_ptr<shader::GunShader> m_GunShader;
input::PlayerController m_PlayerController;
unsigned int m_Texture;
float m_ShootTime;
Camera m_Camera;
BulletRenderer m_BulletRenderer;
public:
MainRenderer(Client* client);
~MainRenderer();
virtual void OnSpectatorChange(const game::PlayerID player) override;
virtual void OnSpectatorChange(game::PlayerID player) override;
virtual void OnPlayerShoot(game::PlayerID player, const Vec3f& position, float yaw, float pitch) override;
virtual void OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) override;
void Update();
void Render();

View File

@@ -0,0 +1,8 @@
#pragma once
#ifndef BLITZ_GL_LOADER_GLBNIDING
#include <GL/glew.h>
#else
#include <glbinding/gl/gl.h>
using namespace gl;
#endif

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/misc/ClassEntity.h"
#include "blitz/common/NonCopyable.h"
#include <vector>
@@ -13,7 +13,7 @@ struct VertexAttribPointer {
unsigned int m_Offset;
};
class ElementBuffer {
class ElementBuffer : private NonCopyable {
private:
unsigned int m_ID = 0;
std::size_t m_TriangleCount;
@@ -33,11 +33,9 @@ class ElementBuffer {
std::size_t GetTriangleCount() const {
return m_TriangleCount;
}
REMOVE_COPY(ElementBuffer);
};
class VertexBuffer {
class VertexBuffer : private NonCopyable {
private:
unsigned int m_ID = 0, m_DataStride;
std::vector<VertexAttribPointer> m_VertexAttribs;
@@ -56,11 +54,9 @@ class VertexBuffer {
void Unbind() const;
void AddVertexAttribPointer(unsigned int index, unsigned int coordinateSize, unsigned int offset);
void BindVertexAttribs() const;
REMOVE_COPY(VertexBuffer);
};
class VertexArray {
class VertexArray : private NonCopyable {
private:
unsigned int m_ID = 0;
ElementBuffer m_ElementBuffer;
@@ -82,8 +78,6 @@ class VertexArray {
void Bind() const;
void Unbind() const;
REMOVE_COPY(VertexArray);
private:
void BindElementArrayBuffer();
};

View File

@@ -1,5 +1,6 @@
#pragma once
#include "blitz/maths/Physics.h"
#include "client/render/loader/GLLoader.h"
#include <memory>
#include <string>
@@ -12,6 +13,7 @@ typedef std::unique_ptr<GL::VertexArray> VaoPtr;
struct Model {
std::vector<VaoPtr> mVaos;
std::vector<maths::AABB> mAABBs;
};
Model LoadModel(const std::string& fileName);

View File

@@ -0,0 +1,30 @@
#pragma once
#include "ShaderProgram.h"
namespace blitz {
namespace shader {
class BulletShader : public ShaderProgram {
private:
unsigned int m_LocationProjectionMatrix = 0;
unsigned int m_LocationViewMatrix = 0;
unsigned int m_LocationAlpha = 0;
unsigned int m_LocationTransform = 0;
protected:
virtual void GetAllUniformLocation() override;
public:
BulletShader();
bool LoadShader();
void SetProjectionMatrix(const Mat4f& proj) const;
void SetViewMatrix(const Mat4f& view) const;
void SetTransform(const Mat4f& trans) const;
void SetDecay(float decay) const;
};
} // namespace shader
} // namespace blitz

View File

@@ -1,8 +1,7 @@
#pragma once
#include "blitz/common/Vector.h"
#include <glbinding/SharedBitfield.h>
#include <glbinding/gl/enum.h>
#include "blitz/maths/Vector.h"
#include "client/render/OpenGL.h"
#include <string>
namespace blitz {
@@ -37,7 +36,7 @@ class ShaderProgram {
unsigned int m_VertexShaderID;
unsigned int m_FragmentShaderID;
int LoadShader(const std::string& source, gl::GLenum type);
int LoadShader(const std::string& source, GLenum type);
};
} // namespace shader

View File

@@ -36,6 +36,8 @@ class Server {
void Restart();
void AddBot();
void RemoveConnexion(std::uint8_t connexionID);
void BroadcastPacket(const protocol::Packet* packet);
@@ -67,6 +69,8 @@ class Server {
std::uint16_t GetListeningPort();
game::PlayerID GetNewPlayerID();
private:
void Accept();
void UpdateSockets();

View File

@@ -42,6 +42,7 @@ class ServerConnexion : public network::Connexion {
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
virtual void HandlePacket(const protocol::ChatPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerShootPacket* packet) override;
std::uint8_t GetID() const {
return m_ID;
@@ -49,8 +50,6 @@ class ServerConnexion : public network::Connexion {
virtual bool UpdateSocket();
REMOVE_COPY(ServerConnexion);
private:
void RegisterHandlers();
void CheckKeepAlive();

View File

@@ -17,6 +17,11 @@ class ServerGame : public game::Game {
ServerGame(Server* server);
virtual ~ServerGame();
void CheckShoot(game::PlayerID player, Vec3f position, float yaw, float pitch);
void AddPlayer(game::PlayerID player, const std::string& name) override;
void RemovePlayer(game::PlayerID player) override;
void Tick(std::uint64_t delta) override;
private:

View File

@@ -79,7 +79,7 @@ bool DataBuffer::ReadFile(const std::string& fileName) {
m_Buffer = DataBuffer::Data(s.begin(), s.end());
m_ReadOffset = 0;
} catch (std::exception& e) {
utils::LOGE(utils::Format("Failed to read file %s ! reason : %s", fileName.c_str(), e.what()));
utils::LOGE(utils::Format("[IO] Failed to read file %s ! reason : %s", fileName.c_str(), e.what()));
return false;
}
return m_Buffer.size() > 0;
@@ -91,7 +91,7 @@ bool DataBuffer::WriteFile(const std::string& fileName) {
file.write(reinterpret_cast<const char*>(m_Buffer.data()), static_cast<std::streamsize>(m_Buffer.size()));
file.flush();
} catch (std::exception& e) {
utils::LOGE(utils::Format("Failed to read file %s ! reason : %s", fileName.c_str(), e.what()));
utils::LOGE(utils::Format("[IO] Failed to read file %s ! reason : %s", fileName.c_str(), e.what()));
return false;
}
return true;

View File

@@ -7,11 +7,11 @@ namespace blitz {
EMASmoother::EMASmoother() : Alpha(1.0f), Current(0.0f) {}
void EMASmoother::TickUnitT(float target) {
Current += Alpha * (target - Current);
Current = target + Alpha * (Current - target);
}
void EMASmoother::Tick(float target, float delta) {
Current += std::pow(Alpha, delta) * (target - Current);
Current = target + std::pow(Alpha, delta) * (Current - target);
}
float EMASmoother::GetAlpha() {
@@ -24,7 +24,7 @@ void EMASmoother::SetAlpha(float alpha) {
}
void EMASmoother::SetSmoothingTime(float t) {
Alpha = 0.99f;
SetAlpha(std::pow(1.0f - 0.999f, 1.0f / t));
};
} // namespace blitz

View File

@@ -30,7 +30,7 @@ DataBuffer& operator<<(DataBuffer& out, const VarInt& var) {
DataBuffer& operator>>(DataBuffer& in, VarInt& var) {
var.m_Value = 0;
int position = 0;
unsigned int position = 0;
std::uint8_t currentByte;
while (true) {

View File

@@ -1,4 +1,4 @@
#include "blitz/misc/Maths.h"
#include "blitz/maths/Maths.h"
#include <cassert>
@@ -89,12 +89,24 @@ Mat4f Inverse(const Mat4f& mat) {
Mat4f Translate(const Vec3f& translation) {
Mat4f mat = Identity<float>();
Vec4f vh {translation.x, translation.y, translation.z, 1.0};
Vec4f vh{translation.x, translation.y, translation.z, 1.0};
mat.at(3, 0) = Dot(Vec4f{mat.at(0, 0), mat.at(1, 0), mat.at(2, 0), mat.at(3, 0)}, vh);
mat.at(3, 1) = Dot(Vec4f{mat.at(0, 1), mat.at(1, 1), mat.at(2, 1), mat.at(3, 1)}, vh);
mat.at(3, 2) = Dot(Vec4f{mat.at(0, 2), mat.at(1, 2), mat.at(2, 2), mat.at(3, 2)}, vh);
mat.at(3, 3) = Dot(Vec4f{mat.at(0, 3), mat.at(1, 3), mat.at(2, 3), mat.at(3, 3)}, vh);
mat.at(3, 0) = vh.x;
mat.at(3, 1) = vh.y;
mat.at(3, 2) = vh.z;
mat.at(3, 3) = vh.w;
return mat;
}
Mat4f Scale(const Vec3f& axisFactor) {
Mat4f mat{};
mat.at(0, 0) = axisFactor.x;
mat.at(1, 1) = axisFactor.y;
mat.at(2, 2) = axisFactor.z;
mat.at(3, 3) = 1.0f;
return mat;
}

63
src/blitz/maths/Physics.cpp Executable file
View File

@@ -0,0 +1,63 @@
#include "blitz/maths/Physics.h"
#include "blitz/maths/Maths.h"
#include <cmath>
namespace blitz {
namespace maths {
/**
* @brief Returns `true` if the half-line `ray` _strictly_ intersects with `aabb`,
* and `false` if it _strictly_ doesn't intersect.
* Note that if it only intersects with corners, edges, or sides of the box,
* or if any coordinate in `ray` is `NAN` or `inf` or if any coordinate in
* `aabb` is `NAN` the result is unspecified.
* */
float Distance(const Ray& ray, const AABB& aabb) {
// This function calculates smallest interval I = ] a, b [, for strictly positive a and b
// such that for all t in I, for all l, r, o, d corresponding
// coordinates in aabb.from, aabb.to, ray.origin, ray.direction, respectively
//
// min(l, r) < o + t * d < max(l, r)
//
// and returns true if it's non-empty i.e. a < b
// m = min(l, r), M = max(l, r)
// m < o + t * d < M
Vec3f l = Min(aabb.from, aabb.to);
Vec3f r = Max(aabb.from, aabb.to);
// m - o < t * d < M - o
l -= ray.origin;
r -= ray.origin;
// (m - o) / d < t < (M - o) / d
l /= ray.direction;
r /= ray.direction;
// but if d is negative the inequality is flipped
l = Min(l, r);
r = Max(l, r);
float tmin = ReduceMax(l);
float tmax = ReduceMin(r);
// Since Min propagates NANs and ReduceMin doesn't, and since NAN !< <any float>
// the inequality becomes ignored for coordinates where a NAN is involved
// (as a result of 0.0 / 0.0). If all coordinates are NAN, this means
// that the box is reduced to a point and the ray has direction 0,
// in which case this returns -1
if (tmin <= tmax) {
return std::fmaxf(tmin, 0.0f);
}
return -1.0f;
}
bool Intersects(const Ray& ray, const AABB& aabb) {
return Distance(ray, aabb) >= 0.0f;
}
} // namespace maths
} // namespace blitz

View File

@@ -1,6 +1,6 @@
#include "blitz/misc/Easing.h"
#include "blitz/misc/Maths.h"
#include "blitz/maths/Maths.h"
namespace blitz {
namespace utils {

View File

@@ -0,0 +1,15 @@
#include "blitz/misc/PrettyLog.h"
namespace blitz {
namespace utils {
std::string GetTextColor(Vec3uc color) {
return "\033[38;2;" + std::to_string(+color.r) + ";" + std::to_string(color.g) + ";" + std::to_string(color.b) + "m";
}
std::string GetTextColorReset() {
return "\033[0m";
}
} // namespace utils
} // namespace blitz

View File

@@ -44,21 +44,6 @@ void Timer::Reset() {
m_InternalTime = 0; // let the timer active once at the beginning
}
bool CooldownTimer::Update(std::uint64_t delta) {
if (m_Cooldown > 0) {
m_Cooldown = static_cast<std::uint64_t>(std::max(static_cast<std::int64_t>(0), static_cast<std::int64_t>(m_Cooldown - delta)));
}
return m_Cooldown == 0;
}
void CooldownTimer::Reset() {
m_Cooldown = 0; // let the timer active once at the beginning
}
void CooldownTimer::ApplyCooldown() {
m_Cooldown = m_CooldownTime;
}
std::uint64_t GetTime() {
return static_cast<std::uint64_t>(
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count());

View File

@@ -9,9 +9,9 @@ namespace network {
NetworkInitializer::NetworkInitializer() {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) < 0) {
utils::LOGE("Failed to initialize network !");
utils::LOGE("[Network] Failed to initialize network !");
} else {
utils::LOG("Network initialized !");
utils::LOG("[Network] Network initialized !");
}
}
NetworkInitializer::~NetworkInitializer() {

View File

@@ -11,7 +11,7 @@
namespace blitz {
namespace network {
TCPListener::TCPListener() {}
TCPListener::TCPListener() : m_Handle(INVALID_SOCKET), m_Port(0), m_MaxConnections(0) {}
TCPListener::~TCPListener() {
Destroy();
@@ -19,7 +19,7 @@ TCPListener::~TCPListener() {
bool TCPListener::Listen(std::uint16_t port, int maxConnections) {
if ((m_Handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
utils::LOGE("Failed to create server socket !");
utils::LOGE("[TCPListener] Failed to create server socket !");
return false;
}
@@ -59,7 +59,7 @@ bool TCPListener::Accept(TCPSocket& newSocket) {
}
void TCPListener::Destroy() {
if (m_Handle < 0)
if (m_Handle > 0)
closesocket(m_Handle);
}

View File

@@ -16,7 +16,7 @@ namespace blitz {
namespace network {
TCPSocket::TCPSocket() :
m_Blocking(false), m_Status(Status::Disconnected), m_Port(0), m_Handle(static_cast<SocketHandle>(INVALID_SOCKET)) {}
m_Blocking(false), m_Status(Status::Disconnected), m_Handle(static_cast<SocketHandle>(INVALID_SOCKET)), m_Port(0) {}
TCPSocket::TCPSocket(TCPSocket&& other) {
@@ -61,7 +61,7 @@ std::size_t TCPSocket::Send(DataBuffer& buffer) {
}
void TCPSocket::Disconnect() {
if (m_Handle < 0)
if (m_Handle > 0)
closesocket(m_Handle);
m_Status = Status::Disconnected;
}
@@ -79,13 +79,13 @@ bool TCPSocket::Connect(const std::string& host, unsigned short port) {
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(host.c_str(), std::to_string(static_cast<int>(port)).c_str(), &hints, &result) != 0) {
utils::LOGE("Failed to get address info !");
utils::LOGE("[TCPSocket] Failed to get address info !");
return false;
}
m_Handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_Handle < 0) {
utils::LOGE("Failed to create socket !");
utils::LOGE("[TCPSocket] Failed to create socket !");
return false;
}
@@ -93,7 +93,7 @@ bool TCPSocket::Connect(const std::string& host, unsigned short port) {
for (ptr = result; ptr != nullptr; ptr = ptr->ai_next) {
struct sockaddr* sockaddr = ptr->ai_addr;
if (connect(m_Handle, sockaddr, sizeof(sockaddr_in)) != 0) {
utils::LOGE("Failed to connect with this address !");
utils::LOGE("[TCPSocket] Failed to connect with this address !");
continue;
}
m_RemoteAddr = *sockaddr;
@@ -103,7 +103,7 @@ bool TCPSocket::Connect(const std::string& host, unsigned short port) {
freeaddrinfo(result);
if (!ptr) {
utils::LOGE("Could not find a suitable interface for connecting !");
utils::LOGE("[TCPSocket] Could not find a suitable interface for connecting !");
return false;
}

View File

@@ -23,6 +23,7 @@ static std::array<PacketPtr, static_cast<std::size_t>(PacketType::PACKET_COUNT)>
std::make_unique<DisconnectPacket>(),
std::make_unique<ChatPacket>(),
std::make_unique<PlayerPositionAndRotationPacket>(),
std::make_unique<PlayerShootPacket>(),
};
const Packet* CreatePacket(PacketType type, DataBuffer& buffer) {

View File

@@ -2,7 +2,9 @@
#include "blitz/protocol/Packets.h"
#define REGISTER_DISPATCH_CLASS(className) \
void className::Dispatch(PacketHandler* handler) const { handler->HandlePacket(this); }
void className::Dispatch(PacketHandler* handler) const { \
handler->HandlePacket(this); \
}
namespace blitz {
namespace protocol {
@@ -22,6 +24,7 @@ REGISTER_DISPATCH_CLASS(DisconnectPacket)
REGISTER_DISPATCH_CLASS(ServerTpsPacket)
REGISTER_DISPATCH_CLASS(ChatPacket)
REGISTER_DISPATCH_CLASS(PlayerPositionAndRotationPacket)
REGISTER_DISPATCH_CLASS(PlayerShootPacket);
} // namespace protocol
} // namespace blitz

View File

@@ -1,6 +1,6 @@
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/common/Vector.h"
#include "blitz/maths/Vector.h"
#include "blitz/misc/Log.h"
#include <map>
#include <sstream>
@@ -46,13 +46,13 @@ std::string ChatPacket::GetTextColor(Vec3uc color) {
ss << std::hex << "\\u";
if (color.r <= 0xF)
ss << 0;
ss << color.r;
ss << +color.r;
if (color.g <= 0xF)
ss << 0;
ss << color.g;
ss << +color.g;
if (color.b <= 0xF)
ss << 0;
ss << color.b;
ss << +color.b;
return ss.str();
}
@@ -84,7 +84,7 @@ ColoredText ChatPacket::ColorizeText(const std::string& text) {
static_cast<float>(std::stoul(blue, nullptr, 16)) / 255.0f, 1.0f};
cursor += 6;
} catch (std::exception& e) {
utils::LOG("warning ! wrong color providen !");
utils::LOG("[ChatPacket] warning ! wrong color providen !");
}
break;
}

View File

@@ -20,7 +20,7 @@ void PlayerListPacket::Deserialize(DataBuffer& data) {
VarInt playerCount;
data >> playerCount;
for (int i = 0; i < playerCount.GetValue(); i++) {
for (std::size_t i = 0; i < playerCount.GetValue(); i++) {
std::uint8_t playerID;
PlayerInfo playerInfo;
data >> playerID >> playerInfo.name;

View File

@@ -0,0 +1,19 @@
#include "blitz/protocol/packets/PlayerShootPacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerShootPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_Player << m_Position << m_Yaw << m_Pitch;
return data;
}
void PlayerShootPacket::Deserialize(DataBuffer& data) {
data >> m_Player >> m_Position >> m_Yaw >> m_Pitch;
}
} // namespace protocol
} // namespace blitz

View File

@@ -9,7 +9,7 @@ namespace utils {
namespace AssetsManager {
DataBuffer GetAsset(const std::string& fileName) {
utils::LOGD(utils::Format("Opening file %s...", fileName.c_str()));
utils::LOGD(utils::Format("[AssetsManager] Opening file %s...", fileName.c_str()));
SDL_RWops* io = SDL_RWFromFile(fileName.c_str(), "rb");

View File

@@ -3,6 +3,7 @@
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/DisconnectPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "blitz/protocol/packets/PlayerShootPacket.h"
#include "client/ClientConnexion.h"
#include "client/game/ClientGame.h"
#include "server/Server.h"
@@ -78,6 +79,13 @@ void Client::SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch)
m_Connexion->SendPacket(&packet);
}
void Client::OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) {
protocol::PlayerShootPacket packet(position, yaw, pitch);
m_Connexion->SendPacket(&packet);
}
game::PlayerID Client::GetPlayerID() const {
return m_Connexion->GetPlayerID();
}
@@ -86,6 +94,10 @@ bool Client::IsConnected() {
return m_Connexion->GetSocketStatus() == network::TCPSocket::Status::Connected;
}
bool Client::IsAdmin() const {
return m_Server->IsRunning();
}
void Client::UpdatePosition(std::uint64_t delta) {
// send position every tick (50 ms)

View File

@@ -2,6 +2,7 @@
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/PrettyLog.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/ConnexionInfoPacket.h"
#include "blitz/protocol/packets/KeepAlivePacket.h"
@@ -11,6 +12,17 @@
namespace blitz {
namespace client {
static std::string PrintColoredText(const protocol::ColoredText& coloredText) {
std::string text;
for (const auto& part : coloredText) {
text += utils::GetTextColor({static_cast<std::uint8_t>(part.color.r * 255), static_cast<std::uint8_t>(part.color.g * 255),
static_cast<std::uint8_t>(part.color.b * 255)}) +
part.text;
}
text += utils::GetTextColorReset();
return text;
}
ClientConnexion::ClientConnexion(Client* client) : network::Connexion(&m_Dispatcher), m_Client(client) {
RegisterHandlers();
}
@@ -35,7 +47,7 @@ bool ClientConnexion::Connect(const std::string& pseudo, const std::string& addr
}
void ClientConnexion::HandlePacket(const protocol::ChatPacket* packet) {
utils::LOG(utils::Format("Chat : %s", protocol::ChatPacket::GetColoredTextString(packet->GetMessage()).c_str()));
utils::LOG("[Chat] " + PrintColoredText(packet->GetMessage()));
m_Client->ChatTextReceived(packet->GetMessage());
}

View File

@@ -1,6 +1,7 @@
#include "client/config/BlitzConfig.h"
#include "blitz/misc/Log.h"
#include "imgui.h"
#include <fstream>
#include <nlohmann/json.hpp>
@@ -22,7 +23,7 @@ void BlitzConfig::LoadConfig() {
LoadDefaultConfig();
if (!file) {
utils::LOG("Could not load config !");
utils::LOG("[BlitzConfig] Could not load config !");
return;
}
@@ -36,8 +37,11 @@ void BlitzConfig::LoadConfig() {
std::memcpy(m_Pseudo.data(), pseudo.data(), pseudo.size() + 1);
jsonInput.at("vsync").get_to<bool>(m_VSync);
jsonInput.at("fps").get_to<bool>(m_DisplayFps);
jsonInput.at("keys").get_to<Keybinds>(m_Keybinds);
utils::LOG("[BlitzConfig] Restored config !");
} catch (std::exception& e) {
utils::LOGE("Failed to load config !");
utils::LOGE("[BlitzConfig] Failed to load config !");
}
}
@@ -46,19 +50,21 @@ void BlitzConfig::LoadDefaultConfig() {
m_VSync = true;
const char defaultPseudo[] = "Pseudo";
std::memcpy(m_Pseudo.data(), defaultPseudo, sizeof(defaultPseudo));
m_Keybinds = {ImGuiKey_Z, ImGuiKey_S, ImGuiKey_D, ImGuiKey_Q};
}
void BlitzConfig::SaveConfig() {
std::ofstream file{"settings.json"};
if (!file) {
utils::LOGE("Could not save config !");
utils::LOGE("[BlitzConfig] Could not save config !");
}
json jsonOutput = {
{"pseudo", GetPseudo().data()},
{"vsync", IsVSyncEnabled()},
{"fps", IsFPSDisplayEnabled()},
{"keys", GetKeys()},
};
file << jsonOutput;

View File

@@ -1,11 +1,10 @@
#include "client/display/Display.h"
#include "client/display/InputManager.h"
#include "client/render/OpenGL.h"
#include <SDL2/SDL.h>
#include <backends/imgui_impl_opengl3.h>
#include <backends/imgui_impl_sdl2.h>
#include <glbinding/gl/gl.h>
#include <glbinding/glbinding.h>
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
@@ -13,17 +12,21 @@
#include "client/gui/BlitzGui.h"
using namespace gl;
#ifndef BLITZ_GL_LOADER_GLBNIDING
#include <GL/glew.h>
#else
#include <glbinding/glbinding.h>
#endif
namespace blitz {
Display::Display(int width, int height, const std::string& windowName, Client* client) :
m_WindowWidth(width),
m_WindowHeight(height),
m_AspectRatio(m_WindowHeight / static_cast<float>(m_WindowWidth)),
m_WindowName(windowName),
m_ShouldClose(false),
m_FullScreen(false),
m_AspectRatio(m_WindowHeight / static_cast<float>(m_WindowWidth)),
m_Client(client),
m_BlitzGui(nullptr) {}
@@ -52,7 +55,7 @@ bool Display::Create() {
m_GL_Context = SDL_GL_CreateContext(m_Window);
if (!m_GL_Context) {
utils::LOGE(utils::Format("Could not create context ! SDL error : %s", SDL_GetError()));
utils::LOGE(utils::Format("[Display] Could not create context ! SDL error : %s", SDL_GetError()));
return false;
}
@@ -86,15 +89,23 @@ bool Display::Create() {
}
utils::LOG(utils::Format(
"GL Context : %i.%i %s, Color : R:%i G:%i B:%i A:%i, Depth bits : %i", major, minor, mask_desc, r, g, b, a, depth));
utils::LOG(
utils::Format("Antialiasing : %s, Number of samples per pixel : %i", multisamples ? "true" : "false", multisamplescount));
utils::LOG(utils::Format("Screen keyboard supported : %s", SDL_HasScreenKeyboardSupport() ? "true" : "false"));
"[Display] GL Context : %i.%i %s, Color : R:%i G:%i B:%i A:%i, Depth bits : %i", major, minor, mask_desc, r, g, b, a, depth));
utils::LOG(utils::Format(
"[Display] Antialiasing : %s, Number of samples per pixel : %i", multisamples ? "true" : "false", multisamplescount));
utils::LOG(utils::Format("[Display] Screen keyboard supported : %s", SDL_HasScreenKeyboardSupport() ? "true" : "false"));
SDL_GL_MakeCurrent(m_Window, m_GL_Context);
SDL_GL_SetSwapInterval(1);
#ifndef BLITZ_GL_LOADER_GLBNIDING
GLenum error = glewInit();
if (error != GLEW_OK) {
utils::LOGE(utils::Format("[Display] Failed to initialise glew : %s", glewGetErrorString(error)));
return false;
}
#else
glbinding::initialize(reinterpret_cast<glbinding::ProcAddress (*)(const char*)>(SDL_GL_GetProcAddress));
#endif
InitImGui();
return true;

View File

@@ -1,11 +1,13 @@
#include "client/display/PlayerController.h"
#include "blitz/game/Player.h"
#include "blitz/maths/Maths.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Maths.h"
#include "client/Client.h"
#include "client/display/InputManager.h"
#include "imgui.h"
#include <algorithm>
#include <iostream>
namespace blitz {
namespace input {
@@ -14,24 +16,24 @@ static constexpr float DEFAULT_JUMP_VEL = 7.5;
static constexpr float DEFAULT_GRAVITY = 20.0;
static constexpr float DEFAULT_MAX_LR_SPEED = 10.;
static constexpr float DEFAULT_MAX_FB_SPEED = 10.;
static constexpr float DEFAULT_LR_TOP_SPEED_REACH_TIME = 0.1;
static constexpr float DEFAULT_FB_TOP_SPEED_REACH_TIME = 0.1;
static constexpr float DEFAULT_LR_SPEED_SMOOTHING_TIME = 1.0;
static constexpr float DEFAULT_FB_SPEED_SMOOTHING_TIME = 1.0;
PlayerController::PlayerController() :
PlayerController::PlayerController(Client* client) :
m_Player(nullptr),
m_Client(client),
m_Dx(0.0),
m_Dy(0.0),
m_Dz(0.0),
m_MaxDx(DEFAULT_MAX_LR_SPEED),
m_MaxDy(DEFAULT_MAX_FB_SPEED),
m_MaxDz(DEFAULT_JUMP_VEL),
m_Dz(0.0),
m_G(DEFAULT_GRAVITY),
m_OnGround(true)
{
m_OnGround(true) {
m_DxSmoother.Current = 0.0f;
m_DySmoother.Current = 0.0f;
m_DxSmoother.SetSmoothingTime(DEFAULT_LR_TOP_SPEED_REACH_TIME);
m_DySmoother.SetSmoothingTime(DEFAULT_FB_TOP_SPEED_REACH_TIME);
m_DxSmoother.SetSmoothingTime(DEFAULT_LR_SPEED_SMOOTHING_TIME);
m_DySmoother.SetSmoothingTime(DEFAULT_FB_SPEED_SMOOTHING_TIME);
InputManager::BindMouseMoveCallback(
std::bind(&PlayerController::MouseMotionEvent, this, std::placeholders::_1, std::placeholders::_2));
}
@@ -52,14 +54,28 @@ void PlayerController::Update(float delta) {
return;
if (InputManager::MouseGrabbed()) {
float lr = static_cast<float>(ImGui::IsKeyDown(ImGuiKey_Z)) - static_cast<float>(ImGui::IsKeyDown(ImGuiKey_S));
float fb = static_cast<float>(ImGui::IsKeyDown(ImGuiKey_Q)) - static_cast<float>(ImGui::IsKeyDown(ImGuiKey_D));
Keybinds keys = m_Client->GetConfig()->GetKeys();
float lr = static_cast<float>(ImGui::IsKeyDown((ImGuiKey(keys[kaAvancer])))) -
static_cast<float>(ImGui::IsKeyDown((ImGuiKey(keys[kaReculer]))));
float fb = static_cast<float>(ImGui::IsKeyDown((ImGuiKey(keys[kaGauche])))) -
static_cast<float>(ImGui::IsKeyDown((ImGuiKey(keys[kaDroite]))));
m_Dx = lr * m_MaxDx;
m_Dy = fb * m_MaxDy;
// scale values in such a way that clamps ||(lr, fb)|| to 1.0
float scale = 1.0f / std::max(sqrt(lr * lr + fb * fb), 1.0f);
m_Dx = lr * m_MaxDx * scale;
m_Dy = fb * m_MaxDy * scale;
if (ImGui::IsKeyDown(ImGuiKey::ImGuiKey_Space) && m_OnGround) {
m_Dz = m_MaxDz;
NotifyListeners(&game::PlayerInputListener::OnLocalPlayerJump);
}
bool canShoot = m_ShootTimer.Update(delta);
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && canShoot) {
NotifyListeners(
&game::PlayerInputListener::OnLocalPlayerShoot, m_Player->GetPosition(), m_Player->GetYaw(), m_Player->GetPitch());
m_ShootTimer.ApplyCooldown();
}
}
@@ -87,7 +103,7 @@ void PlayerController::UpdatePosition(const float delta) {
// assumed to be a negative number
const float floor_dist = 0.0f - m_Player->GetPosition().y;
if (m_OnGround = dz <= floor_dist) {
if ((m_OnGround = (dz <= floor_dist))) {
dz = floor_dist;
m_Dz = 0.0f;
} else {

View File

@@ -6,6 +6,7 @@
#include "blitz/protocol/packets/PlayerLeavePacket.h"
#include "blitz/protocol/packets/PlayerListPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "blitz/protocol/packets/PlayerShootPacket.h"
#include "client/Client.h"
namespace blitz {
@@ -25,6 +26,7 @@ void ClientGame::RegisterHandlers() {
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerLeave, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerList, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerShoot, this);
}
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
@@ -46,6 +48,11 @@ void ClientGame::HandlePacket(const protocol::PlayerListPacket* packet) {
}
}
void ClientGame::HandlePacket(const protocol::PlayerShootPacket* packet) {
m_Client->NotifyListeners(
&GuiListener::OnPlayerShoot, packet->GetPlayer(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
}
void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) {
if (packet->GetPlayer() == m_Client->GetPlayerID())
return;
@@ -61,7 +68,6 @@ void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket* p
}
void ClientGame::Tick(std::uint64_t delta) {
float deltaTime = static_cast<float>(delta) / 1000.0f;
for (auto& [playerId, player] : GetPlayers()) {
player.SetPosition(player.GetPosition() + player.GetVelocity() * (static_cast<float>(delta) / 100.0f));
}

View File

@@ -1,7 +1,9 @@
#include "client/gui/BlitzGui.h"
#include "client/gui/GameChatGui.h"
#include "client/gui/Hud.h"
#include "client/gui/MainMenu.h"
#include "client/gui/ServerGui.h"
#include <imgui.h>
namespace blitz {
@@ -11,6 +13,8 @@ BlitzGui::BlitzGui(Client* client) : GuiWidget(nullptr, client) {
Enable();
AddWidget(std::make_unique<GameChatGui>(this, client));
AddWidget(std::make_unique<MainMenu>(client));
AddWidget(std::make_unique<ServerGui>(this, client));
AddWidget(std::make_unique<Hud>(this, client));
SetCustomTheme();
}

View File

@@ -1,13 +1,20 @@
#include "client/gui/ColorFulText.h"
#include <imgui.h>
#include <imgui_internal.h>
namespace blitz {
namespace gui {
void RenderColorfulText(const protocol::ColoredText& parts, float alpha) {
ImGuiContext& g = *ImGui::GetCurrentContext();
for (auto& part : parts) {
ImGui::TextColored({part.color.r, part.color.g, part.color.b, alpha}, part.text.c_str());
const bool need_backup = (g.CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position if one is already set
if (need_backup)
ImGui::PushTextWrapPos(0.0f);
ImGui::TextColored({part.color.r, part.color.g, part.color.b, alpha}, "%s", part.text.c_str());
if (need_backup)
ImGui::PopTextWrapPos();
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - ImGui::CalcTextSize(".").x);
}

View File

@@ -18,6 +18,9 @@ void CreateGameMenu::Render() {
SetNextWindowFullScreen();
static int InputPort = 0;
const static ImVec2 buttonSize = {300, 60};
auto displaySize = ImGui::GetIO().DisplaySize;
const static int paddingHeight = 40;
ImGui::Begin("CreateWindow", nullptr, GetWindowFullScreenFlags());
{
@@ -32,7 +35,7 @@ void CreateGameMenu::Render() {
ImGui::Text("Port saisi : %d", InputPort);
if (ImGui::Button("Creer")) {
utils::LOGD(utils::Format("Port saisi : %i", InputPort));
utils::LOGD(utils::Format("[CreateGameMenu] Port saisi : %i", InputPort));
if (m_Client->CreateGame(InputPort, m_Client->GetConfig()->GetPseudo().data())) {
InputManager::GrabMouse(true);
@@ -40,7 +43,9 @@ void CreateGameMenu::Render() {
}
}
if (ImGui::Button("Retour") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
ImGui::SetCursorPosX(displaySize.x - buttonSize.x - paddingHeight);
ImGui::SetCursorPosY(displaySize.y - buttonSize.y - paddingHeight);
if (ImGui::Button("Retour", buttonSize) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
Disable();
m_Parent->Enable();
}

View File

@@ -21,22 +21,15 @@ GameChatGui::GameChatGui(GuiWidget* parent, Client* client) : GuiWidget(parent,
}
void GameChatGui::Draw(const char* title, bool* p_open) {
HistoryPos = -1;
static int chat_width = 620;
static int chat_height = 450;
static int chatInput_width = 590;
static int scrolling_width = chat_height - 90;
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - chat_height));
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - 2 * chat_height));
ImGui::SetNextWindowSize(ImVec2(chat_width, chat_height));
// const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
ImGui::Begin(title, p_open, GetWindowFullScreenFlags());
{
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 0.73f));
if (ImGui::BeginChild("ChatContent", ImVec2(0, chat_height - 90), false, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
for (const auto& line : m_Lines) {
RenderColorfulText(line, 1);
}
}
ImGui::PopStyleColor();
ImGui::EndChild();
ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_EscapeClearsAll;
if (m_FocusRequested) {
@@ -44,6 +37,10 @@ void GameChatGui::Draw(const char* title, bool* p_open) {
m_FocusRequested = false;
}
for (const auto& line : m_Lines) {
RenderColorfulText(line, 1);
}
const static ImVec4 chatColorInputText = {1.0f, 0.0f, 0.0f, 0.27f};
ImGui::SetNextItemWidth(chatInput_width);
ImGui::PushStyleColor(ImGuiCol_FrameBg, chatColorInputText);
@@ -51,6 +48,11 @@ void GameChatGui::Draw(const char* title, bool* p_open) {
m_Client->SendChatText(InputBuf);
InputBuf[0] = '\0';
}
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
ImGui::SetScrollHereY(1.0f);
ScrollToBottom = false;
ImGui::PopStyleColor();
}
@@ -59,14 +61,18 @@ void GameChatGui::Draw(const char* title, bool* p_open) {
void GameChatGui::DrawMini(const char* title, bool* p_open) {
static int chat_width = 620;
static int chat_height = 110;
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - chat_height));
static int chat_height = 225;
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - 3.5 * chat_height));
ImGui::SetNextWindowSize(ImVec2(chat_width, chat_height));
ImGui::Begin(title, p_open, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoNav);
{
for (const auto& line : m_TempLines) {
RenderColorfulText(line, utils::EaseOutCubic(m_ChatDisplay / ChatFadeTime));
}
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
ImGui::SetScrollHereY(1.0f);
ScrollToBottom = false;
}
ImGui::End();
}

90
src/client/gui/Hud.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include "client/gui/Hud.h"
#include "client/gui/GuiWidget.h"
#include "client/render/loader/TextureLoader.h"
#include <client/Client.h>
#include <imgui.h>
namespace blitz {
namespace gui {
Hud::Hud(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {
m_GunTexture = TextureLoader::LoadGLTexture("fingergun.png");
m_JP = TextureLoader::LoadGLTexture("jp.png");
}
void Hud::Draw(const char* title, bool* p_open) {
SetNextWindowFullScreen();
ImGui::Begin(title, nullptr, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoInputs);
auto displaySize = ImGui::GetIO().DisplaySize;
const static ImVec2 buttonSize = {300, 60};
const static ImVec2 fingergunSize = {256, 134.5};
const static ImVec2 jpSize = {256 / 2, 256 / 2};
const static int paddingHeight = 40;
const static ImVec2 pvBarPos = {displaySize.x / 2.2f, displaySize.y - 3 * paddingHeight};
const static ImVec2 progressSize = {100.0f, 30.0f};
const static ImVec2 currentWeaponPos = {
displaySize.x - buttonSize.x - 3 * paddingHeight, displaySize.y - buttonSize.y - 1.5f * paddingHeight};
const static ImVec2 currentWeaponPosImage = {
displaySize.x - fingergunSize.x - paddingHeight, displaySize.y - fingergunSize.y + 1.0f / 2.5f * paddingHeight};
ImVec2 spacing = ImGui::GetStyle().ItemInnerSpacing;
ImGui::SetCursorPosX(3 * paddingHeight);
ImGui::SetCursorPosY(pvBarPos.y - 2 * paddingHeight);
ImGui::BeginGroup();
ImGui::Image(reinterpret_cast<ImTextureID>(m_JP), jpSize);
ImGui::SameLine(0.0f, paddingHeight);
// ImGui::EndGroup();
// ImGui::SetCursorPosX(pvBarPos.x);
// ImGui::SetCursorPosY(pvBarPos.y);
ImGui::BeginGroup();
{
// Animate a simple progress bar
static float progress = 0.0f, progress_dir = 1.0f;
progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime;
if (progress >= +1.0f) {
progress = +1.0f;
progress_dir *= -1.0f;
}
if (progress <= 0.0f) {
progress = 0.0f;
progress_dir *= -1.0f;
}
int pv = static_cast<int>(progress * 100);
ImGui::Text("PV : %i", pv);
// ImGui::Dummy();
ImGui::ProgressBar(progress, progressSize, "");
}
ImGui::EndGroup();
ImGui::EndGroup();
ImGui::SetCursorPosX(currentWeaponPos.x);
ImGui::SetCursorPosY(currentWeaponPos.y);
ImGui::BeginGroup();
{
ImGui::Text("FingerGun");
ImGui::SameLine(0.0f, spacing.x * 50);
ImGui::Text("3 | 9");
ImGui::SetCursorPosX(currentWeaponPosImage.x);
ImGui::SetCursorPosY(currentWeaponPosImage.y);
ImGui::Image(reinterpret_cast<ImTextureID>(m_GunTexture), fingergunSize);
}
ImGui::EndGroup();
ImGui::End();
}
void Hud::Render() {
if (!m_Client->IsConnected())
return;
Draw("Hud Blitz", nullptr);
}
} // namespace gui
} // namespace blitz

View File

@@ -17,6 +17,9 @@ void JoinGameMenu::Render() {
SetNextWindowFullScreen();
static int InputPort = 25565;
const static ImVec2 buttonSize = {300, 60};
auto displaySize = ImGui::GetIO().DisplaySize;
const static int paddingHeight = 40;
ImGui::Begin("JoinWindow", nullptr, GetWindowFullScreenFlags());
{
@@ -36,7 +39,7 @@ void JoinGameMenu::Render() {
ImGui::Text("Port saisi : %d", InputPort);
if (ImGui::Button("Rejoindre")) {
utils::LOGD(utils::Format("Adresse saisie : %s, Port saisi : %i", InputAddress, InputPort));
utils::LOGD(utils::Format("[JoinGameMenu] Adresse saisie : %s, Port saisi : %i", InputAddress, InputPort));
if (m_Client->JoinGame(m_Client->GetConfig()->GetPseudo().data(), InputAddress, InputPort)) {
InputManager::GrabMouse(true);
@@ -44,7 +47,9 @@ void JoinGameMenu::Render() {
}
}
if (ImGui::Button("Retour") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
ImGui::SetCursorPosX(displaySize.x - buttonSize.x - paddingHeight);
ImGui::SetCursorPosY(displaySize.y - buttonSize.y - paddingHeight);
if (ImGui::Button("Retour", buttonSize) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
Disable();
m_Parent->Enable();
}

View File

@@ -1,5 +1,7 @@
#include "client/gui/OptionsMenu.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "client/Client.h"
#include "client/display/InputManager.h"
#include "client/gui/FPSMenu.h"
@@ -9,7 +11,86 @@
namespace blitz {
namespace gui {
OptionsMenu::OptionsMenu(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {
static std::string ActionNames[kaMax] = {
"Avancer",
"Reculer",
"Droite",
"Gauche",
};
static std::string GetActionName(KeyAction action) {
return ActionNames[action];
}
static std::string GetImGuiKeyName(int key) {
if (key == ImGuiKey_None) {
return "?";
}
return ImGui::GetKeyName(static_cast<ImGuiKey>(key));
}
void OptionsMenu::HotkeyBindingButton() {
for (std::size_t i = 0; i < m_Client->GetConfig()->GetKeys().size(); i++) {
if (ImGui::Button(utils::Format("%s##%i", GetKeyActionCodeName(KeyAction(i)).c_str(), i).c_str())) {
m_IsKeyPopupOpen = true;
m_CurrentAction = KeyAction(i);
ImGui::OpenPopup("Changer de touche");
}
ImGui::SameLine();
ImGui::Text("%s", GetActionName(KeyAction(i)).c_str());
}
}
void OptionsMenu::HotkeyBindingPopUp() {
// Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("Changer de touche", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text("Entrez la touche pour : ");
ImGui::SameLine();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", GetActionName(m_CurrentAction).c_str());
ImGui::Text("Si vous voulez annulez cette action, appuyez sur Echap !");
ImGui::Dummy({0, 40});
ImGui::Text("La touche pour ");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", GetActionName(m_CurrentAction).c_str());
ImGui::SameLine();
ImGui::Text(" est : ");
ImGui::SameLine();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", GetKeyActionCodeName(m_CurrentAction).c_str());
if (m_KeyPopupShouldClose && m_Timer.Update(ImGui::GetIO().DeltaTime * 1000)) {
m_KeyPopupShouldClose = false;
m_IsKeyPopupOpen = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
OptionsMenu::OptionsMenu(GuiWidget* parent, Client* client) :
GuiWidget(parent, client), m_IsKeyPopupOpen(false), m_KeyPopupShouldClose(false) {
AddWidget(std::make_unique<FPSMenu>(this, client));
InputManager::BindKeyDownCallback(std::bind(&OptionsMenu::OnKeyEvent, this, std::placeholders::_1));
@@ -20,7 +101,37 @@ OptionsMenu::OptionsMenu(GuiWidget* parent, Client* client) : GuiWidget(parent,
SDL_GL_SetSwapInterval(m_VSync);
}
void OptionsMenu::OnKeyEvent(int key) {}
void OptionsMenu::OnKeyEvent(int key) {
if (!m_IsKeyPopupOpen)
return;
if (key == ImGuiKey_Escape) {
m_KeyPopupShouldClose = true;
ImGui::GetIO().ClearInputKeys(); // releases the Escape key
return;
}
m_Client->GetConfig()->GetKeys()[static_cast<std::size_t>(m_CurrentAction)] = key;
m_KeyPopupShouldClose = true;
utils::LOG(std::to_string(key));
}
std::string OptionsMenu::GetKeyActionCodeName(KeyAction act) {
return GetImGuiKeyName(static_cast<int>(m_Client->GetConfig()->GetKeys()[act]));
}
void OptionsMenu::Render() {
GuiWidget::Render();
@@ -34,6 +145,8 @@ void OptionsMenu::Render() {
if (!IsEnabled())
return;
const static ImVec2 buttonSize = {300, 60};
auto displaySize = ImGui::GetIO().DisplaySize;
const static int paddingHeight = 40;
const static int startPos = 15;
@@ -47,31 +160,60 @@ void OptionsMenu::Render() {
ImGui::NewLine();
if (ImGui::Checkbox("AFFICHER LES FPS", &m_ShowFPS)) {
m_SubWidgets[0]->SetState(m_ShowFPS);
m_Client->GetConfig()->SetFPSDisplay(m_ShowFPS);
}
if (ImGui::Checkbox("VSync", &m_VSync)) {
SDL_GL_SetSwapInterval(m_VSync);
m_Client->GetConfig()->SetVSync(m_VSync);
}
if (ImGui::Button("Retour") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
if (ImGui::Button("Retour") || (ImGui::IsKeyPressed(ImGuiKey_Escape, false) && !m_IsKeyPopupOpen)) {
Disable();
if (m_Client->IsConnected()) {
InputManager::GrabMouse(true);
ImGui::SetCursorPosX(displaySize.x - buttonSize.x - paddingHeight);
ImGui::SetCursorPosY(displaySize.y - 2 * buttonSize.y - paddingHeight);
} else {
m_Parent->Enable();
ImGui::SetCursorPosX(displaySize.x - buttonSize.x - paddingHeight);
ImGui::SetCursorPosY(displaySize.y - buttonSize.y - paddingHeight);
}
}
if (m_Client->IsConnected()) {
if (ImGui::Button("Quitter la partie")) {
m_Client->Disconnect();
ImGui::BeginGroup();
if (ImGui::Button("Retour", buttonSize) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
Disable();
m_Parent->Enable();
if (m_Client->IsConnected()) {
InputManager::GrabMouse(true);
} else {
m_Parent->Enable();
}
}
if (m_Client->IsConnected()) {
if (ImGui::Button("Quitter la partie", buttonSize)) {
m_Client->Disconnect();
Disable();
m_Parent->Enable();
}
}
ImGui::EndGroup();
}
ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
if (ImGui::BeginTabBar("OPTIONS", tab_bar_flags)) {
if (ImGui::BeginTabItem("CONTROLES")) {
// Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
HotkeyBindingButton();
HotkeyBindingPopUp();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("GRAPHISMES")) {
if (ImGui::Checkbox("AFFICHER LES FPS", &m_ShowFPS)) {
m_SubWidgets[0]->SetState(m_ShowFPS);
m_Client->GetConfig()->SetFPSDisplay(m_ShowFPS);
}
if (ImGui::Checkbox("VSync", &m_VSync)) {
SDL_GL_SetSwapInterval(m_VSync);
m_Client->GetConfig()->SetVSync(m_VSync);
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("AUDIO")) {
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
}
ImGui::End();

View File

@@ -0,0 +1,32 @@
#include "client/gui/ServerGui.h"
#include "client/Client.h"
#include "server/Server.h"
#include <imgui.h>
namespace blitz {
namespace gui {
ServerGui::ServerGui(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {}
void ServerGui::Render() {
if (!m_Client->IsAdmin())
return;
if (ImGui::IsKeyPressed(ImGuiKey_P)) {
ImGui::OpenPopup("Admin panel");
}
static bool popup_opened = true;
// this is uggly but okay for now
if (ImGui::BeginPopupModal("Admin panel", &popup_opened)) {
if (ImGui::Button("Add Bot")) {
m_Client->GetServer()->AddBot();
}
ImGui::EndPopup();
}
}
} // namespace gui
} // namespace blitz

View File

@@ -0,0 +1,79 @@
#include "client/render/BulletRenderer.h"
#include "blitz/maths/Maths.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Test.h"
#include "client/render/Camera.h"
#include "client/render/OpenGL.h"
#include "client/render/loader/GLLoader.h"
#include "client/render/shader/BulletShader.h"
#include <imgui.h>
namespace blitz {
namespace render {
static const float BULLET_DECAY_TIME = 5.0f;
BulletRenderer::BulletRenderer(const Camera& camera) : m_Camera(camera) {
m_Shader = std::make_unique<shader::BulletShader>();
blitz_debug_assert(m_Shader->LoadShader());
m_BulletModel = ModelLoader::LoadModel("cube.glb");
}
BulletRenderer::~BulletRenderer() {}
void BulletRenderer::AddBullet(const Vec3f& origin, float yaw, float pitch) {
static const float TRAIL_LENGHT = 50;
Vec3f direction = {
std::cos(yaw) * std::cos(pitch),
std::sin(pitch),
std::sin(yaw) * std::cos(pitch),
};
Vec3f middle = origin + direction * (TRAIL_LENGHT / 2.0f);
Mat4f rotate = maths::Dot(maths::RotateX(-pitch), maths::RotateY(yaw + maths::PI / 2));
Mat4f scale = maths::Scale({0.01, 0.01, TRAIL_LENGHT / 2.0f - 0.2f});
Mat4f translate = maths::Translate(middle);
Mat4f transform = maths::Dot(scale, maths::Dot(rotate, translate));
Trail trail{transform, BULLET_DECAY_TIME};
m_Trails.push_back(trail);
}
void BulletRenderer::Update(float delta) {
for (Trail& trail : m_Trails) {
trail.m_Decay -= delta;
}
for (std::size_t i = 0; i < m_Trails.size(); i++) {
if (m_Trails[i].m_Decay < 0) {
m_Trails.erase(m_Trails.begin() + i);
}
}
m_Shader->Start();
m_Shader->SetProjectionMatrix(m_Camera.GetPerspectiveMatrix());
m_Shader->SetViewMatrix(m_Camera.GetViewMatrix());
}
void BulletRenderer::Render() {
m_Shader->Start();
// un peu frauduleux
ModelLoader::VaoPtr& vao = m_BulletModel.mVaos[0];
vao->Bind();
for (Trail& trail : m_Trails) {
m_Shader->SetDecay(trail.m_Decay / BULLET_DECAY_TIME);
m_Shader->SetTransform(trail.m_Transform);
glDrawElements(GL_TRIANGLES, vao->GetVertexCount(), GL_UNSIGNED_INT, nullptr);
}
vao->Unbind();
}
} // namespace render
} // namespace blitz

View File

@@ -1,13 +1,13 @@
#include "client/render/Camera.h"
#include "blitz/game/Player.h"
#include "blitz/misc/Maths.h"
#include "blitz/maths/Maths.h"
#include "imgui.h"
namespace blitz {
namespace render {
static const float eyeHeight = 1.25f;
static const float EyeHeight = 1.25f;
void Camera::Update(float delta) {
int windowWidth = ImGui::GetIO().DisplaySize.x;
@@ -21,6 +21,10 @@ void Camera::Update(float delta) {
}
}
float Camera::GetPlayerEyeHeight() {
return EyeHeight;
}
Mat4f Camera::GetViewMatrix() const {
Vec3f front = {
std::cos(m_Player->GetYaw()) * std::cos(m_Player->GetPitch()),
@@ -28,7 +32,7 @@ Mat4f Camera::GetViewMatrix() const {
std::sin(m_Player->GetYaw()) * std::cos(m_Player->GetPitch()),
};
return maths::Look(m_Player->GetPosition() + Vec3f{0, eyeHeight, 0}, front, {0, 1, 0});
return maths::Look(m_Player->GetPosition() + Vec3f{0, EyeHeight, 0}, front, {0, 1, 0});
}
} // namespace render

View File

@@ -1,22 +1,22 @@
#include "client/render/MainRenderer.h"
#include "blitz/maths/Maths.h"
#include "blitz/misc/Easing.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Maths.h"
#include "blitz/misc/Test.h"
#include "blitz/misc/Time.h"
#include "client/Client.h"
#include "client/game/ClientGame.h"
#include "client/render/OpenGL.h"
#include "client/render/loader/GLLoader.h"
#include "client/render/loader/ModelLoader.h"
#include "client/render/loader/TextureLoader.h"
#include "client/render/shader/BulletShader.h"
#include "client/render/shader/EntityShader.h"
#include "client/render/shader/GunShader.h"
#include "client/render/shader/WorldShader.h"
#include "imgui.h"
#include <glbinding/gl/gl.h>
using namespace gl;
namespace blitz {
namespace render {
@@ -24,11 +24,14 @@ namespace render {
static const Vec4f SkyColor = {0.6, 0.8, 1, 1};
static const Vec4f MenuColor = {0, 0, 0, 0};
MainRenderer::MainRenderer(Client* client) : m_Client(client) {
MainRenderer::MainRenderer(Client* client) :
m_Client(client), m_PlayerController(m_Client), m_ShootTime(0), m_BulletRenderer(m_Camera) {
LoadModels();
client->BindListener(this);
m_PlayerController.BindListener(this);
m_PlayerController.BindListener(client);
m_EntityShader = std::make_unique<shader::EntityShader>();
blitz_debug_assert(m_EntityShader->LoadShader());
@@ -46,6 +49,9 @@ MainRenderer::MainRenderer(Client* client) : m_Client(client) {
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glFrontFace(GL_CW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
MainRenderer::~MainRenderer() {}
@@ -86,6 +92,8 @@ void MainRenderer::Render() {
RenderWorld();
RenderPlayers();
RenderGun();
m_BulletRenderer.Render();
}
void MainRenderer::RenderPlayers() {
@@ -98,13 +106,26 @@ void MainRenderer::RenderPlayers() {
}
}
void MainRenderer::OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) {
m_ShootTime = 1.0f;
}
void MainRenderer::OnPlayerShoot(game::PlayerID player, const Vec3f& position, float yaw, float pitch) {
m_BulletRenderer.AddBullet(position + Vec3f{0.0f, Camera::GetPlayerEyeHeight(), 0.0f}, yaw, pitch);
}
void MainRenderer::RenderGun() {
if (!m_Camera.GetAttachedPlayer())
return;
m_GunShader->Start();
m_GunShader->SetModelTransform(maths::Identity<float>());
float progression = 1.0f - m_ShootTime;
float angle = progression * progression * progression * 7 - progression * progression * 11 + progression * 4;
Mat4f transform = maths::RotateX(-angle);
m_GunShader->SetModelTransform(transform);
for (auto& Vao : m_GunModel.mVaos) {
Vao->Bind();
@@ -133,17 +154,23 @@ void MainRenderer::Update() {
m_PlayerController.Update(delta);
m_Camera.Update(delta);
m_BulletRenderer.Update(delta);
Mat4f projectionMatrix = m_Camera.GetPerspectiveMatrix();
Mat4f viewMatrix = m_Camera.GetViewMatrix();
m_EntityShader->Start();
m_EntityShader->SetProjectionMatrix(m_Camera.GetPerspectiveMatrix());
m_EntityShader->SetViewMatrix(m_Camera.GetViewMatrix());
m_EntityShader->SetProjectionMatrix(projectionMatrix);
m_EntityShader->SetViewMatrix(viewMatrix);
m_WorldShader->Start();
m_WorldShader->SetProjectionMatrix(m_Camera.GetPerspectiveMatrix());
m_WorldShader->SetViewMatrix(m_Camera.GetViewMatrix());
m_WorldShader->SetProjectionMatrix(projectionMatrix);
m_WorldShader->SetViewMatrix(viewMatrix);
m_GunShader->Start();
m_GunShader->SetProjectionMatrix(m_Camera.GetPerspectiveMatrix());
m_GunShader->SetProjectionMatrix(projectionMatrix);
m_ShootTime = std::max(0.0f, m_ShootTime - delta);
}
void MainRenderer::OnSpectatorChange(const game::PlayerID player) {

View File

@@ -1,9 +1,7 @@
#include "client/render/loader/GLLoader.h"
#include "blitz/misc/Log.h"
#include <glbinding/gl/gl.h>
using namespace gl;
#include "client/render/OpenGL.h"
namespace blitz {
namespace GL {

View File

@@ -82,15 +82,19 @@ static VaoPtr ProcessMesh(aiMesh* mesh, const aiScene* scene, const aiMatrix4x4&
return Vao;
}
static void ProcessNode(aiNode* node, const aiScene* scene, std::vector<VaoPtr>& meshes, const aiMatrix4x4& transform) {
static void ProcessNode(
aiNode* node, const aiScene* scene, std::vector<VaoPtr>& meshes, std::vector<maths::AABB>& aabbs, const aiMatrix4x4& transform) {
// recursive
for (unsigned int i = 0; i < node->mNumChildren; i++) {
ProcessNode(node->mChildren[i], scene, meshes, transform * node->mTransformation);
ProcessNode(node->mChildren[i], scene, meshes, aabbs, transform * node->mTransformation);
}
for (unsigned int i = 0; i < node->mNumMeshes; i++) {
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
meshes.push_back(ProcessMesh(mesh, scene, transform * node->mTransformation));
aiAABB& aabb = mesh->mAABB;
aabbs.push_back({Vec3f{aabb.mMin.x, aabb.mMin.y, aabb.mMin.z}, {aabb.mMax.x, aabb.mMax.y, aabb.mMax.z}});
}
}
@@ -104,14 +108,16 @@ Model LoadModel(const std::string& fileName) {
aiProcess_OptimizeMeshes);
if (nullptr == scene) {
utils::LOGE("Failed to load model !");
utils::LOGE("[ModelLoader] Failed to load model !");
return {};
}
utils::LOGD(utils::Format("\tModel nodes : %i", scene->mRootNode->mNumMeshes));
utils::LOGD(utils::Format("[ModelLoader]\tModel nodes : %i", scene->mRootNode->mNumMeshes));
Model model;
ProcessNode(scene->mRootNode, scene, model.mVaos, {});
ProcessNode(scene->mRootNode, scene, model.mVaos, model.mAABBs, {});
utils::LOGD(utils::Format("[ModelLoader]\tAABB count : %i", model.mAABBs.size()));
return model;
}

View File

@@ -3,12 +3,10 @@
#include "client/AssetsManager.h"
#define STB_IMAGE_IMPLEMENTATION
#include "blitz/misc/Log.h"
#include "client/render/OpenGL.h"
#include "stb_image.h"
#include <glbinding/gl/gl.h>
#include <stdexcept>
using namespace gl;
namespace blitz {
namespace TextureLoader {
@@ -21,7 +19,7 @@ unsigned int LoadGLTexture(const std::string& fileName) {
const unsigned char* image = stbi_load_from_memory(buffer.data(), buffer.GetSize(), &width, &height, &comp, STBI_default);
if (image == nullptr) {
utils::LOGE("Erreur lors du chargement de la texture !");
utils::LOGE("[TextureLoader] Erreur lors du chargement de la texture !");
throw(std::runtime_error("Failed to load texture"));
}

View File

@@ -0,0 +1,67 @@
#include "client/render/shader/BulletShader.h"
namespace blitz {
namespace shader {
static const std::string vertexSource = ShaderProgram::GetShaderHeader() + R"(
layout(location = 0) in vec3 position;
layout(location = 1) in float decay;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;
out float pass_decay;
void main(void){
vec4 worldPos = modelMatrix * vec4(position, 1.0);
pass_decay = decay;
gl_Position = projectionMatrix * viewMatrix * worldPos;
}
)";
static const std::string fragmentSource = ShaderProgram::GetShaderHeader() + R"(
in float pass_decay;
out vec4 out_color;
uniform float alpha;
void main(void){
out_color = vec4(1.0, 0.0, 0.0, alpha);
}
)";
BulletShader::BulletShader() : ShaderProgram() {}
bool BulletShader::LoadShader() {
return ShaderProgram::LoadProgram(vertexSource, fragmentSource);
}
void BulletShader::GetAllUniformLocation() {
m_LocationViewMatrix = static_cast<unsigned int>(GetUniformLocation("viewMatrix"));
m_LocationProjectionMatrix = static_cast<unsigned int>(GetUniformLocation("projectionMatrix"));
m_LocationTransform = static_cast<unsigned int>(GetUniformLocation("modelMatrix"));
m_LocationAlpha = static_cast<unsigned int>(GetUniformLocation("alpha"));
}
void BulletShader::SetProjectionMatrix(const Mat4f& proj) const {
LoadMat4(m_LocationProjectionMatrix, proj);
}
void BulletShader::SetViewMatrix(const Mat4f& view) const {
LoadMat4(m_LocationViewMatrix, view);
}
void BulletShader::SetDecay(float alpha) const {
LoadFloat(m_LocationAlpha, alpha);
}
void BulletShader::SetTransform(const Mat4f& trans) const {
LoadMat4(m_LocationTransform, trans);
}
} // namespace shader
} // namespace blitz

View File

@@ -44,6 +44,7 @@ void main(void){
float brightness = diffuse;
out_color = vec4(1.0, 1.0, 1.0, 1.0) * brightness;
out_color.w = 1.0;
}
)";

View File

@@ -35,6 +35,7 @@ out vec4 out_color;
void main(void){
out_color = pos;
out_color.w = 1.0;
// out_color = gl_Position + vec4(0.5, 0.5, 0.5, 0);
// out_color = texture(textureSampler, pass_textureCoords);

View File

@@ -2,14 +2,12 @@
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "client/render/OpenGL.h"
#include <fstream>
#include <glbinding/gl/gl.h>
#include <iostream>
#include <sstream>
#include <vector>
using namespace gl;
namespace blitz {
namespace shader {
@@ -30,7 +28,7 @@ void ShaderProgram::Stop() const {
int ShaderProgram::GetUniformLocation(const std::string& uniformName) const {
const int location = glGetUniformLocation(m_ProgramID, uniformName.c_str());
if (location == -1) {
utils::LOGD(utils::Format("Warning ! Uniform variable %s not found !", uniformName.c_str()));
utils::LOGD(utils::Format("[ShaderProgram] Warning ! Uniform variable %s not found !", uniformName.c_str()));
}
return location;
}
@@ -104,7 +102,7 @@ int ShaderProgram::LoadShader(const std::string& source, GLenum type) {
std::vector<char> shaderError(static_cast<std::size_t>(size));
glGetShaderInfoLog(shaderID, size, &size, shaderError.data());
utils::LOGE("Could not compile shader !");
utils::LOGE("[ShaderProgram] Could not compile shader !");
utils::LOGE(shaderError.data());

View File

@@ -53,7 +53,7 @@ void main(void){
float lightDistance = length(toLightVector);
const vec3 attenuation = vec3(0.3, 0.3, 0.03);
const vec3 attenuation = vec3(0.3, 0.03, 0);
float attenuationFactor = attenuation.x + attenuation.y * lightDistance + attenuation.z * lightDistance * lightDistance;
vec3 unitNormal = normalize(surfaceNormal);
@@ -71,6 +71,7 @@ void main(void){
float brightness = (diffuse + specular) / attenuationFactor;
out_color = brightness * texture(textureSampler, pass_textureCoords);
out_color.w = 1.0;
}
)";

View File

@@ -3,6 +3,7 @@
#include "blitz/game/Game.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Random.h"
#include "blitz/misc/Time.h"
#include "blitz/protocol/PacketFactory.h"
#include "blitz/protocol/packets/ChatPacket.h"
@@ -13,7 +14,7 @@
namespace blitz {
namespace server {
Server::Server() : m_ServerRunning(false), m_TickCounter(SERVER_TPS), m_Game(this) {}
Server::Server() : m_TickCounter(SERVER_TPS), m_Game(this), m_ServerRunning(false) {}
Server::~Server() {
StopThread();
@@ -52,14 +53,14 @@ void Server::StopThread() {
bool Server::Start(std::uint16_t port, bool blocking) {
if (!m_Listener.Listen(port, 10)) {
utils::LOGE(utils::Format("Failed to bind port %u !", port));
utils::LOGE(utils::Format("[Server] Failed to bind port %u !", port));
return false;
}
if (!m_Listener.SetBlocking(false)) {
utils::LOGE("Failed to block server socket !");
utils::LOGE("[Server] Failed to block server socket !");
return false;
}
utils::LOG(utils::Format("Server started at port %u !", m_Listener.GetListeningPort()));
utils::LOG(utils::Format("[Server] Server started at port %u !", m_Listener.GetListeningPort()));
m_TickCounter.Reset();
m_ServerRunning = true;
if (blocking) {
@@ -76,7 +77,7 @@ void Server::Clean() {
m_Connections.clear();
utils::LOG("Server successfully stopped !");
utils::LOG("[Server] Server successfully stopped !");
}
void Server::Stop() {
@@ -100,9 +101,9 @@ void Server::Tick(std::uint64_t delta) {
}
void Server::Accept() {
static std::uint8_t newPlayerID = 0;
network::TCPSocket newSocket;
if (m_Listener.Accept(newSocket)) {
game::PlayerID newPlayerID = GetNewPlayerID();
auto con = std::make_unique<ServerConnexion>(this, newSocket, newPlayerID);
m_Connections.insert(std::move(ConnexionMap::value_type{newPlayerID, std::move(con)}));
m_Connections[newPlayerID]->Start();
@@ -110,6 +111,13 @@ void Server::Accept() {
}
}
game::PlayerID Server::GetNewPlayerID() {
static game::PlayerID lastPlayerID = 0;
game::PlayerID newPlayerID = lastPlayerID;
lastPlayerID++;
return newPlayerID;
}
void Server::UpdateSockets() {
static std::vector<std::int16_t> closeConnexions;
for (auto& connection : m_Connections) {
@@ -154,5 +162,15 @@ std::uint16_t Server::GetListeningPort() {
return m_Listener.GetListeningPort();
}
void Server::AddBot() {
game::PlayerID botID = GetNewPlayerID();
m_Game.AddPlayer(botID, "Bot " + std::to_string(static_cast<unsigned int>(botID)));
// set the bot at a random location to be able to see several of them
game::Player* botPlayer = m_Game.GetPlayerById(botID);
botPlayer->SetPosition({utils::GetRandomReal(-10.0f, 10.0f), 0.0f, utils::GetRandomReal(-10.0f, 10.0f)});
}
} // namespace server
} // namespace blitz

View File

@@ -15,6 +15,7 @@
#include "blitz/protocol/packets/PlayerListPacket.h"
#include "blitz/protocol/packets/PlayerLoginPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "blitz/protocol/packets/PlayerShootPacket.h"
#include "client/gui/ColorFulText.h"
#include "server/Server.h"
#include <unordered_map>
@@ -46,6 +47,7 @@ void ServerConnexion::RegisterHandlers() {
GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerLogin, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::Chat, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerShoot, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, this);
}
@@ -82,32 +84,22 @@ void ServerConnexion::InitPlayerChatColor() {
const std::string& playerName = m_Player->GetName();
std::size_t hash = std::hash<std::string>()(playerName);
unsigned int red = hash >> 16 & 0xFF;
unsigned int green = hash >> 8 & 0xFF;
unsigned int blue = hash & 0xFF;
std::uint8_t red = hash >> 16 & 0xFF;
std::uint8_t green = hash >> 8 & 0xFF;
std::uint8_t blue = hash & 0xFF;
m_ChatColor = protocol::ChatPacket::GetTextColor({red, green, blue});
}
void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket* packet) {
game::Player newPlayer{m_ID};
newPlayer.SetName(packet->GetPlayerName());
SendPlayers();
m_Server->GetGame().GetPlayers().insert({m_ID, newPlayer});
m_Server->GetGame().AddPlayer(m_ID, packet->GetPlayerName());
m_Player = m_Server->GetGame().GetPlayerById(m_ID);
protocol::PlayerJoinPacket joinPacket(m_ID, m_Player->GetName());
m_Server->BroadcastPacket(&joinPacket);
InitPlayerChatColor();
std::string joinMessage = utils::Format("%s a rejoint la partie !", packet->GetPlayerName().c_str());
utils::LOG(joinMessage);
m_Server->BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::YELLOW) + joinMessage);
}
void ServerConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
@@ -139,6 +131,13 @@ void ServerConnexion::HandlePacket(const protocol::PlayerPositionAndRotationPack
m_Player->SetPitch(packet->GetPitch());
}
void ServerConnexion::HandlePacket(const protocol::PlayerShootPacket* packet) {
protocol::PlayerShootPacket broadcastShoot(packet->GetPosition(), packet->GetYaw(), packet->GetPitch(), m_Player->GetID());
m_Server->BroadcastPacket(&broadcastShoot);
m_Server->GetGame().CheckShoot(m_Player->GetID(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
}
void ServerConnexion::Start() {
InitConnection();
SendKeepAlive();
@@ -169,7 +168,7 @@ ServerConnexion::~ServerConnexion() {
if (m_Player) {
std::string leaveMessage = utils::Format("%s a quitte la partie !", m_Player->GetName().c_str());
utils::LOG(leaveMessage);
utils::LOG("[Server] " + leaveMessage);
m_Server->BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::YELLOW) + leaveMessage);
}
}

View File

@@ -1,7 +1,13 @@
#include "server/game/ServerGame.h"
#include "blitz/maths/Physics.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/PlayerJoinPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "server/Server.h"
#include <cmath>
namespace blitz {
namespace server {
@@ -23,5 +29,39 @@ void ServerGame::SendPlayerPositions() {
}
}
void ServerGame::CheckShoot(game::PlayerID shooter, Vec3f position, float yaw, float pitch) {
maths::Ray shootRay;
shootRay.origin = position + Vec3f{0.0, 1.75, 0.0};
shootRay.direction = {
std::cos(yaw) * std::cos(pitch),
std::sin(pitch),
std::sin(yaw) * std::cos(pitch),
};
static const maths::AABB playerStaticAABB = {Vec3f{-0.5f, 0.0f, -0.5f}, Vec3f{0.5f, 1.8f, 0.5f}};
for (const auto& [playerId, player] : GetPlayers()) {
if (playerId != shooter && maths::Distance(shootRay, playerStaticAABB + player.GetPosition()) > 0.0f) {
utils::LOG("[Server] " + player.GetName() + " a été touché !");
}
}
}
void ServerGame::AddPlayer(game::PlayerID player, const std::string& name) {
Game::AddPlayer(player, name);
protocol::PlayerJoinPacket joinPacket(player, name);
m_Server->BroadcastPacket(&joinPacket);
std::string joinMessage = utils::Format("%s a rejoint la partie !", name.c_str());
utils::LOG("[Server] " + joinMessage);
m_Server->BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::YELLOW) + joinMessage);
}
void ServerGame::RemovePlayer(game::PlayerID player) {
Game::RemovePlayer(player);
}
} // namespace server
} // namespace blitz

45
test/test_compression.cpp Normal file
View File

@@ -0,0 +1,45 @@
#include "blitz/misc/Test.h"
#include "blitz/misc/Compression.h"
void ReciprocalTest() {
blitz::DataBuffer original;
original << "Some data to compress and decompress";
// Use your compression functions here
blitz::DataBuffer compressed = blitz::utils::Compress(original);
blitz::DataBuffer decompressed = blitz::utils::Decompress(compressed);
// Check that after compressing and then decompressing, we get back the original data
blitz_test_assert(original == decompressed);
}
void CompressionTest() {
blitz::DataBuffer original;
original << "Some data to compresssssssssssssssssssssssssssssssssssssssssssssssssssssssssss";
// Use your compression functions here
blitz::DataBuffer compressed = blitz::utils::Compress(original);
// Check that the compressed data is smaller than the original
blitz_test_assert(compressed.GetSize() < original.GetSize());
}
void DecompressionTest() {
blitz::DataBuffer original;
original << "Some data to compress and decompress";
// Use your compression functions here
blitz::DataBuffer compressed = blitz::utils::Compress(original);
blitz::DataBuffer decompressed = blitz::utils::Decompress(compressed);
// Check that the decompressed data is the same size as the original
blitz_test_assert(original.GetSize() == decompressed.GetSize());
}
int main() {
ReciprocalTest();
CompressionTest();
DecompressionTest();
return BLITZ_TEST_SUCCESSFUL;
}

58
test/test_intersects.cpp Executable file
View File

@@ -0,0 +1,58 @@
#include "blitz/misc/Test.h"
#include "blitz/maths/Physics.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Format.h"
#include <iostream>
#include <ostream>
#include <limits>
using namespace blitz;
using namespace maths;
#define let auto // sexy boiiii
static void test_left() {
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
let ray = Ray { {-2.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f} };
blitz_test_assert(Intersects(ray, box));
}
static void test_right() {
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
let ray = Ray { {2.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f} };
blitz_test_assert(Intersects(ray, box));
}
static void test_forward() {
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
let ray = Ray { {0.0f, 2.0f, 0.0f}, {0.0f, -1.0f, 0.0f} };
blitz_test_assert(Intersects(ray, box));
}
static void test_backward() {
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
let ray = Ray { {0.0f, -2.0f, 0.0f}, {0.0f, 1.0f, 0.0f} };
blitz_test_assert(Intersects(ray, box));
}
static void test_shifted() {
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
let ray = Ray { {-3.0f, 0.0f, 100.0f}, {1.0f, 0.0f, 0.0f} };
blitz_test_assert(!Intersects(ray, box));
}
int main(int argc, const char* args[]) {
test_left();
test_right();
test_forward();
test_backward();
test_shifted();
return BLITZ_TEST_SUCCESSFUL;
}

46
test/test_network.cpp Normal file
View File

@@ -0,0 +1,46 @@
#include "blitz/misc/Test.h"
#include "blitz/network/TCPListener.h"
#include "blitz/network/TCPSocket.h"
#include "blitz/misc/Random.h"
// Test the connection and disconnection of a TCPSocket
void ConnectDisconnect() {
blitz::network::TCPListener localserver;
localserver.Listen(0, 1);
blitz::network::TCPSocket socket;
// Try to connect to a local server on port 8080
blitz_test_assert(socket.Connect("localhost", localserver.GetListeningPort()));
// Check if the socket status is Connected after connection
blitz_test_assert(socket.GetStatus() == blitz::network::TCPSocket::Status::Connected);
socket.Disconnect();
// Check if the socket status is Disconnected after disconnection
blitz_test_assert(socket.GetStatus() == blitz::network::TCPSocket::Status::Disconnected);
}
// Test the listening and accepting of a TCPListener
void Listener() {
// Choose a random port
std::uint16_t randomPort = blitz::utils::GetRandomInt(30000, 35000);
blitz::network::TCPListener listener;
// Start listening on random port with a maximum of 10 connections
blitz_test_assert(listener.Listen(randomPort, 10));
// Check if the listener is listening on the correct port
blitz_test_assert(listener.GetListeningPort() == randomPort);
// Check if the listener has the correct maximum number of connections
blitz_test_assert(listener.GetMaximumConnections() == 10);
blitz::network::TCPSocket socket;
// Try to connect to the listener
blitz_test_assert(socket.Connect("localhost", randomPort));
blitz::network::TCPSocket newSocket;
// Try to accept the connection from the socket
blitz_test_assert(listener.Accept(newSocket));
}
int main(int argc, char** argv) {
ConnectDisconnect();
Listener();
return BLITZ_TEST_SUCCESSFUL;
}

View File

@@ -1,6 +1,6 @@
#include "blitz/misc/Test.h"
#include "blitz/common/Vector.h"
#include "blitz/maths/Vector.h"
using namespace blitz;

View File

@@ -1,89 +1,13 @@
-- We need that for the tests
set_xmakever("2.8.5")
set_policy("package.install_locally", true)
add_rules("mode.debug", "mode.release")
add_requires("libsdl 2.28.3", {configs = {sdlmain = false}})
add_requires("glbinding >= 3", "zlib", "assimp", "nlohmann_json")
add_rules("mode.debug", "mode.release", "mode.valgrind")
set_languages("c++17")
add_includedirs("include")
-- Game files (with server)
target("Blitz")
if is_os("windows") then
set_kind("static")
add_links("ws2_32") -- link network stuff
else
set_kind("shared")
end
add_files("src/blitz/**.cpp", "src/server/**.cpp")
add_packages("zlib")
-- Server binary (headless)
target("BlitzServer")
set_kind("binary")
set_default(false)
add_files("src/ServerMain.cpp")
-- Libraries
add_deps("Blitz")
-- Client binary (default)
target("BlitzClient")
if is_plat("android") then
set_kind("shared")
else
set_kind("binary")
end
set_default(true)
add_files("src/client/**.cpp", "src/ClientMain.cpp")
-- Libraries
add_deps("Blitz")
add_packages("libsdl", "glbinding", "assimp", "nlohmann_json")
add_includedirs("libs", "libs/imgui")
add_files("libs/imgui/**.cpp")
if is_plat("macosx") then
add_frameworks("OpenGL")
elseif is_plat("windows") then
add_ldflags("/LTCG") -- fix compiltation of glbinding
end
-- Assets
set_rundir("$(projectdir)/assets")
-- Tests
for _, file in ipairs(os.files("test/test_*.cpp")) do
local name = path.basename(file)
target(name)
set_kind("binary")
add_files("test/" .. name .. ".cpp")
set_default(false)
add_deps("Blitz")
add_tests("compile_and_run")
if is_mode("release") then
set_warnings("all", "error")
else
set_warnings("all")
end
includes("xmake/BlitzClient.lua")
includes("xmake/BlitzServer.lua")
includes("xmake/BlitzTest.lua")

15
xmake/Blitz.lua Normal file
View File

@@ -0,0 +1,15 @@
add_requires("zlib")
-- Game files (with server)
target("Blitz")
if is_os("windows") then
set_kind("static")
add_links("ws2_32") -- link network stuff
else
set_kind("shared")
end
add_includedirs("../include")
add_files("../src/blitz/**.cpp", "../src/server/**.cpp")
add_packages("zlib")

41
xmake/BlitzClient.lua Normal file
View File

@@ -0,0 +1,41 @@
includes("Blitz.lua")
add_requires("libsdl 2.28.3", {configs = {sdlmain = false}})
add_requires("glew", "assimp", "nlohmann_json")
-- Client binary (default)
target("BlitzClient")
if is_plat("android") then
set_kind("shared")
else
set_kind("binary")
end
set_default(true)
add_includedirs("../include")
add_files("../src/client/**.cpp", "../src/ClientMain.cpp")
-- Libraries
add_deps("Blitz")
add_packages("libsdl", "glew", "assimp", "nlohmann_json")
add_includedirs("../libs", "../libs/imgui")
add_files("../libs/imgui/**.cpp")
if is_plat("macosx") then
add_frameworks("OpenGL")
elseif is_plat("windows") then
add_ldflags("/LTCG") -- fix compiltation of glbinding
end
-- Assets
set_rundir("../assets")
-- Valgrind test
if is_mode("valgrind") then
on_run(function (target)
os.cd("../assets")
os.execv("valgrind", {"-s", "--leak-check=full", target:targetfile()})
end)
end

Some files were not shown because too many files have changed in this diff Show More