Compare commits

...

6 Commits

Author SHA1 Message Date
Xavier Del Campo Romero 3e341ff440
README.md: Update according to ESP32 port 2024-01-30 23:49:22 +01:00
Xavier Del Campo Romero 986f0d9a37
esp32: Import Geekbit library 2024-01-30 23:49:22 +01:00
Xavier Del Campo Romero decf2bd092
Add FindGeekbit.cmake 2024-01-30 23:49:22 +01:00
Xavier Del Campo Romero 52571b0f5a
gfx: #undef quad
Surprisingly, esp-idf #includes files such as sys/types.h when pulling
other standard header files, even when not explicitly defined. While
this is not a serious issue, incredibly their sys/types.h implementation
uses "#define quad", therefore breaking user code such as anything
related to "struct quad".
2024-01-30 23:49:22 +01:00
Xavier Del Campo Romero 77c4420c06
std/main.c: Use engine_main 2024-01-30 23:49:22 +01:00
Xavier Del Campo Romero a27a35bd77
WIP ESP32 port 2024-01-30 01:16:18 +01:00
42 changed files with 664 additions and 12 deletions

View File

@ -17,12 +17,14 @@ elseif(CMAKE_TOOLCHAIN_FILE MATCHES "win9x")
set(WIN9X_BUILD 1)
set(SDL1_2_BUILD 1)
set(exec_flags WIN32)
elseif(CMAKE_TOOLCHAIN_FILE MATCHES "esp32")
set(ESP32_BUILD 1)
else()
set(HOST_BUILD 1)
set(SDL1_2_BUILD 1)
endif()
add_executable(${PROJECT_NAME} ${exec_flags} "src/main.c")
add_executable(${PROJECT_NAME} ${exec_flags})
if(SDL1_2_BUILD)
find_package(SDL 1.2 REQUIRED)
@ -46,6 +48,8 @@ elseif(WIN9X_BUILD)
include("cmake/win9x.cmake")
elseif(HOST_BUILD)
include("cmake/host.cmake")
elseif(ESP32_BUILD)
include("cmake/esp32.cmake")
endif()
add_subdirectory("res")

View File

