Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
8eea35c
Implement multiplayer mode with Player 2 controls, including keyboard…
dhiegosilva Nov 11, 2025
a88017d
Refine multiplayer mode setup: Ensure Guards are only activated if al…
dhiegosilva Nov 11, 2025
cbff0c5
Enhance Player 2 control handling in multiplayer mode: Implement sing…
dhiegosilva Nov 11, 2025
3a81465
Enhance multiplayer controls: Update Player 2's action key from Space…
dhiegosilva Nov 11, 2025
a6313fa
Enhance multiplayer sword mechanics: Implement control state manageme…
dhiegosilva Nov 12, 2025
7ad7afb
Refine control state management for Player 2: Enhance handling of con…
dhiegosilva Nov 12, 2025
a857dea
Enhance Player 2 control management in multiplayer mode: Refine handl…
dhiegosilva Nov 12, 2025
41df80a
Github workflow pipeline
dhiegosilva Nov 14, 2025
3f0d80b
Merge pull request #1 from dhiegosilva/add-workflow-to-master
dhiegosilva Nov 14, 2025
0ada517
Fix release workflow: only trigger on published releases and fix file…
dhiegosilva Nov 14, 2025
f060333
Merge pull request #2 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
68abe68
Fix Windows build: use MSYS2 shell for DLL paths
dhiegosilva Nov 14, 2025
4efd1f5
Merge pull request #3 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
f402b4f
Add verification steps and fix binary path: prevent build failures wi…
dhiegosilva Nov 14, 2025
53f4be6
Merge pull request #4 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
3132a47
Fix AppImage rename and Windows zip nesting issues
dhiegosilva Nov 14, 2025
85d4962
Merge pull request #5 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
84c0a14
Fix Windows build: install zip package in MSYS2
dhiegosilva Nov 14, 2025
0d11dca
Merge pull request #6 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
4883734
Enhance GitHub Actions workflow: Add 32-bit Windows and ARM64 Linux b…
dhiegosilva Nov 14, 2025
5b6bb40
Merge pull request #7 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
ca465c8
Enhance GitHub Actions workflow: Add ARM32 and ARM64 build jobs, impl…
dhiegosilva Nov 14, 2025
4b50ad0
Merge pull request #8 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
30f9a0e
Fix Windows 32-bit build: Remove non-existent SDL2_image package, bui…
dhiegosilva Nov 14, 2025
9934c9a
Merge pull request #9 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
66559ba
Fix ARM64 and Windows 32-bit builds: Unset PKG_CONFIG to prevent pack…
dhiegosilva Nov 14, 2025
f8f2502
Merge pull request #10 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
5faf22e
Fix Linux 32-bit and Windows 32-bit builds: Build SDL2 from source fo…
dhiegosilva Nov 14, 2025
6367174
Merge pull request #11 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 14, 2025
77cff82
Remove Windows x86 (32-bit) and Linux AppImage 32-bit build jobs
dhiegosilva Nov 15, 2025
6cc6484
Merge pull request #12 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 15, 2025
f0ac26a
Fix Windows 32-bit build: Update workflow to correctly handle SDL2_im…
dhiegosilva Nov 18, 2025
ece8e8f
Merge pull request #13 from dhiegosilva/fix-workflow-paths
dhiegosilva Nov 19, 2025
0e308d7
Enhance release workflow: Add curl for better plugin download handlin…
dhiegosilva Nov 22, 2025
2b17d55
Merge pull request #14 from dhiegosilva/actions
dhiegosilva Nov 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
746 changes: 746 additions & 0 deletions .github/workflows/release.yml

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,19 @@ src/*_private.*
.idea/
src/.idea/
src/cmake-build*/

# Build directories (anywhere in the project)
build/
**/build/
**/build-*/
**/cmake-build*/
**/out/
**/bin/
**/obj/
**/Debug/
**/Release/
**/x64/
**/x86/

# Visual Studio
.vs/
Expand Down Expand Up @@ -88,3 +100,24 @@ screenshots/

# Configuration file generated by the in-game settings menu
*.cfg

# Temporary build tools and installers (specific files)
7z.exe
vs_buildtools.exe
setup_and_build.ps1
install_build_tools.ps1
BUILD_STATUS.md

# Downloaded dependencies
SDL2-*/
mingw/
mingw_temp/
SDL2_temp/

# CMake generated files (additional patterns)
**/CMakeCache.txt
**/CMakeFiles/
**/cmake_install.cmake
**/Makefile
**/*.cmake
!**/CMakeLists.txt
170 changes: 170 additions & 0 deletions MULTIPLAYER_ANALYSIS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Multiplayer 1v1 Implementation Analysis

## Complexity Assessment: **MODERATE** (3-4 weeks of development)

## Current Architecture

