Compare commits
17 Commits
5829ef82c4
...
3eef29c327
|
@ -1,4 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
# SDL::SDL was defined on 3.20.
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
set(TOOLS_PREFIX ${CMAKE_BINARY_DIR}/tools)
|
||||
include(ExternalProject)
|
||||
|
@ -34,10 +35,12 @@ if(SDL1_2_BUILD)
|
|||
target_link_libraries(SDL::SDL_mixer INTERFACE SDL::SDL)
|
||||
endif()
|
||||
|
||||
if(NOT PS1_BUILD)
|
||||
find_package(ENET 1.3 REQUIRED)
|
||||
endif()
|
||||
|
||||
set(cdroot ${CMAKE_BINARY_DIR}/cdimg)
|
||||
file(MAKE_DIRECTORY ${cdroot})
|
||||
# Avoid C11 since it is not supported by the i386-mingw32 toolchain.
|
||||
set(cflags -Wall -g3 -ffunction-sections -fdata-sections -pedantic -std=c99)
|
||||
|
||||
if(PS1_BUILD)
|
||||
include("cmake/ps1.cmake")
|
||||
|
@ -48,48 +51,4 @@ elseif(HOST_BUILD)
|
|||
endif()
|
||||
|
||||
add_subdirectory("res")
|
||||
|
||||
set(components
|
||||
building
|
||||
camera
|
||||
container
|
||||
font
|
||||
game
|
||||
gfx
|
||||
gui
|
||||
header
|
||||
instance
|
||||
keyboard
|
||||
menu
|
||||
mouse
|
||||
pad
|
||||
peripheral
|
||||
player
|
||||
resource
|
||||
sfx
|
||||
system
|
||||
terrain
|
||||
unit
|
||||
util
|
||||
)
|
||||
|
||||
set(interfaces
|
||||
tech
|
||||
)
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC ${cflags})
|
||||
# Dependencies for main.c
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE system menu)
|
||||
|
||||
foreach(c ${components})
|
||||
add_subdirectory("src/${c}")
|
||||
target_compile_options(${c} PUBLIC ${cflags})
|
||||
endforeach()
|
||||
|
||||
foreach(i ${interfaces})
|
||||
add_subdirectory("src/${i}")
|
||||
target_compile_options(${i} INTERFACE ${cflags})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${c})
|
||||
endforeach()
|
||||
|
||||
target_link_options(${PROJECT_NAME} PRIVATE -Wl,--gc-sections)
|
||||
add_subdirectory("src")
|
||||
|
|
|
@ -91,6 +91,7 @@ cd build
|
|||
SDLDIR=<sdl-prefix> \
|
||||
SDLMIXERDIR=<sdl_mixer-prefix> \
|
||||
SDLGFXDIR=<sdl_gfx-prefix> \
|
||||
ENETDIR=<enet-prefix> \
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/win9x-toolchain.cmake
|
||||
make -j$(nproc --all)
|
||||
```
|
||||
|
@ -106,6 +107,9 @@ building `SDL_mixer`.
|
|||
- `SDLGFXDIR` is the path to the cross-compiled version for `SDL_gfx`,
|
||||
which would correspond to `./configure --prefix=$SDLGFXDIR` used in
|
||||
building `SDL_gfx`.
|
||||
- `ENETDIR` is the path to the cross-compiled version for `enet`,
|
||||
which would correspond to `./configure --prefix=$ENETDIR` used in
|
||||
building `enet`.
|
||||
|
||||
A stripped version of the executable, as well as game assets, will be
|
||||
located in `build/cdimg`.
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindENET
|
||||
-----------
|
||||
|
||||
Locate ENET library
|
||||
|
||||
This module defines:
|
||||
|
||||
::
|
||||
|
||||
ENET, the name of the target to use with target_*() commands
|
||||
ENET_LIBRARIES, the name of the library to link against
|
||||
ENET_INCLUDE_DIRS, where to find the headers
|
||||
ENET_FOUND, if false, do not try to link against
|
||||
ENET_VERSION_STRING - human-readable string containing the
|
||||
version of ENET
|
||||
|
||||
$ENETDIR is an environment variable that would correspond to the
|
||||
./configure --prefix=$ENETDIR used in building ENET.
|
||||
#]=======================================================================]
|
||||
|
||||
find_path(ENET_INCLUDE_DIRS
|
||||
NAMES
|
||||
enet/callbacks.h
|
||||
enet/enet.h
|
||||
enet/list.h
|
||||
enet/protocol.h
|
||||
enet/time.h
|
||||
enet/types.h
|
||||
enet/unix.h
|
||||
enet/utility.h
|
||||
enet/win32.h
|
||||
HINTS
|
||||
ENV ENETDIR
|
||||
PATH_SUFFIXES
|
||||
enet
|
||||
# path suffixes to search inside ENV{ENETDIR}
|
||||
include
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(VC_LIB_PATH_SUFFIX lib/x64)
|
||||
else()
|
||||
set(VC_LIB_PATH_SUFFIX lib/x86)
|
||||
endif()
|
||||
|
||||
find_library(ENET_LIBRARIES
|
||||
NAMES enet
|
||||
HINTS
|
||||
ENV ENETDIR
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
${VC_LIB_PATH_SUFFIX}
|
||||
)
|
||||
|
||||
if(ENET_INCLUDE_DIRS AND EXISTS "${ENET_INCLUDE_DIRS}/enet.h")
|
||||
file(STRINGS "${ENET_INCLUDE_DIRS}/enet.h" ENET_VERSION_MAJOR_LINE REGEX "^#define[ \t]+ENET_VERSION_MAJOR[ \t]+[0-9]+$")
|
||||
file(STRINGS "${ENET_INCLUDE_DIRS}/enet.h" ENET_VERSION_MINOR_LINE REGEX "^#define[ \t]+ENET_VERSION_MINOR[ \t]+[0-9]+$")
|
||||
file(STRINGS "${ENET_INCLUDE_DIRS}/enet.h" ENET_VERSION_PATCH_LINE REGEX "^#define[ \t]+ENET_VERSION_PATCH[ \t]+[0-9]+$")
|
||||
string(REGEX REPLACE "^#define[ \t]+ENET_VERSION_MAJOR[ \t]+([0-9]+)$" "\\1" ENET_VERSION_MAJOR "${ENET_VERSION_MAJOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+ENET_VERSION_MINOR[ \t]+([0-9]+)$" "\\1" ENET_VERSION_MINOR "${ENET_VERSION_MINOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+ENET_VERSION_PATCH[ \t]+([0-9]+)$" "\\1" ENET_VERSION_PATCH "${ENET_VERSION_PATCH_LINE}")
|
||||
set(ENET_VERSION_STRING ${ENET_VERSION_MAJOR}.${ENET_VERSION_MINOR}.${ENET_VERSION_PATCH})
|
||||
unset(ENET_VERSION_MAJOR_LINE)
|
||||
unset(ENET_VERSION_MINOR_LINE)
|
||||
unset(ENET_VERSION_PATCH_LINE)
|
||||
unset(ENET_VERSION_MAJOR)
|
||||
unset(ENET_VERSION_MINOR)
|
||||
unset(ENET_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ENET
|
||||
REQUIRED_VARS ENET_LIBRARIES ENET_INCLUDE_DIRS
|
||||
VERSION_VAR ENET_VERSION_STRING)
|
||||
|
||||
if(ENET_FOUND)
|
||||
if(NOT TARGET ENET)
|
||||
add_library(ENET INTERFACE IMPORTED)
|
||||
set_target_properties(ENET PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${ENET_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${ENET_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
|
@ -6,6 +6,7 @@ add_custom_command(OUTPUT ${cdroot}/${PROJECT_NAME}
|
|||
add_custom_target(stripped-exe ALL DEPENDS ${cdroot}/${PROJECT_NAME})
|
||||
|
||||
target_link_libraries(SDL::SDL INTERFACE gdi32 user32 winmm dxguid)
|
||||
target_link_libraries(ENET INTERFACE ws2_32)
|
||||
|
||||
add_compile_options(-march=i386)
|
||||
|
||||
|
|
|
@ -132,3 +132,11 @@ WAVE files, support for other audio formats is not required.
|
|||
CFLAGS='-ffunction-sections -fdata-sections' \
|
||||
CC=i386-mingw32-gcc
|
||||
```
|
||||
|
||||
## ENET
|
||||
|
||||
```sh
|
||||
../enet-1.3.17/configure --prefix=$HOME/enet-1.3.17-win32 \
|
||||
--host=i386-mingw32 CFLAGS='-ffunction-sections -fdata-sections' \
|
||||
CC=i386-mingw32-gcc
|
||||
```
|
||||
|
|
|
@ -1,112 +1,4 @@
|
|||
function(sprite)
|
||||
set(options "")
|
||||
set(multiValueArgs "")
|
||||
set(oneValueArgs NAME X Y TRANSPARENT BPP CX CY)
|
||||
cmake_parse_arguments(SPRITE "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(PS1_BUILD)
|
||||
if(${SPRITE_TRANSPARENT})
|
||||
set(trans -mpink)
|
||||
endif()
|
||||
|
||||
if(NOT "${SPRITE_BPP}" STREQUAL "16")
|
||||
set(clut "-clut=${SPRITE_CX},${SPRITE_CY}")
|
||||
endif()
|
||||
|
||||
add_custom_target(${SPRITE_NAME}_img ALL
|
||||
bmp2tim ${SPRITE_NAME}.bmp ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME}
|
||||
${SPRITE_BPP} -org=${SPRITE_X},${SPRITE_Y} ${clut} ${trans}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${SPRITE_NAME}.bmp
|
||||
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME})
|
||||
add_dependencies(iso ${SPRITE_NAME}_img)
|
||||
elseif(SDL1_2_BUILD)
|
||||
if(${SPRITE_TRANSPARENT})
|
||||
set(trans "transparent=1")
|
||||
else()
|
||||
set(trans "transparent=0")
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME}
|
||||
COMMAND ${TOOLS_PREFIX}/bin/add-header ${trans} ${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(${SPRITE_NAME}_img tools)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(sound)
|
||||
set(options "")
|
||||
set(multiValueArgs "")
|
||||
set(oneValueArgs NAME LOOP)
|
||||
cmake_parse_arguments(SOUND "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(PS1_BUILD)
|
||||
if(${SOUND_LOOP})
|
||||
set(loop -L)
|
||||
endif()
|
||||
|
||||
add_custom_target(${SOUND_NAME}_snd ALL
|
||||
wav2vag ${SOUND_NAME}.wav
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME} ${loop}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${SOUND_NAME}.wav
|
||||
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME})
|
||||
add_dependencies(iso ${SOUND_NAME}_snd)
|
||||
elseif(SDL1_2_BUILD)
|
||||
if(${SOUND_LOOP})
|
||||
set(loop "loop=1")
|
||||
else()
|
||||
set(loop "loop=0")
|
||||
endif()
|
||||
|
||||
# Reference: https://gist.github.com/socantre/7ee63133a0a3a08f3990
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME}
|
||||
COMMAND ${TOOLS_PREFIX}/bin/add-header ${loop} ${SOUND_NAME}.wav ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${SOUND_NAME}.wav
|
||||
VERBATIM)
|
||||
add_custom_target(${SOUND_NAME}_snd
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME})
|
||||
add_dependencies(${SOUND_NAME}_snd tools)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(container)
|
||||
set(options "")
|
||||
set(multiValueArgs SPRITES SOUNDS)
|
||||
set(oneValueArgs NAME)
|
||||
cmake_parse_arguments(CONTAINER "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
|
||||
add_custom_command(OUTPUT ${cdroot}/${CONTAINER_NAME}.cnt
|
||||
COMMAND ${TOOLS_PREFIX}/bin/container ${CONTAINER_SPRITES} ${CONTAINER_SOUNDS}
|
||||
${cdroot}/${CONTAINER_NAME}.cnt
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(${CONTAINER_NAME}_container
|
||||
DEPENDS ${cdroot}/${CONTAINER_NAME}.cnt)
|
||||
add_dependencies(${PROJECT_NAME} ${CONTAINER_NAME}_container)
|
||||
add_dependencies(${CONTAINER_NAME}_container tools)
|
||||
|
||||
foreach(sprite ${CONTAINER_SPRITES})
|
||||
add_dependencies(${CONTAINER_NAME}_container ${sprite}_img)
|
||||
endforeach()
|
||||
|
||||
foreach(sound ${CONTAINER_SOUNDS})
|
||||
add_dependencies(${CONTAINER_NAME}_container ${sound}_snd)
|
||||
endforeach()
|
||||
|
||||
if(PS1_BUILD)
|
||||
add_dependencies(iso ${CONTAINER_NAME}_container)
|
||||
endif()
|
||||
endfunction()
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/functions.cmake)
|
||||
|
||||
sprite(NAME worker_n
|
||||
X 384
|
||||
|
@ -292,6 +184,30 @@ sprite(NAME btn_mid
|
|||
CY 493
|
||||
TRANSPARENT FALSE)
|
||||
|
||||
sprite(NAME line_edit_left
|
||||
X 368
|
||||
Y 148
|
||||
BPP 4
|
||||
CX 368
|
||||
CY 492
|
||||
TRANSPARENT FALSE)
|
||||
|
||||
sprite(NAME line_edit_mid
|
||||
X 370
|
||||
Y 148
|
||||
BPP 4
|
||||
CX 368
|
||||
CY 491
|
||||
TRANSPARENT FALSE)
|
||||
|
||||
sprite(NAME line_edit_right
|
||||
X 378
|
||||
Y 148
|
||||
BPP 4
|
||||
CX 368
|
||||
CY 491
|
||||
TRANSPARENT FALSE)
|
||||
|
||||
sound(NAME acknowledge_01)
|
||||
sound(NAME acknowledge_02)
|
||||
sound(NAME selected_01)
|
||||
|
@ -321,6 +237,9 @@ container(NAME rts
|
|||
sel_down_right
|
||||
sel_mid
|
||||
sel_mid_v
|
||||
line_edit_left
|
||||
line_edit_mid
|
||||
line_edit_right
|
||||
SOUNDS
|
||||
acknowledge_01
|
||||
acknowledge_02
|
||||
|
|
|
@ -51,6 +51,12 @@ btn_mid.bmp:
|
|||
btn_mid_24.bmp:
|
||||
btn_right.bmp:
|
||||
btn_right_24.bmp:
|
||||
line_edit_left.bmp:
|
||||
line_edit_left_24.bmp:
|
||||
line_edit_mid.bmp:
|
||||
line_edit_mid_24.bmp:
|
||||
line_edit_right.bmp:
|
||||
line_edit_right_24.bmp:
|
||||
Derived works from ui_sheet.png
|
||||
|
||||
font.bmp:
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
function(sprite)
|
||||
set(options "")
|
||||
set(multiValueArgs "")
|
||||
set(oneValueArgs NAME X Y TRANSPARENT BPP CX CY)
|
||||
cmake_parse_arguments(SPRITE "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(PS1_BUILD)
|
||||
if(${SPRITE_TRANSPARENT})
|
||||
set(trans -mpink)
|
||||
endif()
|
||||
|
||||
if(NOT "${SPRITE_BPP}" STREQUAL "16")
|
||||
set(clut "-clut=${SPRITE_CX},${SPRITE_CY}")
|
||||
endif()
|
||||
|
||||
add_custom_target(${SPRITE_NAME}_img ALL
|
||||
bmp2tim ${SPRITE_NAME}.bmp ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME}
|
||||
${SPRITE_BPP} -org=${SPRITE_X},${SPRITE_Y} ${clut} ${trans}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${SPRITE_NAME}.bmp
|
||||
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME})
|
||||
add_dependencies(iso ${SPRITE_NAME}_img)
|
||||
elseif(SDL1_2_BUILD)
|
||||
if(${SPRITE_TRANSPARENT})
|
||||
set(trans "transparent=1")
|
||||
else()
|
||||
set(trans "transparent=0")
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME}
|
||||
COMMAND ${TOOLS_PREFIX}/bin/add-header ${trans} ${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(${SPRITE_NAME}_img tools)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(sound)
|
||||
set(options "")
|
||||
set(multiValueArgs "")
|
||||
set(oneValueArgs NAME LOOP)
|
||||
cmake_parse_arguments(SOUND "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(PS1_BUILD)
|
||||
if(${SOUND_LOOP})
|
||||
set(loop -L)
|
||||
endif()
|
||||
|
||||
add_custom_target(${SOUND_NAME}_snd ALL
|
||||
wav2vag ${SOUND_NAME}.wav
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME} ${loop}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${SOUND_NAME}.wav
|
||||
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME})
|
||||
add_dependencies(iso ${SOUND_NAME}_snd)
|
||||
elseif(SDL1_2_BUILD)
|
||||
if(${SOUND_LOOP})
|
||||
set(loop "loop=1")
|
||||
else()
|
||||
set(loop "loop=0")
|
||||
endif()
|
||||
|
||||
# Reference: https://gist.github.com/socantre/7ee63133a0a3a08f3990
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME}
|
||||
COMMAND ${TOOLS_PREFIX}/bin/add-header ${loop} ${SOUND_NAME}.wav ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${SOUND_NAME}.wav
|
||||
VERBATIM)
|
||||
add_custom_target(${SOUND_NAME}_snd
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME})
|
||||
add_dependencies(${SOUND_NAME}_snd tools)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(container)
|
||||
set(options "")
|
||||
set(multiValueArgs SPRITES SOUNDS)
|
||||
set(oneValueArgs NAME)
|
||||
cmake_parse_arguments(CONTAINER "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
|
||||
add_custom_command(OUTPUT ${cdroot}/${CONTAINER_NAME}.cnt
|
||||
COMMAND ${TOOLS_PREFIX}/bin/container ${CONTAINER_SPRITES} ${CONTAINER_SOUNDS}
|
||||
${cdroot}/${CONTAINER_NAME}.cnt
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(${CONTAINER_NAME}_container
|
||||
DEPENDS ${cdroot}/${CONTAINER_NAME}.cnt)
|
||||
add_dependencies(${PROJECT_NAME} ${CONTAINER_NAME}_container)
|
||||
add_dependencies(${CONTAINER_NAME}_container tools)
|
||||
|
||||
foreach(sprite ${CONTAINER_SPRITES})
|
||||
add_dependencies(${CONTAINER_NAME}_container ${sprite}_img)
|
||||
endforeach()
|
||||
|
||||
foreach(sound ${CONTAINER_SOUNDS})
|
||||
add_dependencies(${CONTAINER_NAME}_container ${sound}_snd)
|
||||
endforeach()
|
||||
|
||||
if(PS1_BUILD)
|
||||
add_dependencies(iso ${CONTAINER_NAME}_container)
|
||||
endif()
|
||||
endfunction()
|
Binary file not shown.
After Width: | Height: | Size: 250 B |
Binary file not shown.
After Width: | Height: | Size: 654 B |
Binary file not shown.
After Width: | Height: | Size: 546 B |
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 250 B |
Binary file not shown.
After Width: | Height: | Size: 654 B |
|
@ -32,7 +32,7 @@ saxon_swordsman.png:
|
|||
Author: b_o
|
||||
|
||||
barracks.zip:
|
||||
https://opengameart.org/content/6-isometric-buildings:
|
||||
https://opengameart.org/content/6-isometric-buildings
|
||||
License(s): CC-BY-SA 3.0
|
||||
Author: Scribe
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Avoid C11 since it is not supported by the i386-mingw32 toolchain.
|
||||
set(cflags -Wall -g3 -ffunction-sections -fdata-sections -pedantic -std=c99)
|
||||
|
||||
set(components
|
||||
building
|
||||
camera
|
||||
container
|
||||
font
|
||||
game
|
||||
gfx
|
||||
gui
|
||||
header
|
||||
input
|
||||
instance
|
||||
keyboard
|
||||
menu
|
||||
mouse
|
||||
net
|
||||
pad
|
||||
peripheral
|
||||
player
|
||||
resource
|
||||
sfx
|
||||
system
|
||||
terrain
|
||||
unit
|
||||
util
|
||||
)
|
||||
|
||||
set(interfaces
|
||||
tech
|
||||
)
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC ${cflags})
|
||||
# Dependencies for main.c
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE system menu)
|
||||
|
||||
foreach(c ${components})
|
||||
add_subdirectory("${c}")
|
||||
target_compile_options(${c} PUBLIC ${cflags})
|
||||
endforeach()
|
||||
|
||||
foreach(i ${interfaces})
|
||||
add_subdirectory("${i}")
|
||||
target_compile_options(${i} INTERFACE ${cflags})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${c})
|
||||
endforeach()
|
||||
|
||||
target_link_options(${PROJECT_NAME} PRIVATE -Wl,--gc-sections)
|
|
@ -1,3 +1,12 @@
|
|||
add_library(camera "src/camera.c" "src/pad.c" "src/mouse.c" "src/touch.c")
|
||||
target_include_directories(camera PUBLIC "inc" PRIVATE "privinc")
|
||||
target_link_libraries(camera PUBLIC container mouse pad peripheral util PRIVATE gfx)
|
||||
target_link_libraries(camera
|
||||
PUBLIC
|
||||
container
|
||||
input
|
||||
peripheral
|
||||
util
|
||||
PRIVATE
|
||||
gfx
|
||||
mouse
|
||||
pad)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include <mouse.h>
|
||||
#include <pad.h>
|
||||
#include <input.h>
|
||||
#include <peripheral.h>
|
||||
#include <util.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -50,7 +49,7 @@ struct camera
|
|||
|
||||
extern struct sprite cursor_sprite;
|
||||
|
||||
void camera_update(struct camera *cam, const union peripheral *p);
|
||||
void camera_update(struct camera *cam, const union peripheral *p, const struct input *in);
|
||||
bool camera_translate(const struct camera *cam, const struct util_rect *dim, short *x, short *y);
|
||||
void cursor_init(struct cursor *c);
|
||||
bool cursor_collision(const struct camera *cam, const struct util_rect *d);
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#define CAMERA_PRIVATE_H
|
||||
|
||||
#include <camera.h>
|
||||
#include <input.h>
|
||||
#include <mouse.h>
|
||||
#include <pad.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -15,9 +18,11 @@ enum
|
|||
};
|
||||
|
||||
void camera_update_pos(struct camera *cam);
|
||||
void camera_update_pad(struct camera *cam, const struct pad *p);
|
||||
void camera_update_pad(struct camera *cam, const struct pad *p,
|
||||
const struct input *in);
|
||||
void camera_update_mouse(struct camera *cam, const struct mouse *m);
|
||||
void camera_update_touch(struct camera *cam, const struct mouse *m);
|
||||
void camera_update_touch(struct camera *cam, const struct mouse *m,
|
||||
const struct input *in);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -124,12 +124,13 @@ void cursor_set_pos_list(struct cursor *const c,
|
|||
};
|
||||
}
|
||||
|
||||
void camera_update(struct camera *const cam, const union peripheral *const p)
|
||||
void camera_update(struct camera *const cam,
|
||||
const union peripheral *const p, const struct input *const in)
|
||||
{
|
||||
switch (p->common.type)
|
||||
{
|
||||
case PERIPHERAL_TYPE_PAD:
|
||||
camera_update_pad(cam, &p->pad.pad);
|
||||
camera_update_pad(cam, &p->pad.pad, in);
|
||||
break;
|
||||
|
||||
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
|
||||
|
@ -137,7 +138,7 @@ void camera_update(struct camera *const cam, const union peripheral *const p)
|
|||
break;
|
||||
|
||||
case PERIPHERAL_TYPE_TOUCH:
|
||||
camera_update_touch(cam, &p->kbm.mouse);
|
||||
camera_update_touch(cam, &p->kbm.mouse, in);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ static void update_speed(struct camera *const cam, const struct mouse *const m)
|
|||
{
|
||||
MAX_SPEED = 10,
|
||||
STEP = 1,
|
||||
THRESHOLD_X = CAMERA_CURSOR_WIDTH * 3,
|
||||
THRESHOLD_Y = CAMERA_CURSOR_HEIGHT * 3
|
||||
THRESHOLD_X = CAMERA_CURSOR_WIDTH / 2,
|
||||
THRESHOLD_Y = CAMERA_CURSOR_HEIGHT / 2
|
||||
};
|
||||
|
||||
const struct cursor *const c = &cam->cursor;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <camera.h>
|
||||
#include <camera_private.h>
|
||||
#include <input.h>
|
||||
#include <pad.h>
|
||||
#include <peripheral.h>
|
||||
#include <gfx.h>
|
||||
|
@ -7,7 +8,8 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void cursor_update(struct camera *const cam, const struct pad *const p)
|
||||
static void cursor_update(struct camera *const cam,
|
||||
const struct pad *const p, const struct input *const in)
|
||||
{
|
||||
struct cursor *const c = &cam->cursor;
|
||||
enum {STEP = 4};
|
||||
|
@ -16,29 +18,31 @@ static void cursor_update(struct camera *const cam, const struct pad *const p)
|
|||
|| c->screen.last_h != screen_h)
|
||||
cursor_init(c);
|
||||
|
||||
if (pad_pressed(p, PAD_KEY_LEFT)
|
||||
if (input_pad_pressed(in, p, PAD_KEY_LEFT)
|
||||
&& (c->x - STEP)
|
||||
&& (!cam->x || c->x != c->x_init))
|
||||
c->x -= STEP;
|
||||
else if (pad_pressed(p, PAD_KEY_RIGHT)
|
||||
else if (input_pad_pressed(in, p, PAD_KEY_RIGHT)
|
||||
&& (c->x + STEP < screen_w)
|
||||
&& (c->x != c->x_init || cam->x <= -cam->dim.w))
|
||||
c->x += STEP;
|
||||
|
||||
if (pad_pressed(p, PAD_KEY_UP)
|
||||
if (input_pad_pressed(in, p, PAD_KEY_UP)
|
||||
&& (c->y - STEP)
|
||||
&& (c->y != c->y_init || !cam->y))
|
||||
c->y -= STEP;
|
||||
else if (pad_pressed(p, PAD_KEY_DOWN)
|
||||
else if (input_pad_pressed(in, p, PAD_KEY_DOWN)
|
||||
&& (c->y + STEP < screen_h)
|
||||
&& (c->y != c->y_init || cam->y <= -cam->dim.h))
|
||||
c->y += STEP;
|
||||
|
||||
c->state = pad_pressed(p, PAD_KEY_A) || pad_pressed(p, PAD_KEY_B) ?
|
||||
c->state = input_pad_pressed(in, p, PAD_KEY_A) ||
|
||||
input_pad_pressed(in, p, PAD_KEY_B) ?
|
||||
CURSOR_STATE_PRESSED: CURSOR_STATE_IDLE;
|
||||
}
|
||||
|
||||
static void update_speed(struct camera *const cam, const struct pad *const p)
|
||||
static void update_speed(struct camera *const cam,
|
||||
const struct pad *const p, const struct input *const in)
|
||||
{
|
||||
enum
|
||||
{
|
||||
|
@ -52,14 +56,14 @@ static void update_speed(struct camera *const cam, const struct pad *const p)
|
|||
if (c->x == c->x_init
|
||||
&& (!cam->x_speed || ++cam->xt >= T_STEP))
|
||||
{
|
||||
if (pad_pressed(p, PAD_KEY_RIGHT))
|
||||
if (input_pad_pressed(in, p, PAD_KEY_RIGHT))
|
||||
{
|
||||
if (cam->x_speed > 0)
|
||||
cam->x_speed = -STEP;
|
||||
else if (cam->x_speed - STEP >= -MAX_SPEED)
|
||||
cam->x_speed -= STEP;
|
||||
}
|
||||
else if (pad_pressed(p, PAD_KEY_LEFT))
|
||||
else if (input_pad_pressed(in, p, PAD_KEY_LEFT))
|
||||
{
|
||||
if (cam->x_speed < 0)
|
||||
cam->x_speed = STEP;
|
||||
|
@ -77,14 +81,14 @@ static void update_speed(struct camera *const cam, const struct pad *const p)
|
|||
if (c->y == c->y_init
|
||||
&& (!cam->y_speed || ++cam->yt >= T_STEP))
|
||||
{
|
||||
if (pad_pressed(p, PAD_KEY_DOWN))
|
||||
if (input_pad_pressed(in, p, PAD_KEY_DOWN))
|
||||
{
|
||||
if (cam->y_speed > 0)
|
||||
cam->y_speed = STEP;
|
||||
else if (cam->y_speed - STEP >= -MAX_SPEED)
|
||||
cam->y_speed -= STEP;
|
||||
}
|
||||
else if (pad_pressed(p, PAD_KEY_UP))
|
||||
else if (input_pad_pressed(in, p, PAD_KEY_UP))
|
||||
{
|
||||
if (cam->y_speed < 0)
|
||||
cam->y_speed = -STEP;
|
||||
|
@ -119,7 +123,7 @@ static enum pad_key get_ref_key(struct cursor_pos_rt *const rt,
|
|||
}
|
||||
|
||||
static void cursor_update_fixed(struct camera *const cam,
|
||||
const struct pad *const p)
|
||||
const struct pad *const p, const struct input *const in)
|
||||
{
|
||||
struct cursor *const c = &cam->cursor;
|
||||
struct cursor_pos_rt *const rt = &c->rt;
|
||||
|
@ -129,7 +133,7 @@ static void cursor_update_fixed(struct camera *const cam,
|
|||
{
|
||||
const enum pad_key key = get_ref_key(rt, next);
|
||||
|
||||
if (pad_justpressed(p, key))
|
||||
if (input_pad_justpressed(in, p, key))
|
||||
rt->i = next;
|
||||
}
|
||||
else if (rt->i)
|
||||
|
@ -137,7 +141,7 @@ static void cursor_update_fixed(struct camera *const cam,
|
|||
const size_t prev = rt->i - 1;
|
||||
const enum pad_key key = get_ref_key(rt, prev);
|
||||
|
||||
if (pad_justpressed(p, key))
|
||||
if (input_pad_justpressed(in, p, key))
|
||||
rt->i = prev;
|
||||
}
|
||||
|
||||
|
@ -147,14 +151,15 @@ static void cursor_update_fixed(struct camera *const cam,
|
|||
c->y = cur->y;
|
||||
}
|
||||
|
||||
void camera_update_pad(struct camera *const cam, const struct pad *const p)
|
||||
void camera_update_pad(struct camera *const cam, const struct pad *const p,
|
||||
const struct input *const in)
|
||||
{
|
||||
if (cam->cursor.rt.list)
|
||||
cursor_update_fixed(cam, p);
|
||||
cursor_update_fixed(cam, p, in);
|
||||
else
|
||||
{
|
||||
cursor_update(cam, p);
|
||||
update_speed(cam, p);
|
||||
cursor_update(cam, p, in);
|
||||
update_speed(cam, p, in);
|
||||
camera_update_pos(cam);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,12 @@ static void cursor_update(struct cursor *const c, const struct mouse *const m)
|
|||
c->y = m->y;
|
||||
}
|
||||
|
||||
static void update_speed(struct camera *const cam, const struct mouse *const m)
|
||||
static void update_speed(struct camera *const cam, const struct mouse *const m,
|
||||
const struct input *const in)
|
||||
{
|
||||
int *const sx = &cam->x_speed, *const sy = &cam->y_speed;
|
||||
|
||||
if (mouse_pressed(m, MOUSE_BUTTON_LEFT))
|
||||
if (input_mouse_pressed(in, m, MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
*sx = m->dx;
|
||||
*sy = m->dy;
|
||||
|
@ -42,9 +43,10 @@ static void update_speed(struct camera *const cam, const struct mouse *const m)
|
|||
}
|
||||
}
|
||||
|
||||
void camera_update_touch(struct camera *const cam, const struct mouse *const m)
|
||||
void camera_update_touch(struct camera *const cam, const struct mouse *const m,
|
||||
const struct input *const in)
|
||||
{
|
||||
cursor_update(&cam->cursor, m);
|
||||
update_speed(cam, m);
|
||||
update_speed(cam, m, in);
|
||||
camera_update_pos(cam);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <gfx.h>
|
||||
#include <gui/bar.h>
|
||||
#include <gui/button.h>
|
||||
#include <gui/line_edit.h>
|
||||
#include <gui/rounded_rect.h>
|
||||
#include <resource.h>
|
||||
#include <terrain.h>
|
||||
|
@ -246,6 +247,33 @@ static const struct container c[] =
|
|||
.sprite = &gui_button_sprites[GUI_BUTTON_RIGHT]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
.path = "line_edit_left",
|
||||
.type = CONTAINER_TYPE_SPRITE,
|
||||
.data =
|
||||
{
|
||||
.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_LEFT]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
.path = "line_edit_mid",
|
||||
.type = CONTAINER_TYPE_SPRITE,
|
||||
.data =
|
||||
{
|
||||
.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_MID]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
.path = "line_edit_right",
|
||||
.type = CONTAINER_TYPE_SPRITE,
|
||||
.data =
|
||||
{
|
||||
.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_RIGHT]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static bool init;
|
||||
|
|
|
@ -5,8 +5,9 @@ add_library(gui
|
|||
"src/container.c"
|
||||
"src/gui.c"
|
||||
"src/label.c"
|
||||
"src/line_edit.c"
|
||||
"src/progress_bar.c"
|
||||
"src/rounded_rect.c"
|
||||
)
|
||||
target_include_directories(gui PUBLIC "inc" PRIVATE "privinc")
|
||||
target_link_libraries(gui PUBLIC camera gfx peripheral font)
|
||||
target_link_libraries(gui PUBLIC camera gfx input net peripheral font)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <camera.h>
|
||||
#include <gfx.h>
|
||||
#include <input.h>
|
||||
#include <peripheral.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -16,9 +17,10 @@ struct gui_common
|
|||
{
|
||||
void (*add_child)(struct gui_common *parent, struct gui_common *child);
|
||||
int (*update)(struct gui_common *, const union peripheral *,
|
||||
const struct camera *);
|
||||
const struct camera *, struct input *);
|
||||
int (*render)(const struct gui_common *);
|
||||
void (*get_dim)(const struct gui_common *, short *w, short *h);
|
||||
void (*deinit)(struct gui_common *, struct input *);
|
||||
} *cb;
|
||||
|
||||
short x, y, xoff, yoff;
|
||||
|
@ -29,8 +31,9 @@ struct gui_common
|
|||
void gui_add_child(struct gui_common *parent, struct gui_common *child);
|
||||
void gui_add_sibling(struct gui_common *g, struct gui_common *sibling);
|
||||
int gui_update(struct gui_common *g, const union peripheral *p,
|
||||
const struct camera *c);
|
||||
const struct camera *c, struct input *in);
|
||||
int gui_render(const struct gui_common *g);
|
||||
void gui_deinit(struct gui_common *g, struct input *in);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef GUI_LINE_EDIT_H
|
||||
#define GUI_LINE_EDIT_H
|
||||
|
||||
#include <gui.h>
|
||||
#include <gui/label.h>
|
||||
#include <gfx.h>
|
||||
#include <util.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct gui_line_edit
|
||||
{
|
||||
struct gui_common common;
|
||||
struct gui_label label;
|
||||
short w;
|
||||
bool focus, blink;
|
||||
unsigned blt;
|
||||
char *text;
|
||||
size_t i, sz;
|
||||
};
|
||||
|
||||
void gui_line_edit_init(struct gui_line_edit *l, char *buf, size_t sz);
|
||||
|
||||
UTIL_STATIC_ASSERT(!offsetof(struct gui_line_edit, common),
|
||||
"unexpected offset for struct gui_line_edit");
|
||||
|
||||
enum
|
||||
{
|
||||
GUI_LINE_EDIT_LEFT,
|
||||
GUI_LINE_EDIT_MID,
|
||||
GUI_LINE_EDIT_RIGHT,
|
||||
|
||||
MAX_GUI_LINE_EDIT_SPRITES
|
||||
};
|
||||
|
||||
extern struct sprite gui_line_edit_sprites[MAX_GUI_LINE_EDIT_SPRITES];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GUI_LINE_EDIT_H */
|
|
@ -2,6 +2,9 @@
|
|||
#define GUI_PRIVATE_H
|
||||
|
||||
#include <gui.h>
|
||||
#include <input.h>
|
||||
#include <peripheral.h>
|
||||
#include <camera.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -9,6 +12,10 @@ extern "C"
|
|||
#endif
|
||||
|
||||
void gui_coords(const struct gui_common *g, short *x, short *y);
|
||||
bool gui_pressed(const struct gui_common *g, const struct input *in,
|
||||
const union peripheral *p, const struct camera *cam, short w, short h);
|
||||
bool gui_released(const struct gui_common *g, const union peripheral *p,
|
||||
const struct camera *cam, short w, short h);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <gui_private.h>
|
||||
#include <camera.h>
|
||||
#include <gfx.h>
|
||||
#include <input.h>
|
||||
#include <mouse.h>
|
||||
#include <pad.h>
|
||||
#include <peripheral.h>
|
||||
|
@ -37,47 +38,22 @@ static void get_dim(const struct gui_common *const g,
|
|||
|
||||
static bool pressed(const struct gui_button *const b,
|
||||
const union peripheral *const p,
|
||||
const struct camera *const cam)
|
||||
const struct camera *const cam,
|
||||
const struct input *const in)
|
||||
{
|
||||
bool check = false;
|
||||
short w, h;
|
||||
|
||||
switch (p->common.type)
|
||||
{
|
||||
case PERIPHERAL_TYPE_PAD:
|
||||
check = pad_justpressed(&p->pad.pad, PAD_KEY_A);
|
||||
break;
|
||||
|
||||
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
|
||||
check = mouse_justreleased(&p->kbm.mouse, MOUSE_BUTTON_LEFT);
|
||||
break;
|
||||
|
||||
case PERIPHERAL_TYPE_TOUCH:
|
||||
check = mouse_justpressed(&p->kbm.mouse, MOUSE_BUTTON_LEFT);
|
||||
break;
|
||||
}
|
||||
|
||||
if (check)
|
||||
{
|
||||
short x, y;
|
||||
struct util_rect d;
|
||||
|
||||
gui_coords(&b->common, &x, &y);
|
||||
get_dim(&b->common, &d.w, &d.h);
|
||||
d.x = x;
|
||||
d.y = y;
|
||||
|
||||
return cursor_collision(cam, &d);
|
||||
}
|
||||
|
||||
return false;
|
||||
get_dim(&b->common, &w, &h);
|
||||
return gui_pressed(&b->common, in, p, cam, w, h);
|
||||
}
|
||||
|
||||
static int update(struct gui_common *const g,
|
||||
const union peripheral *const p, const struct camera *const c)
|
||||
const union peripheral *const p, const struct camera *const c,
|
||||
struct input *const in)
|
||||
{
|
||||
struct gui_button *const b = (struct gui_button *)g;
|
||||
|
||||
if (pressed(b, p, c) && b->on_pressed)
|
||||
if (pressed(b, p, c, in) && b->on_pressed)
|
||||
b->on_pressed(b->arg);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <gui/container.h>
|
||||
#include <gui.h>
|
||||
#include <camera.h>
|
||||
#include <input.h>
|
||||
#include <peripheral.h>
|
||||
|
||||
static void add_child(struct gui_common *const parent,
|
||||
|
@ -52,7 +53,8 @@ static void get_dim(const struct gui_common *const g,
|
|||
}
|
||||
|
||||
static int update(struct gui_common *const g,
|
||||
const union peripheral *const p, const struct camera *const cam)
|
||||
const union peripheral *const p, const struct camera *const cam,
|
||||
struct input *const in)
|
||||
{
|
||||
struct gui_container *const c = (struct gui_container *)g;
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include <gui.h>
|
||||
#include <camera.h>
|
||||
#include <input.h>
|
||||
#include <peripheral.h>
|
||||
|
||||
static void get_centered(const struct gui_common *const g,
|
||||
short *const x, short *const y)
|
||||
|
@ -51,6 +54,79 @@ void gui_coords(const struct gui_common *const g, short *const x,
|
|||
get_centered(g, x, y);
|
||||
}
|
||||
|
||||
|
||||
static bool check_collision(const struct gui_common *const g,
|
||||
const union peripheral *const p,
|
||||
const struct camera *cam, const short w, const short h)
|
||||
{
|
||||
short x, y;
|
||||
|
||||
gui_coords(g, &x, &y);
|
||||
|
||||
const struct util_rect d =
|
||||
{
|
||||
.x = x,
|
||||
.y = y,
|
||||
.w = w,
|
||||
.h = h
|
||||
};
|
||||
|
||||
return cursor_collision(cam, &d);
|
||||
}
|
||||
|
||||
bool gui_pressed(const struct gui_common *const g,
|
||||
const struct input *const in,
|
||||
const union peripheral *const p,
|
||||
const struct camera *cam, const short w, const short h)
|
||||
{
|
||||
bool check = false;
|
||||
|
||||
switch (p->common.type)
|
||||
{
|
||||
case PERIPHERAL_TYPE_PAD:
|
||||
check = input_pad_justpressed(in, &p->pad.pad, PAD_KEY_A);
|
||||
break;
|
||||
|
||||
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
|
||||
/* Fall through. */
|
||||
case PERIPHERAL_TYPE_TOUCH:
|
||||
check = input_mouse_justreleased(in, &p->kbm.mouse,
|
||||
MOUSE_BUTTON_LEFT);
|
||||
break;
|
||||
}
|
||||
|
||||
if (check)
|
||||
return check_collision(g, p, cam, w, h);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gui_released(const struct gui_common *const g,
|
||||
const union peripheral *const p,
|
||||
const struct camera *cam, const short w, const short h)
|
||||
{
|
||||
bool check = false;
|
||||
|
||||
switch (p->common.type)
|
||||
{
|
||||
case PERIPHERAL_TYPE_PAD:
|
||||
check = pad_justpressed(&p->pad.pad, PAD_KEY_A);
|
||||
break;
|
||||
|
||||
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
|
||||
/* Fall through. */
|
||||
case PERIPHERAL_TYPE_TOUCH:
|
||||
check = mouse_justreleased(&p->kbm.mouse,
|
||||
MOUSE_BUTTON_LEFT);
|
||||
break;
|
||||
}
|
||||
|
||||
if (check)
|
||||
return !check_collision(g, p, cam, w, h);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void gui_add_sibling(struct gui_common *const g,
|
||||
struct gui_common *const s)
|
||||
{
|
||||
|
@ -77,16 +153,16 @@ void gui_add_child(struct gui_common *const p,
|
|||
}
|
||||
|
||||
int gui_update(struct gui_common *const g, const union peripheral *const p,
|
||||
const struct camera *const c)
|
||||
const struct camera *const c, struct input *const in)
|
||||
{
|
||||
if (g->child && gui_update(g->child, p, c))
|
||||
if (g->child && gui_update(g->child, p, c, in))
|
||||
return -1;
|
||||
|
||||
if (g->cb && g->cb->update && g->cb->update(g, p, c))
|
||||
if (g->cb && g->cb->update && g->cb->update(g, p, c, in))
|
||||
return -1;
|
||||
|
||||
for (struct gui_common *s = g->sibling; s; s = s->sibling)
|
||||
if (gui_update(s, p, c))
|
||||
if (gui_update(s, p, c, in))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
@ -106,3 +182,15 @@ int gui_render(const struct gui_common *const g)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gui_deinit(struct gui_common *const g, struct input *const in)
|
||||
{
|
||||
if (g->cb && g->cb->deinit)
|
||||
g->cb->deinit(g, in);
|
||||
|
||||
if (g->child)
|
||||
gui_deinit(g->child, in);
|
||||
|
||||
for (struct gui_common *s = g->sibling; s; s = s->sibling)
|
||||
gui_deinit(s, in);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
#include <gui.h>
|
||||
#include <gui_private.h>
|
||||
#include <gui/label.h>
|
||||
#include <gui/line_edit.h>
|
||||
#include <camera.h>
|
||||
#include <gfx.h>
|
||||
#include <input.h>
|
||||
#include <mouse.h>
|
||||
#include <pad.h>
|
||||
#include <peripheral.h>
|
||||
#include <string.h>
|
||||
|
||||
struct sprite gui_line_edit_sprites[MAX_GUI_LINE_EDIT_SPRITES];
|
||||
|
||||
/* Alias for readability. */
|
||||
static const struct sprite *const refs = gui_line_edit_sprites;
|
||||
|
||||
static int render_left(const struct gui_line_edit *const l,
|
||||
short *const x, const short y)
|
||||
{
|
||||
sprite_get_or_ret(s, -1);
|
||||
|
||||
if (sprite_clone(&refs[GUI_LINE_EDIT_LEFT], s))
|
||||
return -1;
|
||||
|
||||
s->x = *x;
|
||||
s->y = y;
|
||||
sprite_sort(s);
|
||||
*x = s->x + s->w;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int render_mid(const struct gui_line_edit *const l,
|
||||
short *const x, const short y)
|
||||
{
|
||||
const short mid_w = refs[GUI_LINE_EDIT_MID].w,
|
||||
lw = refs[GUI_LINE_EDIT_LEFT].w,
|
||||
rw = refs[GUI_LINE_EDIT_RIGHT].w,
|
||||
w = l->w - lw - rw;
|
||||
|
||||
if (w > 0)
|
||||
{
|
||||
const short rem_mid = w > 0 ? w % mid_w : 0,
|
||||
whole_mid = w / mid_w,
|
||||
n_mid = rem_mid ? whole_mid + 1 : whole_mid;
|
||||
|
||||
for (struct
|
||||
{
|
||||
size_t i;
|
||||
short x;
|
||||
} a = {.x = lw};
|
||||
a.i < n_mid;
|
||||
a.i++, a.x += mid_w)
|
||||
{
|
||||
sprite_get_or_ret(m, -1);
|
||||
|
||||
if (sprite_clone(&refs[GUI_LINE_EDIT_MID], m))
|
||||
return -1;
|
||||
|
||||
m->x = *x;
|
||||
m->y = y;
|
||||
|
||||
if (rem_mid && a.i + 1 == n_mid)
|
||||
m->w = rem_mid;
|
||||
else
|
||||
m->w = mid_w;
|
||||
|
||||
sprite_sort(m);
|
||||
*x += m->w;
|
||||
}
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int render_right(const short x, const short y)
|
||||
{
|
||||
sprite_get_or_ret(s, -1);
|
||||
|
||||
if (sprite_clone(&refs[GUI_LINE_EDIT_RIGHT], s))
|
||||
return -1;
|
||||
|
||||
s->x = x;
|
||||
s->y = y;
|
||||
sprite_sort(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int render(const struct gui_common *const g)
|
||||
{
|
||||
const struct gui_line_edit *const l = (const struct gui_line_edit *)g;
|
||||
short x, y;
|
||||
|
||||
gui_coords(&l->common, &x, &y);
|
||||
|
||||
if (render_left(l, &x, y)
|
||||
|| render_mid(l, &x, y)
|
||||
|| render_right(x, y))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_dim(const struct gui_common *const g,
|
||||
short *const w, short *const h)
|
||||
{
|
||||
struct gui_line_edit *const l = (struct gui_line_edit *)g;
|
||||
|
||||
*w = l->w;
|
||||
*h = refs->h;
|
||||
}
|
||||
|
||||
static void on_char(const char ch, void *const user)
|
||||
{
|
||||
struct gui_line_edit *const l = user;
|
||||
|
||||
if (l->i + 1 < l->sz)
|
||||
l->text[l->i++] = ch;
|
||||
}
|
||||
|
||||
static void on_erase(void *const user)
|
||||
{
|
||||
struct gui_line_edit *const l = user;
|
||||
|
||||
if (l->i)
|
||||
l->text[--l->i] = '\0';
|
||||
}
|
||||
|
||||
static int update(struct gui_common *const g,
|
||||
const union peripheral *const p, const struct camera *const c,
|
||||
struct input *const in)
|
||||
{
|
||||
struct gui_line_edit *const l = (struct gui_line_edit *)g;
|
||||
|
||||
if (gui_pressed(&l->common, in, p, c, l->w, refs->h))
|
||||
{
|
||||
l->focus = true;
|
||||
|
||||
*in = (const struct input)
|
||||
{
|
||||
.cb = on_char,
|
||||
.erase = on_erase,
|
||||
.user = l
|
||||
};
|
||||
}
|
||||
else if (l->focus && gui_released(&l->common, p, c, l->w, refs->h))
|
||||
{
|
||||
l->focus = false;
|
||||
|
||||
if (in->user == l)
|
||||
*in = (const struct input){0};
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void deinit(struct gui_common *const g, struct input *const in)
|
||||
{
|
||||
struct gui_line_edit *const l = (struct gui_line_edit *)g;
|
||||
|
||||
if (l->focus)
|
||||
*in = (const struct input){0};
|
||||
}
|
||||
|
||||
void gui_line_edit_init(struct gui_line_edit *const l, char *const buf,
|
||||
const size_t sz)
|
||||
{
|
||||
static const struct gui_common_cb cb =
|
||||
{
|
||||
.get_dim = get_dim,
|
||||
.update = update,
|
||||
.render = render,
|
||||
.deinit = deinit
|
||||
};
|
||||
|
||||
*l = (const struct gui_line_edit)
|
||||
{
|
||||
.common =
|
||||
{
|
||||
.cb = &cb
|
||||
},
|
||||
|
||||
.text = buf,
|
||||
.sz = sz
|
||||
};
|
||||
|
||||
gui_label_init(&l->label);
|
||||
memset(l->text, '\0', l->sz);
|
||||
l->label.common.hcentered = true;
|
||||
l->label.common.vcentered = true;
|
||||
l->label.text = l->text;
|
||||
gui_add_child(&l->common, &l->label.common);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
add_library(input
|
||||
"src/input.c"
|
||||
)
|
||||
target_include_directories(input PUBLIC "inc")
|
||||
target_link_libraries(input PUBLIC keyboard mouse pad peripheral)
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
#include <keyboard.h>
|
||||
#include <mouse.h>
|
||||
#include <pad.h>
|
||||
#include <peripheral.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void (*input_ch)(char ch, void *user);
|
||||
typedef void (*input_erase)(void *user);
|
||||
|
||||
struct input
|
||||
{
|
||||
input_ch cb;
|
||||
input_erase erase;
|
||||
void *user;
|
||||
unsigned char t;
|
||||
bool repeat;
|
||||
struct keyboard_combo prev;
|
||||
};
|
||||
|
||||
void input_update(struct input *in, const union peripheral *p);
|
||||
int input_render(const struct input *in, const union peripheral *p);
|
||||
bool input_keyboard_justpressed(const struct input *in,
|
||||
const struct keyboard *k,
|
||||
const struct keyboard_combo *c);
|
||||
bool input_keyboard_pressed(const struct input *in,
|
||||
const struct keyboard *k,
|
||||
const struct keyboard_combo *c);
|
||||
bool input_keyboard_justreleased(const struct input *in,
|
||||
const struct keyboard *k,
|
||||
const struct keyboard_combo *c);
|
||||
bool input_pad_pressed(const struct input *in, const struct pad *p,
|
||||
enum pad_key k);
|
||||
bool input_pad_justpressed(const struct input *in, const struct pad *p,
|
||||
enum pad_key k);
|
||||
bool input_pad_released(const struct input *in, const struct pad *p,
|
||||
enum pad_key k);
|
||||
bool input_mouse_pressed(const struct input *in, const struct mouse *m,
|
||||
enum mouse_button b);
|
||||
bool input_mouse_justpressed(const struct input *in, const struct mouse *m,
|
||||
enum mouse_button b);
|
||||
bool input_mouse_justreleased(const struct input *in, const struct mouse *m,
|
||||
enum mouse_button b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INPUT_H */
|
|
@ -0,0 +1,175 @@
|
|||
#include <input.h>
|
||||
#include <keyboard.h>
|
||||
#include <mouse.h>
|
||||
#include <pad.h>
|
||||
#include <peripheral.h>
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
static void send_input(struct input *const in, const struct keyboard *const k,
|
||||
const enum keyboard_key key)
|
||||
{
|
||||
if (key != KEYBOARD_KEY_NONE)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case KEYBOARD_KEY_BACKSPACE:
|
||||
in->erase(in->user);
|
||||
break;
|
||||
|
||||
case KEYBOARD_KEY_ESC:
|
||||
*in = (const struct input){0};
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
const char ch = keyboard_to_char(k, key);
|
||||
|
||||
if (isprint(ch))
|
||||
in->cb(ch, in->user);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_keyboard(struct input *const in,
|
||||
const struct keyboard *const k)
|
||||
{
|
||||
struct keyboard_combo c;
|
||||
|
||||
if (keyboard_any_justpressed(k, &c))
|
||||
for (size_t i = 0; i < sizeof c.keys / sizeof *c.keys; i++)
|
||||
send_input(in, k, c.keys[i]);
|
||||
else if (keyboard_any_pressed(k, &c))
|
||||
{
|
||||
if (memcmp(&c, &in->prev, sizeof c))
|
||||
{
|
||||
in->repeat = false;
|
||||
in->t = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum {LONG_INTERVAL = 25, SHORT_INTERVAL = 2};
|
||||
|
||||
if (!in->repeat)
|
||||
{
|
||||
if (++in->t >= LONG_INTERVAL)
|
||||
in->repeat = true;
|
||||
}
|
||||
else if (++in->t >= SHORT_INTERVAL)
|
||||
{
|
||||
for (size_t i = 0;
|
||||
i < sizeof c.keys / sizeof *c.keys; i++)
|
||||
send_input(in, k, c.keys[i]);
|
||||
|
||||
in->t = 0;
|
||||
}
|
||||
}
|
||||
|
||||
in->prev = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
in->repeat = false;
|
||||
in->t = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void input_update(struct input *const in, const union peripheral *const p)
|
||||
{
|
||||
switch (p->common.type)
|
||||
{
|
||||
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
|
||||
if (in->cb && in->erase)
|
||||
update_keyboard(in, &p->kbm.keyboard);
|
||||
|
||||
break;
|
||||
|
||||
case PERIPHERAL_TYPE_TOUCH:
|
||||
/* Fall through. */
|
||||
case PERIPHERAL_TYPE_PAD:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int input_render(const struct input *const in, const union peripheral *const p)
|
||||
{
|
||||
switch (p->common.type)
|
||||
{
|
||||
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
|
||||
return 0;
|
||||
|
||||
case PERIPHERAL_TYPE_TOUCH:
|
||||
/* Fall through. */
|
||||
case PERIPHERAL_TYPE_PAD:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool input_keyboard_justpressed(const struct input *const in,
|
||||
const struct keyboard *const k,
|
||||
const struct keyboard_combo *const c)
|
||||
{
|
||||
return in->cb ? false : keyboard_justpressed(k, c);
|
||||
}
|
||||
|
||||
bool input_keyboard_pressed(const struct input *const in,
|
||||
const struct keyboard *const k,
|
||||
const struct keyboard_combo *const c)
|
||||
{
|
||||
return in->cb ? false : keyboard_pressed(k, c);
|
||||
}
|
||||
|
||||
bool input_keyboard_justreleased(const struct input *const in,
|
||||
const struct keyboard *const k,
|
||||
const struct keyboard_combo *const c)
|
||||
{
|
||||
return in->cb ? false : keyboard_justreleased(k, c);
|
||||
}
|
||||
|
||||
bool input_pad_pressed(const struct input *const in,
|
||||
const struct pad *const p,
|
||||
const enum pad_key k)
|
||||
{
|
||||
return in->cb ? false : pad_pressed(p, k);
|
||||
}
|
||||
|
||||
bool input_pad_justpressed(const struct input *const in,
|
||||
const struct pad *const p,
|
||||
const enum pad_key k)
|
||||
{
|
||||
return in->cb ? false : pad_justpressed(p, k);
|
||||
}
|
||||
|
||||
bool input_pad_released(const struct input *const in,
|
||||
const struct pad *const p,
|
||||
const enum pad_key k)
|
||||
{
|
||||
return in->cb ? false : pad_released(p, k);
|
||||
}
|
||||
|
||||
bool input_mouse_pressed(const struct input *const in,
|
||||
const struct mouse *const m,
|
||||
const enum mouse_button b)
|
||||
{
|
||||
return in->cb ? false : mouse_pressed(m, b);
|
||||
}
|
||||
|
||||
bool input_mouse_justpressed(const struct input *const in,
|
||||
const struct mouse *const m,
|
||||
const enum mouse_button b)
|
||||
{
|
||||
return in->cb ? false : mouse_justpressed(m, b);
|
||||
}
|
||||
|
||||
bool input_mouse_justreleased(const struct input *const in,
|
||||
const struct mouse *const m,
|
||||
const enum mouse_button b)
|
||||
{
|
||||
return in->cb ? false : mouse_justreleased(m, b);
|
||||
}
|
|
@ -29,6 +29,9 @@ void keyboard_update(struct keyboard *k);
|
|||
bool keyboard_justpressed(const struct keyboard *k, const struct keyboard_combo *c);
|
||||
bool keyboard_pressed(const struct keyboard *k, const struct keyboard_combo *c);
|
||||
bool keyboard_justreleased(const struct keyboard *k, const struct keyboard_combo *c);
|
||||
bool keyboard_any_justpressed(const struct keyboard *k, struct keyboard_combo *c);
|
||||
bool keyboard_any_pressed(const struct keyboard *k, struct keyboard_combo *c);
|
||||
char keyboard_to_char(const struct keyboard *k, enum keyboard_key key);
|
||||
const char *keyboard_key_str(enum keyboard_key k);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -54,7 +54,11 @@ extern "C"
|
|||
X(KEYBOARD_KEY_RIGHT) \
|
||||
X(KEYBOARD_KEY_UP) \
|
||||
X(KEYBOARD_KEY_DOWN) \
|
||||
X(KEYBOARD_KEY_EXIT)
|
||||
X(KEYBOARD_KEY_EXIT) \
|
||||
X(KEYBOARD_KEY_BACKSPACE) \
|
||||
X(KEYBOARD_KEY_SPACE) \
|
||||
X(KEYBOARD_KEY_MINUS) \
|
||||
X(KEYBOARD_KEY_DOT)
|
||||
|
||||
enum keyboard_key
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@ static void key_event(const SDL_KeyboardEvent *const ev,
|
|||
SDLKey sdl_key;
|
||||
} keymap[] =
|
||||
{
|
||||
{.key = KEYBOARD_KEY_BACKSPACE, .sdl_key = SDLK_BACKSPACE},
|
||||
{.key = KEYBOARD_KEY_LEFT, .sdl_key = SDLK_LEFT},
|
||||
{.key = KEYBOARD_KEY_RIGHT, .sdl_key = SDLK_RIGHT},
|
||||
{.key = KEYBOARD_KEY_UP, .sdl_key = SDLK_UP},
|
||||
|
@ -49,12 +50,58 @@ static void key_event(const SDL_KeyboardEvent *const ev,
|
|||
{.key = KEYBOARD_KEY_RCTRL, .sdl_key = SDLK_RCTRL},
|
||||
{.key = KEYBOARD_KEY_LSHIFT, .sdl_key = SDLK_LSHIFT},
|
||||
{.key = KEYBOARD_KEY_RSHIFT, .sdl_key = SDLK_RSHIFT},
|
||||
{.key = KEYBOARD_KEY_EXIT, .sdl_key = SDLK_ESCAPE},
|
||||
{.key = KEYBOARD_KEY_ESC, .sdl_key = SDLK_ESCAPE},
|
||||
{.key = KEYBOARD_KEY_F11, .sdl_key = SDLK_F11},
|
||||
{.key = KEYBOARD_KEY_W, .sdl_key = SDLK_w},
|
||||
{.key = KEYBOARD_KEY_SPACE, .sdl_key = SDLK_SPACE},
|
||||
{.key = KEYBOARD_KEY_MINUS, .sdl_key = SDLK_MINUS},
|
||||
{.key = KEYBOARD_KEY_A, .sdl_key = SDLK_a},
|
||||
{.key = KEYBOARD_KEY_B, .sdl_key = SDLK_b},
|
||||
{.key = KEYBOARD_KEY_C, .sdl_key = SDLK_c},
|
||||
{.key = KEYBOARD_KEY_D, .sdl_key = SDLK_d},
|
||||
{.key = KEYBOARD_KEY_E, .sdl_key = SDLK_e},
|
||||
{.key = KEYBOARD_KEY_F, .sdl_key = SDLK_f},
|
||||
{.key = KEYBOARD_KEY_G, .sdl_key = SDLK_g},
|
||||
{.key = KEYBOARD_KEY_H, .sdl_key = SDLK_h},
|
||||
{.key = KEYBOARD_KEY_I, .sdl_key = SDLK_i},
|
||||
{.key = KEYBOARD_KEY_J, .sdl_key = SDLK_j},
|
||||
{.key = KEYBOARD_KEY_K, .sdl_key = SDLK_k},
|
||||
{.key = KEYBOARD_KEY_L, .sdl_key = SDLK_l},
|
||||
{.key = KEYBOARD_KEY_M, .sdl_key = SDLK_m},
|
||||
{.key = KEYBOARD_KEY_N, .sdl_key = SDLK_n},
|
||||
{.key = KEYBOARD_KEY_O, .sdl_key = SDLK_o},
|
||||
{.key = KEYBOARD_KEY_P, .sdl_key = SDLK_p},
|
||||
{.key = KEYBOARD_KEY_Q, .sdl_key = SDLK_q},
|
||||
{.key = KEYBOARD_KEY_R, .sdl_key = SDLK_r},
|
||||
{.key = KEYBOARD_KEY_S, .sdl_key = SDLK_s},
|
||||
{.key = KEYBOARD_KEY_D, .sdl_key = SDLK_d}
|
||||
{.key = KEYBOARD_KEY_T, .sdl_key = SDLK_t},
|
||||
{.key = KEYBOARD_KEY_U, .sdl_key = SDLK_u},
|
||||
{.key = KEYBOARD_KEY_V, .sdl_key = SDLK_v},
|
||||
{.key = KEYBOARD_KEY_W, .sdl_key = SDLK_w},
|
||||
{.key = KEYBOARD_KEY_X, .sdl_key = SDLK_x},
|
||||
{.key = KEYBOARD_KEY_Y, .sdl_key = SDLK_y},
|
||||
{.key = KEYBOARD_KEY_Z, .sdl_key = SDLK_z},
|
||||
{.key = KEYBOARD_KEY_0, .sdl_key = SDLK_0},
|
||||
{.key = KEYBOARD_KEY_1, .sdl_key = SDLK_1},
|
||||
{.key = KEYBOARD_KEY_2, .sdl_key = SDLK_2},
|
||||
{.key = KEYBOARD_KEY_3, .sdl_key = SDLK_3},
|
||||
{.key = KEYBOARD_KEY_4, .sdl_key = SDLK_4},
|
||||
{.key = KEYBOARD_KEY_5, .sdl_key = SDLK_5},
|
||||
{.key = KEYBOARD_KEY_6, .sdl_key = SDLK_6},
|
||||
{.key = KEYBOARD_KEY_7, .sdl_key = SDLK_7},
|
||||
{.key = KEYBOARD_KEY_8, .sdl_key = SDLK_8},
|
||||
{.key = KEYBOARD_KEY_9, .sdl_key = SDLK_9},
|
||||
{.key = KEYBOARD_KEY_0, .sdl_key = SDLK_KP0},
|
||||
{.key = KEYBOARD_KEY_1, .sdl_key = SDLK_KP1},
|
||||
{.key = KEYBOARD_KEY_2, .sdl_key = SDLK_KP2},
|
||||
{.key = KEYBOARD_KEY_3, .sdl_key = SDLK_KP3},
|
||||
{.key = KEYBOARD_KEY_4, .sdl_key = SDLK_KP4},
|
||||
{.key = KEYBOARD_KEY_5, .sdl_key = SDLK_KP5},
|
||||
{.key = KEYBOARD_KEY_6, .sdl_key = SDLK_KP6},
|
||||
{.key = KEYBOARD_KEY_7, .sdl_key = SDLK_KP7},
|
||||
{.key = KEYBOARD_KEY_8, .sdl_key = SDLK_KP8},
|
||||
{.key = KEYBOARD_KEY_9, .sdl_key = SDLK_KP9},
|
||||
{.key = KEYBOARD_KEY_DOT, .sdl_key = SDLK_PERIOD},
|
||||
{.key = KEYBOARD_KEY_DOT, .sdl_key = SDLK_KP_PERIOD}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof keymap / sizeof *keymap; i++)
|
||||
|
|
|
@ -1,8 +1,88 @@
|
|||
#include <keyboard.h>
|
||||
#include <keyboard_key.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
bool keyboard_any_justpressed(const struct keyboard *const k,
|
||||
struct keyboard_combo *const c)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
for (size_t i = 0; i < sizeof c->keys / sizeof c->keys; i++)
|
||||
c->keys[i] = KEYBOARD_KEY_NONE;
|
||||
|
||||
for (size_t i = 0, j = 0;
|
||||
i < sizeof k->combo.keys / sizeof *k->combo.keys; i++)
|
||||
{
|
||||
const enum keyboard_key key = k->combo.keys[i];
|
||||
|
||||
if (key != KEYBOARD_KEY_NONE
|
||||
&& k->oldcombo.keys[i] == KEYBOARD_KEY_NONE)
|
||||
{
|
||||
c->keys[j++] = key;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool keyboard_any_pressed(const struct keyboard *const k,
|
||||
struct keyboard_combo *const c)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof k->combo.keys / sizeof *k->combo.keys; i++)
|
||||
{
|
||||
const enum keyboard_key key = k->combo.keys[i];
|
||||
|
||||
if (key != KEYBOARD_KEY_NONE)
|
||||
{
|
||||
*c = k->combo;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char keyboard_to_char(const struct keyboard *const k,
|
||||
const enum keyboard_key key)
|
||||
{
|
||||
if (key >= KEYBOARD_KEY_0 && key <= KEYBOARD_KEY_9)
|
||||
return '0' + key - KEYBOARD_KEY_0;
|
||||
else if (key >= KEYBOARD_KEY_A && key <= KEYBOARD_KEY_Z)
|
||||
{
|
||||
if (keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_LSHIFT))
|
||||
|| keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_RSHIFT)))
|
||||
return 'A' + key - KEYBOARD_KEY_A;
|
||||
else
|
||||
return 'a' + key - KEYBOARD_KEY_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
static const struct map
|
||||
{
|
||||
enum keyboard_key key;
|
||||
char ch;
|
||||
} map[] =
|
||||
{
|
||||
{.key = KEYBOARD_KEY_DOT, .ch = '.'},
|
||||
{.key = KEYBOARD_KEY_SPACE, .ch = ' '},
|
||||
{.key = KEYBOARD_KEY_MINUS, .ch = '-'}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof map / sizeof *map; i++)
|
||||
{
|
||||
const struct map *const m = &map[i];
|
||||
|
||||
if (key == m->key)
|
||||
return m->ch;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool combo_pressed(const struct keyboard_combo *const ref,
|
||||
const struct keyboard_combo *const c)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
add_library(menu
|
||||
"src/gamecfg_menu.c"
|
||||
"src/hostjoin_menu.c"
|
||||
"src/join_menu.c"
|
||||
"src/menu.c"
|
||||
"src/main_menu.c"
|
||||
)
|
||||
target_include_directories(menu PUBLIC "inc" PRIVATE "privinc")
|
||||
target_link_libraries(menu PRIVATE camera game gfx gui system)
|
||||
target_link_libraries(menu PRIVATE camera game gfx gui input system)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define MENU_PRIVATE_H
|
||||
|
||||
#include <camera.h>
|
||||
#include <input.h>
|
||||
#include <peripheral.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -14,6 +15,7 @@ struct menu_common
|
|||
{
|
||||
struct camera cam;
|
||||
union peripheral p;
|
||||
struct input in;
|
||||
};
|
||||
|
||||
int menu_update(struct menu_common *c,
|
||||
|
@ -22,6 +24,7 @@ int menu_update(struct menu_common *c,
|
|||
void *arg);
|
||||
int menu_main(struct menu_common *c);
|
||||
int menu_hostjoin(struct menu_common *c, bool *back);
|
||||
int menu_join(struct menu_common *c);
|
||||
int menu_gamecfg(struct menu_common *c);
|
||||
void menu_on_pressed(void *arg);
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ static int update(struct menu_common *const c, void *const arg)
|
|||
m->r.w = screen_w / 2;
|
||||
m->r.h = screen_h / 2;
|
||||
|
||||
if (gui_update(&m->cnt.common, &c->p, &c->cam)
|
||||
|| gui_update(&m->bcnt.common, &c->p, &c->cam))
|
||||
if (gui_update(&m->cnt.common, &c->p, &c->cam, &c->in)
|
||||
|| gui_update(&m->bcnt.common, &c->p, &c->cam, &c->in))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
@ -77,10 +77,8 @@ int menu_gamecfg(struct menu_common *const c)
|
|||
gui_add_child(&m.bcnt.common, &m.back.common);
|
||||
|
||||
while (!back && !c->p.common.exit && !start)
|
||||
{
|
||||
if (menu_update(c, update, render, &m))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (start)
|
||||
return game(NULL);
|
||||
|
|
|
@ -16,7 +16,7 @@ static int update(struct menu_common *const c, void *const arg)
|
|||
{
|
||||
struct menu_hostjoin *const m = arg;
|
||||
|
||||
if (gui_update(&m->cnt.common, &c->p, &c->cam))
|
||||
if (gui_update(&m->cnt.common, &c->p, &c->cam, &c->in))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
@ -75,9 +75,16 @@ int menu_hostjoin(struct menu_common *const c, bool *const back)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (host || join)
|
||||
if (host)
|
||||
{
|
||||
if (menu_gamecfg(c))
|
||||
return -1;
|
||||
}
|
||||
else if (join)
|
||||
{
|
||||
if (menu_join(c))
|
||||
return -1;
|
||||
}
|
||||
|
||||
} while (!*back && !c->p.common.exit);
|
||||
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
#include <menu.h>
|
||||
#include <menu_private.h>
|
||||
#include <game.h>
|
||||
#include <gui.h>
|
||||
#include <gui/button.h>
|
||||
#include <gui/container.h>
|
||||
#include <gui/label.h>
|
||||
#include <gui/line_edit.h>
|
||||
#include <gui/rounded_rect.h>
|
||||
#include <net.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct join_menu
|
||||
{
|
||||
struct gui_container cnt, bcnt;
|
||||
struct gui_label type_label, address, port, connecting;
|
||||
struct gui_button type_btn, back, connect;
|
||||
struct gui_line_edit address_le, port_le;
|
||||
|
||||
enum
|
||||
{
|
||||
IDLE,
|
||||
CONNECT,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
CONNECT_FAILED
|
||||
} state;
|
||||
|
||||
struct net_socket *socket;
|
||||
size_t domain_i;
|
||||
};
|
||||
|
||||
static const enum net_domain domains[] =
|
||||
{
|
||||
NET_DOMAIN_IPV4,
|
||||
NET_DOMAIN_SERIAL
|
||||
};
|
||||
|
||||
static void on_connected(void *const arg)
|
||||
{
|
||||
struct join_menu *const m = arg;
|
||||
|
||||
if (m->state == IDLE)
|
||||
{
|
||||
m->state = CONNECT;
|
||||
m->connecting.text = "Connecting...";
|
||||
}
|
||||
}
|
||||
|
||||
static void on_disconnected(void *const arg)
|
||||
{
|
||||
struct join_menu *const m = arg;
|
||||
|
||||
m->connecting.text = "Failed to connect";
|
||||
m->state = CONNECT_FAILED;
|
||||
m->socket = NULL;
|
||||
}
|
||||
|
||||
static int on_connect(struct join_menu *const m)
|
||||
{
|
||||
const enum net_domain d = domains[m->domain_i];
|
||||
|
||||
union net_connect c =
|
||||
{
|
||||
.common =
|
||||
{
|
||||
.domain = d,
|
||||
.on_connected = on_connected,
|
||||
.on_disconnected = on_disconnected,
|
||||
.arg = m
|
||||
}
|
||||
};
|
||||
|
||||
switch (d)
|
||||
{
|
||||
case NET_DOMAIN_IPV4:
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
const unsigned long port = strtoul(m->port_le.text, NULL, 0);
|
||||
|
||||
if (errno)
|
||||
return -1;
|
||||
|
||||
c.ipv4.addr = m->address_le.text;
|
||||
c.ipv4.port = port;
|
||||
}
|
||||
break;
|
||||
|
||||
case NET_DOMAIN_SERIAL:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(m->socket = net_connect(&c)))
|
||||
{
|
||||
fprintf(stderr, "%s: net_connect failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int update(struct menu_common *const c, void *const arg)
|
||||
{
|
||||
struct join_menu *const m = arg;
|
||||
|
||||
m->bcnt.common.y = screen_h - 40;
|
||||
|
||||
if (gui_update(&m->cnt.common, &c->p, &c->cam, &c->in)
|
||||
|| gui_update(&m->bcnt.common, &c->p, &c->cam, &c->in))
|
||||
return -1;
|
||||
|
||||
if (m->socket && net_update(m->socket))
|
||||
return -1;
|
||||
|
||||
switch (m->state)
|
||||
{
|
||||
case CONNECT:
|
||||
if (on_connect(m))
|
||||
return -1;
|
||||
|
||||
m->state = CONNECTING;
|
||||
|
||||
if (!m->connecting.common.parent)
|
||||
gui_add_child(&m->cnt.common, &m->connecting.common);
|
||||
|
||||
break;
|
||||
|
||||
case CONNECT_FAILED:
|
||||
net_close(m->socket);
|
||||
m->socket = NULL;
|
||||
m->state = IDLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int render(const struct menu_common *const c, void *const arg)
|
||||
{
|
||||
const struct join_menu *const m = arg;
|
||||
|
||||
if (gui_render(&m->cnt.common)
|
||||
|| gui_render(&m->bcnt.common))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void on_type_pressed(void *const arg)
|
||||
{
|
||||
struct join_menu *const m = arg;
|
||||
|
||||
if (++m->domain_i >= sizeof domains / sizeof *domains)
|
||||
m->domain_i = 0;
|
||||
|
||||
m->type_btn.u.type1.label.text = net_domain_str(domains[m->domain_i]);
|
||||
}
|
||||
|
||||
static void on_connect_pressed(void *const arg)
|
||||
{
|
||||
struct join_menu *const m = arg;
|
||||
|
||||
m->state = CONNECT;
|
||||
}
|
||||
|
||||
int menu_join(struct menu_common *const c)
|
||||
{
|
||||
int ret = -1;
|
||||
struct join_menu m = {0};
|
||||
bool connect = false;
|
||||
bool back = false;
|
||||
|
||||
gui_container_init(&m.cnt);
|
||||
m.cnt.common.hcentered = true;
|
||||
m.cnt.common.vcentered = true;
|
||||
m.cnt.mode = GUI_CONTAINER_MODE_V;
|
||||
m.cnt.spacing = 2;
|
||||
|
||||
gui_label_init(&m.type_label);
|
||||
m.type_label.common.hcentered = true;
|
||||
m.type_label.text = "Type:";
|
||||
gui_add_child(&m.cnt.common, &m.type_label.common);
|
||||
|
||||
gui_button_init(&m.type_btn, GUI_BUTTON_TYPE_1);
|
||||
m.type_btn.arg = &m;
|
||||
m.type_btn.u.type1.w = 140;
|
||||
m.type_btn.common.hcentered = true;
|
||||
m.type_btn.on_pressed = on_type_pressed;
|
||||
m.type_btn.u.type1.label.text = net_domain_str(*domains);
|
||||
gui_add_child(&m.cnt.common, &m.type_btn.common);
|
||||
|
||||
gui_label_init(&m.address);
|
||||
m.address.common.hcentered = true;
|
||||
m.address.text = "Address:";
|
||||
gui_add_child(&m.cnt.common, &m.address.common);
|
||||
|
||||
char address[sizeof "255.255.255.255"];
|
||||
gui_line_edit_init(&m.address_le, address, sizeof address);
|
||||
m.address_le.w = 140;
|
||||
m.address_le.common.hcentered = true;
|
||||
gui_add_child(&m.cnt.common, &m.address_le.common);
|
||||
|
||||
gui_label_init(&m.port);
|
||||
m.port.common.hcentered = true;
|
||||
m.port.text = "Port:";
|
||||
gui_add_child(&m.cnt.common, &m.port.common);
|
||||
|
||||
char port[sizeof "65535"];
|
||||
gui_line_edit_init(&m.port_le, port, sizeof port);
|
||||
m.port_le.w = 80;
|
||||
m.port_le.common.hcentered = true;
|
||||
gui_add_child(&m.cnt.common, &m.port_le.common);
|
||||
|
||||
gui_label_init(&m.connecting);
|
||||
m.connecting.common.hcentered = true;
|
||||
|
||||
gui_container_init(&m.bcnt);
|
||||
m.bcnt.common.hcentered = true;
|
||||
m.bcnt.mode = GUI_CONTAINER_MODE_H;
|
||||
|
||||
gui_button_init(&m.connect, GUI_BUTTON_TYPE_1);
|
||||
m.connect.u.type1.label.text = "Connect";
|
||||
m.connect.u.type1.w = 140;
|
||||
m.connect.common.vcentered = true;
|
||||
m.connect.on_pressed = on_connect_pressed;
|
||||
m.connect.arg = &m;
|
||||
m.back.common.vcentered = true;
|
||||
gui_add_child(&m.bcnt.common, &m.connect.common);
|
||||
|
||||
gui_button_init(&m.back, GUI_BUTTON_TYPE_1);
|
||||
m.back.u.type1.label.text = "Back";
|
||||
m.back.u.type1.w = 100;
|
||||
m.back.common.vcentered = true;
|
||||
m.back.on_pressed = menu_on_pressed;
|
||||
m.back.arg = &back;
|
||||
m.back.common.vcentered = true;
|
||||
gui_add_child(&m.bcnt.common, &m.back.common);
|
||||
|
||||
while (!back && !c->p.common.exit && !connect)
|
||||
{
|
||||
if (menu_update(c, update, render, &m))
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (connect)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
gui_deinit(&m.cnt.common, &c->in);
|
||||
return ret;
|
||||
}
|
|
@ -18,7 +18,7 @@ static int update(struct menu_common *const c, void *const arg)
|
|||
{
|
||||
struct main_menu *const m = arg;
|
||||
|
||||
if (gui_update(&m->play.common, &c->p, &c->cam))
|
||||
if (gui_update(&m->play.common, &c->p, &c->cam, &c->in))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <camera.h>
|
||||
#include <game.h>
|
||||
#include <gfx.h>
|
||||
#include <input.h>
|
||||
#include <peripheral.h>
|
||||
#include <system.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -19,7 +20,8 @@ int menu_update(struct menu_common *const c,
|
|||
{
|
||||
system_loop();
|
||||
peripheral_update(&c->p);
|
||||
camera_update(&c->cam, &c->p);
|
||||
input_update(&c->in, &c->p);
|
||||
camera_update(&c->cam, &c->p, &c->in);
|
||||
|
||||
if (update && update(c, arg))
|
||||
return -1;
|
||||
|
@ -32,6 +34,8 @@ int menu_update(struct menu_common *const c,
|
|||
|
||||
if (render && render(c, arg))
|
||||
return -1;
|
||||
else if (input_render(&c->in, &c->p))
|
||||
return -1;
|
||||
|
||||
switch (c->p.common.type)
|
||||
{
|
||||
|
@ -66,7 +70,7 @@ int menu(void)
|
|||
struct menu_common c = {0};
|
||||
|
||||
if (game_resinit())
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
cursor_init(&c.cam.cursor);
|
||||
peripheral_init(&cfg, &c.p);
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
#include <menu_private.h>
|
||||
#include <gui.h>
|
||||
#include <gui/container.h>
|
||||
#include <gui/label.h>
|
||||
#include <gui/line_edit.h>
|
||||
#include <gui/button.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct menu_settings
|
||||
{
|
||||
struct gui_container cnt;
|
||||
struct gui_button back;
|
||||
};
|
||||
|
||||
static int update(struct menu_common *const c, void *const arg)
|
||||
{
|
||||
struct menu_settings *const m = arg;
|
||||
|
||||
if (gui_update(&m->cnt.common, &c->p, &c->cam, &c->in))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int render(const struct menu_common *const c, void *const arg)
|
||||
{
|
||||
const struct menu_settings *const m = arg;
|
||||
|
||||
if (gui_render(&m->cnt.common))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu_settings(struct menu_common *const c, bool *const back)
|
||||
{
|
||||
do
|
||||
{
|
||||
struct menu_settings m;
|
||||
|
||||
gui_container_init(&m.cnt);
|
||||
m.cnt.common.hcentered = true;
|
||||
m.cnt.common.vcentered = true;
|
||||
m.cnt.spacing = 4;
|
||||
m.cnt.mode = GUI_CONTAINER_MODE_V;
|
||||
|
||||
gui_button_init(&m.back, GUI_BUTTON_TYPE_1);
|
||||
m.back.u.type1.label.text = "Back";
|
||||
m.back.common.hcentered = true;
|
||||
m.back.u.type1.w = 140;
|
||||
m.back.arg = back;
|
||||
m.back.on_pressed = menu_on_pressed;
|
||||
gui_add_child(&m.cnt.common, &m.back.common);
|
||||
|
||||
while (!*back && !c->p.common.exit)
|
||||
if (menu_update(c, update, render, &m))
|
||||
return -1;
|
||||
|
||||
} while (!*back && !c->p.common.exit);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
set(src "src/common.c")
|
||||
|
||||
if(PS1_BUILD)
|
||||
set(src ${src}
|
||||
"src/ps1/net.c"
|
||||
)
|
||||
else()
|
||||
set(src ${src}
|
||||
"src/net.c"
|
||||
"src/enet/ipv4.c"
|
||||
)
|
||||
|
||||
if(WIN9X_BUILD OR ${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
|
||||
set(src ${src} "src/win9x/serial.c")
|
||||
else()
|
||||
# Assume POSIX if the command below executes successfully
|
||||
execute_process(COMMAND uname -m RESULT_VARIABLE result OUTPUT_QUIET)
|
||||
|
||||
if(result)
|
||||
message(FATAL_ERROR "Unknown operating system")
|
||||
else()
|
||||
set(src ${src} "src/posix/serial.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(priv_deps ${priv_deps} util ENET)
|
||||
set(privinc ${privinc} "privinc")
|
||||
endif()
|
||||
|
||||
add_library(net ${src})
|
||||
target_include_directories(net PUBLIC "inc" PRIVATE ${privinc})
|
||||
target_link_libraries(net PRIVATE ${priv_deps})
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef NET_H
|
||||
#define NET_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum net_domain
|
||||
{
|
||||
NET_DOMAIN_IPV4,
|
||||
NET_DOMAIN_SERIAL
|
||||
};
|
||||
|
||||
union net_connect
|
||||
{
|
||||
struct net_connect_common
|
||||
{
|
||||
enum net_domain domain;
|
||||
void (*on_connected)(void *arg);
|
||||
void (*on_disconnected)(void *arg);
|
||||
void *arg;
|
||||
} common;
|
||||
|
||||
struct net_connect_ipv4
|
||||
{
|
||||
struct net_connect_common common;
|
||||
const char *addr;
|
||||
uint16_t port;
|
||||
} ipv4;
|
||||
|
||||
struct net_connect_serial
|
||||
{
|
||||
struct net_connect_common common;
|
||||
const char *dev;
|
||||
unsigned long baud;
|
||||
|
||||
enum
|
||||
{
|
||||
NET_PARITY_NONE,
|
||||
NET_PARITY_ODD,
|
||||
NET_PARITY_EVEN
|
||||
} parity;
|
||||
} serial;
|
||||
};
|
||||
|
||||
union net_server
|
||||
{
|
||||
struct net_server_common
|
||||
{
|
||||
enum net_domain domain;
|
||||
unsigned max_players;
|
||||
} common;
|
||||
|
||||
struct net_server_ipv4
|
||||
{
|
||||
struct net_server_common common;
|
||||
uint16_t port;
|
||||
} ipv4;
|
||||
|
||||
struct net_server_serial
|
||||
{
|
||||
struct net_server_common common;
|
||||
} serial;
|
||||
};
|
||||
|
||||
struct net_socket;
|
||||
|
||||
int net_init(void);
|
||||
void net_deinit(void);
|
||||
int net_update(struct net_socket *s);
|
||||
|
||||
struct net_socket *net_server(const union net_server *srv);
|
||||
struct net_socket *net_connect(const union net_connect *c);
|
||||
int net_read(struct net_socket *s, void *buf, size_t n);
|
||||
int net_write(struct net_socket *s, const void *buf, size_t n);
|
||||
int net_close(struct net_socket *s);
|
||||
const char *net_domain_str(enum net_domain d);
|
||||
|
||||
#endif /* NET_H */
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef NET_PRIVATE_H
|
||||
#define NET_PRIVATE_H
|
||||
|
||||
#include <net.h>
|
||||
|
||||
struct net_socket
|
||||
{
|
||||
enum net_domain d;
|
||||
struct net_socket_domain *s;
|
||||
};
|
||||
|
||||
int net_init_ipv4(void);
|
||||
void net_deinit_ipv4(void);
|
||||
struct net_socket_domain *net_server_ipv4(const union net_server *srv);
|
||||
struct net_socket_domain *net_connect_ipv4(const union net_connect *c);
|
||||
int net_read_ipv4(struct net_socket_domain *h, void *buf, size_t n);
|
||||
int net_write_ipv4(struct net_socket_domain *h, const void *buf, size_t n);
|
||||
int net_close_ipv4(struct net_socket_domain *h);
|
||||
int net_update_ipv4(struct net_socket_domain *h);
|
||||
|
||||
int net_init_serial(void);
|
||||
void net_deinit_serial(void);
|
||||
struct net_socket_domain *net_server_serial(const union net_server *srv);
|
||||
struct net_socket_domain *net_connect_serial(const union net_connect *c);
|
||||
int net_read_serial(struct net_socket_domain *h, void *buf, size_t n);
|
||||
int net_write_serial(struct net_socket_domain *h, const void *buf, size_t n);
|
||||
int net_close_serial(struct net_socket_domain *h);
|
||||
int net_update_serial(struct net_socket_domain *h);
|
||||
|
||||
#endif /* NET_PRIVATE_H */
|
|
@ -0,0 +1,12 @@
|
|||
#include <net.h>
|
||||
|
||||
const char *net_domain_str(const enum net_domain d)
|
||||
{
|
||||
static const char *const s[] =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = "UDP/IPv4",
|
||||
[NET_DOMAIN_SERIAL] = "Serial"
|
||||
};
|
||||
|
||||
return s[d];
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
#include <net.h>
|
||||
#include <net_private.h>
|
||||
#include <enet/enet.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct net_socket_domain
|
||||
{
|
||||
ENetHost *host;
|
||||
ENetPeer *peers;
|
||||
void (*on_connected)(void *arg);
|
||||
void (*on_disconnected)(void *arg);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CHANNEL,
|
||||
MAX_CHANNELS
|
||||
};
|
||||
|
||||
struct net_socket_domain *net_connect_ipv4(const union net_connect *const c)
|
||||
{
|
||||
struct net_socket_domain *const s = calloc(1, sizeof *s);
|
||||
|
||||
if (!s)
|
||||
goto failure;
|
||||
|
||||
s->on_connected = c->common.on_connected;
|
||||
s->on_disconnected = c->common.on_disconnected;
|
||||
s->arg = c->common.arg;
|
||||
s->host = enet_host_create(NULL, 1, MAX_CHANNELS, 0, 0);
|
||||
|
||||
if (!s->host)
|
||||
{
|
||||
fprintf(stderr, "%s: enet_host_create failed\n", __func__);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ENetAddress addr;
|
||||
|
||||
if (enet_address_set_host(&addr, c->ipv4.addr))
|
||||
{
|
||||
fprintf(stderr, "%s: enet_address_set_host failed\n", __func__);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
addr.port = c->ipv4.port;
|
||||
|
||||
if (!(s->peers = enet_host_connect(s->host, &addr, MAX_CHANNELS, 0)))
|
||||
{
|
||||
fprintf(stderr, "%s: enet_host_connect failed\n", __func__);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
failure:
|
||||
|
||||
if (s && s->host)
|
||||
enet_host_destroy(s->host);
|
||||
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_read_ipv4(struct net_socket_domain *const s, void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_write_ipv4(struct net_socket_domain *const s, const void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_close_ipv4(struct net_socket_domain *const s)
|
||||
{
|
||||
if (s && s->host)
|
||||
enet_host_destroy(s->host);
|
||||
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int net_update_ipv4(struct net_socket_domain *const s)
|
||||
{
|
||||
int res;
|
||||
ENetEvent ev;
|
||||
|
||||
while ((res = enet_host_service(s->host, &ev, 0)) > 0)
|
||||
{
|
||||
switch (ev.type)
|
||||
{
|
||||
case ENET_EVENT_TYPE_CONNECT:
|
||||
if (s->on_connected)
|
||||
s->on_connected(s->arg);
|
||||
|
||||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
if (s->on_disconnected)
|
||||
s->on_disconnected(s->arg);
|
||||
|
||||
case ENET_EVENT_TYPE_RECEIVE:
|
||||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: enet_host_service failed\n", __func__);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_server_ipv4(const union net_server *const srv)
|
||||
{
|
||||
struct net_socket_domain *const s = calloc(1, sizeof *s);
|
||||
|
||||
if (!s)
|
||||
goto failure;
|
||||
|
||||
const ENetAddress addr =
|
||||
{
|
||||
.port = srv->ipv4.port
|
||||
};
|
||||
|
||||
s->host = enet_host_create(&addr, srv->common.max_players,
|
||||
MAX_CHANNELS, 0, 0);
|
||||
|
||||
if (!s->host)
|
||||
{
|
||||
fprintf(stderr, "%s: enet_host_create failed\n", __func__);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
failure:
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init_ipv4(void)
|
||||
{
|
||||
return enet_initialize();
|
||||
}
|
||||
|
||||
void net_deinit_ipv4(void)
|
||||
{
|
||||
enet_deinitialize();
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
#include <net.h>
|
||||
#include <net_private.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct net_socket *net_connect(const union net_connect *const c)
|
||||
{
|
||||
struct net_socket *const s = calloc(1, sizeof *s);
|
||||
|
||||
if (!s)
|
||||
goto failure;
|
||||
|
||||
static struct net_socket_domain *(*const f[])(const union net_connect *) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_connect_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_connect_serial
|
||||
};
|
||||
|
||||
if (!(s->s = f[c->common.domain](c)))
|
||||
goto failure;
|
||||
|
||||
return s;
|
||||
|
||||
failure:
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_read(struct net_socket *const s, void *const buf, const size_t n)
|
||||
{
|
||||
static int (*const f[])(struct net_socket_domain *, void *, size_t) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_read_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_read_serial
|
||||
};
|
||||
|
||||
return f[s->d](s->s, buf, n);
|
||||
}
|
||||
|
||||
int net_write(struct net_socket *const s, const void *const buf, const size_t n)
|
||||
{
|
||||
static int (*const f[])(struct net_socket_domain *, const void *, size_t) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_write_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_write_serial
|
||||
};
|
||||
|
||||
return f[s->d](s->s, buf, n);
|
||||
}
|
||||
|
||||
int net_close(struct net_socket *const s)
|
||||
{
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
static int (*const f[])(struct net_socket_domain *) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_close_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_close_serial
|
||||
};
|
||||
|
||||
const int res = f[s->d](s->s);
|
||||
|
||||
free(s);
|
||||
return res;
|
||||
}
|
||||
|
||||
int net_update(struct net_socket *const s)
|
||||
{
|
||||
static int (*const f[])(struct net_socket_domain *) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_update_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_update_serial
|
||||
};
|
||||
|
||||
return f[s->d](s->s);
|
||||
}
|
||||
|
||||
struct net_socket *net_server(const union net_server *const srv)
|
||||
{
|
||||
struct net_socket *const s = calloc(1, sizeof *s);
|
||||
|
||||
if (!s)
|
||||
goto failure;
|
||||
|
||||
s->d = srv->common.domain;
|
||||
|
||||
static struct net_socket_domain *(*const f[])(const union net_server *) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_server_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_server_serial
|
||||
};
|
||||
|
||||
if (!(s->s = f[s->d](srv)))
|
||||
goto failure;
|
||||
|
||||
failure:
|
||||
net_close(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init(void)
|
||||
{
|
||||
return net_init_ipv4() || net_init_serial();
|
||||
}
|
||||
|
||||
void net_deinit(void)
|
||||
{
|
||||
net_deinit_ipv4();
|
||||
net_deinit_serial();
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#include <net.h>
|
||||
#include <net_private.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int net_read_serial(struct net_socket_domain *const h, void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_write_serial(struct net_socket_domain *const h, const void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_close_serial(struct net_socket_domain *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_update_serial(struct net_socket_domain *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_connect_serial(const union net_connect *const srv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_server_serial(const union net_server *const srv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init_serial(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_deinit_serial(void)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#include <net.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int net_read(struct net_socket *const h, void *const buf, const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_write(struct net_socket *const h, const void *const buf, const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_close(struct net_socket *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_update(struct net_socket *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct net_socket *net_connect(const union net_connect *const c)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct net_socket *net_server(const union net_server *const c)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void net_deinit(void)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#include <net.h>
|
||||
#include <net_private.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int net_read_serial(struct net_socket_domain *const h, void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_write_serial(struct net_socket_domain *const h, const void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_close_serial(struct net_socket_domain *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_update_serial(struct net_socket_domain *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_connect_serial(const union net_connect *const srv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_server_serial(const union net_server *const srv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init_serial(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_deinit_serial(void)
|
||||
{
|
||||
}
|
|
@ -56,6 +56,7 @@ UTIL_STATIC_ASSERT(!offsetof(struct peripheral_kbm, common),
|
|||
"unexpected offsetof for struct peripheral_kbm");
|
||||
|
||||
void peripheral_init(const struct peripheral_cfg *cfg, union peripheral *p);
|
||||
void peripheral_input_set(union peripheral *p, void (*cb)(char, void *));
|
||||
void peripheral_update(union peripheral *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -11,6 +11,7 @@ target_link_libraries(player
|
|||
gfx
|
||||
keyboard
|
||||
instance
|
||||
input
|
||||
mouse
|
||||
pad
|
||||
resource
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <camera.h>
|
||||
#include <keyboard.h>
|
||||
#include <instance.h>
|
||||
#include <input.h>
|
||||
#include <mouse.h>
|
||||
#include <pad.h>
|
||||
#include <peripheral.h>
|
||||
|
@ -32,6 +33,7 @@ struct human_player
|
|||
struct player pl;
|
||||
struct camera cam;
|
||||
union peripheral periph;
|
||||
struct input in;
|
||||
|
||||
struct sel_instance
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <gfx.h>
|
||||
#include <gui.h>
|
||||
#include <instance.h>
|
||||
#include <input.h>
|
||||
#include <keyboard.h>
|
||||
#include <pad.h>
|
||||
#include <resource.h>
|
||||
|
@ -542,26 +543,28 @@ static void update_target(struct human_player *const h)
|
|||
static void update_from_pad(struct human_player *const h,
|
||||
struct player_others *const o)
|
||||
{
|
||||
struct pad *const p = &h->periph.pad.pad;
|
||||
const struct pad *const p = &h->periph.pad.pad;
|
||||
const struct input *const in = &h->in;
|
||||
|
||||
if (pad_justpressed(p, PAD_KEY_A))
|
||||
if (input_pad_justpressed(in, p, PAD_KEY_A))
|
||||
select_instances(h, o, false, false);
|
||||
else if (pad_justpressed(p, PAD_KEY_B))
|
||||
else if (input_pad_justpressed(in, p, PAD_KEY_B))
|
||||
move_units(h, o);
|
||||
else if (pad_justpressed(p, PAD_KEY_C))
|
||||
else if (input_pad_justpressed(in, p, PAD_KEY_C))
|
||||
deselect_instances(h);
|
||||
else if (pad_justpressed(p, PAD_KEY_E))
|
||||
else if (input_pad_justpressed(in, p, PAD_KEY_E))
|
||||
h->top_gui ^= true;
|
||||
}
|
||||
|
||||
static void update_from_touch(struct human_player *const h,
|
||||
struct player_others *const o)
|
||||
{
|
||||
struct mouse *const m = &h->periph.kbm.mouse;
|
||||
const struct mouse *const m = &h->periph.kbm.mouse;
|
||||
const struct input *const in = &h->in;
|
||||
struct peripheral_kbm *const kbm = &h->periph.kbm;
|
||||
bool *const pan = &h->cam.pan;
|
||||
|
||||
if (mouse_pressed(m, MOUSE_BUTTON_LEFT) && !*pan)
|
||||
if (input_mouse_pressed(in, m, MOUSE_BUTTON_LEFT) && !*pan)
|
||||
{
|
||||
enum {LONG_PRESS_THRESHOLD = 30};
|
||||
|
||||
|
@ -573,7 +576,7 @@ static void update_from_touch(struct human_player *const h,
|
|||
deselect_instances(h);
|
||||
}
|
||||
}
|
||||
else if (mouse_justreleased(m, MOUSE_BUTTON_LEFT))
|
||||
else if (input_mouse_justreleased(in, m, MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
if (!*pan && !select_instances(h, o, false, true))
|
||||
move_units(h, o);
|
||||
|
@ -587,19 +590,22 @@ static void update_from_touch(struct human_player *const h,
|
|||
static void update_from_keyboard_mouse(struct human_player *const h,
|
||||
struct player_others *const o)
|
||||
{
|
||||
struct mouse *const m = &h->periph.kbm.mouse;
|
||||
struct keyboard *const k = &h->periph.kbm.keyboard;
|
||||
const struct mouse *const m = &h->periph.kbm.mouse;
|
||||
const struct keyboard *const k = &h->periph.kbm.keyboard;
|
||||
const struct input *const in = &h->in;
|
||||
|
||||
if (mouse_justreleased(m, MOUSE_BUTTON_LEFT))
|
||||
if (input_mouse_justreleased(in, m, MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
const bool shift_pressed =
|
||||
keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_LSHIFT))
|
||||
|| keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_RSHIFT));
|
||||
input_keyboard_pressed(in, k,
|
||||
&KEYBOARD_COMBO(KEYBOARD_KEY_LSHIFT))
|
||||
|| input_keyboard_pressed(in, k,
|
||||
&KEYBOARD_COMBO(KEYBOARD_KEY_RSHIFT));
|
||||
|
||||
if (!select_instances(h, o, !shift_pressed, false))
|
||||
deselect_instances(h);
|
||||
}
|
||||
else if (mouse_justreleased(m, MOUSE_BUTTON_RIGHT))
|
||||
else if (input_mouse_justreleased(in, m, MOUSE_BUTTON_RIGHT))
|
||||
move_units(h, o);
|
||||
}
|
||||
|
||||
|
@ -614,6 +620,7 @@ void human_player_update(struct human_player *const h,
|
|||
update_selected(h);
|
||||
update_target(h);
|
||||
peripheral_update(&h->periph);
|
||||
input_update(&h->in, &h->periph);
|
||||
|
||||
switch (h->periph.common.type)
|
||||
{
|
||||
|
@ -630,7 +637,7 @@ void human_player_update(struct human_player *const h,
|
|||
break;
|
||||
}
|
||||
|
||||
camera_update(&h->cam, &h->periph);
|
||||
camera_update(&h->cam, &h->periph, &h->in);
|
||||
player_update(p);
|
||||
}
|
||||
}
|
||||
|
@ -702,7 +709,8 @@ int human_player_render(const struct human_player *const h,
|
|||
|| render_own_units(h)
|
||||
|| render_own_buildings(h)
|
||||
|| render_resources(h, o->res, o->n_res)
|
||||
|| human_player_gui_render(h))
|
||||
|| human_player_gui_render(h)
|
||||
|| input_render(&h->in, &h->periph))
|
||||
return -1;
|
||||
|
||||
switch (h->periph.common.type)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
set(inc "inc")
|
||||
set(privdeps gfx sfx)
|
||||
set(privdeps gfx sfx net)
|
||||
|
||||
if(PS1_BUILD)
|
||||
set(src "ps1/src/init.c")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <gfx.h>
|
||||
#include <net.h>
|
||||
#include <sfx.h>
|
||||
#include <system.h>
|
||||
#include <psx.h>
|
||||
|
@ -20,13 +21,14 @@ void system_deinit(void)
|
|||
{
|
||||
gfx_deinit();
|
||||
sfx_deinit();
|
||||
net_deinit();
|
||||
}
|
||||
|
||||
int system_init(void)
|
||||
{
|
||||
SetVBlankHandler(vblank);
|
||||
|
||||
if (gfx_init() || sfx_init())
|
||||
if (gfx_init() || sfx_init() || net_init())
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <gfx.h>
|
||||
#include <sfx.h>
|
||||
#include <net.h>
|
||||
#include <system.h>
|
||||
#include <SDL.h>
|
||||
#include <stdio.h>
|
||||
|
@ -19,6 +20,7 @@ void system_deinit(void)
|
|||
{
|
||||
gfx_deinit();
|
||||
sfx_deinit();
|
||||
net_deinit();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
|
@ -29,7 +31,7 @@ int system_init(void)
|
|||
fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
|
||||
goto failure;
|
||||
}
|
||||
else if (gfx_init() || sfx_init())
|
||||
else if (gfx_init() || sfx_init() || net_init())
|
||||
goto failure;
|
||||
|
||||
SDL_WM_SetCaption("rts", NULL);
|
||||
|
|
Loading…
Reference in New Issue