Skip to content

Commit

Permalink
Merge branch 'master' into psemek-audio
Browse files Browse the repository at this point in the history
  • Loading branch information
jhasse committed Sep 24, 2023
2 parents a3b77f1 + bc95ded commit bb93a47
Show file tree
Hide file tree
Showing 15 changed files with 573 additions and 323 deletions.
4 changes: 2 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cache:
key: cpm
paths: [.cache/cpm]

image: registry.fedoraproject.org/fedora-minimal:37
image: registry.fedoraproject.org/fedora-minimal:38

linux:
stage: build
Expand All @@ -29,7 +29,7 @@ linux:
mingw:
stage: build
script:
- microdnf install -y cmake ninja-build mingw64-gcc-c++ mingw64-pkg-config mingw64-libvorbis mingw64-SDL2 mingw64-fontconfig mingw64-libwebp mingw64-dlfcn > /dev/null
- microdnf install -y cmake ninja-build mingw64-gcc-c++ mingw64-pkg-config mingw64-libvorbis mingw64-SDL2 mingw64-fontconfig mingw64-libwebp mingw64-dlfcn mingw64-gcc-c++ > /dev/null
- mingw64-cmake -GNinja -Bbuild-debug -DCMAKE_BUILD_TYPE=Debug
- ninja -C build-debug
- mingw64-cmake -GNinja -Bbuild-release -DCMAKE_BUILD_TYPE=Release
Expand Down
797 changes: 503 additions & 294 deletions doc/Doxyfile

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions doc/index.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<img height="175px" alt="Just a Neat Game Library" src="jngl.svg"/>
# Just a Neat Game Library

Easy to use C++ game library for Linux, Windows, macOS, Android, iOS, Xbox, the Nintendo
Switch<sup><a href="#fn1">1</a></sup> and the Web.

