Skip to content

Commit

Permalink
a beeg commit
Browse files Browse the repository at this point in the history
fixes #92
  • Loading branch information
ITotalJustice committed Sep 6, 2022
1 parent c4fb449 commit 7943f92
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,4 @@ web builds are the easiest way to quickly test a game. builds are automatically
- zayd for info on rtc <https://beanmachine.alt.icu/post/rtc/>
- pokeemerald for a being a good reference <https://github.com/pret/pokeemerald>
- kenney for the onscreen control buttons <https://www.kenney.nl/assets/onscreen-controls>
- ifeelfine for yoshi gif <https://tenor.com/view/yoshi-bloated-cute-gif-12835998>
Binary file added assets/gif/yoshi-bloated.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/frontend/emscripten/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ endif()

file(COPY "${CMAKE_SOURCE_DIR}/assets/buttons" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets")
file(COPY "${CMAKE_SOURCE_DIR}/assets/menu" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets")
file(COPY "${CMAKE_SOURCE_DIR}/assets/gif" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets")
file(COPY "${CMAKE_SOURCE_DIR}/assets/web/" DESTINATION "${CMAKE_BINARY_DIR}/bin/")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/netlify.toml" DESTINATION "${CMAKE_BINARY_DIR}/bin/")

Expand Down
11 changes: 10 additions & 1 deletion src/frontend/emscripten/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,8 @@ App::App(int argc, char** argv) : frontend::sdl2::Sdl2Base(argc, argv)
emscripten_console_logf("[EM] failed to lock orientation\n");
}

load_gif("assets/gif/yoshi-bloated.gif");

change_menu(Menu::SIDEBAR);
running = true;
}
Expand Down Expand Up @@ -793,7 +795,14 @@ auto App::render() -> void
update_texture_from_pixels();

// render gba
SDL_RenderCopy(renderer, texture, nullptr, &emu_rect);
if (has_rom)
{
SDL_RenderCopy(renderer, texture, nullptr, &emu_rect);
}
else
{
gif_render();
}

if (menu == Menu::SIDEBAR)
{
Expand Down
6 changes: 5 additions & 1 deletion src/frontend/sdl2/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ auto App::render() -> void

update_texture_from_pixels();

SDL_RenderCopy(renderer, texture, nullptr, &emu_rect);
if (has_rom)
{
SDL_RenderCopy(renderer, texture, nullptr, &emu_rect);
}

SDL_RenderPresent(renderer);
}

Expand Down
16 changes: 15 additions & 1 deletion src/frontend/sdl2_base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@ cmake_minimum_required(VERSION 3.20.0)

project(sdl2_base LANGUAGES CXX)

include(FetchContent)
Set(FETCHCONTENT_QUIET FALSE)

FetchContent_Declare(stb
GIT_REPOSITORY https://github.com/nothings/stb.git
GIT_TAG af1a5bc
GIT_PROGRESS TRUE
)

FetchContent_MakeAvailable(stb)

add_library(stb INTERFACE)
target_include_directories(stb INTERFACE ${stb_SOURCE_DIR})

add_library(sdl2_base sdl2_base.cpp)

find_package(SDL2 CONFIG REQUIRED)

target_link_libraries(sdl2_base PUBLIC frontend_base)
target_link_libraries(sdl2_base PUBLIC SDL2::SDL2 SDL2::SDL2main)
target_link_libraries(sdl2_base PUBLIC SDL2::SDL2 SDL2::SDL2main stb)

target_include_directories(sdl2_base PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(sdl2_base PROPERTIES CXX_STANDARD 23)
Expand Down
104 changes: 104 additions & 0 deletions src/frontend/sdl2_base/sdl2_base.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
// Copyright 2022 TotalJustice.
// SPDX-License-Identifier: GPL-3.0-only
#include "sdl2_base.hpp"
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_GIF
#define STBI_NO_STDIO
#include "stb_image.h"
#include <cstdio>
#include <cstring>

namespace frontend::sdl2 {
Expand Down Expand Up @@ -119,6 +124,11 @@ auto Sdl2Base::init_audio(void* user, SDL_AudioCallback sdl2_cb, gba::AudioCallb

Sdl2Base::~Sdl2Base()
{
for (auto& tex : gif_textures)
{
SDL_DestroyTexture(tex);
}

for (auto& [_, controller] : controllers)
{
SDL_GameControllerClose(controller);
Expand Down Expand Up @@ -881,4 +891,98 @@ auto Sdl2Base::update_audio_device_pause_status() -> void
SDL_PauseAudioDevice(audio_device, pause_on);
}

auto Sdl2Base::load_gif(const char* path) -> bool
{
if (has_gif)
{
std::printf("only 1 beeg gif allowed!\n");
return false;
}

const auto gif_data = loadfile(path);
if (gif_data.empty())
{
std::printf("failed to load gif: %s\n", path);
return false;
}

auto data = stbi_load_gif_from_memory(gif_data.data(), gif_data.size(), &gif_delays, &gif_w, &gif_h, &gif_z, &gif_comp, 0);
if (!data)
{
std::printf("failed to load gif into stbi\n");
return false;
}

// https://wiki.libsdl.org/SDL_CreateRGBSurface
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
const uint32_t rmask = 0xff000000;
const uint32_t gmask = 0x00ff0000;
const uint32_t bmask = 0x0000ff00;
const uint32_t amask = 0x000000ff;
#else
const uint32_t rmask = 0x000000ff;
const uint32_t gmask = 0x0000ff00;
const uint32_t bmask = 0x00ff0000;
const uint32_t amask = 0xff000000;
#endif

gif_textures.resize(gif_z);

auto surface = SDL_CreateRGBSurface(0, gif_w, gif_h, 32, rmask, gmask, bmask, amask);
if (!surface)
{
std::printf("failed to create surface: %s\n", SDL_GetError());
stbi_image_free(data);
return false;
}

for (auto i = 0; i < gif_z; i++)
{
std::memcpy(surface->pixels, data + (gif_w * gif_h * gif_comp * i), gif_w * gif_h * gif_comp);
gif_textures[i] = SDL_CreateTextureFromSurface(renderer, surface);
// printf("i: %d delay: %d\n", i, gif_delays[i]);
}

SDL_FreeSurface(surface);
stbi_image_free(data);

has_gif = true;
return true;
}

auto Sdl2Base::gif_render(SDL_Rect* src_rect, SDL_Rect* dst_rect) -> void
{
if (!has_gif)
{
return;
}

SDL_Rect rect;

if (dst_rect == nullptr)
{
const auto [screen_w, screen_h] = get_renderer_size();
const auto scale_w = screen_w / gif_w;
const auto scale_h = screen_h / gif_h;
const auto gif_scale = std::min(scale_w, scale_h);

rect.w = gif_w * gif_scale;
rect.h = gif_h * gif_scale;
rect.x = (screen_w - gif_w) / 2;
rect.y = (screen_h - gif_h) / 2;

dst_rect = &rect;
}

SDL_RenderCopy(renderer, gif_textures[gif_index], src_rect, dst_rect);

const auto ticks = SDL_GetTicks();

if (gif_delta + gif_delays[gif_index] <= ticks)
{
gif_index = (gif_index + 1) % gif_z;
gif_delta = ticks;
}
}

} // namespace frontend::sdl2
15 changes: 15 additions & 0 deletions src/frontend/sdl2_base/sdl2_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
#include "../frontend_base.hpp"

#include <SDL.h>
#include <cstddef>
#include <unordered_map>
#include <mutex>
#include <vector>

namespace frontend::sdl2 {

Expand Down Expand Up @@ -71,11 +73,24 @@ struct Sdl2Base : frontend::Base
// todo: this needs to be re-written
auto update_audio_device_pause_status() -> void;

auto load_gif(const char* path) -> bool;
auto gif_render(SDL_Rect* src_rect = nullptr, SDL_Rect* dst_rect = nullptr) -> void;

public:
SDL_Window* window{};
SDL_Renderer* renderer{};
SDL_Texture* texture{};

std::vector<SDL_Texture*> gif_textures{};
std::size_t gif_index{};
std::uint32_t gif_delta{};
int gif_w{};
int gif_h{};
int gif_z{};
int gif_comp{};
int* gif_delays{};
bool has_gif{false};

SDL_Rect emu_rect{};

SDL_AudioDeviceID audio_device{};
Expand Down

0 comments on commit 7943f92

Please sign in to comment.