diff --git a/CMakeLists.txt b/CMakeLists.txt index c40fbed..a801a40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,74 +2,99 @@ cmake_minimum_required(VERSION 3.14...3.25) get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(NOT is_multi_config AND NOT (CMAKE_BUILD_TYPE OR DEFINED ENV{CMAKE_BUILD_TYPE})) - set(CMAKE_BUILD_TYPE Release CACHE STRING "Release default") + set(CMAKE_BUILD_TYPE Release CACHE STRING "Release default") endif() project(NTSC-CRT LANGUAGES C) -option(live "live video using PL3D-KC") +option(LIVE "Live video using PL3D-KC" OFF) +option(VIDEO "Convert video (series of frames) instead of single image" OFF) +set(CRT_SYSTEM "0" CACHE STRING "The system to be compiled (0 - CRT_SYSTEM_NTSC - standard NTSC, 5 - CRT_SYSTEM_NTSCVHS - standard NTSC VHS)") include(ExternalProject) include(GNUInstallDirs) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${PROJECT_BINARY_DIR}" CACHE PATH "default install path" FORCE) + set(CMAKE_INSTALL_PREFIX "${PROJECT_BINARY_DIR}" CACHE PATH "default install path" FORCE) endif() # --- PL3D-KC -if(live) -if(UNIX) - find_package(X11 REQUIRED) -endif() +if(LIVE) + if(UNIX) + find_package(X11 REQUIRED) + endif() -set(fw_url https://github.com/LMP88959/PL3D-KC.git) -set(fw_tag 3fa35ad) -set(fw_args --DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} --DCMAKE_BUILD_TYPE=Release --DBUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS} --DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -) + set(fw_url https://github.com/LMP88959/PL3D-KC.git) + set(fw_tag 3fa35ad) + set(fw_args + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} + -DCMAKE_BUILD_TYPE=Release + -DBUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + ) -set(FW_LIBRARY ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}fw${CMAKE_STATIC_LIBRARY_SUFFIX}) -set(FW_INCLUDE_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) + set(FW_LIBRARY ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}fw${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(FW_INCLUDE_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) -ExternalProject_Add(fw -GIT_REPOSITORY ${fw_url} -GIT_TAG ${fw_tag} -GIT_SHALLOW true -CMAKE_ARGS ${fw_args} -BUILD_BYPRODUCTS ${FW_LIBRARY} -TLS_VERIFY true -INACTIVITY_TIMEOUT 60 -CONFIGURE_HANDLED_BY_BUILD ON -) + ExternalProject_Add(fw + GIT_REPOSITORY ${fw_url} + GIT_TAG ${fw_tag} + GIT_SHALLOW true + CMAKE_ARGS ${fw_args} + BUILD_BYPRODUCTS ${FW_LIBRARY} + TLS_VERIFY true + INACTIVITY_TIMEOUT 60 + CONFIGURE_HANDLED_BY_BUILD ON + ) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include) -add_library(fw::fw INTERFACE IMPORTED) -target_link_libraries(fw::fw INTERFACE ${FW_LIBRARY} -$<$:X11::Xext> -$<$:winmm> -) -target_include_directories(fw::fw INTERFACE ${FW_INCLUDE_DIR}) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include) + add_library(fw::fw INTERFACE IMPORTED) + target_link_libraries(fw::fw INTERFACE ${FW_LIBRARY} + $<$:X11::Xext> + $<$:winmm> + ) + target_include_directories(fw::fw INTERFACE ${FW_INCLUDE_DIR}) -add_dependencies(fw::fw fw) + add_dependencies(fw::fw fw) endif() # --- NTSC program -add_executable(ntsc crt_core.c crt_ntsc.c crt_nes.c crt_pv1k.c crt_template.c crt_snes.c crt_main.c ppm_rw.c bmp_rw.c) -target_include_directories(ntsc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_compile_definitions(ntsc PRIVATE -CMD_LINE_VERSION=$> -$<$:_CRT_SECURE_NO_WARNINGS> -) -target_link_libraries(ntsc PRIVATE -$<$:fw::fw> -$<$:winmm> -) +# --- Check CRT_SYSTEM value +if((CRT_SYSTEM LESS 0) OR (CRT_SYSTEM GREATER 5)) + message(FATAL_ERROR "Wrong CRT_SYSTEM value! Possible values: 0 - 5") +endif() + +# --- video_convert +if(VIDEO) + add_executable(ntsc_video video_convert.c crt_core.c crt_ntsc.c crt_ntscvhs.c crt_pv1k.c crt_template.c bmp_rw.c) + target_include_directories(ntsc_video PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_definitions(ntsc_video PRIVATE CRT_SYSTEM=${CRT_SYSTEM}) + target_compile_definitions(ntsc_video PRIVATE + CMD_LINE_VERSION=$> + $<$:_CRT_SECURE_NO_WARNINGS> + ) + target_link_libraries(ntsc_video PRIVATE + $<$:fw::fw> + $<$:winmm> + ) + +# --- default +else() + add_executable(ntsc crt_core.c crt_ntsc.c crt_nes.c crt_pv1k.c crt_template.c crt_snes.c crt_main.c ppm_rw.c bmp_rw.c) + target_include_directories(ntsc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_definitions(ntsc PRIVATE CRT_SYSTEM=${CRT_SYSTEM}) + target_compile_definitions(ntsc PRIVATE + CMD_LINE_VERSION=$> + $<$:_CRT_SECURE_NO_WARNINGS> + ) + target_link_libraries(ntsc PRIVATE + $<$:fw::fw> + $<$:winmm> + ) +endif() # --- auto-ignore build directory if(NOT EXISTS ${PROJECT_BINARY_DIR}/.gitignore) - file(WRITE ${PROJECT_BINARY_DIR}/.gitignore "*") + file(WRITE ${PROJECT_BINARY_DIR}/.gitignore "*") endif() diff --git a/README.md b/README.md index b8691ed..7a4369f 100644 --- a/README.md +++ b/README.md @@ -81,10 +81,14 @@ cc -O3 -o ntsc *.c or using CMake on Linux, macOS, or Windows: +**Note:** There are 3 available flags / variables: +- `LIVE` (default: `off`) - Set to `on` to enable rendering to a video window from an input PPM/BMP image file +- `VIDEO` (default: `off`) - Set to `on` to enable rendering of sequence of frames. See `video_convert.c` for details +- `CRT_SYSTEM` (default: `0`) - 0 - CRT_SYSTEM_NTSC (standard NTSC), 5 - CRT_SYSTEM_NTSCVHS (standard NTSC VHS). See `crt_core.h` for details + ```sh -cmake -B build -cmake --build build -build/ntsc +cmake -B build -DLIVE=off -DVIDEO=on -DCRT_SYSTEM=5 +cmake --build build --config Release ``` The default command line takes a single PPM or BMP image file and outputs a processed PPM or BMP file: @@ -107,12 +111,34 @@ sample usage: ./ntsc - 832 624 0 90 in.ppm out.ppm by default, the image will be full color, interlaced, and scaled to the output dimensions ``` -There is also the option of "live" rendering to a video window from an input PPM/BMP image file: +If `-DVIDEO=on` is specified, the command line output will look like this: -```sh -cmake -B build -Dlive=on -cmake --build build -build/ntsc my.ppm +``` +NTSC/CRT v2.2.1 by EMMIR 2018-2023 +This program does not operate on video files, only sequences of +images. Please make sure you have the FFMPEG command line tools +installed and follow these instructions to convert a video +using the NTSC/CRT library: + mkdir frames + mkdir output + ffmpeg -r 1 -i your_video.mov -r 1 ./frames/$frame%06d.bmp + ./ntsc_video.exe + ffmpeg -r 30 -f image2 -s 640x480 -i ./output/%06d.bmp -vcodec libx264 -crf 10 -pix_fmt yuv420p out.mp4 + +------------------------------------------------------------ +usage: ntsc_video.exe -m|o|p|s|h num_frames outwidth outheight noise +sample usage: ntsc_video.exe -oa 5000 640 480 0 +sample usage: ntsc_video.exe - 1400 832 624 12 +-- NOTE: the - after the program name is required +------------------------------------------------------------ + m : monochrome + o : do not prompt when overwriting files + a : mess up the bottom of the frame (useful for the VHS look) + s : fill in gaps between scan lines + p : progressive scan (rather than interlaced) + h : print help + +by default, the image will be full color and interlaced ``` ### Adding NTSC-CRT to your C/C++ project: diff --git a/crt_core.h b/crt_core.h index 1ae133b..bb09b00 100644 --- a/crt_core.h +++ b/crt_core.h @@ -35,7 +35,9 @@ extern "C" { #define CRT_SYSTEM_NTSCVHS 5 /* standard NTSC VHS */ /* the system to be compiled */ +#ifndef CRT_SYSTEM #define CRT_SYSTEM CRT_SYSTEM_NTSC +#endif #if (CRT_SYSTEM == CRT_SYSTEM_NES) #include "crt_nes.h"