* [GitHub](https://github.com/jhasse/jngl)
* [Try JNGL in your browser](https://jhasse.gitlab.io/ggj2021)

## Features
### Features

* C++17
* [zlib License](http://en.wikipedia.org/wiki/Zlib_license), so suitable for commercial use and
Expand All @@ -17,7 +17,7 @@ Switch<sup><a href="#fn1">1</a></sup> and the Web.
* Theora video playback support
* UTF-8 text output using [FreeType](http://www.freetype.org/)

## Games
### Games

* [**Boomshine Plus**](https://bixense.com/boomshineplus/)<br>
Simple and chilly, but addictive puzzle game for Android, iOS and PC
Expand Down
Binary file added doc/jngl-logo-discord.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/jngl-logo-github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/jngl-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 13 additions & 1 deletion src/jngl/Singleton.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Jan Niklas Hasse <jhasse@bixense.com>
// Copyright 2022-2023 Jan Niklas Hasse <jhasse@bixense.com>
// For conditions of distribution and use, see copyright notice in LICENSE.txt
/// Contains jngl::Singleton base class
/// \file
Expand All @@ -8,6 +8,18 @@

namespace jngl {

/// Inherit from this class to create a singleton that will be destroyed when your games exits. You
/// should use this instead of global / static variables, because some platforms (Android) don't
/// destroy the process on exit and instead re-enter the main function.
///
/// \code
/// class Foo : public jngl::Singleton<Foo>
/// // ...
/// }
///
/// // somewhere else:
/// Foo::handle().bar();
/// \endcode
template <class T> class Singleton {
public:
~Singleton() = default;
Expand Down
41 changes: 24 additions & 17 deletions src/jngl/Video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

#include "../audio/constants.hpp"
#include "../audio/effect/pitch.hpp"
#include "../theoraplay/theoraplay.h"
#include "../Sound.hpp"
#include "../audio.hpp"
#include "../main.hpp"
#include "../opengl.hpp"
#include "../theoraplay/theoraplay.h"
#include "Shader.hpp"
#include "debug.hpp"
#include "screen.hpp"
Expand All @@ -42,7 +42,7 @@ class Video::Impl : public Stream {
while (!video) {
video = THEORAPLAY_getVideo(decoder);
}
timePerFrame = 1. / double(video->fps);
timePerFrame = 1. / video->fps;
assert(timePerFrame > 0);

while (!audio) {
Expand Down Expand Up @@ -71,8 +71,8 @@ class Video::Impl : public Stream {
if (started() && !video) {
video = THEORAPLAY_getVideo(decoder);
}
if (!shaderProgram || (video && double(video->playms) / 1000. <= now)) {
if (started() && now - double(video->playms) / 1000. >= timePerFrame) {
if (!shaderProgram || (video && static_cast<double>(video->playms) / 1000. <= now)) {
if (started() && now - static_cast<double>(video->playms) / 1000. >= timePerFrame) {
// Skip frames to catch up, but keep track of the last one in case we catch up to a
// series of dupe frames, which means we'd have to draw that final frame and then
// wait for more.
Expand All @@ -83,7 +83,9 @@ class Video::Impl : public Stream {
jngl::debugLn("ms\x1b[0m");
THEORAPLAY_freeVideo(last);
last = video;
if (now - double(video->playms) / 1000. < timePerFrame) { break; }
if (now - static_cast<double>(video->playms) / 1000. < timePerFrame) {
break;
}
}

if (!video) {
Expand Down Expand Up @@ -164,18 +166,21 @@ class Video::Impl : public Stream {
glUniformMatrix4fv(projectionUniform, 1, GL_FALSE, opengl::projection.data);

textureY = opengl::genAndBindTexture();
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, video->width, video->height, 0, GL_RED,
GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, static_cast<GLsizei>(video->width),
static_cast<GLsizei>(video->height), 0, GL_RED, GL_UNSIGNED_BYTE,
nullptr);

textureU = opengl::genAndBindTexture();
// U and V components are a quarter of the size of the video:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, video->width / 2, video->height / 2, 0,
GL_RED, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, static_cast<GLsizei>(video->width / 2),
static_cast<GLsizei>(video->height / 2), 0, GL_RED, GL_UNSIGNED_BYTE,
nullptr);

textureV = opengl::genAndBindTexture();
// U and V components are a quarter of the size of the video:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, video->width / 2, video->height / 2, 0,
GL_RED, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, static_cast<GLsizei>(video->width / 2),
static_cast<GLsizei>(video->height / 2), 0, GL_RED, GL_UNSIGNED_BYTE,
nullptr);

const auto preciseWidth = static_cast<float>(video->width * getScaleFactor());
const auto preciseHeight = static_cast<float>(video->height * getScaleFactor());
Expand Down Expand Up @@ -207,17 +212,19 @@ class Video::Impl : public Stream {
}

glBindTexture(GL_TEXTURE_2D, textureY);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, video->width, video->height, GL_RED,
GL_UNSIGNED_BYTE, video->pixels);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(video->width),
static_cast<GLsizei>(video->height), GL_RED, GL_UNSIGNED_BYTE,
video->pixels);

assert(video->width % 2 == 0 && video->height % 2 == 0);
glBindTexture(GL_TEXTURE_2D, textureU);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, video->width / 2, video->height / 2, GL_RED,
GL_UNSIGNED_BYTE, video->pixels + video->width * video->height);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(video->width / 2),
static_cast<GLsizei>(video->height / 2), GL_RED, GL_UNSIGNED_BYTE,
video->pixels + static_cast<size_t>(video->width) * video->height);

glBindTexture(GL_TEXTURE_2D, textureV);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, video->width / 2, video->height / 2, GL_RED,
GL_UNSIGNED_BYTE,
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(video->width / 2),
static_cast<GLsizei>(video->height / 2), GL_RED, GL_UNSIGNED_BYTE,
video->pixels + std::lround(1.25 * video->width * video->height));

THEORAPLAY_freeVideo(video);
Expand Down
5 changes: 5 additions & 0 deletions src/jngl/input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,13 @@ void setRelativeMouseMode(bool relative);

bool getRelativeMouseMode();

/// By default the mouse cursor of the OS is visible and can be hidden by passing false
void setMouseVisible(bool visible);

/// Returns whether the mouse cursor of the OS is currently visible
///
/// Even when this method returns true, it could still be visible outside of the window or hidden by
/// the OS for other means (e.g. while the user is typing).
bool isMouseVisible();

/// Returns true when there's more than one finger touching the screen
Expand Down
4 changes: 3 additions & 1 deletion src/jngl/other.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ unsigned int getStepsPerSecond();
/// How many times Work::step should be called per second (default: 60)
void setStepsPerSecond(unsigned int);

/// Toggles MSAA
/// Toggles Multisample anti-aliasing (MSAA)
///
/// Many devices don't support this, so this function will do nothing.
void setAntiAliasing(bool enabled);

/// Returns whether MSAA is enabled. If the device doesn't support it, it will always return false.
Expand Down
5 changes: 4 additions & 1 deletion src/jngl/screen.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2012-2020 Jan Niklas Hasse <jhasse@bixense.com>
// Copyright 2012-2023 Jan Niklas Hasse <jhasse@bixense.com>
// For conditions of distribution and use, see copyright notice in LICENSE.txt
/// @file
#pragma once
Expand All @@ -10,6 +10,9 @@ namespace jngl {
/// Size of one screen pixel in actual pixels
double getScaleFactor();

/// Overwrite the size of one screen pixel
///
/// Normally you wouldn't use this, but set AppParameters::screenSize to a lower value instead.
void setScaleFactor(double);

/// jngl::getScreenSize().x
Expand Down
8 changes: 8 additions & 0 deletions src/jngl/shapes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,15 @@ void pushAlpha(unsigned char alpha);
/// \deprecated Use setAlpha instead
void popAlpha();

[[deprecated("Use drawRectangle instead")]]
/// \deprecated Use drawRectangle instead
void setLineWidth(float width);

/// Draws a line from start to end, the width can be set using setLineWidth
void drawLine(Vec2 start, Vec2 end);

[[deprecated("Use drawRectangle instead")]]
/// \deprecated Use drawRectangle instead
void drawLine(double xstart, double ystart, double xend, double yend);

/// Draws a line from (0, 0) to \a end
Expand All @@ -60,8 +65,11 @@ void drawCircle(Mat3 modelview, float radius, float startAngle = 0);

void drawPoint(double x, double y);

/// Draws the triangle a -> b -> c
void drawTriangle(Vec2 a, Vec2 b, Vec2 c);

[[deprecated("Use drawTriangle(Vec2, Vec2, Vec2) instead")]]
/// \deprecated Use drawTriangle(Vec2, Vec2, Vec2) instead
void drawTriangle(double A_x, double A_y, double B_x, double B_y, double C_x, double C_y);

void drawRect(double xposition, double yposition, double width, double height);
Expand Down
6 changes: 5 additions & 1 deletion src/jngl/window.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2012-2022 Jan Niklas Hasse <jhasse@bixense.com>
// Copyright 2012-2023 Jan Niklas Hasse <jhasse@bixense.com>
// For conditions of distribution and use, see copyright notice in LICENSE.txt

/// Functions related to the main window.
Expand Down Expand Up @@ -28,6 +28,10 @@ void hideWindow();
/// Call this function once when the window is hidden
///
/// The function shouldn't throw and will be called at the next hideWindow() call.
///
/// Use this function for any cleanup tasks when you game exits. Note that on Android, the process
/// doesn't exit necessarely and the main function can be reentered - so C functions like atexit
/// or destructors of global objects won't work.
void atExit(std::function<void()>);

/// Returns the width of the window in actual pixels (i.e. ignoring jngl::getScaleFactor)
Expand Down
2 changes: 1 addition & 1 deletion src/test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ void Test::drawBackground() const {
static_cast<float>(0.5 - factor / 2), static_cast<float>(0.5 + factor / 2));
}
jngl::setColor(255, 0, 0, 100);
jngl::drawTriangle(600, 30, 700, 30, 650, 130);
jngl::drawTriangle({ 600, 30 }, { 700, 30 }, { 650, 130 });
jngl::setColor(0, 255, 0, 100);
jngl::drawRect(600, 400, 100, 100);
jngl::setColor(0, 0, 255, 100);
Expand Down
4 changes: 2 additions & 2 deletions src/win32/windowimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,8 @@ void Window::SetIcon(const std::string& filename) {

auto bgra =
std::make_unique<char[]>(imageData->getWidth() * imageData->getHeight() * CHANNELS);
for (size_t x = 0; x < imageData->getWidth(); ++x) {
for (size_t y = 0; y < imageData->getHeight(); ++y) {
for (size_t x = 0; x < static_cast<size_t>(imageData->getWidth()); ++x) {
for (size_t y = 0; y < static_cast<size_t>(imageData->getHeight()); ++y) {
// transform RGBA to BGRA:
bgra[y * imageData->getWidth() * CHANNELS + x * CHANNELS] =
imageData->pixels()[y * imageData->getWidth() * CHANNELS + x * CHANNELS + 2];
Expand Down

0 comments on commit bb93a47

Please sign in to comment.