diff --git a/.github/workflows/doxygen-gh-pages.yml b/.github/workflows/doxygen-gh-pages.yml index 6de4b2145..c295a0685 100644 --- a/.github/workflows/doxygen-gh-pages.yml +++ b/.github/workflows/doxygen-gh-pages.yml @@ -34,11 +34,10 @@ jobs: sudo apt-get install doxygen -y shell: bash - - name: "Build Doxygen Doc" + - name: "Build Doxygen Doc with CMake" run: | - cd pvsneslib - export PVSNESLIB_HOME=`pwd` - make docs + cmake -B build -DPVSNESLIB_BUILD_DOCS=ON + cmake --build build --target docs shell: bash # 3. Dรฉploiement sur les Github Pages diff --git a/.github/workflows/pvsneslib_build_package.yml b/.github/workflows/pvsneslib_build_package.yml index b5d22ac6a..0d6fe1996 100644 --- a/.github/workflows/pvsneslib_build_package.yml +++ b/.github/workflows/pvsneslib_build_package.yml @@ -78,23 +78,10 @@ jobs: # ------------------------------------ # # Compiling sources and create release # # ------------------------------------ # - - name: Build & Release PVSNESLIB for Linux - if: (matrix.name == 'linux') + - name: Build & Release PVSNESLIB with CMake run: | - export PVSNESLIB_HOME=$(pwd) - make release | tee pvsneslib_release_${{ matrix.name }}.log - - name: Build & Release PVSNESLIB for Windows - if: (matrix.name == 'windows') - shell: msys2 {0} - run: | - export PVSNESLIB_HOME=$(pwd) - make release | tee pvsneslib_release_${{ matrix.name }}.log - - name: Build & Release PVSNESLIB for MacOS - if: (matrix.name == 'darwin') - run: | - export PVSNESLIB_HOME=$(pwd) - export PATH="/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH" - make release | tee pvsneslib_release_${{ matrix.name }}.log + cmake -B build -DPVSNESLIB_BUILD_EXAMPLES=ON -DPVSNESLIB_AUTO_SUBMODULES=ON + cmake --build build --target release | tee pvsneslib_release_${{ matrix.name }}.log # ------------------------------------ # # Checking libraries linking # @@ -115,7 +102,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: PVSNESLIB Release for ${{ matrix.name }} - path: release/pvsneslib_64b_${{ matrix.name }}.zip + path: release/pvsneslib_*_${{ matrix.name }}.tar.gz # ------------------------------------ # # Upload releases # diff --git a/.gitignore b/.gitignore index 64c1276a1..bea9b36d8 100644 --- a/.gitignore +++ b/.gitignore @@ -74,4 +74,13 @@ soundbank.h *.dbg # Mac OS cache files -.DS_Store \ No newline at end of file +.DS_Store + +# CMake build directory +build/ + +# Release directory +release/ + +# CMake generated files +pvsneslib/source/comp_defs.asm diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..a3dd2f343 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,237 @@ +cmake_minimum_required(VERSION 3.16) +project(PVSnesLib VERSION 4.4.0 LANGUAGES C CXX) + +# Set C standard +set(CMAKE_C_STANDARD 90) +set(CMAKE_C_STANDARD_REQUIRED ON) + +# Set C++ standard for tools that need it +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Pure CMake build system - no Make dependencies +option(PVSNESLIB_BUILD_EXAMPLES "Build SNES examples" ON) +option(PVSNESLIB_AUTO_SUBMODULES "Automatically initialize submodules" ON) +option(PVSNESLIB_BUILD_DOCS "Build documentation (requires Doxygen)" ON) + +# Set PVSNESLIB_HOME - support both environment variable and local builds +if(DEFINED ENV{PVSNESLIB_HOME}) + set(PVSNESLIB_HOME $ENV{PVSNESLIB_HOME} CACHE PATH "PVSnesLib home directory") + message(STATUS "Using PVSNESLIB_HOME from environment: ${PVSNESLIB_HOME}") +else() + set(PVSNESLIB_HOME ${CMAKE_SOURCE_DIR} CACHE PATH "PVSnesLib home directory") + message(STATUS "Using local PVSnesLib build: ${PVSNESLIB_HOME}") +endif() + +# Platform detection (mirroring existing Makefile logic) +if(WIN32) + set(PVSNESLIB_OS "windows") +elseif(CMAKE_SYSTEM_NAME MATCHES "MINGW") + set(PVSNESLIB_OS "mingw") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(PVSNESLIB_OS "darwin") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(PVSNESLIB_OS "linux") +elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(PVSNESLIB_OS "freebsd") +else() + message(FATAL_ERROR "Unsupported operating system: ${CMAKE_SYSTEM_NAME}") +endif() + +# Architecture detection (improved over hardcoded 64b) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64") + set(PVSNESLIB_ARCH "arm64") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") + set(PVSNESLIB_ARCH "x64") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686") + set(PVSNESLIB_ARCH "x86") +else() + # Fallback to original naming for unknown architectures + set(PVSNESLIB_ARCH "64b") +endif() + +message(STATUS "Building PVSnesLib for: ${PVSNESLIB_ARCH}_${PVSNESLIB_OS}") +message(STATUS "PVSnesLib home: ${PVSNESLIB_HOME}") +message(STATUS "Detected architecture: ${CMAKE_SYSTEM_PROCESSOR} โ†’ ${PVSNESLIB_ARCH}") + +message(STATUS "Using pure CMake build system") + +# Include ExternalProject for handling submodules +include(ExternalProject) + +# Add our CMake modules +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +# Automatically initialize and update submodules if requested +if(PVSNESLIB_AUTO_SUBMODULES) + message(STATUS "Synchronizing submodules to match superproject...") + + find_package(Git REQUIRED) + execute_process( + COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE GIT_RESULT + OUTPUT_VARIABLE GIT_OUTPUT + ERROR_VARIABLE GIT_ERROR + ) + + if(NOT GIT_RESULT EQUAL 0) + message(WARNING "Failed to synchronize submodules.") + message(WARNING "Please run manually: git submodule update --init --recursive") + message(WARNING "Git output: ${GIT_OUTPUT}") + message(WARNING "Git error: ${GIT_ERROR}") + else() + message(STATUS "Submodules synchronized successfully!") + endif() +endif() + +# Create directories that match existing structure +file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/devkitsnes/bin) +file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/devkitsnes/tools) + +# Add subdirectories in dependency order (matching existing Makefile) +add_subdirectory(compiler) +add_subdirectory(tools) +add_subdirectory(pvsneslib) + +if(PVSNESLIB_BUILD_EXAMPLES) + add_subdirectory(snes-examples) +endif() + + +# Documentation is handled in pvsneslib/CMakeLists.txt + +#============================================================================= +# ESSENTIAL TARGETS - Only 3 Things You Need +#============================================================================= + +# 1. Absolute minimum to write SNES programs and make ROMs +add_custom_target(minimal + DEPENDS compiler tools library + COMMENT "๐Ÿ”ง Minimal SNES development environment (compiler + tools + library only)" +) + +# 2. Build examples only (assumes minimal is already built) +add_custom_target(examples_only + DEPENDS examples audio_examples games_examples logo_examples sram_examples objects_examples input_examples advanced_examples + COMMENT "๐ŸŽฎ Build working SNES examples (40+ ROMs)" +) + +# 3. Build absolutely everything +add_custom_target(everything + DEPENDS compiler tools library examples audio_examples games_examples logo_examples sram_examples objects_examples input_examples advanced_examples + COMMENT "๐Ÿš€ Build everything (minimal + working examples)" +) + +# Note: Clean aliases (compiler, tools, library) are defined in their respective subdirectories + +#============================================================================= +# RELEASE SYSTEM - Complete Package Creation +#============================================================================= + +# Release target that matches and improves upon original Makefile release +add_custom_target(release + # Prerequisites: Build everything and generate documentation + DEPENDS everything docs + + # Create release directory structure + COMMAND ${CMAKE_COMMAND} -E remove_directory release + COMMAND ${CMAKE_COMMAND} -E make_directory release/pvsneslib + + # Copy core development tools (compiler and utilities) + COMMAND ${CMAKE_COMMAND} -E copy_directory devkitsnes release/ + + # Copy library components + COMMAND ${CMAKE_COMMAND} -E copy_directory pvsneslib/include release/pvsneslib + COMMAND ${CMAKE_COMMAND} -E copy_directory pvsneslib/lib release/pvsneslib + COMMAND ${CMAKE_COMMAND} -E copy_directory pvsneslib/docs/html release/pvsneslib + + # Copy library metadata and documentation + COMMAND ${CMAKE_COMMAND} -E copy pvsneslib/PVSnesLib_Logo.png release/pvsneslib/ + COMMAND ${CMAKE_COMMAND} -E copy pvsneslib/pvsneslib_license.txt release/pvsneslib/ + COMMAND ${CMAKE_COMMAND} -E copy pvsneslib/pvsneslib_snesmod.txt release/pvsneslib/ + COMMAND ${CMAKE_COMMAND} -E copy pvsneslib/pvsneslib_version.txt release/pvsneslib/ + + # Copy examples and CMake system for external projects + COMMAND ${CMAKE_COMMAND} -E copy_directory snes-examples release/snes-examples + COMMAND ${CMAKE_COMMAND} -E copy_directory cmake release/cmake + + # Create release archive with version and platform info + COMMAND ${CMAKE_COMMAND} -E chdir release tar czf pvsneslib_${PROJECT_VERSION}_${PVSNESLIB_ARCH}_${PVSNESLIB_OS}.tar.gz pvsneslib cmake + + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "๐Ÿš€ Creating PVSnesLib ${PROJECT_VERSION} release package for ${PVSNESLIB_ARCH}_${PVSNESLIB_OS}" + VERBATIM +) + +# Version information target +add_custom_target(version + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐ŸŽฎ PVSnesLib Version Information" + COMMAND ${CMAKE_COMMAND} -E echo "=================================" + COMMAND ${CMAKE_COMMAND} -E echo "Library Version: ${PROJECT_VERSION}" + COMMAND ${CMAKE_COMMAND} -E echo "Build Platform: ${PVSNESLIB_OS}" + COMMAND ${CMAKE_COMMAND} -E echo "Architecture: ${PVSNESLIB_ARCH}" + COMMAND ${CMAKE_COMMAND} -E echo "Release Name: pvsneslib_${PROJECT_VERSION}_${PVSNESLIB_ARCH}_${PVSNESLIB_OS}.tar.gz" + COMMAND ${CMAKE_COMMAND} -E echo "CMake Version: ${CMAKE_VERSION}" + COMMAND ${CMAKE_COMMAND} -E echo "Build Type: ${CMAKE_BUILD_TYPE}" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMENT "Display PVSnesLib version information" +) + +#============================================================================= +# CUSTOM HELP TARGET - User-Friendly Target Overview +#============================================================================= + +add_custom_target(guide + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐ŸŽฎ PVSnesLib - 3 Essential Targets" + COMMAND ${CMAKE_COMMAND} -E echo "==================================" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐Ÿ”ง 1. MINIMAL - Absolute minimum to write SNES programs:" + COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build --target minimal" + COMMAND ${CMAKE_COMMAND} -E echo " Result: C compiler + assembler + tools + library" + COMMAND ${CMAKE_COMMAND} -E echo " Use this: To write your own SNES programs" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐ŸŽฎ 2. EXAMPLES_ONLY - Build all example ROMs:" + COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build --target examples_only" + COMMAND ${CMAKE_COMMAND} -E echo " Result: 60+ example SNES ROMs" + COMMAND ${CMAKE_COMMAND} -E echo " Use this: To learn from existing examples" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐Ÿš€ 3. EVERYTHING - Build absolutely everything:" + COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build --target everything" + COMMAND ${CMAKE_COMMAND} -E echo " Result: Complete development environment + all examples" + COMMAND ${CMAKE_COMMAND} -E echo " Use this: For complete setup" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐Ÿ“‹ QUICK START:" + COMMAND ${CMAKE_COMMAND} -E echo " cmake -B build -DPVSNESLIB_BUILD_EXAMPLES=ON" + COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build --target everything" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐Ÿ“– 4. DOCUMENTATION - Generate API docs [requires Doxygen]:" + COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build --target docs" + COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build --target docspdf # HTML + PDF manual" + COMMAND ${CMAKE_COMMAND} -E echo " Result: HTML documentation in pvsneslib/docs/html/" + COMMAND ${CMAKE_COMMAND} -E echo " Use this: To browse the complete API reference" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐Ÿš€ 5. RELEASE - Create distribution package:" + COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build --target release" + COMMAND ${CMAKE_COMMAND} -E echo " Result: pvsneslib_${PROJECT_VERSION}_${PVSNESLIB_ARCH}_${PVSNESLIB_OS}.tar.gz" + COMMAND ${CMAKE_COMMAND} -E echo " Use this: To create release packages for distribution" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "โ„น๏ธ 6. VERSION INFO - Display version information:" + COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build --target version" + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "๐ŸŽฏ INDIVIDUAL COMPONENTS - if needed:" + COMMAND ${CMAKE_COMMAND} -E echo " compiler, tools, library, examples, hello_world, effects, etc." + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMENT "Displaying PVSnesLib essential targets" +) + +# Print build summary +message(STATUS "") +message(STATUS "PVSnesLib ${PROJECT_VERSION} build configuration:") +message(STATUS " OS: ${PVSNESLIB_OS}") +message(STATUS " Build examples: ${PVSNESLIB_BUILD_EXAMPLES}") +message(STATUS " Build docs: ${PVSNESLIB_BUILD_DOCS}") +message(STATUS " Install prefix: ${CMAKE_INSTALL_PREFIX}") +message(STATUS "") diff --git a/devkitsnes/bin/.keepme b/a similarity index 100% rename from devkitsnes/bin/.keepme rename to a diff --git a/cmake/SNESGame.cmake b/cmake/SNESGame.cmake new file mode 100644 index 000000000..680df7ce8 --- /dev/null +++ b/cmake/SNESGame.cmake @@ -0,0 +1,367 @@ +# Helper functions for building SNES games with PVSnesLib + +# Function to add a SNES game target +# Usage: add_snes_game(target_name +# SOURCES source1.c source2.c ... +# GRAPHICS sprite.png background.bmp ... +# AUDIO music.it sound.wav ... +# ROM_NAME output_name +# HIROM ON/OFF +# FASTROM ON/OFF +# ) +function(add_snes_game target_name) + cmake_parse_arguments(SNES + "HIROM;FASTROM" + "ROM_NAME;SOUNDBANK" + "SOURCES;GRAPHICS;AUDIO;ASM_SOURCES;DATA_FILES;AUDIO_FILES;INCLUDE_DIRS" + ${ARGN} + ) + + if(NOT SNES_ROM_NAME) + set(SNES_ROM_NAME ${target_name}) + endif() + + if(NOT SNES_SOURCES) + message(FATAL_ERROR "add_snes_game: No SOURCES specified for ${target_name}") + endif() + + # Determine library configuration + if(SNES_HIROM) + set(ROM_TYPE "HiROM") + set(TCC_HIROM_FLAG "-H") + else() + set(ROM_TYPE "LoROM") + set(TCC_HIROM_FLAG "") + endif() + + if(SNES_FASTROM) + set(ROM_SPEED "FastROM") + set(TCC_FASTROM_FLAG "-F") + else() + set(ROM_SPEED "SlowROM") + set(TCC_FASTROM_FLAG "") + endif() + + set(LIB_CONFIG "${ROM_TYPE}_${ROM_SPEED}") + + # Get PVSNESLIB_HOME - either from environment or parent project + if(DEFINED ENV{PVSNESLIB_HOME}) + set(PVSNESLIB_HOME_PATH $ENV{PVSNESLIB_HOME}) + elseif(DEFINED PVSNESLIB_HOME) + set(PVSNESLIB_HOME_PATH ${PVSNESLIB_HOME}) + else() + message(FATAL_ERROR "PVSNESLIB_HOME not found. Please set PVSNESLIB_HOME environment variable or ensure you're building within PVSnesLib source tree.") + endif() + + # Set up paths using PVSNESLIB_HOME + set(TCC_COMPILER "${PVSNESLIB_HOME_PATH}/devkitsnes/bin/816-tcc") + set(WLA_ASSEMBLER "${PVSNESLIB_HOME_PATH}/devkitsnes/bin/wla-65816") + set(WLA_LINKER "${PVSNESLIB_HOME_PATH}/devkitsnes/bin/wlalink") + set(OPTIMIZER "${PVSNESLIB_HOME_PATH}/devkitsnes/tools/816-opt") + set(CONSTIFY "${PVSNESLIB_HOME_PATH}/devkitsnes/tools/constify") + + set(LIB_DIR "${PVSNESLIB_HOME_PATH}/pvsneslib/lib/${LIB_CONFIG}") + + # Include directories + set(INCLUDE_DIRS + -I${PVSNESLIB_HOME_PATH}/pvsneslib/include + -I${PVSNESLIB_HOME_PATH}/devkitsnes/include + -I${CMAKE_CURRENT_SOURCE_DIR} + ) + + # Add additional include directories if specified + foreach(inc_dir ${SNES_INCLUDE_DIRS}) + list(APPEND INCLUDE_DIRS -I${CMAKE_CURRENT_SOURCE_DIR}/${inc_dir}) + endforeach() + + # Simplified path management - determine source directory from first source file + # Default to target name directory if no sources or source is in current dir + set(target_source_dir "${CMAKE_CURRENT_SOURCE_DIR}") + if(SNES_SOURCES) + list(GET SNES_SOURCES 0 first_source) + get_filename_component(source_dir ${first_source} DIRECTORY) + if(source_dir) + get_filename_component(target_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/${source_dir}" ABSOLUTE) + endif() + endif() + + # Validate that the source directory exists + if(NOT EXISTS "${target_source_dir}") + message(WARNING "Source directory ${target_source_dir} does not exist for target ${target_name}") + set(target_source_dir "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + # Convert graphics files + set(CONVERTED_GRAPHICS "") + foreach(gfx ${SNES_GRAPHICS}) + get_filename_component(gfx_name ${gfx} NAME_WE) + get_filename_component(gfx_ext ${gfx} EXT) + get_filename_component(gfx_full_name ${gfx} NAME) + get_filename_component(gfx_dir ${gfx} DIRECTORY) + + # Check if pre-converted files exist (including Mode7 formats) + set(existing_pic "${CMAKE_CURRENT_SOURCE_DIR}/${gfx_dir}/${gfx_name}.pic") + set(existing_pal "${CMAKE_CURRENT_SOURCE_DIR}/${gfx_dir}/${gfx_name}.pal") + set(existing_pc7 "${CMAKE_CURRENT_SOURCE_DIR}/${gfx_dir}/${gfx_name}.pc7") + set(existing_mp7 "${CMAKE_CURRENT_SOURCE_DIR}/${gfx_dir}/${gfx_name}.mp7") + + set(gfx_output "${target_name}_${gfx_full_name}.pic") + set(pal_output "${target_name}_${gfx_full_name}.pal") + + if(EXISTS ${existing_pc7} AND EXISTS ${existing_mp7}) + # Use existing Mode7 converted files + set(gfx_output "${target_name}_${gfx_full_name}.pc7") + set(pal_output "${target_name}_${gfx_full_name}.mp7") + add_custom_command(OUTPUT ${gfx_output} ${pal_output} + COMMAND ${CMAKE_COMMAND} -E copy ${existing_pc7} ${CMAKE_CURRENT_BINARY_DIR}/${gfx_output} + COMMAND ${CMAKE_COMMAND} -E copy ${existing_mp7} ${CMAKE_CURRENT_BINARY_DIR}/${pal_output} + DEPENDS ${existing_pc7} ${existing_mp7} + COMMENT "Using existing Mode7 graphics ${gfx_name}" + ) + elseif(EXISTS ${existing_pic} AND EXISTS ${existing_pal}) + # Use existing converted files + add_custom_command(OUTPUT ${gfx_output} ${pal_output} + COMMAND ${CMAKE_COMMAND} -E copy ${existing_pic} ${CMAKE_CURRENT_BINARY_DIR}/${gfx_output} + COMMAND ${CMAKE_COMMAND} -E copy ${existing_pal} ${CMAKE_CURRENT_BINARY_DIR}/${pal_output} + DEPENDS ${existing_pic} ${existing_pal} + COMMENT "Using existing converted graphics ${gfx_name}" + ) + elseif(gfx_ext STREQUAL ".png") + # PNG files - use gfx4snes - include full filename to avoid conflicts + get_filename_component(gfx_absolute ${CMAKE_CURRENT_SOURCE_DIR}/${gfx} ABSOLUTE) + get_filename_component(gfx_dir_abs ${gfx_absolute} DIRECTORY) + add_custom_command(OUTPUT ${gfx_output} ${pal_output} + COMMAND ${PVSNESLIB_HOME_PATH}/devkitsnes/tools/gfx4snes -s 8 -o 16 -u 16 -p -e 0 -i ${gfx_absolute} + COMMAND ${CMAKE_COMMAND} -E copy ${gfx_dir_abs}/${gfx_name}.pic ${CMAKE_CURRENT_BINARY_DIR}/${gfx_output} + COMMAND ${CMAKE_COMMAND} -E copy ${gfx_dir_abs}/${gfx_name}.pal ${CMAKE_CURRENT_BINARY_DIR}/${pal_output} + DEPENDS ${gfx_absolute} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Converting ${gfx} (PNG) to SNES format" + ) + elseif(gfx_ext STREQUAL ".bmp") + # BMP files - use gfx2snes (which properly supports BMP) - include full filename to avoid conflicts + get_filename_component(gfx_absolute ${CMAKE_CURRENT_SOURCE_DIR}/${gfx} ABSOLUTE) + get_filename_component(gfx_dir_abs ${gfx_absolute} DIRECTORY) + add_custom_command(OUTPUT ${gfx_output} ${pal_output} + COMMAND ${PVSNESLIB_HOME_PATH}/devkitsnes/tools/gfx2snes -pc16 -gs8 -pe0 -p -m -fbmp ${gfx_absolute} + COMMAND ${CMAKE_COMMAND} -E copy ${gfx_dir_abs}/${gfx_name}.pic ${CMAKE_CURRENT_BINARY_DIR}/${gfx_output} + COMMAND ${CMAKE_COMMAND} -E copy ${gfx_dir_abs}/${gfx_name}.pal ${CMAKE_CURRENT_BINARY_DIR}/${pal_output} + DEPENDS ${gfx_absolute} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Converting ${gfx} (BMP) to SNES format" + ) + endif() + list(APPEND CONVERTED_GRAPHICS ${gfx_output} ${pal_output}) + endforeach() + + # Convert audio files and generate soundbank + set(CONVERTED_AUDIO "") + set(SOUNDBANK_DEPS "") + if(SNES_AUDIO_FILES AND SNES_SOUNDBANK) + # Generate soundbank from IT files using smconv - make unique per target + get_filename_component(soundbank_name ${SNES_SOUNDBANK} NAME) + string(REPLACE "/" "_" soundbank_unique "${SNES_SOUNDBANK}") + set(soundbank_asm "${target_name}_${soundbank_unique}.asm") + set(soundbank_obj "${target_name}_${soundbank_unique}.obj") + set(soundbank_bnk "${target_name}_${soundbank_unique}.bnk") + set(soundbank_h "${target_name}_${soundbank_unique}.h") + + # Create smconv command with all audio files + set(SMCONV_CMD "${PVSNESLIB_HOME_PATH}/devkitsnes/tools/smconv") + set(SMCONV_ARGS "-s" "-o" "${SNES_SOUNDBANK}" "-V" "-b" "5") + + # Generate soundbank and copy object file to build directory in one step + set(unique_soundbank_obj "${CMAKE_CURRENT_BINARY_DIR}/${soundbank_obj}") + add_custom_command(OUTPUT ${unique_soundbank_obj} ${soundbank_asm} ${soundbank_bnk} ${soundbank_h} + COMMAND ${SMCONV_CMD} ${SMCONV_ARGS} ${SNES_AUDIO_FILES} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${SNES_SOUNDBANK}.obj ${unique_soundbank_obj} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${SNES_SOUNDBANK}.h ${target_source_dir}/soundbank.h + DEPENDS ${SNES_AUDIO_FILES} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Generating soundbank from ${SNES_AUDIO_FILES}" + ) + + list(APPEND SOUNDBANK_DEPS ${unique_soundbank_obj}) + list(APPEND CONVERTED_AUDIO ${soundbank_asm}) + list(APPEND OBJ_FILES ${unique_soundbank_obj}) + endif() + + # Legacy audio conversion for individual files + foreach(audio ${SNES_AUDIO}) + get_filename_component(audio_name ${audio} NAME_WE) + get_filename_component(audio_ext ${audio} EXT) + + if(audio_ext STREQUAL ".it" OR audio_ext STREQUAL ".mod") + set(audio_output "${audio_name}.bnk") + add_custom_command(OUTPUT ${audio_output} + COMMAND ${PVSNESLIB_HOME_PATH}/devkitsnes/tools/smconv ${audio} + DEPENDS ${audio} + COMMENT "Converting ${audio} to SNES format" + ) + list(APPEND CONVERTED_AUDIO ${audio_output}) + endif() + endforeach() + + # Handle data files (.dat files) - copy them to build directory + set(CONVERTED_DATA "") + foreach(data_file ${SNES_DATA_FILES}) + get_filename_component(data_name ${data_file} NAME) + set(data_output "${target_name}_${data_name}") + add_custom_command(OUTPUT ${data_output} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${data_file} ${data_output} + DEPENDS ${data_file} + COMMENT "Copying data file ${data_file}" + ) + list(APPEND CONVERTED_DATA ${data_output}) + endforeach() + + # Compile C sources to assembly + set(ASM_FILES "") + foreach(src ${SNES_SOURCES}) + get_filename_component(src_name ${src} NAME_WE) + # Make output files unique per target to avoid conflicts + set(ps_file "${target_name}_${src_name}.ps") + set(asm_file "${target_name}_${src_name}.asm") + set(obj_file "${target_name}_${src_name}.obj") + + # C -> .ps (intermediate) - use absolute paths + get_filename_component(src_absolute ${src} ABSOLUTE) + add_custom_command(OUTPUT ${ps_file} + COMMAND ${TCC_COMPILER} ${INCLUDE_DIRS} -Wall -c ${src_absolute} ${TCC_HIROM_FLAG} ${TCC_FASTROM_FLAG} -o ${ps_file} + DEPENDS ${src_absolute} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Compiling ${src} to .ps" + ) + + # .ps -> .asm (optimized) + add_custom_command(OUTPUT ${asm_file} + COMMAND ${OPTIMIZER} ${ps_file} > ${src_name}.asp + COMMAND ${CONSTIFY} ${src_absolute} ${src_name}.asp ${asm_file} + COMMAND ${CMAKE_COMMAND} -E remove ${src_name}.asp + DEPENDS ${ps_file} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Optimizing ${ps_file} to ${asm_file}" + ) + + # .asm -> .obj (copy necessary includes to build dir) + # Look for hdr.asm and data.asm using a helper function + function(find_asm_file filename result_var) + # First check in ASM_SOURCES list + foreach(asm_src ${SNES_ASM_SOURCES}) + get_filename_component(asm_name ${asm_src} NAME) + if(asm_name STREQUAL ${filename}) + get_filename_component(full_path "${CMAKE_CURRENT_SOURCE_DIR}/${asm_src}" ABSOLUTE) + if(EXISTS "${full_path}") + set(${result_var} "${full_path}" PARENT_SCOPE) + return() + endif() + endif() + endforeach() + + # Then check in target source directory + set(fallback_path "${target_source_dir}/${filename}") + if(EXISTS "${fallback_path}") + set(${result_var} "${fallback_path}" PARENT_SCOPE) + else() + message(WARNING "Required ASM file ${filename} not found for target ${target_name}") + set(${result_var} "${fallback_path}" PARENT_SCOPE) # Use anyway, might be generated + endif() + endfunction() + + find_asm_file("hdr.asm" hdr_asm_path) + find_asm_file("data.asm" data_asm_path) + + add_custom_command(OUTPUT ${obj_file} + COMMAND ${CMAKE_COMMAND} -E copy ${hdr_asm_path} ${CMAKE_CURRENT_BINARY_DIR}/hdr.asm + COMMAND ${CMAKE_COMMAND} -E copy ${data_asm_path} ${CMAKE_CURRENT_BINARY_DIR}/data.asm + COMMAND ${WLA_ASSEMBLER} -d -s -x -o ${obj_file} ${asm_file} + DEPENDS ${asm_file} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Assembling ${asm_file} to ${obj_file}" + ) + + list(APPEND ASM_FILES ${asm_file}) + list(APPEND OBJ_FILES ${obj_file}) + endforeach() + + # Handle additional ASM sources - make output files unique per target + foreach(asm ${SNES_ASM_SOURCES}) + get_filename_component(asm_name ${asm} NAME_WE) + get_filename_component(asm_absolute ${asm} ABSOLUTE) + get_filename_component(asm_dir ${asm_absolute} DIRECTORY) + set(obj_file "${target_name}_${asm_name}.obj") + + add_custom_command(OUTPUT ${obj_file} + COMMAND ${WLA_ASSEMBLER} -d -s -x -o ${CMAKE_CURRENT_BINARY_DIR}/${obj_file} ${asm_absolute} + DEPENDS ${asm_absolute} + WORKING_DIRECTORY ${asm_dir} + COMMENT "Assembling ${asm} to ${obj_file}" + ) + + list(APPEND OBJ_FILES ${obj_file}) + endforeach() + + # Create linkfile and link ROM + set(ROM_FILE "${target_source_dir}/${SNES_ROM_NAME}.sfc") + set(LINKFILE "${target_name}_linkfile") + set(SYM_FILE "${target_name}_${SNES_ROM_NAME}.sym") + + # Create linkfile generation script + set(LINKFILE_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/create_${target_name}_linkfile.cmake") + file(WRITE ${LINKFILE_SCRIPT} + "file(WRITE \"${LINKFILE}\" \"[objects]\\n\")\n" + ) + foreach(obj_file ${OBJ_FILES}) + file(APPEND ${LINKFILE_SCRIPT} + "file(APPEND \"${LINKFILE}\" \"${obj_file}\\n\")\n" + ) + endforeach() + # Add library objects + file(APPEND ${LINKFILE_SCRIPT} + "file(APPEND \"${LINKFILE}\" \"${LIB_DIR}/crt0_snes.obj\\n\")\n" + "file(APPEND \"${LINKFILE}\" \"${LIB_DIR}/libm.obj\\n\")\n" + "file(APPEND \"${LINKFILE}\" \"${LIB_DIR}/libtcc.obj\\n\")\n" + "file(APPEND \"${LINKFILE}\" \"${LIB_DIR}/libc.obj\\n\")\n" + ) + + add_custom_command(OUTPUT ${ROM_FILE} + # Create linkfile + COMMAND ${CMAKE_COMMAND} -P ${LINKFILE_SCRIPT} + + # Link ROM + COMMAND ${WLA_LINKER} -d -s -v -A -c -L ${LIB_DIR} ${LINKFILE} ${ROM_FILE} + + # Clean up + COMMAND ${CMAKE_COMMAND} -E remove ${LINKFILE} + + DEPENDS ${OBJ_FILES} ${CONVERTED_GRAPHICS} ${CONVERTED_AUDIO} ${CONVERTED_DATA} ${SOUNDBANK_DEPS} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Linking ${ROM_FILE}" + ) + + # Create the target + add_custom_target(${target_name} + DEPENDS ${ROM_FILE} + COMMENT "Building SNES game: ${SNES_ROM_NAME}" + ) + + # Note: Individual clean targets removed for simplicity + # Use 'cmake --build build --target clean' to clean everything + +endfunction() + +# Helper function for simple SNES games (most common case) +function(add_simple_snes_game target_name) + cmake_parse_arguments(SIMPLE "" "ROM_NAME" "SOURCES" ${ARGN}) + + if(NOT SIMPLE_ROM_NAME) + set(SIMPLE_ROM_NAME ${target_name}) + endif() + + add_snes_game(${target_name} + SOURCES ${SIMPLE_SOURCES} + ROM_NAME ${SIMPLE_ROM_NAME} + HIROM OFF + FASTROM OFF + ) +endfunction() diff --git a/cmake/replace_text.cmake b/cmake/replace_text.cmake new file mode 100644 index 000000000..499bbb227 --- /dev/null +++ b/cmake/replace_text.cmake @@ -0,0 +1,22 @@ +# Cross-platform text replacement utility for CMake +# Usage: cmake -DINPUT_FILE=input.txt -DOUTPUT_FILE=output.txt -DPATTERN="old" -DREPLACEMENT="new" -P replace_text.cmake + +if(NOT INPUT_FILE OR NOT OUTPUT_FILE OR NOT DEFINED PATTERN OR NOT DEFINED REPLACEMENT) + message(FATAL_ERROR "Usage: cmake -DINPUT_FILE=input.txt -DOUTPUT_FILE=output.txt -DPATTERN=\"old\" -DREPLACEMENT=\"new\" -P replace_text.cmake") +endif() + +# Read the input file +file(READ "${INPUT_FILE}" FILE_CONTENT) + +# Perform the replacement - use string(REPLACE) for literal replacement to avoid regex escaping issues +if(PATTERN MATCHES ".*hdr.*") + # Special handling for hdr.asm patterns + string(REPLACE ".include \"hdr.asm\"" "${REPLACEMENT}" FILE_CONTENT "${FILE_CONTENT}") + string(REPLACE ".INCLUDE \"hdr.asm\"" "${REPLACEMENT}" FILE_CONTENT "${FILE_CONTENT}") +else() + # Use regex replace for other patterns + string(REGEX REPLACE "${PATTERN}" "${REPLACEMENT}" FILE_CONTENT "${FILE_CONTENT}") +endif() + +# Write to output file +file(WRITE "${OUTPUT_FILE}" "${FILE_CONTENT}") diff --git a/compiler/CMakeLists.txt b/compiler/CMakeLists.txt new file mode 100644 index 000000000..4f5399240 --- /dev/null +++ b/compiler/CMakeLists.txt @@ -0,0 +1,89 @@ +# Compiler tools: TCC (816-tcc) and WLA-DX (wla-65816, wla-spc700, wlalink) + +# Set variables matching existing Makefile +set(TCC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tcc") +set(WLA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wla-dx") +set(BIN_DIR "${CMAKE_SOURCE_DIR}/devkitsnes/bin") + +# Platform-specific settings (matching existing Makefile) +if(WIN32) + set(CMAKE_TYPE "MSYS Makefiles") +else() + set(CMAKE_TYPE "Unix Makefiles") +endif() + +# TCC Compiler (816-tcc) +# Check if TCC submodule is initialized +if(EXISTS ${TCC_DIR}/configure) + message(STATUS "TCC submodule found, building 816-tcc compiler") + ExternalProject_Add(tcc_compiler + SOURCE_DIR ${TCC_DIR} + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E chdir ${TCC_DIR} ./configure + BUILD_COMMAND ${CMAKE_COMMAND} -E chdir ${TCC_DIR} $(MAKE) + INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${TCC_DIR}/816-tcc ${BIN_DIR}/816-tcc + BUILD_IN_SOURCE TRUE + BUILD_ALWAYS FALSE + ) +else() + message(WARNING "TCC submodule not initialized. Run: git submodule update --init --recursive") + # Create a dummy target that fails with helpful message + add_custom_target(tcc_compiler + COMMAND ${CMAKE_COMMAND} -E echo "Error: TCC submodule not initialized" + COMMAND ${CMAKE_COMMAND} -E echo "Please run: git submodule update --init --recursive" + COMMAND ${CMAKE_COMMAND} -E false + COMMENT "TCC submodule missing" + ) +endif() + +# WLA-DX Assembler (already uses CMake!) +# Check if WLA-DX submodule is initialized +if(EXISTS ${WLA_DIR}/CMakeLists.txt) + message(STATUS "WLA-DX submodule found, building assembler tools") + ExternalProject_Add(wla_assembler + SOURCE_DIR ${WLA_DIR} + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -G "${CMAKE_TYPE}" + BUILD_COMMAND ${CMAKE_COMMAND} --build --target wla-65816 wla-spc700 wlalink + INSTALL_COMMAND + ${CMAKE_COMMAND} -E copy /binaries/wla-65816 ${BIN_DIR}/wla-65816 + COMMAND + ${CMAKE_COMMAND} -E copy /binaries/wla-spc700 ${BIN_DIR}/wla-spc700 + COMMAND + ${CMAKE_COMMAND} -E copy /binaries/wlalink ${BIN_DIR}/wlalink + BUILD_ALWAYS FALSE + ) +else() + message(WARNING "WLA-DX submodule not initialized. Run: git submodule update --init --recursive") + # Create a dummy target that fails with helpful message + add_custom_target(wla_assembler + COMMAND ${CMAKE_COMMAND} -E echo "Error: WLA-DX submodule not initialized" + COMMAND ${CMAKE_COMMAND} -E echo "Please run: git submodule update --init --recursive" + COMMAND ${CMAKE_COMMAND} -E false + COMMENT "WLA-DX submodule missing" + ) +endif() + +# Create a combined target for all compiler tools +add_custom_target(pvsneslib_compiler + DEPENDS tcc_compiler wla_assembler + COMMENT "Building PVSnesLib compiler tools" +) + +# Clean target for compiler +add_custom_target(clean_compiler + COMMAND ${CMAKE_COMMAND} -E chdir ${TCC_DIR} $(MAKE) clean || true + COMMAND ${CMAKE_COMMAND} -E chdir ${WLA_DIR} $(MAKE) clean || true + COMMAND ${CMAKE_COMMAND} -E remove -f ${WLA_DIR}/CMakeCache.txt + COMMENT "Cleaning compiler tools" +) + +# Create clean alias for compiler +add_custom_target(compiler + DEPENDS pvsneslib_compiler + COMMENT "๐Ÿ”ง SNES C compiler and assembler" +) + +# Note: Submodule updates should be done manually with: +# git submodule update --remote --merge tcc +# git submodule update --remote --merge wla-dx diff --git a/devkitsnes/snes_rules b/devkitsnes/snes_rules index c94767e98..82593d769 100644 --- a/devkitsnes/snes_rules +++ b/devkitsnes/snes_rules @@ -172,13 +172,13 @@ endif $(LD) -d -s -v -A -c -L ${LIBDIRSOBJS} linkfile $@ # remove unattended characters - @sed -i 's/://' $(ROMNAME).sym + @sed -i.bak 's/://' $(ROMNAME).sym && rm -f $(ROMNAME).sym.bak #keep with section label if needed # @cp -f $(ROMNAME).sym $(ROMNAME).symfull # remove duplicated labels for mesen debugger - @sed -i '/ SECTIONSTART_/d;/ SECTIONEND_/d;/ RAM_USAGE_SLOT_/d;' $(ROMNAME).sym + @sed -i.bak '/ SECTIONSTART_/d;/ SECTIONEND_/d;/ RAM_USAGE_SLOT_/d;' $(ROMNAME).sym && rm -f $(ROMNAME).sym.bak @echo @echo Build finished successfully ! diff --git a/devkitsnes/tools/.keepme b/devkitsnes/tools/.keepme deleted file mode 100644 index e69de29bb..000000000 diff --git a/pvsneslib/CMakeLists.txt b/pvsneslib/CMakeLists.txt new file mode 100644 index 000000000..b6840c156 --- /dev/null +++ b/pvsneslib/CMakeLists.txt @@ -0,0 +1,144 @@ +# PVSnesLib core library + +# Use version from parent project +set(PVSNESLIB_MAJOR ${PROJECT_VERSION_MAJOR}) +set(PVSNESLIB_MINOR ${PROJECT_VERSION_MINOR}) +set(PVSNESLIB_PATCH ${PROJECT_VERSION_PATCH}) +set(PVSNESLIB_VERSION ${PROJECT_VERSION}) + +# Create version header +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/include/snes/libversion.h.in + ${CMAKE_CURRENT_SOURCE_DIR}/include/snes/libversion.h + @ONLY +) + +# Create version text file +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/pvsneslib_version.txt.in + ${CMAKE_CURRENT_SOURCE_DIR}/pvsneslib_version.txt + @ONLY +) + +# Add tool validation function +function(validate_required_tools) + # Check for required external tools + find_program(GIT_EXECUTABLE git) + if(NOT GIT_EXECUTABLE) + message(WARNING "Git not found. Submodule operations may fail.") + endif() + + # Validate that our build tools will exist after being built + set(REQUIRED_TOOLS + "${CMAKE_SOURCE_DIR}/devkitsnes/bin/816-tcc" + "${CMAKE_SOURCE_DIR}/devkitsnes/bin/wla-65816" + "${CMAKE_SOURCE_DIR}/devkitsnes/tools/816-opt" + "${CMAKE_SOURCE_DIR}/devkitsnes/tools/constify" + ) + + # Note: We can't check if these exist yet since they're built by this system + # But we can validate the build targets exist + message(STATUS "Tool validation: Required tools will be built by targets: tcc_compiler, wla_assembler, 816-opt, constify") +endfunction() + +# Validate tools at configuration time +validate_required_tools() + +# Build default library configuration (LoROM SlowROM - what 99% of users need) +# This approach leverages existing library files built by the traditional Makefile +# and provides CMake targets for them +set(LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib/LoROM_SlowROM") +set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/source") + +# Create library directory +file(MAKE_DIRECTORY ${LIB_DIR}) + +# Library files that should exist (built by Make system) +set(LIBRARY_OBJECTS + ${LIB_DIR}/crt0_snes.obj + ${LIB_DIR}/libm.obj + ${LIB_DIR}/libtcc.obj + ${LIB_DIR}/libc.obj +) + +# Check if library files exist, if not, build them using traditional method +set(MISSING_OBJECTS "") +foreach(obj_file ${LIBRARY_OBJECTS}) + if(NOT EXISTS ${obj_file}) + list(APPEND MISSING_OBJECTS ${obj_file}) + endif() +endforeach() + +if(MISSING_OBJECTS) + message(STATUS "Building missing library objects using traditional Makefile") + add_custom_command(OUTPUT ${LIBRARY_OBJECTS} + COMMAND ${CMAKE_COMMAND} -E env $(MAKE) -C ${SOURCE_DIR} all + DEPENDS tcc_compiler wla_assembler 816-opt constify + WORKING_DIRECTORY ${SOURCE_DIR} + COMMENT "Building PVSnesLib library using traditional Makefile" + ) +endif() + +# Install library objects to lib directory +add_custom_target(pvsneslib_library + DEPENDS ${LIBRARY_OBJECTS} + COMMENT "Building PVSnesLib library (LoROM SlowROM)" +) + +# Create alias for SNESGame.cmake compatibility +add_custom_target(library + DEPENDS pvsneslib_library + COMMENT "PVSnesLib library alias" +) + +# Documentation target (if Doxygen is available) +find_package(Doxygen QUIET) +if(PVSNESLIB_BUILD_DOCS) + if(NOT DOXYGEN_FOUND) + message(STATUS "") + message(STATUS "๐Ÿ“– Documentation build requested but Doxygen not found!") + message(STATUS "") + message(STATUS "To install Doxygen:") + message(STATUS " macOS: brew install doxygen") + message(STATUS " Ubuntu/Debian: sudo apt-get install doxygen") + message(STATUS " Windows: Download from doxygen.nl") + message(STATUS "") + message(STATUS "Skipping documentation generation...") + message(STATUS "") + endif() +endif() + +if(DOXYGEN_FOUND AND PVSNESLIB_BUILD_DOCS) + message(STATUS "๐Ÿ“– Doxygen found (${DOXYGEN_VERSION}) - documentation will be generated") + set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/docs/pvsneslib.dox) + set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + set(DOXY_OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs/html) + set(PVSDOCSDIR ${CMAKE_CURRENT_SOURCE_DIR}/docs) + + # Read the dox file and replace variables directly in CMake + file(READ ${DOXYFILE_IN} DOXYFILE_CONTENT) + string(REPLACE "$(PVSDOCSDIR)" "${PVSDOCSDIR}" DOXYFILE_CONTENT "${DOXYFILE_CONTENT}") + string(REPLACE "$(PVSNESLIB_VERSION)" "${PVSNESLIB_VERSION}" DOXYFILE_CONTENT "${DOXYFILE_CONTENT}") + file(WRITE ${DOXYFILE_OUT} "${DOXYFILE_CONTENT}") + + add_custom_target(docs + COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOXY_OUTPUT_DIR} + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} + COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_SOURCE_DIR}/docs/latex + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Generating PVSnesLib documentation (HTML only)" + VERBATIM + ) + + # PDF documentation target (mimics original Makefile docspdf target) + add_custom_target(docspdf + COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOXY_OUTPUT_DIR} + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} + COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR}/docs/latex ${CMAKE_MAKE_PROGRAM} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/docs/latex/refman.pdf ${CMAKE_CURRENT_SOURCE_DIR}/docs/pvsneslib_manual.pdf + COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_SOURCE_DIR}/docs/latex + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Generating PVSnesLib documentation with PDF manual" + VERBATIM + ) +endif() \ No newline at end of file diff --git a/pvsneslib/include/snes/libversion.h b/pvsneslib/include/snes/libversion.h index 047d5ed85..e44cff8cc 100644 --- a/pvsneslib/include/snes/libversion.h +++ b/pvsneslib/include/snes/libversion.h @@ -1,9 +1,9 @@ #ifndef __PVSNESLIBVERSION_H__ #define __PVSNESLIBVERSION_H__ -#define _PVSNESLIB_MAJOR_ 4 -#define _PVSNESLIB_MINOR_ 4 -#define _PVSNESLIB_PATCH_ 0 +#define _PVSNESLIB_MAJOR_ 4 +#define _PVSNESLIB_MINOR_ 4 +#define _PVSNESLIB_PATCH_ 0 #define _PVSNESLIB_STRING_ "PVSnesLib V4.4.0" diff --git a/pvsneslib/include/snes/libversion.h.in b/pvsneslib/include/snes/libversion.h.in new file mode 100644 index 000000000..e999eff24 --- /dev/null +++ b/pvsneslib/include/snes/libversion.h.in @@ -0,0 +1,10 @@ +#ifndef __PVSNESLIBVERSION_H__ +#define __PVSNESLIBVERSION_H__ + +#define _PVSNESLIB_MAJOR_ @PVSNESLIB_MAJOR @ +#define _PVSNESLIB_MINOR_ @PVSNESLIB_MINOR @ +#define _PVSNESLIB_PATCH_ @PVSNESLIB_PATCH @ + +#define _PVSNESLIB_STRING_ "PVSnesLib V@PVSNESLIB_MAJOR@.@PVSNESLIB_MINOR@.@PVSNESLIB_PATCH@" + +#endif // __PVSNESLIBVERSION_H__ diff --git a/pvsneslib/pvsneslib_version.txt.in b/pvsneslib/pvsneslib_version.txt.in new file mode 100644 index 000000000..1ed627474 --- /dev/null +++ b/pvsneslib/pvsneslib_version.txt.in @@ -0,0 +1 @@ +@PVSNESLIB_VERSION@ diff --git a/pvsneslib/source/Makefile b/pvsneslib/source/Makefile index fac1c8d35..6e9ef9125 100644 --- a/pvsneslib/source/Makefile +++ b/pvsneslib/source/Makefile @@ -37,7 +37,7 @@ else $(CC) $(CFLAGS) -Wall -c $< -o $@ endif endif - sed -i 's/.include "hdr.asm"//' $@ + sed -i.bak 's/.include "hdr.asm"//' $@ && rm -f $@.bak reset_comp: @echo "; HIROM / FASTROM definitions" > comp_defs.asm diff --git a/snes-examples/CMakeLists.txt b/snes-examples/CMakeLists.txt new file mode 100644 index 000000000..2fe098b6b --- /dev/null +++ b/snes-examples/CMakeLists.txt @@ -0,0 +1,656 @@ +# SNES Examples using PVSnesLib - PURE CMAKE IMPLEMENTATION +# NO MAKEFILES - ONLY CMAKE + +# Include our SNES game helper functions +include(${CMAKE_SOURCE_DIR}/cmake/SNESGame.cmake) + +# Hello World example +add_snes_game(hello_world + SOURCES hello_world/src/hello_world.c + GRAPHICS hello_world/pvsneslibfont.png + ASM_SOURCES hello_world/data.asm hello_world/hdr.asm + ROM_NAME hello_world +) + +# Breakpoints example +add_snes_game(breakpoints + SOURCES breakpoints/src/breakpoints.c + GRAPHICS breakpoints/pvsneslibfont.png + ASM_SOURCES breakpoints/data.asm breakpoints/hdr.asm + ROM_NAME breakpoints +) + +# Debug example (no graphics) +add_snes_game(debug + SOURCES debug/debug.c + ASM_SOURCES debug/data.asm debug/hdr.asm + ROM_NAME debug +) + +# Random example +add_snes_game(random + SOURCES random/random.c + GRAPHICS random/pvsneslibfont.bmp + ASM_SOURCES random/data.asm random/hdr.asm + ROM_NAME random +) + +# Scoring example +add_snes_game(scoring + SOURCES scoring/scoring.c + GRAPHICS scoring/pvsneslibfont.bmp + ASM_SOURCES scoring/data.asm scoring/hdr.asm + ROM_NAME scoring +) + +# Timer example +add_snes_game(timer + SOURCES timer/timer.c + GRAPHICS timer/pvsneslibfont.bmp + ASM_SOURCES timer/data.asm timer/hdr.asm + ROM_NAME timer +) + +# Test region example +add_snes_game(testregion + SOURCES testregion/testregion.c + GRAPHICS testregion/pvsneslibfont.bmp + ASM_SOURCES testregion/data.asm testregion/hdr.asm + ROM_NAME testregion +) + +# Memory mapping example (uses HiROM) +add_snes_game(memory_mapping + SOURCES memory_mapping/src/memory_mapping.c + GRAPHICS memory_mapping/pvsneslibfont.png + ASM_SOURCES memory_mapping/data.asm memory_mapping/hdr.asm + ROM_NAME memory_mapping + HIROM ON + FASTROM ON +) + +# Type console example (uses pal_ntsc.c) +add_snes_game(typeconsole + SOURCES typeconsole/src/pal_ntsc.c + GRAPHICS typeconsole/pvsneslibfont.bmp + ASM_SOURCES typeconsole/data.asm typeconsole/hdr.asm + ROM_NAME typeconsole +) + +#============================================================================= +# AUDIO EXAMPLES - Advanced sound and music examples +#============================================================================= + +# Audio effects example +add_snes_game(effects + SOURCES audio/effects/effects.c + GRAPHICS audio/effects/pvsneslibfont.bmp + ASM_SOURCES audio/effects/data.asm audio/effects/hdr.asm + AUDIO_FILES audio/effects/res/effectssfx.it + SOUNDBANK audio/effects/res/soundbank + ROM_NAME effects +) + +# Effects and music combined example +add_snes_game(effectsandmusic + SOURCES audio/effectsandmusic/effectsandmusic.c + GRAPHICS audio/effectsandmusic/pvsneslibfont.bmp + ASM_SOURCES audio/effectsandmusic/data.asm audio/effectsandmusic/hdr.asm + AUDIO_FILES audio/effectsandmusic/res/effectssfx.it audio/effectsandmusic/res/pollen8.it + SOUNDBANK audio/effectsandmusic/res/soundbank + ROM_NAME effectsandmusic +) + +# Basic music example +add_snes_game(music + SOURCES audio/music/music.c + GRAPHICS audio/music/pvsneslibfont.bmp + ASM_SOURCES audio/music/data.asm audio/music/hdr.asm + AUDIO_FILES audio/music/res/pollen8.it + SOUNDBANK audio/music/res/soundbank + ROM_NAME music +) + +# Music example 2 +add_snes_game(music2 + SOURCES audio/music2/music2.c + GRAPHICS audio/music2/pvsneslibfont.bmp + ASM_SOURCES audio/music2/data.asm audio/music2/hdr.asm + AUDIO_FILES audio/music2/res/pollen8.it + SOUNDBANK audio/music2/res/soundbank + ROM_NAME music2 +) + +# Large music example (>32KB) +add_snes_game(musicGreaterThan32k + SOURCES audio/musicGreaterThan32k/musicGreaterThan32k.c + GRAPHICS audio/musicGreaterThan32k/pvsneslibfont.bmp + ASM_SOURCES audio/musicGreaterThan32k/data.asm audio/musicGreaterThan32k/hdr.asm + AUDIO_FILES audio/musicGreaterThan32k/res/whatislove.it + SOUNDBANK audio/musicGreaterThan32k/res/soundbank + ROM_NAME musicGreaterThan32k +) + +# HiROM music example +add_snes_game(musicHiROM + SOURCES audio/musicHiROM/musicHiROM.c + GRAPHICS audio/musicHiROM/pvsneslibfont.bmp audio/musicHiROM/dancer.png + ASM_SOURCES audio/musicHiROM/data.asm audio/musicHiROM/hdr.asm + AUDIO_FILES audio/musicHiROM/res/whatislove.it + SOUNDBANK audio/musicHiROM/res/soundbank + ROM_NAME musicHiROM + HIROM ON +) + +# Simple sound effect example +add_snes_game(tada + SOURCES audio/tada/tada.c + GRAPHICS audio/tada/pvsneslibfont.bmp + ASM_SOURCES audio/tada/data.asm audio/tada/hdr.asm + ROM_NAME tada +) + +#============================================================================= +# GRAPHICS EXAMPLES - Advanced graphics and visual effects +#============================================================================= + +# Background Examples +add_snes_game(Mode0 + SOURCES graphics/Backgrounds/Mode0/Mode0.c + GRAPHICS graphics/Backgrounds/Mode0/bg0.bmp graphics/Backgrounds/Mode0/bg1.bmp graphics/Backgrounds/Mode0/bg2.bmp graphics/Backgrounds/Mode0/bg3.bmp + ASM_SOURCES graphics/Backgrounds/Mode0/data.asm graphics/Backgrounds/Mode0/hdr.asm + ROM_NAME Mode0 +) + +add_snes_game(Mode1 + SOURCES graphics/Backgrounds/Mode1/Mode1.c + GRAPHICS graphics/Backgrounds/Mode1/pvsneslib.png + ASM_SOURCES graphics/Backgrounds/Mode1/data.asm graphics/Backgrounds/Mode1/hdr.asm + ROM_NAME Mode1 +) + +add_snes_game(Mode1BG3HighPriority + SOURCES graphics/Backgrounds/Mode1BG3HighPriority/Mode1BG3HighPriority.c + GRAPHICS graphics/Backgrounds/Mode1BG3HighPriority/BG1.bmp graphics/Backgrounds/Mode1BG3HighPriority/BG2.bmp graphics/Backgrounds/Mode1BG3HighPriority/BG3.bmp + ASM_SOURCES graphics/Backgrounds/Mode1BG3HighPriority/data.asm graphics/Backgrounds/Mode1BG3HighPriority/hdr.asm + ROM_NAME Mode1BG3HighPriority +) + +add_snes_game(Mode1ContinuousScroll + SOURCES graphics/Backgrounds/Mode1ContinuosScroll/Mode1ContinuosScroll.c + GRAPHICS graphics/Backgrounds/Mode1ContinuosScroll/BG1.bmp graphics/Backgrounds/Mode1ContinuosScroll/BG2.bmp graphics/Backgrounds/Mode1ContinuosScroll/BG3.bmp graphics/Backgrounds/Mode1ContinuosScroll/character.bmp + ASM_SOURCES graphics/Backgrounds/Mode1ContinuosScroll/data.asm graphics/Backgrounds/Mode1ContinuosScroll/hdr.asm + ROM_NAME Mode1ContinuousScroll +) + +add_snes_game(Mode1LZ77 + SOURCES graphics/Backgrounds/Mode1LZ77/Mode1LZ77.c + GRAPHICS graphics/Backgrounds/Mode1LZ77/pvsneslib.png + ASM_SOURCES graphics/Backgrounds/Mode1LZ77/data.asm graphics/Backgrounds/Mode1LZ77/hdr.asm + ROM_NAME Mode1LZ77 +) + +add_snes_game(Mode1MixedScroll + SOURCES graphics/Backgrounds/Mode1MixedScroll/Mode1MixedScroll.c + GRAPHICS graphics/Backgrounds/Mode1MixedScroll/pvsneslib.bmp graphics/Backgrounds/Mode1MixedScroll/shader.bmp + ASM_SOURCES graphics/Backgrounds/Mode1MixedScroll/data.asm graphics/Backgrounds/Mode1MixedScroll/hdr.asm + ROM_NAME Mode1MixedScroll +) + +add_snes_game(Mode1Png + SOURCES graphics/Backgrounds/Mode1Png/Mode1.c + GRAPHICS graphics/Backgrounds/Mode1Png/pvsneslib.png + ASM_SOURCES graphics/Backgrounds/Mode1Png/data.asm graphics/Backgrounds/Mode1Png/hdr.asm + ROM_NAME Mode1Png +) + +add_snes_game(Mode1Scroll + SOURCES graphics/Backgrounds/Mode1Scroll/Mode1Scroll.c + GRAPHICS graphics/Backgrounds/Mode1Scroll/map_512_512.bmp graphics/Backgrounds/Mode1Scroll/pvsneslibfont.bmp + ASM_SOURCES graphics/Backgrounds/Mode1Scroll/data.asm graphics/Backgrounds/Mode1Scroll/hdr.asm + ROM_NAME Mode1Scroll +) + +add_snes_game(Mode3 + SOURCES graphics/Backgrounds/Mode3/Mode3.c + GRAPHICS graphics/Backgrounds/Mode3/pvsneslib.bmp + ASM_SOURCES graphics/Backgrounds/Mode3/data.asm graphics/Backgrounds/Mode3/hdr.asm + ROM_NAME Mode3 +) + +add_snes_game(Mode5 + SOURCES graphics/Backgrounds/Mode5/Mode5.c + GRAPHICS graphics/Backgrounds/Mode5/pvsneslib.png + ASM_SOURCES graphics/Backgrounds/Mode5/data.asm graphics/Backgrounds/Mode5/hdr.asm + ROM_NAME Mode5 +) + +add_snes_game(Mode7 + SOURCES graphics/Backgrounds/Mode7/Mode7.c + GRAPHICS graphics/Backgrounds/Mode7/mode7bg.bmp + ASM_SOURCES graphics/Backgrounds/Mode7/data.asm graphics/Backgrounds/Mode7/hdr.asm + ROM_NAME Mode7 +) + +add_snes_game(Mode7Perspective + SOURCES graphics/Backgrounds/Mode7Perspective/Mode7Perspective.c + GRAPHICS graphics/Backgrounds/Mode7Perspective/ground.png graphics/Backgrounds/Mode7Perspective/sky.png + ASM_SOURCES graphics/Backgrounds/Mode7Perspective/data.asm graphics/Backgrounds/Mode7Perspective/hdr.asm + ROM_NAME Mode7Perspective +) + +# Effects Examples +add_snes_game(Fading + SOURCES graphics/Effects/Fading/Fading.c + GRAPHICS graphics/Effects/Fading/pvsneslib.bmp + ASM_SOURCES graphics/Effects/Fading/data.asm graphics/Effects/Fading/hdr.asm + ROM_NAME Fading +) + +add_snes_game(GradientColors + SOURCES graphics/Effects/GradientColors/GradientColors.c + GRAPHICS graphics/Effects/GradientColors/pvsneslib.png + ASM_SOURCES graphics/Effects/GradientColors/data.asm graphics/Effects/GradientColors/hdr.asm + ROM_NAME GradientColors +) + +add_snes_game(HDMAGradient + SOURCES graphics/Effects/HDMAGradient/HDMAGradient.c + GRAPHICS graphics/Effects/HDMAGradient/pvsneslib.bmp + ASM_SOURCES graphics/Effects/HDMAGradient/data.asm graphics/Effects/HDMAGradient/hdr.asm + ROM_NAME HDMAGradient +) + +add_snes_game(MosaicShading + SOURCES graphics/Effects/MosaicShading/MosaicShading.c + GRAPHICS graphics/Effects/MosaicShading/pvsneslib.bmp + ASM_SOURCES graphics/Effects/MosaicShading/data.asm graphics/Effects/MosaicShading/hdr.asm + ROM_NAME MosaicShading +) + +add_snes_game(ParallaxScrolling + SOURCES graphics/Effects/ParallaxScrolling/ParallaxScrolling.c + ASM_SOURCES graphics/Effects/ParallaxScrolling/data.asm graphics/Effects/ParallaxScrolling/hdr.asm + ROM_NAME ParallaxScrolling +) + +add_snes_game(Transparency + SOURCES graphics/Effects/Transparency/Transparency.c + GRAPHICS graphics/Effects/Transparency/backgrounds.bmp graphics/Effects/Transparency/clouds.bmp + ASM_SOURCES graphics/Effects/Transparency/data.asm graphics/Effects/Transparency/hdr.asm + ROM_NAME Transparency +) + +add_snes_game(TransparentWindow + SOURCES graphics/Effects/TransparentWindow/src/main.c graphics/Effects/TransparentWindow/src/window.c + GRAPHICS graphics/Effects/TransparentWindow/res/background.png + ASM_SOURCES graphics/Effects/TransparentWindow/data.asm graphics/Effects/TransparentWindow/hdr.asm + ROM_NAME TransparentWindow +) + +add_snes_game(Waves + SOURCES graphics/Effects/Waves/Waves.c + ASM_SOURCES graphics/Effects/Waves/data.asm graphics/Effects/Waves/hdr.asm + ROM_NAME Waves +) + +add_snes_game(Window + SOURCES graphics/Effects/Window/Window.c + GRAPHICS graphics/Effects/Window/pvsneslibbg1.png graphics/Effects/Window/pvsneslibbg2.png + ASM_SOURCES graphics/Effects/Window/data.asm graphics/Effects/Window/hdr.asm + ROM_NAME Window +) + +# Sprite Examples +add_snes_game(AnimatedSprite + SOURCES graphics/Sprites/AnimatedSprite/AnimatedSprite.c + GRAPHICS graphics/Sprites/AnimatedSprite/sprites.bmp + ASM_SOURCES graphics/Sprites/AnimatedSprite/data.asm graphics/Sprites/AnimatedSprite/hdr.asm + ROM_NAME AnimatedSprite +) + +add_snes_game(DynamicEngineMetaSprite + SOURCES graphics/Sprites/DynamicEngineMetaSprite/DynamicEngineMetaSprite.c + GRAPHICS graphics/Sprites/DynamicEngineMetaSprite/pvsneslib.png graphics/Sprites/DynamicEngineMetaSprite/sprite16.png graphics/Sprites/DynamicEngineMetaSprite/sprite32.png + ASM_SOURCES graphics/Sprites/DynamicEngineMetaSprite/data.asm graphics/Sprites/DynamicEngineMetaSprite/hdr.asm + ROM_NAME DynamicEngineMetaSprite +) + +add_snes_game(DynamicEngineSprite + SOURCES graphics/Sprites/DynamicEngineSprite/DynamicEngineSprite.c + GRAPHICS graphics/Sprites/DynamicEngineSprite/pvsneslib.png graphics/Sprites/DynamicEngineSprite/sprite16.png graphics/Sprites/DynamicEngineSprite/sprite32.png graphics/Sprites/DynamicEngineSprite/sprite8.png + ASM_SOURCES graphics/Sprites/DynamicEngineSprite/data.asm graphics/Sprites/DynamicEngineSprite/hdr.asm + ROM_NAME DynamicEngineSprite +) + +add_snes_game(DynamicSprite + SOURCES graphics/Sprites/DynamicSprite/DynamicSprite.c + GRAPHICS graphics/Sprites/DynamicSprite/sprites.bmp + ASM_SOURCES graphics/Sprites/DynamicSprite/data.asm graphics/Sprites/DynamicSprite/hdr.asm + ROM_NAME DynamicSprite +) + +add_snes_game(ObjectSize + SOURCES graphics/Sprites/ObjectSize/ObjectSize.c + GRAPHICS graphics/Sprites/ObjectSize/sprite8.bmp graphics/Sprites/ObjectSize/sprite16.bmp graphics/Sprites/ObjectSize/sprite32.bmp graphics/Sprites/ObjectSize/sprite64.bmp graphics/Sprites/ObjectSize/pvsneslibfont.bmp + ASM_SOURCES graphics/Sprites/ObjectSize/data.asm graphics/Sprites/ObjectSize/hdr.asm + ROM_NAME ObjectSize +) + +add_snes_game(SimpleSprite + SOURCES graphics/Sprites/SimpleSprite/SimpleSprite.c + GRAPHICS graphics/Sprites/SimpleSprite/sprites.bmp + ASM_SOURCES graphics/Sprites/SimpleSprite/data.asm graphics/Sprites/SimpleSprite/hdr.asm + ROM_NAME SimpleSprite +) + +# Palette Example +add_snes_game(GetColors + SOURCES graphics/Palette/GetColors/GetColors.c + GRAPHICS graphics/Palette/GetColors/ortf.png + ASM_SOURCES graphics/Palette/GetColors/data.asm graphics/Palette/GetColors/hdr.asm + ROM_NAME GetColors +) + +#============================================================================= +# GAMES EXAMPLES - Full game implementations +#============================================================================= + +add_snes_game(breakout + SOURCES games/breakout/breakout.c + ASM_SOURCES games/breakout/data.asm games/breakout/hdr.asm + DATA_FILES games/breakout/backpal.dat games/breakout/bg1map.dat games/breakout/bg2map.dat games/breakout/palette.dat games/breakout/tiles1.dat games/breakout/tiles2.dat + ROM_NAME breakout +) + +add_snes_game(likemario + SOURCES games/likemario/LikeMario.c + GRAPHICS games/likemario/tiles.png games/likemario/mario_sprite.bmp games/likemario/mariofont.bmp + ASM_SOURCES games/likemario/data.asm games/likemario/hdr.asm + AUDIO_FILES games/likemario/overworld.it + SOUNDBANK games/likemario/soundbank + ROM_NAME likemario +) + +#============================================================================= +# INPUT EXAMPLES - Controller, mouse, and input device examples +#============================================================================= + +add_snes_game(controller + SOURCES input/controller/controller.c + GRAPHICS input/controller/pvsneslibfont.bmp + ASM_SOURCES input/controller/data.asm input/controller/hdr.asm + ROM_NAME controller +) + +add_snes_game(mouse + SOURCES input/mouse/mouse.c + GRAPHICS input/mouse/pvsneslibfont.bmp input/mouse/cursor.png input/mouse/buttons.png + ASM_SOURCES input/mouse/data.asm input/mouse/hdr.asm + ROM_NAME mouse +) + +add_snes_game(mouse-data-test + SOURCES input/mouse-data-test/mouse-data-test.c + GRAPHICS input/mouse-data-test/pvsneslibfont.bmp + ASM_SOURCES input/mouse-data-test/data.asm input/mouse-data-test/hdr.asm + ROM_NAME mouse-data-test +) + +add_snes_game(multiplay5 + SOURCES input/multiplay5/multiplay5.c + GRAPHICS input/multiplay5/pvsneslibfont.bmp + ASM_SOURCES input/multiplay5/data.asm input/multiplay5/hdr.asm + ROM_NAME multiplay5 +) + +add_snes_game(superscope + SOURCES input/superscope/superscope.c + GRAPHICS input/superscope/aim_adjust_target.png input/superscope/sprites.png input/superscope/pvsneslibfont.bmp + ASM_SOURCES input/superscope/data.asm input/superscope/hdr.asm + ROM_NAME superscope +) + +#============================================================================= +# LOGO EXAMPLES - Company logo demonstrations +#============================================================================= + +add_snes_game(LogoCapcom + SOURCES logo/snes-logo-capcom/src/main.c logo/snes-logo-capcom/src/logo.c + GRAPHICS logo/snes-logo-capcom/res/logo.bmp + ASM_SOURCES logo/snes-logo-capcom/data.asm logo/snes-logo-capcom/hdr.asm + AUDIO_FILES logo/snes-logo-capcom/res/logo.it + SOUNDBANK logo/snes-logo-capcom/soundbank + ROM_NAME LogoCapcom +) + +add_snes_game(LogoKonami + SOURCES logo/snes-logo-konami/src/main.c logo/snes-logo-konami/src/logo.c + GRAPHICS logo/snes-logo-konami/res/companyFire.bmp logo/snes-logo-konami/res/companyLogo.bmp + ASM_SOURCES logo/snes-logo-konami/data.asm logo/snes-logo-konami/hdr.asm + AUDIO_FILES logo/snes-logo-konami/res/logo.it + SOUNDBANK logo/snes-logo-konami/soundbank + ROM_NAME LogoKonami +) + +add_snes_game(LogoPVSnesLib + SOURCES logo/snes-logo-pvsneslib/src/main.c logo/snes-logo-pvsneslib/src/logo.c + GRAPHICS logo/snes-logo-pvsneslib/res/logo.bmp + ASM_SOURCES logo/snes-logo-pvsneslib/data.asm logo/snes-logo-pvsneslib/hdr.asm + AUDIO_FILES logo/snes-logo-pvsneslib/res/logo.it + SOUNDBANK logo/snes-logo-pvsneslib/soundbank + ROM_NAME LogoPVSnesLib +) + +#============================================================================= +# MAPS EXAMPLES - Advanced mapping and scrolling +#============================================================================= + +add_snes_game(DynamicMap + SOURCES maps/DynamicMap/DynamicMap.c maps/DynamicMap/map32x32.c maps/DynamicMap/map64x64.c maps/DynamicMap/maputil.c + GRAPHICS maps/DynamicMap/pvsneslibfont.bmp maps/DynamicMap/sprite16.bmp maps/DynamicMap/sprite16_64x64.bmp + ASM_SOURCES maps/DynamicMap/data.asm maps/DynamicMap/hdr.asm maps/DynamicMap/c64_sprite.asm maps/DynamicMap/ram.asm + ROM_NAME DynamicMap +) + +# Special handling for mapbuffer - preprocess ASM file to fix include path +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mapbufferextensionA_fixed.asm + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/maps/mapbuffer/src/addons/mapbufferextensionA.asm ${CMAKE_CURRENT_BINARY_DIR}/mapbufferextensionA_fixed.asm + COMMAND ${CMAKE_COMMAND} -DINPUT_FILE="${CMAKE_CURRENT_BINARY_DIR}/mapbufferextensionA_fixed.asm" -DOUTPUT_FILE="${CMAKE_CURRENT_BINARY_DIR}/mapbufferextensionA_fixed.asm" -DPATTERN="\.include \"hdr\.asm\"" -DREPLACEMENT=".include \"../../hdr.asm\"" -P "${CMAKE_SOURCE_DIR}/cmake/replace_text.cmake" + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/maps/mapbuffer/src/addons/mapbufferextensionA.asm + COMMENT "Preprocessing mapbuffer ASM file to fix include path" +) + +add_snes_game(mapbuffer + SOURCES maps/mapbuffer/mapbuffer.c maps/mapbuffer/src/gameobjects/mario.c maps/mapbuffer/src/addons/mapbufferextension.c + GRAPHICS maps/mapbuffer/gfx/mario.png maps/mapbuffer/gfx/tilesMario.png + ASM_SOURCES maps/mapbuffer/data.asm maps/mapbuffer/hdr.asm ${CMAKE_CURRENT_BINARY_DIR}/mapbufferextensionA_fixed.asm + INCLUDE_DIRS maps/mapbuffer/src/gameobjects maps/mapbuffer/src/addons maps/mapbuffer/maps + ROM_NAME mapbuffer +) + +add_snes_game(mapscroll + SOURCES maps/mapscroll/mapscroll.c + GRAPHICS maps/mapscroll/mario.png maps/mapscroll/tilesMario.png maps/mapscroll/bg_L1.png + ASM_SOURCES maps/mapscroll/data.asm maps/mapscroll/hdr.asm + ROM_NAME mapscroll +) + +add_snes_game(slopemario + SOURCES maps/slopemario/slopemario.c + GRAPHICS maps/slopemario/mario_sprite.bmp maps/slopemario/mariofont.bmp maps/slopemario/tiles.png + ASM_SOURCES maps/slopemario/data.asm maps/slopemario/hdr.asm + AUDIO_FILES maps/slopemario/overworld.it + SOUNDBANK maps/slopemario/soundbank + ROM_NAME slopemario +) + +add_snes_game(tiled + SOURCES maps/tiled/tiled.c + GRAPHICS maps/tiled/maplevel1.png maps/tiled/tileslevel1.png + ASM_SOURCES maps/tiled/data.asm maps/tiled/hdr.asm + ROM_NAME tiled +) + +#============================================================================= +# OBJECTS EXAMPLES - Object and sprite management +#============================================================================= + +add_snes_game(mapandobjects + SOURCES objects/mapandobjects/mapandobjects.c objects/mapandobjects/mario.c objects/mapandobjects/goomba.c objects/mapandobjects/koopatroopa.c + GRAPHICS objects/mapandobjects/mario.png objects/mapandobjects/goomba.png objects/mapandobjects/koopatroopa.png objects/mapandobjects/tileset.png objects/mapandobjects/tilesMario.png objects/mapandobjects/bg_L1.png + ASM_SOURCES objects/mapandobjects/data.asm objects/mapandobjects/hdr.asm + ROM_NAME mapandobjects +) + +add_snes_game(moveobjects + SOURCES objects/moveobjects/moveobjects.c + GRAPHICS objects/moveobjects/sprites.bmp + ASM_SOURCES objects/moveobjects/data.asm objects/moveobjects/hdr.asm + ROM_NAME moveobjects +) + +add_snes_game(nogravityobjects + SOURCES objects/nogravityobject/nogravityobjects.c objects/nogravityobject/link.c + GRAPHICS objects/nogravityobject/link.png objects/nogravityobject/mapzelda.png objects/nogravityobject/tiles.png + ASM_SOURCES objects/nogravityobject/data.asm objects/nogravityobject/hdr.asm + ROM_NAME nogravityobjects +) + +#============================================================================= +# SRAM EXAMPLES - Save game and persistent storage +#============================================================================= + +add_snes_game(sramoffset + SOURCES sram/sramoffset/sramoffset.c + GRAPHICS sram/sramoffset/pvsneslibfont.bmp + ASM_SOURCES sram/sramoffset/data.asm sram/sramoffset/hdr.asm + ROM_NAME sramoffset +) + +add_snes_game(sramsimple + SOURCES sram/sramsimple/sram.c + GRAPHICS sram/sramsimple/pvsneslibfont.bmp + ASM_SOURCES sram/sramsimple/data.asm sram/sramsimple/hdr.asm + ROM_NAME sramsimple +) + +# Combined target for basic working examples +add_custom_target(examples + DEPENDS + hello_world + breakpoints + debug + random + scoring + timer + testregion + typeconsole + COMMENT "Building basic working SNES examples" +) + +# Advanced examples target (includes examples that need special ROM configurations) +add_custom_target(advanced_examples + DEPENDS + memory_mapping + COMMENT "Building advanced SNES examples (HiROM/FastROM)" +) + +# Audio examples target +add_custom_target(audio_examples + DEPENDS + effects + effectsandmusic + music + music2 + musicGreaterThan32k + musicHiROM + tada + COMMENT "Building audio SNES examples" +) + +# Graphics examples target +add_custom_target(graphics_examples + DEPENDS + Mode0 Mode1 Mode1BG3HighPriority Mode1ContinuousScroll Mode1LZ77 + Mode1MixedScroll Mode1Png Mode1Scroll Mode3 Mode5 Mode7 Mode7Perspective + Fading GradientColors HDMAGradient MosaicShading ParallaxScrolling + Transparency TransparentWindow Waves Window + AnimatedSprite DynamicEngineMetaSprite DynamicEngineSprite DynamicSprite + ObjectSize SimpleSprite GetColors + COMMENT "Building graphics SNES examples" +) + +# Games examples target +add_custom_target(games_examples + DEPENDS + breakout + likemario + COMMENT "Building game SNES examples" +) + +# Input examples target +add_custom_target(input_examples + DEPENDS + controller + mouse + mouse-data-test + multiplay5 + superscope + COMMENT "Building input SNES examples" +) + +# Logo examples target +add_custom_target(logo_examples + DEPENDS + LogoCapcom + LogoKonami + LogoPVSnesLib + COMMENT "Building logo SNES examples" +) + +# Maps examples target +add_custom_target(maps_examples + DEPENDS + DynamicMap + mapbuffer + mapscroll + slopemario + tiled + COMMENT "Building maps SNES examples" +) + +# Objects examples target +add_custom_target(objects_examples + DEPENDS + mapandobjects + moveobjects + nogravityobjects + COMMENT "Building objects SNES examples" +) + +# SRAM examples target +add_custom_target(sram_examples + DEPENDS + sramoffset + sramsimple + COMMENT "Building SRAM SNES examples" +) + +# Comprehensive target for ALL examples (60+ examples!) +add_custom_target(all_examples + DEPENDS + examples + advanced_examples + audio_examples + graphics_examples + games_examples + input_examples + logo_examples + maps_examples + objects_examples + sram_examples + COMMENT "Building ALL SNES examples (60+ examples!)" +) + +message(STATUS "SNES examples configured. Use 'cmake --build . --target examples' to build all or 'cmake --build . --target hello_world' for individual games.") diff --git a/snes-examples/audio/effects/res/effectssfx.bak b/snes-examples/audio/effects/res/effectssfx.bak deleted file mode 100644 index b2326dabe..000000000 Binary files a/snes-examples/audio/effects/res/effectssfx.bak and /dev/null differ diff --git a/tools/816-opt/Makefile b/tools/816-opt/Makefile index fad634a3c..fd5973eb8 100644 --- a/tools/816-opt/Makefile +++ b/tools/816-opt/Makefile @@ -37,9 +37,13 @@ $(EXE)$(EXT): $(OBJS) @echo "Linking $<" $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $@ +# Create build directory +$(OBJ): + @mkdir -p $(OBJ) + # Define the recipe for compiling object files %.o : %.c -$(OBJ)/%.o: $(SRC)/%.c +$(OBJ)/%.o: $(SRC)/%.c | $(OBJ) @echo "Compiling $<" $(CC) $(CFLAGS) -I$(SRC) -c $< -o $@ diff --git a/tools/816-opt/build/.keepme b/tools/816-opt/build/.keepme deleted file mode 100644 index e69de29bb..000000000 diff --git a/tools/816-opt/src/main.c b/tools/816-opt/src/main.c index 5bf945be7..108491d4b 100644 --- a/tools/816-opt/src/main.c +++ b/tools/816-opt/src/main.c @@ -59,9 +59,9 @@ int main(int argc, char **argv) /* -------------------------------- */ dynArray optAsm = optimizeAsm(file, bss, verbose); - for (size_t i = 0; i < optAsm.used; i++) + for (size_t j = 0; j < optAsm.used; j++) { - fprintf(stdout, "%s\n", optAsm.arr[i]); + fprintf(stdout, "%s\n", optAsm.arr[j]); } /* -------------------------------- */ diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 000000000..88012f700 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,198 @@ +# PVSnesLib development tools + +# Set common variables +set(TOOLS_DIR "${CMAKE_SOURCE_DIR}/devkitsnes/tools") +set(VERSION "1.0.0") +string(TIMESTAMP DATESTRING "%Y%m%d") + +# Create tools directory +file(MAKE_DIRECTORY ${TOOLS_DIR}) + +# Modern CMake approach - use properties instead of raw flags +# Common compiler definitions for tools +set(TOOL_COMPILE_DEFINITIONS + __BUILD_DATE="${DATESTRING}" + __BUILD_VERSION="${VERSION}" +) + +# Common compiler features and standards +set(TOOL_C_STANDARD 99) +set(TOOL_CXX_STANDARD 11) + +# Platform-specific settings +if(WIN32) + set(EXE_EXT ".exe") + set(TOOL_STATIC_LINKING TRUE) +else() + set(EXE_EXT "") + if(NOT APPLE) + set(TOOL_STATIC_LINKING TRUE) + else() + set(TOOL_STATIC_LINKING FALSE) + endif() +endif() + +# Helper function to configure tool targets with modern CMake practices +function(configure_tool_target target_name) + # Set C/C++ standard based on target type + get_target_property(target_type ${target_name} TYPE) + if(target_type STREQUAL "EXECUTABLE") + # Determine if it's C or C++ based on source files + get_target_property(sources ${target_name} SOURCES) + set(is_cpp FALSE) + foreach(source ${sources}) + get_filename_component(ext ${source} EXT) + if(ext MATCHES "\\.(cpp|cxx|cc)$") + set(is_cpp TRUE) + break() + endif() + endforeach() + + if(is_cpp) + set_target_properties(${target_name} PROPERTIES + CXX_STANDARD ${TOOL_CXX_STANDARD} + CXX_STANDARD_REQUIRED ON + ) + else() + set_target_properties(${target_name} PROPERTIES + C_STANDARD ${TOOL_C_STANDARD} + C_STANDARD_REQUIRED ON + ) + endif() + endif() + + # Set compile options using target properties + target_compile_options(${target_name} PRIVATE + $<$:-g> + $<$:-O2> + -Wall + $<$:-Wno-implicit-function-declaration> + $<$:-Wno-unused-result> + ) + + # Set compile definitions + target_compile_definitions(${target_name} PRIVATE ${TOOL_COMPILE_DEFINITIONS}) + + # Set linking options + if(TOOL_STATIC_LINKING) + target_link_options(${target_name} PRIVATE -static) + endif() + + # Install target + install(TARGETS ${target_name} RUNTIME DESTINATION ${TOOLS_DIR}) +endfunction() + +# 816-opt: Assembly optimizer +add_executable(816-opt + 816-opt/src/main.c + 816-opt/src/optimizer.c + 816-opt/src/helpers.c +) + +configure_tool_target(816-opt) +target_link_libraries(816-opt PRIVATE pthread) + +if(WIN32) + target_compile_definitions(816-opt PRIVATE PCRE2_STATIC) + target_link_libraries(816-opt PRIVATE pcre2-posix pcre2-8 iconv) +endif() + +# bin2txt: Binary to text converter +add_executable(bin2txt + bin2txt/bin2txt.c +) + +configure_tool_target(bin2txt) + +# constify: Constant optimizer +add_executable(constify + constify/constify.cpp +) + +configure_tool_target(constify) + +# gfx2snes: Graphics converter (legacy) +add_executable(gfx2snes + gfx2snes/gfx2snes.c + gfx2snes/imgtools.c + gfx2snes/loadimg.c + gfx2snes/lodepng.c + gfx2snes/lz77.c +) + +configure_tool_target(gfx2snes) +target_include_directories(gfx2snes PRIVATE gfx2snes) + +# gfx4snes: Modern graphics converter +file(GLOB GFX4SNES_SOURCES gfx4snes/src/*.c) +add_executable(gfx4snes ${GFX4SNES_SOURCES}) + +configure_tool_target(gfx4snes) +target_include_directories(gfx4snes PRIVATE gfx4snes/src) + +# smconv: Music converter +add_executable(smconv + smconv/brr.cpp + smconv/conversion.cpp + smconv/convert.cpp + smconv/inputdata.cpp + smconv/io.cpp + smconv/it2spc.cpp + smconv/itloader.cpp +) + +configure_tool_target(smconv) +target_include_directories(smconv PRIVATE smconv) + +# snesbrr: BRR audio converter +add_executable(snesbrr + snesbrr/base/FileStream.cpp + snesbrr/base/MemoryStream.cpp + snesbrr/base/OptionParser.cpp + snesbrr/base/Stream.cpp + snesbrr/base/StreamException.cpp + snesbrr/brr/BrrCodec.cpp + snesbrr/brr/main.cpp +) + +configure_tool_target(snesbrr) +target_include_directories(snesbrr PRIVATE snesbrr snesbrr/base snesbrr/brr) + +# snestools: General SNES utilities +add_executable(snestools + snestools/snestools.c + snestools/errors.c +) + +configure_tool_target(snestools) + +# tmx2snes: Tiled map converter +add_executable(tmx2snes + tmx2snes/tmx2snes.c +) + +configure_tool_target(tmx2snes) +target_include_directories(tmx2snes PRIVATE tmx2snes) + +# Create combined target for all tools +add_custom_target(pvsneslib_tools + DEPENDS 816-opt bin2txt constify gfx2snes gfx4snes smconv snesbrr snestools tmx2snes + COMMENT "Building PVSnesLib development tools" +) + +# Create clean alias +add_custom_target(tools + DEPENDS pvsneslib_tools + COMMENT "๐Ÿ› ๏ธ SNES development tools" +) + +# Ensure compiler tools are built first (if they exist) +if(TARGET pvsneslib_compiler) + add_dependencies(pvsneslib_tools pvsneslib_compiler) +endif() + +# Copy tools to devkitsnes/tools (matching existing behavior) +add_custom_command(TARGET pvsneslib_tools POST_BUILD + COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --prefix ${CMAKE_SOURCE_DIR} + COMMENT "Installing tools to devkitsnes/tools" +)