### ✅ What's Already in Place:
1. **Character System**: The game already has `Kid` (player) and `Guard` (opponent) as separate `char_type` structures
2. **Dual Character Processing**: The game loop already processes both characters:
- `play_kid_frame()` - handles Kid
- `play_guard_frame()` - handles Guard (currently AI-controlled)
3. **Input System**: SDL2 already supports multiple gamepads/controllers
4. **Control Functions**: The `control()` function works for any character when `Char` is set appropriately
5. **Sword Fighting**: The combat system already supports two characters fighting

### ❌ What Needs to Be Added:

## Implementation Requirements

### 1. **Input System Extension** (Medium Complexity)
- **Current**: Single set of control variables (`control_x`, `control_y`, `control_shift`, etc.)
- **Needed**: Second set for Player 2 (`control_x_p2`, `control_y_p2`, etc.)
- **Location**: `src/data.h` - add new control variables
- **Files to modify**:
- `src/data.h` - add Player 2 control variables
- `src/seg000.c` - `read_keyb_control()` and `read_joyst_control()` functions
- `src/seg009.c` - `process_events()` for second controller detection

### 2. **Multiplayer Mode Flag** (Low Complexity)
- **Add**: `is_multiplayer_mode` boolean flag
- **Location**: `src/data.h`
- **Usage**: Check this flag to determine if Guard should use AI or Player 2 input

### 3. **Guard Control Modification** (Medium Complexity)
- **Current**: `play_guard()` calls `autocontrol_opponent()` (AI)
- **Needed**: In multiplayer mode, call `user_control_p2()` instead
- **Location**: `src/seg006.c` - `play_guard()` function
- **Implementation**:
```c
if (is_multiplayer_mode) {
user_control_p2(); // Player 2 controls Guard
} else {
autocontrol_opponent(); // AI controls Guard
}
```

### 4. **Player 2 Input Function** (Medium Complexity)
- **Create**: `user_control_p2()` function (similar to `user_control()`)
- **Location**: `src/seg006.c`
- **Logic**:
- Set `Char = Guard` (temporarily)
- Read Player 2 controls into the control variables
- Call `control()`
- Restore `Char`

### 5. **Initialization** (Low-Medium Complexity)
- **Add**: Function to initialize multiplayer mode
- **Location**: `src/seg003.c` - `init_game()` or new function
- **Tasks**:
- Spawn Kid and Guard facing each other
- Set both characters to active state
- Initialize both with swords drawn (optional)
- Set starting positions

### 6. **Menu Integration** (Low Complexity)
- **Add**: Menu option to select "Multiplayer 1v1" mode
- **Location**: `src/menu.c` (if menu system is used) or title screen
- **Alternative**: Command-line argument like `prince multiplayer`

### 7. **Controller Assignment** (Low-Medium Complexity)
- **Detect**: Second controller automatically, or allow manual assignment
- **Fallback**: If only one controller, use keyboard for Player 1, controller for Player 2
- **Location**: `src/seg009.c` - controller initialization

## Code Changes Summary

### Files to Modify:

1. **src/data.h**
- Add Player 2 control variables
- Add `is_multiplayer_mode` flag

2. **src/seg000.c**
- Modify `read_user_control()` to read Player 2 input
- Add `read_user_control_p2()` function

3. **src/seg006.c**
- Modify `play_guard()` to check multiplayer mode
- Add `user_control_p2()` function

4. **src/seg003.c**
- Add multiplayer initialization function
- Modify `init_game()` or `play_level()` to support multiplayer

5. **src/seg009.c**
- Enhance controller detection for multiple controllers
- Add keyboard mapping for Player 2 (WASD or separate keys)

6. **src/config.h** (optional)
- Add `USE_MULTIPLAYER` compile-time flag

7. **src/proto.h**
- Add function declarations for multiplayer functions

## Estimated Implementation Steps

### Phase 1: Core Infrastructure (1 week)
1. Add Player 2 control variables to `data.h`
2. Create `read_user_control_p2()` function
3. Add `is_multiplayer_mode` flag
4. Test input reading for both players

### Phase 2: Guard Control (1 week)
1. Create `user_control_p2()` function
2. Modify `play_guard()` to use Player 2 input in multiplayer mode
3. Test that Guard responds to Player 2 input

### Phase 3: Initialization & Setup (1 week)
1. Create multiplayer initialization function
2. Set up starting positions (players facing each other)
3. Add menu/command-line option to start multiplayer
4. Handle controller assignment

### Phase 4: Polish & Testing (1 week)
1. Test all game mechanics in multiplayer
2. Fix any bugs with collision, sword fighting, etc.
3. Add UI indicators (optional: "Player 1" / "Player 2" labels)
4. Ensure single-player mode is unaffected

## Potential Challenges