@ -112,7 +112,7 @@ building `enet`.
A stripped version of the executable, as well as game assets, will be
located in `build/cdimg`.
#### Dependencies
##### Dependencies
A cross-compiled `i386-mingw32` version of all required dependencies
is needed before building `jancity`.
@ -126,6 +126,32 @@ of this writing, so it is provisionally provided on
Read [the documentation](doc/BUILD-win9x.md) for further reference on
how to build the dependencies from source.
#### Espressif ESP32
```sh
. $IDF_PATH/export.sh
ENETDIR=<enet-prefix> \
cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/win9x-toolchain.cmake
cmake --build build
```
Where:
- `ENETDIR` is the path to the cross-compiled version for `enet`.
##### Dependencies
[`esp-idf`](https://github.com/espressif/esp-idf) is required to build this
or any ESP32-related project. The `release/v5.1` branch is assumed here.
As pointed out by
[their documentation](https://docs.espressif.com/projects/esp-idf/en/v5.1.2/esp32/api-guides/build-system.html?highlight=idf_path#initialization),
remember to assign the `IDF_PATH` environment variable to the directory
where `esp-idf` is located.
`esp-idf` requires to build `enet` using a custom CMake wrapper on top of it.
For this project, this has been provided by the
[`enet-esp32`](https://gitea.privatedns.org/xavi/enet-esp32) repository.
## License
Unless stated otherwise, **jancity** follows the license described by the

84
cmake/FindGeekbit.cmake Normal file
View File

@ -0,0 +1,84 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindGeekbit
-----------
Find Geekbit (an open source software development kit for the Geekbit
handheld video game console) libraries and header files.
Imported targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` targets:
``geekbit::geekbit``,
The geekbit library, if found.
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``GEEKBIT_FOUND``
true if geekbit libraries and header files were found.
``GEEKBIT_VERSION``
geekbit release version
``GEEKBIT_INCLUDE_DIRS``
the directory containing the geekbit headers; note
``GEEKBIT_INCLUDE_DIRS`` is also required
``GEEKBIT_LIBRARIES``
geekbit libraries to be linked; note ``GEEKBIT_LIBRARIES`` is also
required
#]=======================================================================]
find_path(GEEKBIT_INCLUDE_DIRS
NAMES
geekbit/gb.h
HINTS
ENV GEEKBIT_PATH
PATH_SUFFIXES
include
)
find_library(GEEKBIT_LIBRARIES
NAMES geekbit
HINTS
ENV GEEKBIT_PATH
PATH_SUFFIXES
lib
)
# Header files are meant to be included as "geekbit/<file>.h". Therefore,
# the "geekbit" directory must not be referred to by GEEKBIT_INCLUDE_DIRS.
string(REGEX REPLACE "include/geekbit[/]*$"
"include" GEEKBIT_INCLUDE_DIRS ${GEEKBIT_INCLUDE_DIRS})
if(GEEKBIT_INCLUDE_DIRS AND EXISTS "${GEEKBIT_INCLUDE_DIRS}/geekbit/version.h")
set(version_regex "^#define[ \t]+GEEKBIT_VERSION_STRING[ \t]+\"([0-9\.]+)\"$")
file(STRINGS "${GEEKBIT_INCLUDE_DIRS}/geekbit/version.h" GEEKBIT_VERSION_LINE REGEX ${version_regex})
string(REGEX REPLACE ${version_regex} "\\1" GEEKBIT_VERSION "${GEEKBIT_VERSION_LINE}")
unset(GEEKBIT_VERSION_LINE)
unset(version_regex)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Geekbit
REQUIRED_VARS
GEEKBIT_LIBRARIES GEEKBIT_INCLUDE_DIRS
VERSION_VAR
GEEKBIT_VERSION
)
if(GEEKBIT_FOUND)
if(NOT TARGET Geekbit::Geekbit)
add_library(Geekbit::Geekbit INTERFACE IMPORTED)
target_include_directories(Geekbit::Geekbit
INTERFACE "${GEEKBIT_INCLUDE_DIRS}")
set_target_properties(Geekbit::Geekbit PROPERTIES
IMPORTED_LOCATION "${GEEKBIT_LIBRARIES}")
endif()
endif()

22
cmake/esp32.cmake Normal file
View File

@ -0,0 +1,22 @@
find_package(Geekbit 0.0.1 REQUIRED)
set(cdroot ${CMAKE_BINARY_DIR})
if(NOT DEFINED ENV{IDF_PATH})
message(FATAL_ERROR "Please define environment variable IDF_PATH")
endif()
include($ENV{IDF_PATH}/tools/cmake/idf.cmake)
idf_build_process(esp32
BUILD_DIR ${CMAKE_BINARY_DIR})
target_link_libraries(${PROJECT_NAME}
PRIVATE
idf::freertos
idf::spi_flash
idf::newlib
)
idf_build_executable(${PROJECT_NAME})
include("${CMAKE_CURRENT_LIST_DIR}/fetch-libfixmath.cmake")
add_subdirectory(libfixmath)

View File

@ -37,6 +37,15 @@ function(sprite)
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME})
add_dependencies(${PROJECT_NAME} ${SPRITE_NAME}_img)
add_dependencies(${SPRITE_NAME}_img tools)
elseif(ESP32_BUILD)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME}
COMMAND cp ${SPRITE_NAME}_24.bmp ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${SPRITE_NAME}_24.bmp
VERBATIM)
add_custom_target(${SPRITE_NAME}_img
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME})
add_dependencies(${PROJECT_NAME} ${SPRITE_NAME}_img)
endif()
endfunction()
@ -76,6 +85,9 @@ function(sound)
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME})
add_dependencies(${PROJECT_NAME} ${SOUND_NAME}_snd)
add_dependencies(${SOUND_NAME}_snd tools)
elseif(ESP32_BUILD)
add_custom_target(${SOUND_NAME}_snd
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/${SOUND_NAME}.wav)
endif()
endfunction()

View File

@ -1,5 +1,5 @@
# Avoid C11 since it is not supported by the i386-mingw32 toolchain.
set(cflags ${cflags} -Wall -g3 -ffunction-sections -fdata-sections -pedantic)
set(cflags ${cflags} -Wall -g3 -ffunction-sections -fdata-sections)
set(components
building
@ -13,6 +13,7 @@ set(components
input
instance
keyboard
main
menu
mouse
net
@ -34,13 +35,18 @@ set(interfaces
target_compile_options(${PROJECT_NAME} PUBLIC ${cflags})
# Dependencies for main.c
target_link_libraries(${PROJECT_NAME} PRIVATE system menu)
target_link_libraries(${PROJECT_NAME} PRIVATE main)
foreach(c ${components})
add_subdirectory("${c}")
target_compile_options(${c} PUBLIC ${cflags})
target_compile_features(${c} PUBLIC c_std_99)
set_target_properties(${c} PROPERTIES C_STANDARD 99 C_EXTENSIONS OFF)
if(${c} STREQUAL "net" AND NOT ESP32_BUILD)
# ESP32 builds pull non-portable header files (e.g.: xt_utils.h).
set_target_properties(${c} PROPERTIES C_STANDARD 99 C_EXTENSIONS OFF)
target_compile_options(${c} PUBLIC -pedantic)
target_compile_features(${c} PUBLIC c_std_99)
endif()
endforeach()
foreach(i ${interfaces})

View File

@ -4,6 +4,8 @@ if(PS1_BUILD)
set(inc ${inc} "ps1/inc")
elseif(SDL1_2_BUILD)
set(inc ${inc} "sdl-1.2/inc")
elseif(ESP32_BUILD)
set(inc ${inc} "esp32/inc")
endif()
add_library(container "src/container.c")

View File

@ -0,0 +1,6 @@
#ifndef CONTAINER_ESP32_H
#define CONTAINER_ESP32_H
#define container_load(path, list, n) container_load_ex(path, list, n)
#endif /* CONTAINER_ESP32_H */

View File

@ -26,6 +26,15 @@ elseif(SDL1_2_BUILD)
"sdl-1.2/src/quad.c")
set(deps ${deps} SDL::SDL)
set(privdeps ${privdeps} header SDL::SDL_gfx)
elseif(ESP32_BUILD)
set(inc ${inc} "esp32/inc")
set(privinc ${privinc} "esp32/privinc")
set(src ${src}
"esp32/src/env.c"
"esp32/src/line.c"
"esp32/src/rect.c"
"esp32/src/sprite.c"
"esp32/src/quad.c")
endif()
add_library(gfx ${src})

View File

@ -0,0 +1,57 @@
#ifndef GFX_ESP32_H
#define GFX_ESP32_H
#include <stdbool.h>
#undef quad
#ifdef __cplusplus
extern "C"
{
#endif
struct sprite
{
short x, y, w, h;
unsigned char u, v;
bool transparent;
};
struct quad
{
unsigned char r, g, b;
short x0, x1, x2, x3;
short y0, y1, y2, y3;
unsigned char u0, u1, u2, u3;
unsigned char v0, v1, v2, v3;
short w, h;
bool transparent;
};
struct rect
{
unsigned char r, g, b;
short x, y, w, h;
bool stp;
};
struct stp_4line
{
short x, y;
unsigned char r, g, b;
struct stp_4line_vtx
{
unsigned char r, g, b;
short x, y;
} vertices[4];
};
#define common_get_or_ret(t, x, ret) \
struct t x##__, *const x = &x##__
#ifdef __cplusplus
}
#endif
#endif /* GFX_ESP32_H */

View File

@ -0,0 +1,21 @@
#ifndef GFX_ESP32_PRIVATE_H
#define GFX_ESP32_PRIVATE_H
#include <gfx.h>
#ifdef __cplusplus
extern "C"
{
#endif
enum
{
SCREEN_W = 320,
SCREEN_H = 240
};
#ifdef __cplusplus
}
#endif
#endif /* GFX_ESP32_PRIVATE_H */

61
src/gfx/esp32/src/env.c Normal file
View File

@ -0,0 +1,61 @@
#include <gfx.h>
#include <gfx_private.h>
#include <esp32/gfx_private.h>
#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int screen_w = SCREEN_W, screen_h = SCREEN_H;
void gfx_deinit(void)
{
}
int gfx_display_size(short *const w, short *const h)
{
*w = SCREEN_W;
*h = SCREEN_H;
return 0;
}
int gfx_init(void)
{
return -1;
}
bool gfx_inside_drawenv(const short x, const short y, const short w,
const short h)
{
return (x + w >= 0)
&& x < screen_w
&& (y + h >= 0)
&& y < screen_h;
}
int gfx_toggle_fullscreen(void)
{
return -1;
}
int gfx_set_fullscreen(const short w, const short h)
{
return -1;
}
bool gfx_fullscreen_available(void)
{
return false;
}
bool gfx_fullscreen(void)
{
return true;
}
int gfx_draw(void)
{
return -1;
}

17
src/gfx/esp32/src/line.c Normal file
View File

@ -0,0 +1,17 @@
#include <gfx.h>
#include <gfx/port.h>
#include <esp32/gfx_private.h>
#include <stddef.h>
void stp_4line_init(struct stp_4line *const l)
{
}
void semitrans_stp_4line_init(struct stp_4line *r)
{
}
int stp_4line_sort(struct stp_4line *const r)
{
return 0;
}

17
src/gfx/esp32/src/quad.c Normal file
View File

@ -0,0 +1,17 @@
#include <gfx.h>
#include <gfx/port.h>
#include <esp32/gfx_private.h>
#include <stddef.h>
#include <stdlib.h>
#undef quad
int quad_from_sprite(const struct sprite *const s, struct quad *const q)
{
return -1;
}
int quad_sort(struct quad *const q)
{
return -1;
}

19
src/gfx/esp32/src/rect.c Normal file
View File

@ -0,0 +1,19 @@
#include <gfx.h>
#include <gfx/port.h>
#include <esp32/gfx_private.h>
int rect_sort(struct rect *const r)
{
return -1;
}
void rect_init(struct rect *const r)
{
*r = (const struct rect){0};
}
void semitrans_rect_init(struct rect *const r)
{
rect_init(r);
r->stp = true;
}

View File

@ -0,0 +1,23 @@
#include <gfx.h>
#include <gfx/port.h>
#include <esp32/gfx_private.h>
void sprite_free(struct sprite *const s)
{
}
int sprite_clone(const struct sprite *const src, struct sprite *const dst)
{
*dst = *src;
return 0;
}
int sprite_from_fp(struct sprite *const s, FILE *const f)
{
return -1;
}
int sprite_sort(struct sprite *const s)
{
return -1;
}

View File

@ -1,9 +1,9 @@
#ifndef GFX_H
#define GFX_H
#include <gfx/port.h>
#include <stdbool.h>
#include <stdio.h>
#include <gfx/port.h>
#ifdef __cplusplus
extern "C"

View File

@ -9,6 +9,9 @@ elseif(SDL1_2_BUILD)
set(src ${src} "sdl-1.2/src/keyboard.c")
set(inc ${inc} "sdl-1.2/inc")
set(privdeps ${privdeps} SDL::SDL)
elseif(ESP32_BUILD)
set(src ${src} "esp32/src/keyboard.c")
set(inc ${inc} "esp32/inc")
endif()
add_library(keyboard ${src})

View File

@ -0,0 +1,20 @@
#ifndef KEYBOARD_SDL_1_2_H
#define KEYBOARD_SDL_1_2_H
#include <keyboard.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct keyboard_port
{
int dummy;
};
#ifdef __cplusplus
}
#endif
#endif /* KEYBOARD_SDL_1_2_H */

View File

@ -0,0 +1,12 @@
#include <keyboard.h>
#include <keyboard/port.h>
#include <keyboard/key.h>
void keyboard_update(struct keyboard *const k)
{
}
bool keyboard_available(void)
{
return false;
}

9
src/main/CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
add_library(main "src/main.c")
target_include_directories(main PUBLIC "inc")
target_link_libraries(main PRIVATE menu system)
if(ESP32_BUILD)
target_sources(${PROJECT_NAME} PRIVATE "esp32/src/main.c")
else()
target_sources(${PROJECT_NAME} PRIVATE "std/src/main.c")
endif()

View File

@ -0,0 +1,6 @@
#include <engine_main.h>
void app_main(void)
{
engine_main();
}

View File

@ -0,0 +1,15 @@
#ifndef MAIN_PRIVATE_H
#define MAIN_PRIVATE_H
#ifdef __cplusplus
extern "C"
{
#endif
int engine_main(void);
#ifdef __cplusplus
}
#endif
#endif /* MAIN_PRIVATE_H */

View File

@ -1,13 +1,14 @@
#include <engine_main.h>
#include <menu.h>
#include <system.h>
#include <stdlib.h>
int main(void)
int engine_main(void)
{
int ret = EXIT_SUCCESS;
int ret = 0;
if (system_init() || menu())
ret = EXIT_FAILURE;
ret = -1;
system_deinit();
return ret;

6
src/main/std/src/main.c Normal file
View File

@ -0,0 +1,6 @@
#include <engine_main.h>
int main(void)
{
return engine_main();
}

View File

@ -7,6 +7,8 @@ if(PS1_BUILD)
elseif(SDL1_2_BUILD)
set(src ${src} "sdl-1.2/src/mouse.c")
set(privdeps ${privdeps} SDL::SDL)
elseif(ESP32_BUILD)
set(src ${src} "esp32/src/mouse.c")
endif()
add_library(mouse ${src})

View File

@ -0,0 +1,11 @@
#include <mouse.h>
#include <stdbool.h>
void mouse_update(struct mouse *const m)
{
}
bool mouse_available(void)
{
return false;
}

View File

@ -14,6 +14,9 @@ else()
if(WIN9X_BUILD OR ${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
set(src ${src} "win9x/src/serial.c")
elseif(ESP32_BUILD)
include($ENV{IDF_PATH}/tools/cmake/idf.cmake)
set(priv_deps ${priv_deps} idf::lwip idf::esp_phy)
else()
# Assume POSIX if the command below executes successfully
execute_process(COMMAND uname -m RESULT_VARIABLE result OUTPUT_QUIET)

View File

@ -10,6 +10,9 @@ elseif(SDL1_2_BUILD)
set(src ${src} "sdl-1.2/src/pad.c")
set(inc ${inc} "sdl-1.2/inc")
set(deps ${deps} SDL::SDL)
elseif(ESP32_BUILD)
set(src ${src} "esp32/src/pad.c")
set(inc ${inc} "esp32/inc")
endif()
add_library(pad ${src})

View File

@ -0,0 +1,18 @@
#ifndef PAD_ESP32_H
#define PAD_ESP32_H
#ifdef __cplusplus
extern "C"
{
#endif
struct pad_port
{
int dummy;
};
#ifdef __cplusplus
}
#endif
#endif /* PAD_SDL_1_2_H */

20
src/pad/esp32/src/pad.c Normal file
View File

@ -0,0 +1,20 @@
#include <pad.h>
#include <stdio.h>
void pad_port_update(struct pad *const p)
{
}
void pad_init(const int id, struct pad *const p)
{
}
size_t pad_count(void)
{
return 1;
}
const char *pad_name(const int id)
{
return NULL;
}

View File

@ -7,6 +7,8 @@ if(PS1_BUILD)
set(inc ${inc} "ps1/inc")
elseif(SDL1_2_BUILD)
set(inc ${inc} "sdl-1.2/inc")
elseif(ESP32_BUILD)
set(inc ${inc} "esp32/inc")
endif()
target_include_directories(settings PUBLIC ${inc})

View File

@ -0,0 +1,15 @@
#ifndef SETTINGS_PORT_H
#define SETTINGS_PORT_H
#ifdef __cplusplus
extern "C"
{
#endif
#define settings_load(...) settings_load_ex(__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif /* SETTINGS_PORT_H */

View File

@ -11,6 +11,10 @@ elseif(SDL1_2_BUILD)
set(inc ${inc} "sdl-1.2/inc")
set(deps ${deps} SDL::SDL_mixer)
set(privdeps ${privdeps} SDL::SDL header)
elseif(ESP32_BUILD)
set(src
"esp32/src/sound.c")
set(inc ${inc} "esp32/inc")
endif()
add_library(sfx ${src})

View File

@ -0,0 +1,20 @@
#ifndef SFX_ESP32_H
#define SFX_ESP32_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct sound
{
bool loop;
};
#ifdef __cplusplus
}
#endif
#endif /* SFX_SDL1_2_H */

28
src/sfx/esp32/src/sound.c Normal file
View File

@ -0,0 +1,28 @@
#include <sfx.h>
#include <sfx/port.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
void sfx_free(struct sound *const s)
{
}
int sfx_play(const struct sound *const s)
{
return -1;
}
int sfx_sound_from_fp(struct sound *const s, FILE *const f, const size_t sz)
{
return -1;
}
void sfx_deinit(void)
{
}
int sfx_init(void)
{
return -1;
}

View File

@ -17,6 +17,11 @@ elseif(SDL1_2_BUILD)
else()
set(src ${src} "sdl-1.2/src/stubs.c")
endif()
elseif(ESP32_BUILD)
set(src "esp32/src/system.c")
set(inc ${inc} "esp32/inc")
set(privinc ${privinc} "esp32/privinc")
set(privdeps ${privdeps} Geekbit::Geekbit)
endif()
add_library(system ${src})

View File

@ -0,0 +1,13 @@
#ifndef INIT_ESP32_H
#define INIT_ESP32_H
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __cplusplus
}
#endif
#endif /* INIT_SDL_H */

View File

@ -0,0 +1,15 @@
#ifndef SYSTEM_PRIVATE_H
#define SYSTEM_PRIVATE_H
#ifdef __cplusplus
extern "C"
{
#endif
int system_init_os(void);
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_PRIVATE_H */

View File

@ -0,0 +1,6 @@
#include <system_private.h>
int system_init_os(void)
{
return 0;
}

View File

@ -0,0 +1,26 @@
#include <system.h>
#include <system_private.h>
#include <geekbit/gb.h>
#include <gfx.h>
#include <net.h>
#include <sfx.h>
#include <stdio.h>
#include <stdlib.h>
bool system_can_exit(void)
{
return false;
}
void system_loop(void)
{
}
void system_deinit(void)
{
}
int system_init(void)
{
return gb_init();
}

View File

@ -8,5 +8,8 @@ endif()
add_library(transport ${src})
target_include_directories(transport PUBLIC "inc" PRIVATE "privinc")
enable_testing()
add_subdirectory(test)
if(NOT CMAKE_CROSSCOMPILING)
enable_testing()
add_subdirectory(test)
endif()