1. **Input Conflicts**: Need to ensure Player 2 input doesn't interfere with Player 1
2. **Character State**: The `Char` and `Opp` globals are used throughout - need careful management
3. **Room Transitions**: Both players need to be handled when changing rooms
4. **Win Conditions**: Define what happens when one player dies in multiplayer
5. **Replay System**: May need to handle multiplayer replays differently

## Advantages of Current Architecture

✅ **Good News**:
- The game already processes two characters per frame
- Sword fighting system already supports two combatants
- Input system is modular and can be extended
- Character control logic is reusable (`control()` function)
- SDL2 natively supports multiple controllers

## Complexity Rating Breakdown

- **Input System**: ⭐⭐⭐ (Medium) - Need to handle two input sources
- **Control Logic**: ⭐⭐ (Low-Medium) - Mostly reusing existing code
- **Initialization**: ⭐⭐ (Low-Medium) - Straightforward setup
- **Testing**: ⭐⭐⭐⭐ (High) - Need to test all game mechanics
- **Integration**: ⭐⭐ (Low-Medium) - Well-isolated changes

## Recommendation

**This is very feasible!** The architecture is well-suited for this addition. The main work is:
1. Duplicating the input reading system for Player 2
2. Replacing AI control with Player 2 input in multiplayer mode
3. Adding initialization and menu options

The single-player experience can remain completely unchanged by using a compile-time or runtime flag.

## Next Steps

Would you like me to:
1. Start implementing the multiplayer mode?
2. Create a detailed implementation plan with code examples?
3. Begin with a specific phase (e.g., input system first)?

57 changes: 46 additions & 11 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.5)
project(SDLPoP)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c99")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration")

# Add optimization flags for release builds
if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug"))
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -ffast-math -funroll-loops")
# Additional optimizations
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
# Link-time optimization for better performance (optional, may not work with all toolchains)
# Check if compiler supports LTO before enabling
include(CheckCCompilerFlag)
check_c_compiler_flag("-flto" COMPILER_SUPPORTS_LTO)
if(COMPILER_SUPPORTS_LTO)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
endif()
endif()

# have CMake output binaries to the directory that contains the source files
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${SDLPoP_SOURCE_DIR}/..")

# SDLPoP requires the SDL2 and SDL2_image development libraries.
# You can pass the SDL2 location to CMake like so: -DSDL2="C:/work/libraries/SDL2-2.0.8"
# You can pass the SDL2 location to CMake like so: -DSDL2="C:/work/libraries/SDL2-2.30.0"
# Or alternatively, specify the SDL2 location below:

#set(SDL2 "C:/work/libraries/SDL2-2.0.8")
#set(SDL2 "C:/work/libraries/SDL2-2.30.0")

# On macOS, if you used Homebrew to install SDL2, the location may be something like this:

Expand All @@ -39,18 +54,38 @@ if (WIN32)
# If the location of SDL2 is not specified, we will try to guess it.
if (NOT(DEFINED SDL2))
cmake_policy(SET CMP0015 NEW) # suppress warning about relative paths
set(SDL2 "../../SDL2-2.0.8")
# Try MSYS2 installation first (common on Windows)
if(EXISTS "C:/msys64/mingw64")
set(SDL2 "C:/msys64/mingw64")
set(USE_MSYS2_SDL2 TRUE)
elseif(EXISTS "../../SDL2-2.30.0")
set(SDL2 "../../SDL2-2.30.0")
set(USE_MSYS2_SDL2 FALSE)
else()
message(FATAL_ERROR "SDL2 not found. Please install SDL2 via MSYS2 (pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_image) or set SDL2 variable.")
endif()
else()
set(USE_MSYS2_SDL2 FALSE)
endif()

# Automatically detect whether we need the x86 or x64 version of the SDL2 library.
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(SDL2_ARCH "x86_64-w64-mingw32")
if(USE_MSYS2_SDL2)
# MSYS2 installation - headers are in include/SDL2 subdirectory
include_directories(${SDL2}/include)
include_directories(${SDL2}/include/SDL2)
link_directories(${SDL2}/lib)
else()
set(SDL2_ARCH "i686-w64-mingw32")
# SDL2 development package - use architecture-specific paths
# Automatically detect whether we need the x86 or x64 version of the SDL2 library.
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(SDL2_ARCH "x86_64-w64-mingw32")
else()
set(SDL2_ARCH "i686-w64-mingw32")
endif()

include_directories(${SDL2}/${SDL2_ARCH}/include)
include_directories(${SDL2}/${SDL2_ARCH}/include/SDL2)
link_directories(${SDL2}/${SDL2_ARCH}/lib)
endif()

include_directories(${SDL2}/${SDL2_ARCH}/include)
link_directories(${SDL2}/${SDL2_ARCH}/lib)
endif()

set(SOURCE_FILES
Expand Down
75 changes: 0 additions & 75 deletions src/build.bat

This file was deleted.

Loading