Restore support for the Nokia N-Gage (#12148)
This commit is contained in:
parent
26f9940f82
commit
7ae64592c9
51 changed files with 4184 additions and 44 deletions
102
.github/actions/setup-ngage-sdk/action.yml
vendored
Normal file
102
.github/actions/setup-ngage-sdk/action.yml
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
name: 'Setup Nonka N-Gage SDK'
|
||||
description: 'Download and setup Nokia N-Gage SDK'
|
||||
inputs:
|
||||
path:
|
||||
description: 'Installation path'
|
||||
default: 'default'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: 'Verify platform'
|
||||
id: calc
|
||||
shell: sh
|
||||
run: |
|
||||
case "${{ runner.os }}-${{ runner.arch }}" in
|
||||
"Windows-X86" | "Windows-X64")
|
||||
echo "ok!"
|
||||
echo "cache-key=ngage-sdk-windows" >> ${GITHUB_OUTPUT}
|
||||
default_install_path="C:/ngagesdk"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported ${{ runner.os }}-${{ runner.arch }}"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
install_path="${{ inputs.path }}"
|
||||
if [ "x$install_path" = "xdefault" ]; then
|
||||
install_path="$default_install_path"
|
||||
fi
|
||||
echo "install-path=$install_path" >> ${GITHUB_OUTPUT}
|
||||
|
||||
toolchain_repo="https://github.com/ngagesdk/ngage-toolchain"
|
||||
toolchain_branch="main"
|
||||
echo "toolchain-repo=${toolchain_repo}" >> ${GITHUB_OUTPUT}
|
||||
echo "toolchain-branch=${toolchain_branch}" >> ${GITHUB_OUTPUT}
|
||||
|
||||
sdk_repo="https://github.com/ngagesdk/sdk"
|
||||
sdk_branch="main"
|
||||
echo "sdk-repo=${sdk_repo}" >> ${GITHUB_OUTPUT}
|
||||
echo "sdk-branch=${sdk_branch}" >> ${GITHUB_OUTPUT}
|
||||
|
||||
tools_repo="https://github.com/ngagesdk/tools"
|
||||
tools_branch="main"
|
||||
echo "tools-repo=${tools_repo}" >> ${GITHUB_OUTPUT}
|
||||
echo "tools-branch=${tools_branch}" >> ${GITHUB_OUTPUT}
|
||||
|
||||
extras_repo="https://github.com/ngagesdk/extras"
|
||||
extras_branch="main"
|
||||
echo "extras-repo=${extras_repo}" >> ${GITHUB_OUTPUT}
|
||||
echo "extras-branch=${extras_branch}" >> ${GITHUB_OUTPUT}
|
||||
# - name: 'Restore cached ${{ steps.calc.outputs.archive }}'
|
||||
# id: cache-restore
|
||||
# uses: actions/cache/restore@v4
|
||||
# with:
|
||||
# path: '${{ runner.temp }}'
|
||||
# key: ${{ steps.calc.outputs.cache-key }}
|
||||
- name: 'Download N-Gage SDK'
|
||||
# if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
|
||||
Invoke-WebRequest "${{ steps.calc.outputs.toolchain-repo }}/archive/refs/heads/${{ steps.calc.outputs.toolchain-branch }}.zip" -OutFile "${{ runner.temp }}/ngage-toolchain.zip"
|
||||
Invoke-WebRequest "${{ steps.calc.outputs.sdk-repo }}/archive/refs/heads/${{ steps.calc.outputs.sdk-branch }}.zip" -OutFile "${{ runner.temp }}/sdk.zip"
|
||||
Invoke-WebRequest "${{ steps.calc.outputs.tools-repo }}/archive/refs/heads/${{ steps.calc.outputs.tools-branch }}.zip" -OutFile "${{ runner.temp }}/tools.zip"
|
||||
Invoke-WebRequest "${{ steps.calc.outputs.extras-repo }}/archive/refs/heads/${{ steps.calc.outputs.extras-branch }}.zip" -OutFile "${{ runner.temp }}/extras.zip"
|
||||
|
||||
# - name: 'Cache ${{ steps.calc.outputs.archive }}'
|
||||
# if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }}
|
||||
# uses: actions/cache/save@v4
|
||||
# with:
|
||||
# path: |
|
||||
# ${{ runner.temp }}/apps.zip
|
||||
# ${{ runner.temp }}/sdk.zip
|
||||
# ${{ runner.temp }}/tools.zip
|
||||
# key: ${{ steps.calc.outputs.cache-key }}
|
||||
- name: 'Extract N-Gage SDK'
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Path "${{ steps.calc.outputs.install-path }}" -Force
|
||||
|
||||
New-Item -ItemType Directory -Path "${{ runner.temp }}/ngage-toolchain-temp" -Force
|
||||
7z "-o${{ runner.temp }}/ngage-toolchain-temp" x "${{ runner.temp }}/ngage-toolchain.zip"
|
||||
Move-Item -Path "${{ runner.temp }}/ngage-toolchain-temp/ngage-toolchain-${{ steps.calc.outputs.toolchain-branch }}/*" -Destination "${{ steps.calc.outputs.install-path }}"
|
||||
|
||||
7z "-o${{ steps.calc.outputs.install-path }}/sdk" x "${{ runner.temp }}/sdk.zip"
|
||||
Move-Item -Path "${{ steps.calc.outputs.install-path }}/sdk/sdk-${{ steps.calc.outputs.sdk-branch }}" -Destination "${{ steps.calc.outputs.install-path }}/sdk/sdk"
|
||||
|
||||
7z "-o${{ steps.calc.outputs.install-path }}/sdk" x "${{ runner.temp }}/tools.zip"
|
||||
Move-Item -Path "${{ steps.calc.outputs.install-path }}/sdk/tools-${{ steps.calc.outputs.tools-branch }}" -Destination "${{ steps.calc.outputs.install-path }}/sdk/tools"
|
||||
|
||||
7z "-o${{ steps.calc.outputs.install-path }}/sdk" x "${{ runner.temp }}/extras.zip"
|
||||
Move-Item -Path "${{ steps.calc.outputs.install-path }}/sdk/extras-${{ steps.calc.outputs.extras-branch }}" -Destination "${{ steps.calc.outputs.install-path }}/sdk/extras"
|
||||
- name: 'Set output variables'
|
||||
id: final
|
||||
shell: sh
|
||||
run: |
|
||||
echo "${{ steps.calc.outputs.install-path }}/sdk/sdk/6.1/Shared/EPOC32/gcc/bin" >> $GITHUB_PATH
|
||||
echo "${{ steps.calc.outputs.install-path }}/sdk/sdk/6.1/Shared/EPOC32/ngagesdk/bin" >> $GITHUB_PATH
|
||||
echo "NGAGESDK=${{ steps.calc.outputs.install-path }}" >> $GITHUB_ENV
|
||||
echo "CMAKE_TOOLCHAIN_FILE=${{ steps.calc.outputs.install-path }}/cmake/ngage-toolchain.cmake" >> $GITHUB_ENV
|
21
.github/workflows/create-test-plan.py
vendored
21
.github/workflows/create-test-plan.py
vendored
|
@ -54,6 +54,7 @@ class SdlPlatform(Enum):
|
|||
Riscos = "riscos"
|
||||
FreeBSD = "freebsd"
|
||||
NetBSD = "netbsd"
|
||||
NGage = "ngage"
|
||||
|
||||
|
||||
class Msys2Platform(Enum):
|
||||
|
@ -139,11 +140,12 @@ JOB_SPECS = {
|
|||
"riscos": JobSpec(name="RISC OS", os=JobOs.UbuntuLatest, platform=SdlPlatform.Riscos, artifact="SDL-riscos", container="riscosdotinfo/riscos-gccsdk-4.7:latest", ),
|
||||
"netbsd": JobSpec(name="NetBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.NetBSD, artifact="SDL-netbsd-x64", ),
|
||||
"freebsd": JobSpec(name="FreeBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.FreeBSD, artifact="SDL-freebsd-x64", ),
|
||||
"ngage": JobSpec(name="N-Gage", os=JobOs.WindowsLatest, platform=SdlPlatform.NGage, artifact="SDL-ngage", ),
|
||||
}
|
||||
|
||||
|
||||
class StaticLibType(Enum):
|
||||
MSVC = "SDL3-static.lib"
|
||||
STATIC_LIB = "SDL3-static.lib"
|
||||
A = "libSDL3.a"
|
||||
|
||||
|
||||
|
@ -223,6 +225,7 @@ class JobDetails:
|
|||
check_sources: bool = False
|
||||
setup_python: bool = False
|
||||
pypi_packages: list[str] = dataclasses.field(default_factory=list)
|
||||
setup_gage_sdk_path: str = ""
|
||||
|
||||
def to_workflow(self, enable_artifacts: bool) -> dict[str, str|bool]:
|
||||
data = {
|
||||
|
@ -290,6 +293,7 @@ class JobDetails:
|
|||
"check-sources": self.check_sources,
|
||||
"setup-python": self.setup_python,
|
||||
"pypi-packages": my_shlex_join(self.pypi_packages),
|
||||
"setup-ngage-sdk-path": self.setup_gage_sdk_path,
|
||||
}
|
||||
return {k: v for k, v in data.items() if v != ""}
|
||||
|
||||
|
@ -365,7 +369,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
|||
job.msvc_project_flags.append("-p:TreatWarningsAsError=true")
|
||||
job.test_pkg_config = False
|
||||
job.shared_lib = SharedLibType.WIN32
|
||||
job.static_lib = StaticLibType.MSVC
|
||||
job.static_lib = StaticLibType.STATIC_LIB
|
||||
job.cmake_arguments.extend((
|
||||
"-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase",
|
||||
"-DCMAKE_EXE_LINKER_FLAGS=-DEBUG",
|
||||
|
@ -740,6 +744,19 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
|||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update"
|
||||
job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
|
||||
case SdlPlatform.NGage:
|
||||
build_parallel = False
|
||||
job.cmake_build_type = "Release"
|
||||
job.setup_ninja = True
|
||||
job.static_lib = StaticLibType.STATIC_LIB
|
||||
job.shared_lib = None
|
||||
job.clang_tidy = False
|
||||
job.werror = False # FIXME: enable SDL_WERROR
|
||||
job.shared = False
|
||||
job.run_tests = False
|
||||
job.setup_gage_sdk_path = "C:/ngagesdk"
|
||||
job.cmake_toolchain_file = "C:/ngagesdk/cmake/ngage-toolchain.cmake"
|
||||
job.test_pkg_config = False
|
||||
case _:
|
||||
raise ValueError(f"Unsupported platform={spec.platform}")
|
||||
|
||||
|
|
5
.github/workflows/generic.yml
vendored
5
.github/workflows/generic.yml
vendored
|
@ -93,6 +93,11 @@ jobs:
|
|||
with:
|
||||
arch: ${{ matrix.platform.msvc-vcvars-arch }}
|
||||
sdk: ${{ matrix.platform.msvc-vcvars-sdk }}
|
||||
- name: 'Set up Nokia N-Gage SDK'
|
||||
uses: ./.github/actions/setup-ngage-sdk
|
||||
if: ${{ matrix.platform.setup-ngage-sdk-path != '' }}
|
||||
with:
|
||||
path: '${{ matrix.platform.setup-ngage-sdk-path }}'
|
||||
- name: 'Set up Windows GDK Desktop'
|
||||
uses: ./.github/actions/setup-gdk-desktop
|
||||
if: ${{ matrix.platform.setup-gdk-folder != '' }}
|
||||
|
|
102
CMakeLists.txt
102
CMakeLists.txt
|
@ -76,6 +76,7 @@ include("${SDL3_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake")
|
|||
include("${SDL3_SOURCE_DIR}/cmake/3rdparty.cmake")
|
||||
include("${SDL3_SOURCE_DIR}/cmake/PreseedMSVCCache.cmake")
|
||||
include("${SDL3_SOURCE_DIR}/cmake/PreseedEmscriptenCache.cmake")
|
||||
include("${SDL3_SOURCE_DIR}/cmake/PreseedNokiaNGageCache.cmake")
|
||||
|
||||
SDL_DetectCompiler()
|
||||
SDL_DetectTargetCPUArchitectures(SDL_CPUS)
|
||||
|
@ -155,7 +156,7 @@ endif()
|
|||
# The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers,
|
||||
# so we'll just use libusb when it's available. libusb does not support iOS,
|
||||
# so we default to yes on iOS.
|
||||
if(IOS OR TVOS OR VISIONOS OR WATCHOS OR ANDROID)
|
||||
if(IOS OR TVOS OR VISIONOS OR WATCHOS OR ANDROID OR NGAGE)
|
||||
set(SDL_HIDAPI_LIBUSB_AVAILABLE FALSE)
|
||||
else()
|
||||
set(SDL_HIDAPI_LIBUSB_AVAILABLE TRUE)
|
||||
|
@ -219,7 +220,7 @@ if(EMSCRIPTEN)
|
|||
set(SDL_SHARED_AVAILABLE OFF)
|
||||
endif()
|
||||
|
||||
if(VITA OR PSP OR PS2 OR N3DS OR RISCOS)
|
||||
if(VITA OR PSP OR PS2 OR N3DS OR RISCOS OR NGAGE)
|
||||
set(SDL_SHARED_AVAILABLE OFF)
|
||||
endif()
|
||||
|
||||
|
@ -414,6 +415,24 @@ if(VITA)
|
|||
set_option(VIDEO_VITA_PVR "Build with PSVita PVR gles/gles2 support" OFF)
|
||||
endif()
|
||||
|
||||
if (NGAGE)
|
||||
set(SDL_GPU OFF)
|
||||
set(SDL_CAMERA OFF)
|
||||
set(SDL_JOYSTICK OFF)
|
||||
set(SDL_HAPTIC OFF)
|
||||
set(SDL_HIDAPI OFF)
|
||||
set(SDL_POWER OFF)
|
||||
set(SDL_SENSOR OFF)
|
||||
set(SDL_DIALOG OFF)
|
||||
set(SDL_DISKAUDIO OFF)
|
||||
set(SDL_DUMMYAUDIO OFF)
|
||||
set(SDL_DUMMYCAMERA OFF)
|
||||
set(SDL_DUMMYVIDEO OFF)
|
||||
set(SDL_OFFSCREEN OFF)
|
||||
set(SDL_RENDER_GPU OFF)
|
||||
set(SDL_VIRTUAL_JOYSTICK OFF)
|
||||
endif()
|
||||
|
||||
if(NOT (SDL_SHARED OR SDL_STATIC))
|
||||
message(FATAL_ERROR "SDL_SHARED and SDL_STATIC cannot both be disabled")
|
||||
endif()
|
||||
|
@ -2931,6 +2950,81 @@ elseif(N3DS)
|
|||
set(HAVE_SDL_LOCALE TRUE)
|
||||
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/io/n3ds/*.c")
|
||||
|
||||
elseif(NGAGE)
|
||||
|
||||
enable_language(CXX)
|
||||
|
||||
set(SDL_MAIN_USE_CALLBACKS 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/ngage/*.c")
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/ngage/*.cpp")
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/ngage/*.cpp")
|
||||
set(HAVE_SDL_MAIN_CALLBACKS TRUE)
|
||||
|
||||
if(SDL_AUDIO)
|
||||
set(SDL_AUDIO_DRIVER_NGAGE 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/audio/ngage/*.c")
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/audio/ngage/*.cpp")
|
||||
set(HAVE_SDL_AUDIO TRUE)
|
||||
endif()
|
||||
|
||||
set(SDL_FILESYSTEM_NGAGE 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/filesystem/ngage/*.c")
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/filesystem/ngage/*.cpp")
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/filesystem/posix/*.c")
|
||||
set(HAVE_SDL_FILESYSTEM TRUE)
|
||||
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/locale/ngage/*.cpp")
|
||||
|
||||
if(SDL_RENDER)
|
||||
set(SDL_VIDEO_RENDER_NGAGE 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/render/ngage/*.c")
|
||||
endif()
|
||||
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/time/ngage/*.cpp")
|
||||
set(SDL_TIME_NGAGE 1)
|
||||
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/render/ngage/*.cpp")
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/time/unix/*.c")
|
||||
|
||||
set(SDL_TIMER_NGAGE 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/timer/ngage/*.cpp")
|
||||
|
||||
set(SDL_FSOPS_POSIX 1)
|
||||
|
||||
set(SDL_VIDEO_DRIVER_NGAGE 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/video/ngage/*.c")
|
||||
set(HAVE_SDL_TIMERS TRUE)
|
||||
|
||||
set_option(SDL_LEAN_AND_MEAN "Enable lean and mean" ON)
|
||||
if(SDL_LEAN_AND_MEAN)
|
||||
sdl_compile_definitions(
|
||||
PRIVATE
|
||||
SDL_LEAN_AND_MEAN
|
||||
)
|
||||
endif()
|
||||
|
||||
sdl_link_dependency(ngage
|
||||
LINK_OPTIONS "SHELL:-s MAIN_COMPAT=0"
|
||||
PKG_CONFIG_LINK_OPTIONS "-s;MAIN_COMPAT=0"
|
||||
LIBS
|
||||
NRenderer
|
||||
3dtypes
|
||||
cone
|
||||
libgcc
|
||||
libgcc_ngage
|
||||
mediaclientaudiostream
|
||||
charconv
|
||||
bitgdi
|
||||
euser
|
||||
estlib
|
||||
ws32
|
||||
hal
|
||||
fbscli
|
||||
efsrv
|
||||
scdv
|
||||
gdi
|
||||
)
|
||||
endif()
|
||||
|
||||
sdl_sources(${SDL3_SOURCE_DIR}/src/dialog/SDL_dialog.c)
|
||||
|
@ -3111,8 +3205,8 @@ endif()
|
|||
|
||||
# We always need to have threads and timers around
|
||||
if(NOT HAVE_SDL_THREADS)
|
||||
# The emscripten platform has been carefully vetted to work without threads
|
||||
if(EMSCRIPTEN)
|
||||
# The Emscripten and N-Gage platform has been carefully vetted to work without threads
|
||||
if(EMSCRIPTEN OR NGAGE)
|
||||
set(SDL_THREADS_DISABLED 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/thread/generic/*.c")
|
||||
else()
|
||||
|
|
189
cmake/PreseedNokiaNGageCache.cmake
Normal file
189
cmake/PreseedNokiaNGageCache.cmake
Normal file
|
@ -0,0 +1,189 @@
|
|||
if(NGAGESDK)
|
||||
function(SDL_Preseed_CMakeCache)
|
||||
set(COMPILER_SUPPORTS_ARMNEON "" CACHE INTERNAL "Test COMPILER_SUPPORTS_ARMNEON")
|
||||
set(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS "" CACHE INTERNAL "Test COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS")
|
||||
set(COMPILER_SUPPORTS_SYNC_LOCK_TEST_AND_SET "" CACHE INTERNAL "Test COMPILER_SUPPORTS_SYNC_LOCK_TEST_AND_SET")
|
||||
set(HAVE_CLANG_COMMENT_BLOCK_COMMANDS "" CACHE INTERNAL "Test HAVE_CLANG_COMMENT_BLOCK_COMMANDS")
|
||||
set(HAVE_ALLOCA_H "" CACHE INTERNAL "Have include alloca.h")
|
||||
set(HAVE_LIBM "1" CACHE INTERNAL "Have library m")
|
||||
set(HAVE_POSIX_SPAWN "" CACHE INTERNAL "Have symbol posix_spawn")
|
||||
set(HAVE_MALLOC "1" CACHE INTERNAL "Have include malloc.h")
|
||||
set(LIBC_HAS_ABS "1" CACHE INTERNAL "Have symbol abs")
|
||||
set(LIBC_HAS_ACOS "1" CACHE INTERNAL "Have symbol acos")
|
||||
set(LIBC_HAS_ACOSF "" CACHE INTERNAL "Have symbol acosf")
|
||||
set(LIBC_HAS_ASIN "1" CACHE INTERNAL "Have symbol asin")
|
||||
set(LIBC_HAS_ASINF "" CACHE INTERNAL "Have symbol asinf")
|
||||
set(LIBC_HAS_ATAN "1" CACHE INTERNAL "Have symbol atan")
|
||||
set(LIBC_HAS_ATAN2 "1" CACHE INTERNAL "Have symbol atan2")
|
||||
set(LIBC_HAS_ATAN2F "" CACHE INTERNAL "Have symbol atan2f")
|
||||
set(LIBC_HAS_ATANF "" CACHE INTERNAL "Have symbol atanf")
|
||||
set(LIBC_HAS_ATOF "" CACHE INTERNAL "Have symbol atof")
|
||||
set(LIBC_HAS_ATOI "" CACHE INTERNAL "Have symbol atoi")
|
||||
set(LIBC_HAS_BCOPY "1" CACHE INTERNAL "Have symbol bcopy")
|
||||
set(LIBC_HAS_CALLOC "" CACHE INTERNAL "Have symbol calloc")
|
||||
set(LIBC_HAS_CEIL "1" CACHE INTERNAL "Have symbol ceil")
|
||||
set(LIBC_HAS_CEILF "" CACHE INTERNAL "Have symbol ceilf")
|
||||
set(LIBC_HAS_COPYSIGN "1" CACHE INTERNAL "Have symbol copysign")
|
||||
set(LIBC_HAS_COPYSIGNF "1" CACHE INTERNAL "Have symbol copysignf")
|
||||
set(LIBC_HAS_COS "1" CACHE INTERNAL "Have symbol cos")
|
||||
set(LIBC_HAS_COSF "" CACHE INTERNAL "Have symbol cosf")
|
||||
set(LIBC_HAS_EXP "1" CACHE INTERNAL "Have symbol exp")
|
||||
set(LIBC_HAS_EXPF "" CACHE INTERNAL "Have symbol expf")
|
||||
set(LIBC_HAS_FABS "1" CACHE INTERNAL "Have symbol fabs")
|
||||
set(LIBC_HAS_FABSF "1" CACHE INTERNAL "Have symbol fabsf")
|
||||
set(LIBC_HAS_FLOAT_H "1" CACHE INTERNAL "Have include float.h")
|
||||
set(LIBC_HAS_FLOOR "1" CACHE INTERNAL "Have symbol floor")
|
||||
set(LIBC_HAS_FLOORF "" CACHE INTERNAL "Have symbol floorf")
|
||||
set(LIBC_HAS_FMOD "" CACHE INTERNAL "Have symbol fmod")
|
||||
set(LIBC_HAS_FMODF "" CACHE INTERNAL "Have symbol fmodf")
|
||||
set(LIBC_HAS_FOPEN64 "" CACHE INTERNAL "Have symbol fopen64")
|
||||
set(LIBC_HAS_FREE "1" CACHE INTERNAL "Have symbol free")
|
||||
set(LIBC_HAS_FSEEKO "" CACHE INTERNAL "Have symbol fseeko")
|
||||
set(LIBC_HAS_FSEEKO64 "" CACHE INTERNAL "Have symbol fseeko64")
|
||||
set(LIBC_HAS_GETENV "" CACHE INTERNAL "Have symbol getenv")
|
||||
set(LIBC_HAS_ICONV_H "" CACHE INTERNAL "Have include iconv.h")
|
||||
set(LIBC_HAS_INDEX "1" CACHE INTERNAL "Have symbol index")
|
||||
set(LIBC_HAS_INTTYPES_H "1" CACHE INTERNAL "Have include inttypes.h")
|
||||
set(LIBC_HAS_ISINF "1" CACHE INTERNAL "Have include isinf(double)")
|
||||
set(LIBC_ISINF_HANDLES_FLOAT "1" CACHE INTERNAL "Have include isinf(float)")
|
||||
set(LIBC_HAS_ISINFF "1" CACHE INTERNAL "Have include isinff(float)")
|
||||
set(LIBC_HAS_ISNAN "1" CACHE INTERNAL "Have include isnan(double)")
|
||||
set(LIBC_ISNAN_HANDLES_FLOAT "1" CACHE INTERNAL "Have include isnan(float)")
|
||||
set(LIBC_HAS_ISNANF "1" CACHE INTERNAL "Have include isnanf(float)")
|
||||
set(LIBC_HAS_ITOA "" CACHE INTERNAL "Have symbol itoa")
|
||||
set(LIBC_HAS_LIMITS_H "1" CACHE INTERNAL "Have include limits.h")
|
||||
set(LIBC_HAS_LOG "1" CACHE INTERNAL "Have symbol log")
|
||||
set(LIBC_HAS_LOG10 "" CACHE INTERNAL "Have symbol log10")
|
||||
set(LIBC_HAS_LOG10F "" CACHE INTERNAL "Have symbol log10f")
|
||||
set(LIBC_HAS_LOGF "" CACHE INTERNAL "Have symbol logf")
|
||||
set(LIBC_HAS_LROUND "" CACHE INTERNAL "Have symbol lround")
|
||||
set(LIBC_HAS_LROUNDF "" CACHE INTERNAL "Have symbol lroundf")
|
||||
set(LIBC_HAS_MALLOC "1" CACHE INTERNAL "Have symbol malloc")
|
||||
set(LIBC_HAS_MALLOC_H "" CACHE INTERNAL "Have include malloc.h")
|
||||
set(LIBC_HAS_MATH_H "1" CACHE INTERNAL "Have include math.h")
|
||||
set(LIBC_HAS_MEMCMP "1" CACHE INTERNAL "Have symbol memcmp")
|
||||
set(LIBC_HAS_MEMCPY "" CACHE INTERNAL "Have symbol memcpy")
|
||||
set(LIBC_HAS_MEMMOVE "" CACHE INTERNAL "Have symbol memmove")
|
||||
set(LIBC_HAS_MEMORY_H "" CACHE INTERNAL "Have include memory.h")
|
||||
set(LIBC_HAS_MEMSET "" CACHE INTERNAL "Have symbol memset")
|
||||
set(LIBC_HAS_MODF "1" CACHE INTERNAL "Have symbol modf")
|
||||
set(LIBC_HAS_MODFF "" CACHE INTERNAL "Have symbol modff")
|
||||
set(LIBC_HAS_POW "1" CACHE INTERNAL "Have symbol pow")
|
||||
set(LIBC_HAS_POWF "" CACHE INTERNAL "Have symbol powf")
|
||||
set(LIBC_HAS_PUTENV "" CACHE INTERNAL "Have symbol putenv")
|
||||
set(LIBC_HAS_REALLOC "" CACHE INTERNAL "Have symbol realloc")
|
||||
set(LIBC_HAS_RINDEX "1" CACHE INTERNAL "Have symbol rindex")
|
||||
set(LIBC_HAS_ROUND "" CACHE INTERNAL "Have symbol round")
|
||||
set(LIBC_HAS_ROUNDF "" CACHE INTERNAL "Have symbol roundf")
|
||||
set(LIBC_HAS_SCALBN "1" CACHE INTERNAL "Have symbol scalbn")
|
||||
set(LIBC_HAS_SCALBNF "" CACHE INTERNAL "Have symbol scalbnf")
|
||||
set(LIBC_HAS_SETENV "" CACHE INTERNAL "Have symbol setenv")
|
||||
set(LIBC_HAS_SIGNAL_H "" CACHE INTERNAL "Have include signal.h")
|
||||
set(LIBC_HAS_SIN "1" CACHE INTERNAL "Have symbol sin")
|
||||
set(LIBC_HAS_SINF "" CACHE INTERNAL "Have symbol sinf")
|
||||
set(LIBC_HAS_SQR "" CACHE INTERNAL "Have symbol sqr")
|
||||
set(LIBC_HAS_SQRT "1" CACHE INTERNAL "Have symbol sqrt")
|
||||
set(LIBC_HAS_SQRTF "" CACHE INTERNAL "Have symbol sqrtf")
|
||||
set(LIBC_HAS_SSCANF "1" CACHE INTERNAL "Have symbol sscanf")
|
||||
set(LIBC_HAS_STDARG_H "1" CACHE INTERNAL "Have include stdarg.h")
|
||||
set(LIBC_HAS_STDBOOL_H "1" CACHE INTERNAL "Have include stdbool.h")
|
||||
set(LIBC_HAS_STDDEF_H "1" CACHE INTERNAL "Have include stddef.h")
|
||||
set(LIBC_HAS_STDINT_H "1" CACHE INTERNAL "Have include stdint.h")
|
||||
set(LIBC_HAS_STDIO_H "1" CACHE INTERNAL "Have include stdio.h")
|
||||
set(LIBC_HAS_STDLIB_H "1" CACHE INTERNAL "Have include stdlib.h")
|
||||
set(LIBC_HAS_STRCASESTR "" CACHE INTERNAL "Have symbol strcasestr")
|
||||
set(LIBC_HAS_STRCHR "1" CACHE INTERNAL "Have symbol strchr")
|
||||
set(LIBC_HAS_STRCMP "1" CACHE INTERNAL "Have symbol strcmp")
|
||||
set(LIBC_HAS_STRINGS_H "" CACHE INTERNAL "Have include strings.h")
|
||||
set(LIBC_HAS_STRING_H "1" CACHE INTERNAL "Have include string.h")
|
||||
set(LIBC_HAS_STRLCAT "" CACHE INTERNAL "Have symbol strlcat")
|
||||
set(LIBC_HAS_STRLCPY "" CACHE INTERNAL "Have symbol strlcpy")
|
||||
set(LIBC_HAS_STRLEN "1" CACHE INTERNAL "Have symbol strlen")
|
||||
set(LIBC_HAS_STRNCMP "1" CACHE INTERNAL "Have symbol strncmp")
|
||||
set(LIBC_HAS_STRNLEN "" CACHE INTERNAL "Have symbol strnlen")
|
||||
set(LIBC_HAS_STRNSTR "" CACHE INTERNAL "Have symbol strnstr")
|
||||
set(LIBC_HAS_STRPBRK "1" CACHE INTERNAL "Have symbol strpbrk")
|
||||
set(LIBC_HAS_STRRCHR "1" CACHE INTERNAL "Have symbol strrchr")
|
||||
set(LIBC_HAS_STRSTR "1" CACHE INTERNAL "Have symbol strstr")
|
||||
set(LIBC_HAS_STRTOD "" CACHE INTERNAL "Have symbol strtod")
|
||||
set(LIBC_HAS_STRTOK_R "" CACHE INTERNAL "Have symbol strtok_r")
|
||||
set(LIBC_HAS_STRTOL "" CACHE INTERNAL "Have symbol strtol")
|
||||
set(LIBC_HAS_STRTOLL "" CACHE INTERNAL "Have symbol strtoll")
|
||||
set(LIBC_HAS_STRTOUL "" CACHE INTERNAL "Have symbol strtoul")
|
||||
set(LIBC_HAS_STRTOULL "" CACHE INTERNAL "Have symbol strtoull")
|
||||
set(LIBC_HAS_SYS_TYPES_H "1" CACHE INTERNAL "Have include sys/types.h")
|
||||
set(LIBC_HAS_TAN "1" CACHE INTERNAL "Have symbol tan")
|
||||
set(LIBC_HAS_TANF "" CACHE INTERNAL "Have symbol tanf")
|
||||
set(LIBC_HAS_TIME_H "1" CACHE INTERNAL "Have include time.h")
|
||||
set(LIBC_HAS_TRUNC "" CACHE INTERNAL "Have symbol trunc")
|
||||
set(LIBC_HAS_TRUNCF "" CACHE INTERNAL "Have symbol truncf")
|
||||
set(LIBC_HAS_UNSETENV "" CACHE INTERNAL "Have symbol unsetenv")
|
||||
set(LIBC_HAS_VSNPRINTF "" CACHE INTERNAL "Have symbol vsnprintf")
|
||||
set(LIBC_HAS_VSSCANF "" CACHE INTERNAL "Have symbol vsscanf")
|
||||
set(LIBC_HAS_WCHAR_H "1" CACHE INTERNAL "Have include wchar.h")
|
||||
set(LIBC_HAS_WCSCMP "" CACHE INTERNAL "Have symbol wcscmp")
|
||||
set(LIBC_HAS_WCSDUP "" CACHE INTERNAL "Have symbol wcsdup")
|
||||
set(LIBC_HAS_WCSLCAT "" CACHE INTERNAL "Have symbol wcslcat")
|
||||
set(LIBC_HAS_WCSLCPY "" CACHE INTERNAL "Have symbol wcslcpy")
|
||||
set(LIBC_HAS_WCSLEN "" CACHE INTERNAL "Have symbol wcslen")
|
||||
set(LIBC_HAS_WCSNCMP "" CACHE INTERNAL "Have symbol wcsncmp")
|
||||
set(LIBC_HAS_WCSNLEN "" CACHE INTERNAL "Have symbol wcsnlen")
|
||||
set(LIBC_HAS_WCSSTR "" CACHE INTERNAL "Have symbol wcsstr")
|
||||
set(LIBC_HAS_WCSTOL "" CACHE INTERNAL "Have symbol wcstol")
|
||||
set(LIBC_HAS__EXIT "" CACHE INTERNAL "Have symbol _Exit")
|
||||
set(LIBC_HAS__I64TOA "" CACHE INTERNAL "Have symbol _i64toa")
|
||||
set(LIBC_HAS__LTOA "" CACHE INTERNAL "Have symbol _ltoa")
|
||||
set(LIBC_HAS__STRREV "" CACHE INTERNAL "Have symbol _strrev")
|
||||
set(LIBC_HAS__UI64TOA "" CACHE INTERNAL "Have symbol _ui64toa")
|
||||
set(LIBC_HAS__UITOA "" CACHE INTERNAL "Have symbol _uitoa")
|
||||
set(LIBC_HAS__ULTOA "" CACHE INTERNAL "Have symbol _ultoa")
|
||||
set(LIBC_HAS__WCSDUP "" CACHE INTERNAL "Have symbol _wcsdup")
|
||||
set(LIBC_IS_GLIBC "" CACHE INTERNAL "Have symbol __GLIBC__")
|
||||
set(_ALLOCA_IN_MALLOC_H "" CACHE INTERNAL "Have symbol _alloca")
|
||||
set(HAVE_GCC_WALL "1" CACHE INTERNAL "Test HAVE_GCC_WALL")
|
||||
set(HAVE_GCC_WUNDEF "1" CACHE INTERNAL "Test HAVE_GCC_WUNDEF")
|
||||
set(HAVE_GCC_WFLOAT_CONVERSION "" CACHE INTERNAL "Test HAVE_GCC_WFLOAT_CONVERSION")
|
||||
set(HAVE_GCC_NO_STRICT_ALIASING "1" CACHE INTERNAL "Test HAVE_GCC_NO_STRICT_ALIASING")
|
||||
set(HAVE_GCC_WDOCUMENTATION "" CACHE INTERNAL "Test HAVE_GCC_WDOCUMENTATION")
|
||||
set(HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND "" CACHE INTERNAL "Test HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND")
|
||||
set(HAVE_GCC_COMMENT_BLOCK_COMMANDS "" CACHE INTERNAL "Test HAVE_GCC_COMMENT_BLOCK_COMMANDS")
|
||||
set(HAVE_GCC_WSHADOW "1" CACHE INTERNAL "Test HAVE_GCC_WSHADOW")
|
||||
set(HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS "" CACHE INTERNAL "Test HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS")
|
||||
set(HAVE_GCC_WIMPLICIT_FALLTHROUGH "" CACHE INTERNAL "Test HAVE_GCC_WIMPLICIT_FALLTHROUGH")
|
||||
set(HAVE_GCC_FVISIBILITY "" CACHE INTERNAL "Test HAVE_GCC_FVISIBILITY")
|
||||
set(HAVE_ST_MTIM "" CACHE INTERNAL "Test HAVE_ST_MTIM")
|
||||
#set(HAVE_O_CLOEXEC "" CACHE INTERNAL "Test HAVE_O_CLOEXEC")
|
||||
#set(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR "" CACHE INTERNAL "Test COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR")
|
||||
set(COMPILER_SUPPORTS_GCC_ATOMICS "" CACHE INTERNAL "Test COMPILER_SUPPORTS_GCC_ATOMICS")
|
||||
set(LINKER_SUPPORTS_VERSION_SCRIPT "" CACHE INTERNAL "Test LINKER_SUPPORTS_VERSION_SCRIPT")
|
||||
set(LINKER_SUPPORTS_WL_NO_UNDEFINED "" CACHE INTERNAL "Test LINKER_SUPPORTS_WL_NO_UNDEFINED")
|
||||
set(ICONV_IN_LIBC "" CACHE INTERNAL "Test ICONV_IN_LIBC")
|
||||
set(ICONV_IN_LIBICONV "" CACHE INTERNAL "Test ICONV_IN_LIBICONV")
|
||||
#set(LIBC_HAS_WORKING_LIBUNWIND "" CACHE INTERNAL "Test LIBC_HAS_WORKING_LIBUNWIND")
|
||||
#set(LIBUNWIND_HAS_WORKINGLIBUNWIND "" CACHE INTERNAL "Test LIBUNWIND_HAS_WORKINGLIBUNWIND")
|
||||
set(HAVE_GETPAGESIZE "" CACHE INTERNAL "Have symbol getpagesize")
|
||||
set(HAVE_SIGACTION "" CACHE INTERNAL "Have symbol sigaction")
|
||||
set(HAVE_SA_SIGACTION "" CACHE INTERNAL "Have symbol sa_sigaction")
|
||||
set(HAVE_SETJMP "" CACHE INTERNAL "Have symbol setjmp")
|
||||
set(HAVE_NANOSLEEP "" CACHE INTERNAL "Have symbol nanosleep")
|
||||
set(HAVE_GMTIME_R "" CACHE INTERNAL "Have symbol gmtime_r")
|
||||
set(HAVE_LOCALTIME_R "" CACHE INTERNAL "Have symbol localtime_r")
|
||||
set(HAVE_NL_LANGINFO "" CACHE INTERNAL "Have symbol nl_langinfo")
|
||||
set(HAVE_SYSCONF "" CACHE INTERNAL "Have symbol sysconf")
|
||||
set(HAVE_SYSCTLBYNAME "" CACHE INTERNAL "Have symbol sysctlbyname")
|
||||
set(HAVE_GETAUXVAL "" CACHE INTERNAL "Have symbol getauxval")
|
||||
set(HAVE_ELF_AUX_INFO "" CACHE INTERNAL "Have symbol elf_aux_info")
|
||||
set(HAVE_POLL "" CACHE INTERNAL "Have symbol poll")
|
||||
set(HAVE_MEMFD_CREATE "" CACHE INTERNAL "Have symbol memfd_create")
|
||||
set(HAVE_POSIX_FALLOCATE "" CACHE INTERNAL "Have symbol posix_fallocate")
|
||||
set(HAVE_DLOPEN_IN_LIBC "" CACHE INTERNAL "Have symbol dlopen")
|
||||
|
||||
set(HAVE_GETHOSTNAME "" CACHE INTERNAL "Have symbol gethostname")
|
||||
set(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR "" CACHE INTERNAL "Have symbol addchdir")
|
||||
set(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP "" CACHE INTERNAL "Have symbol addchdir_np")
|
||||
set(HAVE_FDATASYNC "" CACHE INTERNAL "Have symbol fdatasync")
|
||||
|
||||
set(HAVE_SDL_FSOPS "1" CACHE INTERNAL "Enable SDL_FSOPS")
|
||||
set(HAVE_SDL_LOCALE "1" CACHE INTERNAL "Enable SDL_LOCALE")
|
||||
endfunction()
|
||||
endif()
|
|
@ -22,6 +22,8 @@ function(SDL_DetectCMakePlatform)
|
|||
set(sdl_cmake_platform Haiku)
|
||||
elseif(NINTENDO_3DS)
|
||||
set(sdl_cmake_platform n3ds)
|
||||
elseif(NGAGESDK)
|
||||
set(sdl_cmake_platform ngage)
|
||||
elseif(PS2)
|
||||
set(sdl_cmake_platform ps2)
|
||||
elseif(VITA)
|
||||
|
|
|
@ -96,12 +96,14 @@ if(TEST_STATIC)
|
|||
add_executable(gui-static WIN32 main_gui.c)
|
||||
target_link_libraries(gui-static PRIVATE SDL3::SDL3-static)
|
||||
|
||||
# Assume SDL library has been built with `set(CMAKE_POSITION_INDEPENDENT_CODE ON)`
|
||||
add_library(sharedlib-static SHARED main_lib.c)
|
||||
target_link_libraries(sharedlib-static PRIVATE SDL3::SDL3-static)
|
||||
generate_export_header(sharedlib-static EXPORT_MACRO_NAME MYLIBRARY_EXPORT)
|
||||
target_compile_definitions(sharedlib-static PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-static_export.h\"")
|
||||
set_target_properties(sharedlib-static PROPERTIES C_VISIBILITY_PRESET "hidden")
|
||||
if(TEST_SHARED)
|
||||
# Assume SDL library has been built with `set(CMAKE_POSITION_INDEPENDENT_CODE ON)`
|
||||
add_library(sharedlib-static SHARED main_lib.c)
|
||||
target_link_libraries(sharedlib-static PRIVATE SDL3::SDL3-static)
|
||||
generate_export_header(sharedlib-static EXPORT_MACRO_NAME MYLIBRARY_EXPORT)
|
||||
target_compile_definitions(sharedlib-static PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-static_export.h\"")
|
||||
set_target_properties(sharedlib-static PROPERTIES C_VISIBILITY_PRESET "hidden")
|
||||
endif()
|
||||
|
||||
if(TEST_TEST)
|
||||
add_executable(sdltest-static sdltest.c)
|
||||
|
|
|
@ -1,24 +1,37 @@
|
|||
#include <SDL3/SDL.h>
|
||||
#define SDL_MAIN_USE_CALLBACKS
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
static SDL_Window *window;
|
||||
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_Window *window = NULL;
|
||||
SDL_Surface *screenSurface = NULL;
|
||||
screenSurface = SDL_GetWindowSurface(window);
|
||||
SDL_FillSurfaceRect(screenSurface, NULL, SDL_MapSurfaceRGB(screenSurface, 0xff, 0xff, 0xff));
|
||||
SDL_UpdateWindowSurface(window);
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Could not initialize SDL: %s", SDL_GetError());
|
||||
return 1;
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
window = SDL_CreateWindow("Hello SDL", 640, 480, 0);
|
||||
if (!window) {
|
||||
SDL_Log("could not create window: %s", SDL_GetError());
|
||||
return 1;
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
screenSurface = SDL_GetWindowSurface(window);
|
||||
SDL_FillSurfaceRect(screenSurface, NULL, SDL_MapSurfaceRGB(screenSurface, 0xff, 0xff, 0xff));
|
||||
SDL_UpdateWindowSurface(window);
|
||||
SDL_Delay(100);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result) {
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
#define SDL_MAIN_USE_CALLBACKS
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3/SDL_test.h>
|
||||
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDLTest_CommonState state;
|
||||
SDLTest_CommonDefaultArgs(&state, argc, argv);
|
||||
return 0;
|
||||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result) {
|
||||
}
|
||||
|
|
|
@ -1,5 +1,64 @@
|
|||
Support for the Nokia N-Gage has been removed from SDL3 (but will make a
|
||||
comeback when newer compilers are available for the platform).
|
||||
# Nokia N-Gage
|
||||
|
||||
SDL2 still supports this platform.
|
||||
SDL port for the Nokia N-Gage
|
||||
[Homebrew toolchain](https://github.com/ngagesdk/ngage-toolchain)
|
||||
contributed by:
|
||||
|
||||
- [Michael Fitzmayer](https://github.com/mupfdev)
|
||||
|
||||
- [Anonymous Maarten](https://github.com/madebr)
|
||||
|
||||
Many thanks to:
|
||||
|
||||
- icculus and slouken for always making room for us — even when we show up in 2025
|
||||
still waving the N-Gage flag.
|
||||
|
||||
- The Nokia N-Gage [Discord community](https://discord.gg/dbUzqJ26vs)
|
||||
who keeps the platform alive.
|
||||
|
||||
- The staff and supporters of the
|
||||
[Suomen pelimuseo](https://www.vapriikki.fi/nayttelyt/fantastinen-floppi/), and
|
||||
to Heikki Jungmann, for their ongoing love and dedication for the Nokia N-Gage — you
|
||||
guys are awesome!
|
||||
|
||||
## History
|
||||
|
||||
When SDL support was discontinued due to the lack of C99 support at the time,
|
||||
this version was rebuilt from the ground up after resolving the compiler issues.
|
||||
|
||||
In contrast to the earlier SDL2 port, this version features a dedicated rendering
|
||||
backend and a functional, albeit limited, audio interface. Support for the
|
||||
software renderer has been removed.
|
||||
|
||||
The outcome is a significantly leaner and more efficient SDL port, which we hope
|
||||
will breathe new life into this beloved yet obscure platform.
|
||||
|
||||
## To the Stubborn Legends of the DC Scene
|
||||
|
||||
This port is lovingly dedicated to the ever-nostalgic Dreamcast homebrew scene —
|
||||
because if we managed to pull this off for the N-Gage (yes, the N-Gage), surely
|
||||
you guys can stop clinging to SDL2 like it's a rare Shenmue prototype and finally
|
||||
make the leap to SDL3. It’s 2025, not 1999 — and let’s be honest, you’re rocking
|
||||
a state-of-the-art C23 compiler. The irony writes itself.
|
||||
|
||||
## Existing Issues and Limitations
|
||||
|
||||
- For now, the new
|
||||
[SDL3 main callbacks](https://wiki.libsdl.org/SDL3/README/main-functions#how-to-use-main-callbacks-in-sdl3)
|
||||
are not optional and must be used. This is important as the callbacks
|
||||
are optional on other platforms.
|
||||
|
||||
- If the application is put in the background while sound is playing,
|
||||
some of the audio is looped until the app is back in focus.
|
||||
|
||||
- It is recommended initialising SDLs audio sub-system even when it
|
||||
is not required. The backend is started at a higher level. Initialising
|
||||
SDLs audio sub-system ensures that the backend is properly deinitialised.
|
||||
|
||||
- Because the audio sample rate can change during phone calls, the sample
|
||||
rate is currently fixed at 8kHz to ensure stable behavior. Although
|
||||
dynamically adjusting the sample rate is theoretically possible, the
|
||||
current implementation doesn't support it yet. This limitation is
|
||||
expected to be resolved in a future update.
|
||||
|
||||
- Dependency tracking is currently non-functional.
|
||||
|
|
|
@ -111,6 +111,10 @@ macro(add_sdl_example_executable TARGET)
|
|||
elseif(EMSCRIPTEN)
|
||||
set_property(TARGET ${TARGET} PROPERTY SUFFIX ".html")
|
||||
target_link_options(${TARGET} PRIVATE -sALLOW_MEMORY_GROWTH=1)
|
||||
elseif(NGAGE)
|
||||
string(MD5 TARGET_MD5 "${TARGET}")
|
||||
string(SUBSTRING "${TARGET_MD5}" 0 8 TARGET_MD5_8)
|
||||
target_link_options(${TARGET} PRIVATE "SHELL:-s UID3=0x${TARGET_MD5_8}")
|
||||
endif()
|
||||
|
||||
if(OPENGL_FOUND)
|
||||
|
|
|
@ -132,7 +132,7 @@ extern "C" {
|
|||
#define SDL_TriggerBreakpoint() __debugbreak()
|
||||
#elif defined(_MSC_VER) && defined(_M_IX86)
|
||||
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
|
||||
#elif defined(ANDROID)
|
||||
#elif defined(ANDROID) || defined(__SYMBIAN32__)
|
||||
#include <assert.h>
|
||||
#define SDL_TriggerBreakpoint() assert(0)
|
||||
#elif SDL_HAS_BUILTIN(__builtin_debugtrap)
|
||||
|
|
|
@ -389,7 +389,7 @@
|
|||
#endif /* SDL_FORCE_INLINE not defined */
|
||||
|
||||
#ifndef SDL_NORETURN
|
||||
#ifdef __GNUC__
|
||||
#if defined(__GNUC__)
|
||||
#define SDL_NORETURN __attribute__((noreturn))
|
||||
#elif defined(_MSC_VER)
|
||||
#define SDL_NORETURN __declspec(noreturn)
|
||||
|
|
|
@ -317,7 +317,7 @@
|
|||
#define SDL_PLATFORM_CYGWIN 1
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)
|
||||
#if (defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)) && !defined(__NGAGE__)
|
||||
|
||||
/**
|
||||
* A preprocessor macro that is only defined if compiling for Windows.
|
||||
|
@ -473,4 +473,14 @@
|
|||
#define SDL_PLATFORM_3DS 1
|
||||
#endif
|
||||
|
||||
#ifdef __NGAGE__
|
||||
|
||||
/**
|
||||
* A preprocessor macro that is only defined if compiling for the Nokia N-Gage.
|
||||
*
|
||||
* \since This macro is available since SDL 3.4.0.
|
||||
*/
|
||||
#define SDL_PLATFORM_NGAGE 1
|
||||
#endif
|
||||
|
||||
#endif /* SDL_platform_defines_h_ */
|
||||
|
|
|
@ -277,6 +277,7 @@
|
|||
#cmakedefine SDL_AUDIO_DRIVER_PSP 1
|
||||
#cmakedefine SDL_AUDIO_DRIVER_PS2 1
|
||||
#cmakedefine SDL_AUDIO_DRIVER_N3DS 1
|
||||
#cmakedefine SDL_AUDIO_DRIVER_NGAGE 1
|
||||
#cmakedefine SDL_AUDIO_DRIVER_QNX 1
|
||||
|
||||
#cmakedefine SDL_AUDIO_DRIVER_PRIVATE 1
|
||||
|
@ -365,6 +366,7 @@
|
|||
#cmakedefine SDL_TIME_PSP 1
|
||||
#cmakedefine SDL_TIME_PS2 1
|
||||
#cmakedefine SDL_TIME_N3DS 1
|
||||
#cmakedefine SDL_TIME_NGAGE 1
|
||||
|
||||
/* Enable various timer systems */
|
||||
#cmakedefine SDL_TIMER_HAIKU 1
|
||||
|
@ -387,6 +389,7 @@
|
|||
#cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_N3DS 1
|
||||
#cmakedefine SDL_VIDEO_DRIVER_NGAGE 1
|
||||
#cmakedefine SDL_VIDEO_DRIVER_OFFSCREEN 1
|
||||
#cmakedefine SDL_VIDEO_DRIVER_PS2 1
|
||||
#cmakedefine SDL_VIDEO_DRIVER_PSP 1
|
||||
|
@ -438,6 +441,7 @@
|
|||
#cmakedefine SDL_VIDEO_RENDER_VULKAN 1
|
||||
#cmakedefine SDL_VIDEO_RENDER_OGL 1
|
||||
#cmakedefine SDL_VIDEO_RENDER_OGL_ES2 1
|
||||
#cmakedefine SDL_VIDEO_RENDER_NGAGE 1
|
||||
#cmakedefine SDL_VIDEO_RENDER_PS2 1
|
||||
#cmakedefine SDL_VIDEO_RENDER_PSP 1
|
||||
#cmakedefine SDL_VIDEO_RENDER_VITA_GXM 1
|
||||
|
|
|
@ -728,6 +728,8 @@ const char *SDL_GetPlatform(void)
|
|||
return "macOS";
|
||||
#elif defined(SDL_PLATFORM_NETBSD)
|
||||
return "NetBSD";
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
return "Nokia N-Gage";
|
||||
#elif defined(SDL_PLATFORM_OPENBSD)
|
||||
return "OpenBSD";
|
||||
#elif defined(SDL_PLATFORM_OS2)
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include "stdlib/SDL_vacopy.h"
|
||||
|
||||
// Simple error handling in SDL
|
||||
|
||||
#include "SDL_error_c.h"
|
||||
|
|
|
@ -587,6 +587,25 @@ void SDL_LogMessageV(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_S
|
|||
return;
|
||||
}
|
||||
|
||||
#if defined(SDL_PLATFORM_NGAGE)
|
||||
extern void NGAGE_vnprintf(char *buf, size_t size, const char *fmt, va_list ap);
|
||||
char buf[1024];
|
||||
NGAGE_vnprintf(buf, sizeof(buf), fmt, ap);
|
||||
|
||||
#ifdef ENABLE_FILE_LOG
|
||||
FILE* file;
|
||||
file = fopen("E:/SDL_Log.txt", "a");
|
||||
if (file)
|
||||
{
|
||||
vfprintf(file, fmt, ap);
|
||||
fprintf(file, "\n");
|
||||
(void)fclose(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Render into stack buffer
|
||||
va_copy(aq, ap);
|
||||
len = SDL_vsnprintf(stack_buf, sizeof(stack_buf), fmt, aq);
|
||||
|
@ -767,9 +786,14 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
|||
(void)fclose(pFile);
|
||||
}
|
||||
}
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
{
|
||||
/* Nothing to do here. */
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_STDIO_H) && \
|
||||
!(defined(SDL_PLATFORM_APPLE) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT))) && \
|
||||
!(defined(SDL_PLATFORM_NGAGE)) && \
|
||||
!(defined(SDL_PLATFORM_WIN32))
|
||||
(void)fprintf(stderr, "%s%s\n", GetLogPriorityPrefix(priority), message);
|
||||
#endif
|
||||
|
|
|
@ -77,6 +77,9 @@ static const AudioBootStrap *const bootstrap[] = {
|
|||
#ifdef SDL_AUDIO_DRIVER_N3DS
|
||||
&N3DSAUDIO_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_AUDIO_DRIVER_NGAGE
|
||||
&NGAGEAUDIO_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_AUDIO_DRIVER_EMSCRIPTEN
|
||||
&EMSCRIPTENAUDIO_bootstrap,
|
||||
#endif
|
||||
|
|
|
@ -393,6 +393,7 @@ extern AudioBootStrap PS2AUDIO_bootstrap;
|
|||
extern AudioBootStrap PSPAUDIO_bootstrap;
|
||||
extern AudioBootStrap VITAAUD_bootstrap;
|
||||
extern AudioBootStrap N3DSAUDIO_bootstrap;
|
||||
extern AudioBootStrap NGAGEAUDIO_bootstrap;
|
||||
extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap;
|
||||
extern AudioBootStrap QSAAUDIO_bootstrap;
|
||||
|
||||
|
|
103
src/audio/ngage/SDL_ngageaudio.c
Normal file
103
src/audio/ngage/SDL_ngageaudio.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_NGAGE
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include "SDL_ngageaudio.h"
|
||||
|
||||
static SDL_AudioDevice *devptr = NULL;
|
||||
|
||||
SDL_AudioDevice *NGAGE_GetAudioDeviceAddr()
|
||||
{
|
||||
return devptr;
|
||||
}
|
||||
|
||||
static bool NGAGEAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
SDL_PrivateAudioData *phdata = SDL_calloc(1, sizeof(SDL_PrivateAudioData));
|
||||
if (!phdata) {
|
||||
SDL_OutOfMemory();
|
||||
return false;
|
||||
}
|
||||
device->hidden = phdata;
|
||||
|
||||
phdata->buffer = SDL_calloc(1, device->buffer_size);
|
||||
if (!phdata->buffer) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(phdata);
|
||||
return false;
|
||||
}
|
||||
devptr = device;
|
||||
|
||||
// Since the phone can change the sample rate during a phone call,
|
||||
// we set the sample rate to 8KHz to be safe. Even though it
|
||||
// might be possible to adjust the sample rate dynamically, it's
|
||||
// not supported by the current implementation.
|
||||
|
||||
device->spec.format = SDL_AUDIO_S16LE;
|
||||
device->spec.channels = 1;
|
||||
device->spec.freq = 8000;
|
||||
|
||||
SDL_UpdatedAudioDeviceFormat(device);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static Uint8 *NGAGEAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
||||
{
|
||||
SDL_PrivateAudioData *phdata = (SDL_PrivateAudioData *)device->hidden;
|
||||
if (!phdata) {
|
||||
*buffer_size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*buffer_size = device->buffer_size;
|
||||
return phdata->buffer;
|
||||
}
|
||||
|
||||
static void NGAGEAUDIO_CloseDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
if (device->hidden) {
|
||||
SDL_free(device->hidden->buffer);
|
||||
SDL_free(device->hidden);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static bool NGAGEAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
impl->OpenDevice = NGAGEAUDIO_OpenDevice;
|
||||
impl->GetDeviceBuf = NGAGEAUDIO_GetDeviceBuf;
|
||||
impl->CloseDevice = NGAGEAUDIO_CloseDevice;
|
||||
|
||||
impl->ProvidesOwnCallbackThread = true;
|
||||
impl->OnlyHasDefaultPlaybackDevice = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AudioBootStrap NGAGEAUDIO_bootstrap = { "N-Gage", "N-Gage audio driver", NGAGEAUDIO_Init, false };
|
||||
|
||||
#endif // SDL_AUDIO_DRIVER_NGAGE
|
368
src/audio/ngage/SDL_ngageaudio.cpp
Normal file
368
src/audio/ngage/SDL_ngageaudio.cpp
Normal file
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "SDL_ngageaudio.h"
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_NGAGE
|
||||
|
||||
#include "SDL_ngageaudio.hpp"
|
||||
|
||||
CAudio::CAudio() : CActive(EPriorityStandard), iBufDes(NULL, 0) {}
|
||||
|
||||
CAudio *CAudio::NewL(TInt aLatency)
|
||||
{
|
||||
CAudio *self = new (ELeave) CAudio();
|
||||
CleanupStack::PushL(self);
|
||||
self->ConstructL(aLatency);
|
||||
CleanupStack::Pop(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
void CAudio::ConstructL(TInt aLatency)
|
||||
{
|
||||
CActiveScheduler::Add(this);
|
||||
User::LeaveIfError(iTimer.CreateLocal());
|
||||
iTimerCreated = ETrue;
|
||||
|
||||
iStream = CMdaAudioOutputStream::NewL(*this);
|
||||
if (!iStream) {
|
||||
SDL_Log("Error: Failed to create audio stream");
|
||||
User::Leave(KErrNoMemory);
|
||||
}
|
||||
|
||||
iLatency = aLatency;
|
||||
iLatencySamples = aLatency * 8; // 8kHz.
|
||||
|
||||
// Determine minimum and maximum number of samples to write with one
|
||||
// WriteL request.
|
||||
iMinWrite = iLatencySamples / 8;
|
||||
iMaxWrite = iLatencySamples / 2;
|
||||
|
||||
// Set defaults.
|
||||
iState = EStateNone;
|
||||
iTimerCreated = EFalse;
|
||||
iTimerActive = EFalse;
|
||||
}
|
||||
|
||||
CAudio::~CAudio()
|
||||
{
|
||||
if (iStream) {
|
||||
iStream->Stop();
|
||||
|
||||
while (iState != EStateDone) {
|
||||
User::After(100000); // 100ms.
|
||||
}
|
||||
|
||||
delete iStream;
|
||||
}
|
||||
}
|
||||
|
||||
void CAudio::Start()
|
||||
{
|
||||
if (iStream) {
|
||||
// Set to 8kHz mono audio.
|
||||
iStreamSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
|
||||
iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
|
||||
iStream->Open(&iStreamSettings);
|
||||
iState = EStateOpening;
|
||||
} else {
|
||||
SDL_Log("Error: Failed to open audio stream");
|
||||
}
|
||||
}
|
||||
|
||||
// Feeds more processed data to the audio stream.
|
||||
void CAudio::Feed()
|
||||
{
|
||||
// If a WriteL is already in progress, or we aren't even playing;
|
||||
// do nothing!
|
||||
if ((iState != EStateWriting) && (iState != EStatePlaying)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out the number of samples that really have been played
|
||||
// through the output.
|
||||
TTimeIntervalMicroSeconds pos = iStream->Position();
|
||||
|
||||
TInt played = 8 * (pos.Int64() / TInt64(1000)).GetTInt(); // 8kHz.
|
||||
|
||||
played += iBaseSamplesPlayed;
|
||||
|
||||
// Determine the difference between the number of samples written to
|
||||
// CMdaAudioOutputStream and the number of samples it has played.
|
||||
// The difference is the amount of data in the buffers.
|
||||
if (played < 0) {
|
||||
played = 0;
|
||||
}
|
||||
|
||||
TInt buffered = iSamplesWritten - played;
|
||||
if (buffered < 0) {
|
||||
buffered = 0;
|
||||
}
|
||||
|
||||
if (iState == EStateWriting) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The trick for low latency: Do not let the buffers fill up beyond the
|
||||
// latency desired! We write as many samples as the difference between
|
||||
// the latency target (in samples) and the amount of data buffered.
|
||||
TInt samplesToWrite = iLatencySamples - buffered;
|
||||
|
||||
// Do not write very small blocks. This should improve efficiency, since
|
||||
// writes to the streaming API are likely to be expensive.
|
||||
if (samplesToWrite < iMinWrite) {
|
||||
// Not enough data to write, set up a timer to fire after a while.
|
||||
// Try againwhen it expired.
|
||||
if (iTimerActive) {
|
||||
return;
|
||||
}
|
||||
iTimerActive = ETrue;
|
||||
SetActive();
|
||||
iTimer.After(iStatus, (1000 * iLatency) / 8);
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not write more than the set number of samples at once.
|
||||
int numSamples = samplesToWrite;
|
||||
if (numSamples > iMaxWrite) {
|
||||
numSamples = iMaxWrite;
|
||||
}
|
||||
|
||||
SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr();
|
||||
if (device) {
|
||||
SDL_PrivateAudioData *phdata = (SDL_PrivateAudioData *)device->hidden;
|
||||
|
||||
iBufDes.Set(phdata->buffer, 2 * numSamples, 2 * numSamples);
|
||||
iStream->WriteL(iBufDes);
|
||||
iState = EStateWriting;
|
||||
|
||||
// Keep track of the number of samples written (for latency calculations).
|
||||
iSamplesWritten += numSamples;
|
||||
} else {
|
||||
// Output device not ready yet. Let's go for another round.
|
||||
if (iTimerActive) {
|
||||
return;
|
||||
}
|
||||
iTimerActive = ETrue;
|
||||
SetActive();
|
||||
iTimer.After(iStatus, (1000 * iLatency) / 8);
|
||||
}
|
||||
}
|
||||
|
||||
void CAudio::RunL()
|
||||
{
|
||||
iTimerActive = EFalse;
|
||||
Feed();
|
||||
}
|
||||
|
||||
void CAudio::DoCancel()
|
||||
{
|
||||
iTimerActive = EFalse;
|
||||
iTimer.Cancel();
|
||||
}
|
||||
|
||||
void CAudio::StartThread()
|
||||
{
|
||||
TInt heapMinSize = 8192; // 8 KB initial heap size.
|
||||
TInt heapMaxSize = 1024 * 1024; // 1 MB maximum heap size.
|
||||
|
||||
TInt err = iProcess.Create(_L("ProcessThread"), ProcessThreadCB, KDefaultStackSize * 2, heapMinSize, heapMaxSize, this);
|
||||
if (err == KErrNone) {
|
||||
iProcess.SetPriority(EPriorityLess);
|
||||
iProcess.Resume();
|
||||
} else {
|
||||
SDL_Log("Error: Failed to create audio processing thread: %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
void CAudio::StopThread()
|
||||
{
|
||||
if (iStreamStarted) {
|
||||
iProcess.Kill(KErrNone);
|
||||
iProcess.Close();
|
||||
iStreamStarted = EFalse;
|
||||
}
|
||||
}
|
||||
|
||||
TInt CAudio::ProcessThreadCB(TAny *aPtr)
|
||||
{
|
||||
CAudio *self = static_cast<CAudio *>(aPtr);
|
||||
SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr();
|
||||
|
||||
while (self->iStreamStarted) {
|
||||
if (device) {
|
||||
SDL_PlaybackAudioThreadIterate(device);
|
||||
} else {
|
||||
device = NGAGE_GetAudioDeviceAddr();
|
||||
}
|
||||
User::After(100000); // 100ms.
|
||||
}
|
||||
return KErrNone;
|
||||
}
|
||||
|
||||
void CAudio::MaoscOpenComplete(TInt aError)
|
||||
{
|
||||
if (aError == KErrNone) {
|
||||
iStream->SetVolume(1);
|
||||
iStreamStarted = ETrue;
|
||||
StartThread();
|
||||
|
||||
} else {
|
||||
SDL_Log("Error: Failed to open audio stream: %d", aError);
|
||||
}
|
||||
}
|
||||
|
||||
void CAudio::MaoscBufferCopied(TInt aError, const TDesC8 & /*aBuffer*/)
|
||||
{
|
||||
if (aError == KErrNone) {
|
||||
iState = EStatePlaying;
|
||||
Feed();
|
||||
} else if (aError == KErrAbort) {
|
||||
// The stream has been stopped.
|
||||
iState = EStateDone;
|
||||
} else {
|
||||
SDL_Log("Error: Failed to copy audio buffer: %d", aError);
|
||||
}
|
||||
}
|
||||
|
||||
void CAudio::MaoscPlayComplete(TInt aError)
|
||||
{
|
||||
// If we finish due to an underflow, we'll need to restart playback.
|
||||
// Normally KErrUnderlow is raised at stream end, but in our case the API
|
||||
// should never see the stream end -- we are continuously feeding it more
|
||||
// data! Many underflow errors mean that the latency target is too low.
|
||||
if (aError == KErrUnderflow) {
|
||||
// The number of samples played gets resetted to zero when we restart
|
||||
// playback after underflow.
|
||||
iBaseSamplesPlayed = iSamplesWritten;
|
||||
|
||||
iStream->Stop();
|
||||
Cancel();
|
||||
|
||||
iStream->SetAudioPropertiesL(TMdaAudioDataSettings::ESampleRate8000Hz, TMdaAudioDataSettings::EChannelsMono);
|
||||
|
||||
iState = EStatePlaying;
|
||||
Feed();
|
||||
return;
|
||||
|
||||
} else if (aError != KErrNone) {
|
||||
// Handle error.
|
||||
}
|
||||
|
||||
// We shouldn't get here.
|
||||
SDL_Log("%s: %d", __FUNCTION__, aError);
|
||||
}
|
||||
|
||||
static TBool gAudioRunning;
|
||||
|
||||
TBool AudioIsReady()
|
||||
{
|
||||
return gAudioRunning;
|
||||
}
|
||||
|
||||
TInt AudioThreadCB(TAny *aParams)
|
||||
{
|
||||
CTrapCleanup *cleanup = CTrapCleanup::New();
|
||||
if (!cleanup) {
|
||||
return KErrNoMemory;
|
||||
}
|
||||
|
||||
CActiveScheduler *scheduler = new CActiveScheduler();
|
||||
if (!scheduler) {
|
||||
delete cleanup;
|
||||
return KErrNoMemory;
|
||||
}
|
||||
|
||||
CActiveScheduler::Install(scheduler);
|
||||
|
||||
TRAPD(err,
|
||||
{
|
||||
TInt latency = *(TInt *)aParams;
|
||||
CAudio *audio = CAudio::NewL(latency);
|
||||
CleanupStack::PushL(audio);
|
||||
|
||||
gAudioRunning = ETrue;
|
||||
audio->Start();
|
||||
TBool once = EFalse;
|
||||
|
||||
while (gAudioRunning) {
|
||||
// Allow active scheduler to process any events.
|
||||
TInt error;
|
||||
CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle);
|
||||
|
||||
if (!once) {
|
||||
SDL_AudioDevice *device = NGAGE_GetAudioDeviceAddr();
|
||||
if (device) {
|
||||
// Stream ready; start feeding audio data.
|
||||
// After feeding it once, the callbacks will take over.
|
||||
audio->iState = CAudio::EStatePlaying;
|
||||
audio->Feed();
|
||||
once = ETrue;
|
||||
}
|
||||
}
|
||||
|
||||
User::After(100000); // 100ms.
|
||||
}
|
||||
|
||||
CleanupStack::PopAndDestroy(audio);
|
||||
});
|
||||
|
||||
delete scheduler;
|
||||
delete cleanup;
|
||||
return err;
|
||||
}
|
||||
|
||||
RThread audioThread;
|
||||
|
||||
void InitAudio(TInt *aLatency)
|
||||
{
|
||||
_LIT(KAudioThreadName, "AudioThread");
|
||||
|
||||
TInt err = audioThread.Create(KAudioThreadName, AudioThreadCB, KDefaultStackSize, 0, aLatency);
|
||||
if (err != KErrNone) {
|
||||
User::Leave(err);
|
||||
}
|
||||
|
||||
audioThread.Resume();
|
||||
}
|
||||
|
||||
void DeinitAudio()
|
||||
{
|
||||
gAudioRunning = EFalse;
|
||||
|
||||
TRequestStatus status;
|
||||
audioThread.Logon(status);
|
||||
User::WaitForRequest(status);
|
||||
|
||||
audioThread.Close();
|
||||
}
|
||||
|
||||
#endif // SDL_AUDIO_DRIVER_NGAGE
|
44
src/audio/ngage/SDL_ngageaudio.h
Normal file
44
src/audio/ngage/SDL_ngageaudio.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_ngageaudio_h
|
||||
#define SDL_ngageaudio_h
|
||||
|
||||
typedef struct SDL_PrivateAudioData
|
||||
{
|
||||
Uint8 *buffer;
|
||||
|
||||
} SDL_PrivateAudioData;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
SDL_AudioDevice *NGAGE_GetAudioDeviceAddr();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDL_ngageaudio_h
|
98
src/audio/ngage/SDL_ngageaudio.hpp
Normal file
98
src/audio/ngage/SDL_ngageaudio.hpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_ngageaudio_hpp
|
||||
#define SDL_ngageaudio_hpp
|
||||
|
||||
#include <e32base.h>
|
||||
#include <e32std.h>
|
||||
#include <mda/common/audio.h>
|
||||
#include <mdaaudiooutputstream.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include "SDL_ngageaudio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
TBool AudioIsReady();
|
||||
void InitAudio(TInt *aLatency);
|
||||
void DeinitAudio();
|
||||
|
||||
class CAudio : public CActive, public MMdaAudioOutputStreamCallback
|
||||
{
|
||||
public:
|
||||
static CAudio *NewL(TInt aLatency);
|
||||
~CAudio();
|
||||
|
||||
void ConstructL(TInt aLatency);
|
||||
void Start();
|
||||
void Feed();
|
||||
|
||||
void RunL();
|
||||
void DoCancel();
|
||||
|
||||
static TInt ProcessThreadCB(TAny * /*aPtr*/);
|
||||
|
||||
// From MMdaAudioOutputStreamCallback
|
||||
void MaoscOpenComplete(TInt aError);
|
||||
void MaoscBufferCopied(TInt aError, const TDesC8 &aBuffer);
|
||||
void MaoscPlayComplete(TInt aError);
|
||||
|
||||
enum
|
||||
{
|
||||
EStateNone = 0,
|
||||
EStateOpening,
|
||||
EStatePlaying,
|
||||
EStateWriting,
|
||||
EStateDone
|
||||
} iState;
|
||||
|
||||
private:
|
||||
CAudio();
|
||||
void StartThread();
|
||||
void StopThread();
|
||||
|
||||
CMdaAudioOutputStream *iStream;
|
||||
TMdaAudioDataSettings iStreamSettings;
|
||||
TBool iStreamStarted;
|
||||
|
||||
TPtr8 iBufDes; // Descriptor for the buffer.
|
||||
TInt iLatency; // Latency target in ms
|
||||
TInt iLatencySamples; // Latency target in samples.
|
||||
TInt iMinWrite; // Min number of samples to write per turn.
|
||||
TInt iMaxWrite; // Max number of samples to write per turn.
|
||||
TInt iBaseSamplesPlayed; // amples played before last restart.
|
||||
TInt iSamplesWritten; // Number of samples written so far.
|
||||
|
||||
RTimer iTimer;
|
||||
TBool iTimerCreated;
|
||||
TBool iTimerActive;
|
||||
|
||||
RThread iProcess;
|
||||
};
|
||||
|
||||
#endif // SDL_ngageaudio_hpp
|
77
src/core/ngage/SDL_ngage.cpp
Normal file
77
src/core/ngage/SDL_ngage.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include <e32std.h>
|
||||
#include <e32svr.h>
|
||||
#include <hal.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool NGAGE_IsClassicModel()
|
||||
{
|
||||
int phone_id;
|
||||
HAL::Get(HALData::EMachineUid, phone_id);
|
||||
|
||||
return (0x101f8c19 == phone_id);
|
||||
}
|
||||
|
||||
void NGAGE_printf(const char *fmt, ...)
|
||||
{
|
||||
char buffer[512] = { 0 };
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buffer, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
TBuf<512> buf;
|
||||
buf.Copy(TPtrC8((TText8 *)buffer));
|
||||
|
||||
RDebug::Print(_L("%S"), &buf);
|
||||
}
|
||||
|
||||
void NGAGE_vnprintf(char *buf, size_t size, const char *fmt, va_list ap)
|
||||
{
|
||||
char buffer[512] = { 0 };
|
||||
|
||||
vsprintf(buffer, fmt, ap);
|
||||
|
||||
TBuf<512> tbuf;
|
||||
tbuf.Copy(TPtrC8((TText8 *)buffer));
|
||||
|
||||
RDebug::Print(_L("%S"), &tbuf);
|
||||
|
||||
strncpy(buf, buffer, size - 1);
|
||||
buf[size - 1] = '\0';
|
||||
}
|
||||
|
||||
TInt NGAGE_GetFreeHeapMemory()
|
||||
{
|
||||
TInt free = 0;
|
||||
return User::Available(free);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
36
src/core/ngage/SDL_ngage.h
Normal file
36
src/core/ngage/SDL_ngage.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_ngage_h
|
||||
#define SDL_ngage_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool NGAGE_IsClassicModel();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SDL_ngage_h */
|
|
@ -421,6 +421,12 @@ static int CPU_haveARMSIMD(void)
|
|||
return regs.r[0];
|
||||
}
|
||||
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
static int CPU_haveARMSIMD(void)
|
||||
{
|
||||
// The RM920T is based on the ARMv4T architecture and doesn't have SIMD.
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int CPU_haveARMSIMD(void)
|
||||
{
|
||||
|
@ -468,6 +474,8 @@ static int CPU_haveNEON(void)
|
|||
return 1;
|
||||
#elif defined(SDL_PLATFORM_3DS)
|
||||
return 0;
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
return 0; // The ARM920T is based on the ARMv4T architecture and doesn't have NEON.
|
||||
#elif defined(SDL_PLATFORM_APPLE) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7)
|
||||
// (note that sysctlbyname("hw.optional.neon") doesn't work!)
|
||||
return 1; // all Apple ARMv7 chips and later have NEON.
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
#define SDL_DYNAMIC_API 0 // vitasdk doesn't support dynamic linking
|
||||
#elif defined(SDL_PLATFORM_3DS)
|
||||
#define SDL_DYNAMIC_API 0 // devkitARM doesn't support dynamic linking
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(DYNAPI_NEEDS_DLOPEN) && !defined(HAVE_DLOPEN)
|
||||
#define SDL_DYNAMIC_API 0 // we need dlopen(), but don't have it....
|
||||
#endif
|
||||
|
|
67
src/filesystem/ngage/SDL_sysfilesystem.c
Normal file
67
src/filesystem/ngage/SDL_sysfilesystem.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
extern void NGAGE_GetAppPath(char* path);
|
||||
|
||||
char *SDL_SYS_GetBasePath(void)
|
||||
{
|
||||
char app_path[512];
|
||||
NGAGE_GetAppPath(app_path);
|
||||
char *base_path = SDL_strdup(app_path);
|
||||
return base_path;
|
||||
}
|
||||
|
||||
char *SDL_SYS_GetPrefPath(const char *org, const char *app)
|
||||
{
|
||||
char *pref_path;
|
||||
if (SDL_asprintf(&pref_path, "C:/System/Apps/%s/%s/", org, app) < 0)
|
||||
return NULL;
|
||||
else
|
||||
return pref_path;
|
||||
}
|
||||
|
||||
char *SDL_SYS_GetUserFolder(SDL_Folder folder)
|
||||
{
|
||||
const char *folder_path = NULL;
|
||||
switch (folder)
|
||||
{
|
||||
case SDL_FOLDER_HOME:
|
||||
folder_path = "C:/";
|
||||
break;
|
||||
case SDL_FOLDER_PICTURES:
|
||||
folder_path = "C:/Nokia/Pictures/";
|
||||
break;
|
||||
case SDL_FOLDER_SAVEDGAMES:
|
||||
folder_path = "C:/";
|
||||
break;
|
||||
case SDL_FOLDER_SCREENSHOTS:
|
||||
folder_path = "C:/Nokia/Pictures/";
|
||||
break;
|
||||
case SDL_FOLDER_VIDEOS:
|
||||
folder_path = "C:/Nokia/Videos/";
|
||||
break;
|
||||
default:
|
||||
folder_path = "C:/Nokia/Others/";
|
||||
break;
|
||||
}
|
||||
return SDL_strdup(folder_path);
|
||||
}
|
68
src/filesystem/ngage/SDL_sysfilesystem.cpp
Normal file
68
src/filesystem/ngage/SDL_sysfilesystem.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <e32base.h>
|
||||
#include <e32std.h>
|
||||
#include <f32file.h>
|
||||
#include <utf.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void NGAGE_GetAppPath(char* path)
|
||||
{
|
||||
TBuf<512> aPath;
|
||||
|
||||
TFileName fullExePath = RProcess().FileName();
|
||||
|
||||
TParsePtrC parser(fullExePath);
|
||||
aPath.Copy(parser.DriveAndPath());
|
||||
|
||||
TBuf8<512> utf8Path; // Temporary buffer for UTF-8 data.
|
||||
CnvUtfConverter::ConvertFromUnicodeToUtf8(utf8Path, aPath);
|
||||
|
||||
// Copy UTF-8 data to the provided char* buffer.
|
||||
strncpy(path, (const char*)utf8Path.Ptr(), utf8Path.Length());
|
||||
path[utf8Path.Length()] = '\0';
|
||||
|
||||
// Replace backslashes with forward slashes.
|
||||
for (int i = 0; i < utf8Path.Length(); i++)
|
||||
{
|
||||
if (path[i] == '\\')
|
||||
{
|
||||
path[i] = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
307
src/locale/ngage/SDL_syslocale.cpp
Normal file
307
src/locale/ngage/SDL_syslocale.cpp
Normal file
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../SDL_syslocale.h"
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include <bautils.h>
|
||||
#include <e32base.h>
|
||||
#include <e32cons.h>
|
||||
#include <e32std.h>
|
||||
|
||||
bool SDL_SYS_GetPreferredLocales(char *buf, size_t buflen)
|
||||
{
|
||||
TLanguage language = User::Language();
|
||||
const char *locale;
|
||||
|
||||
switch (language) {
|
||||
case ELangFrench:
|
||||
case ELangSwissFrench:
|
||||
locale = "fr_CH";
|
||||
break;
|
||||
case ELangBelgianFrench:
|
||||
locale = "fr_BE";
|
||||
break;
|
||||
case ELangInternationalFrench:
|
||||
locale = "fr_FR";
|
||||
break;
|
||||
case ELangGerman:
|
||||
case ELangSwissGerman:
|
||||
case ELangAustrian:
|
||||
locale = "de_DE";
|
||||
break;
|
||||
case ELangSpanish:
|
||||
case ELangInternationalSpanish:
|
||||
case ELangLatinAmericanSpanish:
|
||||
locale = "es_ES";
|
||||
break;
|
||||
case ELangItalian:
|
||||
case ELangSwissItalian:
|
||||
locale = "it_IT";
|
||||
break;
|
||||
case ELangSwedish:
|
||||
case ELangFinlandSwedish:
|
||||
locale = "sv_SE";
|
||||
break;
|
||||
case ELangDanish:
|
||||
locale = "da_DK";
|
||||
break;
|
||||
case ELangNorwegian:
|
||||
case ELangNorwegianNynorsk:
|
||||
locale = "no_NO";
|
||||
break;
|
||||
case ELangFinnish:
|
||||
locale = "fi_FI";
|
||||
break;
|
||||
case ELangPortuguese:
|
||||
locale = "pt_PT";
|
||||
break;
|
||||
case ELangBrazilianPortuguese:
|
||||
locale = "pt_BR";
|
||||
break;
|
||||
case ELangTurkish:
|
||||
case ELangCyprusTurkish:
|
||||
locale = "tr_TR";
|
||||
break;
|
||||
case ELangIcelandic:
|
||||
locale = "is_IS";
|
||||
break;
|
||||
case ELangRussian:
|
||||
locale = "ru_RU";
|
||||
break;
|
||||
case ELangHungarian:
|
||||
locale = "hu_HU";
|
||||
break;
|
||||
case ELangDutch:
|
||||
locale = "nl_NL";
|
||||
break;
|
||||
case ELangBelgianFlemish:
|
||||
locale = "nl_BE";
|
||||
break;
|
||||
case ELangAustralian:
|
||||
case ELangNewZealand:
|
||||
locale = "en_AU";
|
||||
break;
|
||||
case ELangCzech:
|
||||
locale = "cs_CZ";
|
||||
break;
|
||||
case ELangSlovak:
|
||||
locale = "sk_SK";
|
||||
break;
|
||||
case ELangPolish:
|
||||
locale = "pl_PL";
|
||||
break;
|
||||
case ELangSlovenian:
|
||||
locale = "sl_SI";
|
||||
break;
|
||||
case ELangTaiwanChinese:
|
||||
locale = "zh_TW";
|
||||
break;
|
||||
case ELangHongKongChinese:
|
||||
locale = "zh_HK";
|
||||
break;
|
||||
case ELangPrcChinese:
|
||||
locale = "zh_CN";
|
||||
break;
|
||||
case ELangJapanese:
|
||||
locale = "ja_JP";
|
||||
break;
|
||||
case ELangThai:
|
||||
locale = "th_TH";
|
||||
break;
|
||||
case ELangAfrikaans:
|
||||
locale = "af_ZA";
|
||||
break;
|
||||
case ELangAlbanian:
|
||||
locale = "sq_AL";
|
||||
break;
|
||||
case ELangAmharic:
|
||||
locale = "am_ET";
|
||||
break;
|
||||
case ELangArabic:
|
||||
locale = "ar_SA";
|
||||
break;
|
||||
case ELangArmenian:
|
||||
locale = "hy_AM";
|
||||
break;
|
||||
case ELangAzerbaijani:
|
||||
locale = "az_AZ";
|
||||
break;
|
||||
case ELangBelarussian:
|
||||
locale = "be_BY";
|
||||
break;
|
||||
case ELangBengali:
|
||||
locale = "bn_IN";
|
||||
break;
|
||||
case ELangBulgarian:
|
||||
locale = "bg_BG";
|
||||
break;
|
||||
case ELangBurmese:
|
||||
locale = "my_MM";
|
||||
break;
|
||||
case ELangCatalan:
|
||||
locale = "ca_ES";
|
||||
break;
|
||||
case ELangCroatian:
|
||||
locale = "hr_HR";
|
||||
break;
|
||||
case ELangEstonian:
|
||||
locale = "et_EE";
|
||||
break;
|
||||
case ELangFarsi:
|
||||
locale = "fa_IR";
|
||||
break;
|
||||
case ELangCanadianFrench:
|
||||
locale = "fr_CA";
|
||||
break;
|
||||
case ELangScotsGaelic:
|
||||
locale = "gd_GB";
|
||||
break;
|
||||
case ELangGeorgian:
|
||||
locale = "ka_GE";
|
||||
break;
|
||||
case ELangGreek:
|
||||
case ELangCyprusGreek:
|
||||
locale = "el_GR";
|
||||
break;
|
||||
case ELangGujarati:
|
||||
locale = "gu_IN";
|
||||
break;
|
||||
case ELangHebrew:
|
||||
locale = "he_IL";
|
||||
break;
|
||||
case ELangHindi:
|
||||
locale = "hi_IN";
|
||||
break;
|
||||
case ELangIndonesian:
|
||||
locale = "id_ID";
|
||||
break;
|
||||
case ELangIrish:
|
||||
locale = "ga_IE";
|
||||
break;
|
||||
case ELangKannada:
|
||||
locale = "kn_IN";
|
||||
break;
|
||||
case ELangKazakh:
|
||||
locale = "kk_KZ";
|
||||
break;
|
||||
case ELangKhmer:
|
||||
locale = "km_KH";
|
||||
break;
|
||||
case ELangKorean:
|
||||
locale = "ko_KR";
|
||||
break;
|
||||
case ELangLao:
|
||||
locale = "lo_LA";
|
||||
break;
|
||||
case ELangLatvian:
|
||||
locale = "lv_LV";
|
||||
break;
|
||||
case ELangLithuanian:
|
||||
locale = "lt_LT";
|
||||
break;
|
||||
case ELangMacedonian:
|
||||
locale = "mk_MK";
|
||||
break;
|
||||
case ELangMalay:
|
||||
locale = "ms_MY";
|
||||
break;
|
||||
case ELangMalayalam:
|
||||
locale = "ml_IN";
|
||||
break;
|
||||
case ELangMarathi:
|
||||
locale = "mr_IN";
|
||||
break;
|
||||
case ELangMoldavian:
|
||||
locale = "ro_MD";
|
||||
break;
|
||||
case ELangMongolian:
|
||||
locale = "mn_MN";
|
||||
break;
|
||||
case ELangPunjabi:
|
||||
locale = "pa_IN";
|
||||
break;
|
||||
case ELangRomanian:
|
||||
locale = "ro_RO";
|
||||
break;
|
||||
case ELangSerbian:
|
||||
locale = "sr_RS";
|
||||
break;
|
||||
case ELangSinhalese:
|
||||
locale = "si_LK";
|
||||
break;
|
||||
case ELangSomali:
|
||||
locale = "so_SO";
|
||||
break;
|
||||
case ELangSwahili:
|
||||
locale = "sw_KE";
|
||||
break;
|
||||
case ELangTajik:
|
||||
locale = "tg_TJ";
|
||||
break;
|
||||
case ELangTamil:
|
||||
locale = "ta_IN";
|
||||
break;
|
||||
case ELangTelugu:
|
||||
locale = "te_IN";
|
||||
break;
|
||||
case ELangTibetan:
|
||||
locale = "bo_CN";
|
||||
break;
|
||||
case ELangTigrinya:
|
||||
locale = "ti_ET";
|
||||
break;
|
||||
case ELangTurkmen:
|
||||
locale = "tk_TM";
|
||||
break;
|
||||
case ELangUkrainian:
|
||||
locale = "uk_UA";
|
||||
break;
|
||||
case ELangUrdu:
|
||||
locale = "ur_PK";
|
||||
break;
|
||||
case ELangUzbek:
|
||||
locale = "uz_UZ";
|
||||
break;
|
||||
case ELangVietnamese:
|
||||
locale = "vi_VN";
|
||||
break;
|
||||
case ELangWelsh:
|
||||
locale = "cy_GB";
|
||||
break;
|
||||
case ELangZulu:
|
||||
locale = "zu_ZA";
|
||||
break;
|
||||
case ELangEnglish:
|
||||
locale = "en_GB";
|
||||
break;
|
||||
case ELangAmerican:
|
||||
case ELangCanadianEnglish:
|
||||
case ELangInternationalEnglish:
|
||||
case ELangSouthAfricanEnglish:
|
||||
default:
|
||||
locale = "en_US";
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_strlcpy(buf, locale, buflen);
|
||||
|
||||
return true;
|
||||
}
|
31
src/main/ngage/SDL_sysmain_callbacks.c
Normal file
31
src/main/ngage/SDL_sysmain_callbacks.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_PLATFORM_NGAGE
|
||||
|
||||
int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
|
||||
{
|
||||
// Intentionally does nothing; Callbacks are called using the RunL() method.
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // SDL_PLATFORM_NGAGE
|
199
src/main/ngage/SDL_sysmain_main.cpp
Normal file
199
src/main/ngage/SDL_sysmain_main.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
extern SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]);
|
||||
extern SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event);
|
||||
extern SDL_AppResult SDL_AppIterate(void* appstate);
|
||||
extern void SDL_AppQuit(void* appstate, SDL_AppResult result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <e32std.h>
|
||||
#include <estlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "SDL_sysmain_main.hpp"
|
||||
#include "../../audio/ngage/SDL_ngageaudio.hpp"
|
||||
#include "../../render/ngage/SDL_render_ngage_c.hpp"
|
||||
|
||||
CRenderer *gRenderer = 0;
|
||||
|
||||
GLDEF_C TInt E32Main()
|
||||
{
|
||||
// Get args and environment.
|
||||
int argc = 1;
|
||||
char* argv[] = { "game", NULL };
|
||||
char** envp = NULL;
|
||||
|
||||
// Create lvalue variables for __crt0 arguments.
|
||||
char** argv_lvalue = argv;
|
||||
char** envp_lvalue = envp;
|
||||
|
||||
CTrapCleanup* cleanup = CTrapCleanup::New();
|
||||
if (!cleanup)
|
||||
{
|
||||
return KErrNoMemory;
|
||||
}
|
||||
|
||||
TRAPD(err,
|
||||
{
|
||||
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
|
||||
CleanupStack::PushL(scheduler);
|
||||
CActiveScheduler::Install(scheduler);
|
||||
|
||||
TInt posixErr = SpawnPosixServerThread();
|
||||
if (posixErr != KErrNone)
|
||||
{
|
||||
SDL_Log("Error: Failed to spawn POSIX server thread: %d", posixErr);
|
||||
User::Leave(posixErr);
|
||||
}
|
||||
|
||||
__crt0(argc, argv_lvalue, envp_lvalue);
|
||||
|
||||
// Increase heap size.
|
||||
RHeap* newHeap = User::ChunkHeap(NULL, 7500000, 7500000, KMinHeapGrowBy);
|
||||
if (!newHeap)
|
||||
{
|
||||
SDL_Log("Error: Failed to create new heap");
|
||||
User::Leave(KErrNoMemory);
|
||||
}
|
||||
CleanupStack::PushL(newHeap);
|
||||
|
||||
RHeap* oldHeap = User::SwitchHeap(newHeap);
|
||||
|
||||
TInt targetLatency = 225;
|
||||
InitAudio(&targetLatency);
|
||||
|
||||
// Wait until audio is ready.
|
||||
while (!AudioIsReady())
|
||||
{
|
||||
User::After(100000); // 100ms.
|
||||
}
|
||||
|
||||
// Create and start the rendering backend.
|
||||
gRenderer = CRenderer::NewL();
|
||||
CleanupStack::PushL(gRenderer);
|
||||
|
||||
// Create and start the SDL main runner.
|
||||
CSDLmain* mainApp = CSDLmain::NewL();
|
||||
CleanupStack::PushL(mainApp);
|
||||
mainApp->Start();
|
||||
|
||||
// Start the active scheduler to handle events.
|
||||
CActiveScheduler::Start();
|
||||
|
||||
CleanupStack::PopAndDestroy(gRenderer);
|
||||
CleanupStack::PopAndDestroy(mainApp);
|
||||
|
||||
User::SwitchHeap(oldHeap);
|
||||
|
||||
CleanupStack::PopAndDestroy(newHeap);
|
||||
CleanupStack::PopAndDestroy(scheduler);
|
||||
});
|
||||
|
||||
if (err != KErrNone)
|
||||
{
|
||||
SDL_Log("Error: %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
CSDLmain* CSDLmain::NewL()
|
||||
{
|
||||
CSDLmain* self = new (ELeave) CSDLmain();
|
||||
CleanupStack::PushL(self);
|
||||
self->ConstructL();
|
||||
CleanupStack::Pop(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
CSDLmain::CSDLmain() : CActive(EPriorityLow) {}
|
||||
|
||||
void CSDLmain::ConstructL()
|
||||
{
|
||||
CActiveScheduler::Add(this);
|
||||
}
|
||||
|
||||
CSDLmain::~CSDLmain()
|
||||
{
|
||||
Cancel();
|
||||
}
|
||||
|
||||
void CSDLmain::Start()
|
||||
{
|
||||
SetActive();
|
||||
TRequestStatus* status = &iStatus;
|
||||
User::RequestComplete(status, KErrNone);
|
||||
}
|
||||
|
||||
void CSDLmain::DoCancel() {}
|
||||
|
||||
static bool callbacks_initialized = false;
|
||||
|
||||
void CSDLmain::RunL()
|
||||
{
|
||||
if (callbacks_initialized)
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
iResult = SDL_AppIterate(NULL);
|
||||
if (iResult != SDL_APP_CONTINUE)
|
||||
{
|
||||
DeinitAudio();
|
||||
SDL_AppQuit(NULL, iResult);
|
||||
SDL_Quit();
|
||||
CActiveScheduler::Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_PumpEvents();
|
||||
if (SDL_PollEvent(&event))
|
||||
{
|
||||
iResult = SDL_AppEvent(NULL, &event);
|
||||
if (iResult != SDL_APP_CONTINUE)
|
||||
{
|
||||
DeinitAudio();
|
||||
SDL_AppQuit(NULL, iResult);
|
||||
SDL_Quit();
|
||||
CActiveScheduler::Stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetMainReady();
|
||||
SDL_AppInit(NULL, 0, NULL);
|
||||
callbacks_initialized = true;
|
||||
Start();
|
||||
}
|
||||
}
|
46
src/main/ngage/SDL_sysmain_main.hpp
Normal file
46
src/main/ngage/SDL_sysmain_main.hpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_sysmain_main_hpp_
|
||||
#define SDL_sysmain_main_hpp_
|
||||
|
||||
#include <e32std.h>
|
||||
|
||||
class CSDLmain : public CActive
|
||||
{
|
||||
public:
|
||||
static CSDLmain* NewL();
|
||||
~CSDLmain();
|
||||
|
||||
void Start();
|
||||
|
||||
protected:
|
||||
void DoCancel() ;
|
||||
void RunL();
|
||||
|
||||
private:
|
||||
CSDLmain();
|
||||
void ConstructL();
|
||||
SDL_AppResult iResult;
|
||||
};
|
||||
|
||||
#endif // SDL_sysmain_main_hpp_
|
|
@ -120,6 +120,9 @@ static const SDL_RenderDriver *render_drivers[] = {
|
|||
#ifdef SDL_VIDEO_RENDER_METAL
|
||||
&METAL_RenderDriver,
|
||||
#endif
|
||||
#ifdef SDL_VIDEO_RENDER_NGAGE
|
||||
&NGAGE_RenderDriver,
|
||||
#endif
|
||||
#ifdef SDL_VIDEO_RENDER_OGL
|
||||
&GL_RenderDriver,
|
||||
#endif
|
||||
|
|
|
@ -357,6 +357,7 @@ extern SDL_RenderDriver D3D12_RenderDriver;
|
|||
extern SDL_RenderDriver GL_RenderDriver;
|
||||
extern SDL_RenderDriver GLES2_RenderDriver;
|
||||
extern SDL_RenderDriver METAL_RenderDriver;
|
||||
extern SDL_RenderDriver NGAGE_RenderDriver;
|
||||
extern SDL_RenderDriver VULKAN_RenderDriver;
|
||||
extern SDL_RenderDriver PS2_RenderDriver;
|
||||
extern SDL_RenderDriver PSP_RenderDriver;
|
||||
|
|
544
src/render/ngage/SDL_render_ngage.c
Normal file
544
src/render/ngage/SDL_render_ngage.c
Normal file
|
@ -0,0 +1,544 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_RENDER_NGAGE
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef Int2Fix
|
||||
#define Int2Fix(i) ((i) << 16)
|
||||
#endif
|
||||
|
||||
#ifndef Fix2Int
|
||||
#define Fix2Int(i) ((((unsigned int)(i) > 0xFFFF0000) ? 0 : ((i) >> 16)))
|
||||
#endif
|
||||
|
||||
#ifndef Fix2Real
|
||||
#define Fix2Real(i) ((i) / 65536.0)
|
||||
#endif
|
||||
|
||||
#ifndef Real2Fix
|
||||
#define Real2Fix(i) ((int)((i) * 65536.0))
|
||||
#endif
|
||||
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "SDL_render_ngage_c.h"
|
||||
|
||||
static void NGAGE_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event);
|
||||
static bool NGAGE_GetOutputSize(SDL_Renderer *renderer, int *w, int *h);
|
||||
static bool NGAGE_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode);
|
||||
static bool NGAGE_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props);
|
||||
static bool NGAGE_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
static bool NGAGE_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
static bool NGAGE_QueueDrawVertices(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count);
|
||||
static bool NGAGE_QueueFillRects(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count);
|
||||
static bool NGAGE_QueueCopy(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect);
|
||||
static bool NGAGE_QueueCopyEx(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_FRect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y);
|
||||
static bool NGAGE_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const float *xy, int xy_stride, const SDL_FColor *color, int color_stride, const float *uv, int uv_stride, int num_vertices, const void *indices, int num_indices, int size_indices, float scale_x, float scale_y);
|
||||
|
||||
static void NGAGE_InvalidateCachedState(SDL_Renderer *renderer);
|
||||
static bool NGAGE_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
|
||||
static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch);
|
||||
|
||||
static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch);
|
||||
static void NGAGE_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||
static void NGAGE_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode);
|
||||
static bool NGAGE_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||
static SDL_Surface *NGAGE_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect);
|
||||
static bool NGAGE_RenderPresent(SDL_Renderer *renderer);
|
||||
static void NGAGE_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||
|
||||
static void NGAGE_DestroyRenderer(SDL_Renderer *renderer);
|
||||
|
||||
static bool NGAGE_SetVSync(SDL_Renderer *renderer, int vsync);
|
||||
|
||||
static bool NGAGE_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
|
||||
{
|
||||
SDL_SetupRendererColorspace(renderer, create_props);
|
||||
|
||||
if (renderer->output_colorspace != SDL_COLORSPACE_RGB_DEFAULT) {
|
||||
return SDL_SetError("Unsupported output colorspace");
|
||||
}
|
||||
|
||||
NGAGE_RendererData *phdata = SDL_calloc(1, sizeof(NGAGE_RendererData));
|
||||
if (!phdata) {
|
||||
SDL_OutOfMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
renderer->WindowEvent = NGAGE_WindowEvent;
|
||||
renderer->GetOutputSize = NGAGE_GetOutputSize;
|
||||
renderer->SupportsBlendMode = NGAGE_SupportsBlendMode;
|
||||
renderer->CreateTexture = NGAGE_CreateTexture;
|
||||
renderer->QueueSetViewport = NGAGE_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = NGAGE_QueueSetDrawColor;
|
||||
renderer->QueueDrawPoints = NGAGE_QueueDrawVertices;
|
||||
renderer->QueueDrawLines = NGAGE_QueueDrawVertices;
|
||||
renderer->QueueFillRects = NGAGE_QueueFillRects;
|
||||
renderer->QueueCopy = NGAGE_QueueCopy;
|
||||
renderer->QueueCopyEx = NGAGE_QueueCopyEx;
|
||||
renderer->QueueGeometry = NGAGE_QueueGeometry;
|
||||
|
||||
renderer->InvalidateCachedState = NGAGE_InvalidateCachedState;
|
||||
renderer->RunCommandQueue = NGAGE_RunCommandQueue;
|
||||
renderer->UpdateTexture = NGAGE_UpdateTexture;
|
||||
renderer->LockTexture = NGAGE_LockTexture;
|
||||
renderer->UnlockTexture = NGAGE_UnlockTexture;
|
||||
// renderer->SetTextureScaleMode = NGAGE_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = NGAGE_SetRenderTarget;
|
||||
renderer->RenderReadPixels = NGAGE_RenderReadPixels;
|
||||
renderer->RenderPresent = NGAGE_RenderPresent;
|
||||
renderer->DestroyTexture = NGAGE_DestroyTexture;
|
||||
|
||||
renderer->DestroyRenderer = NGAGE_DestroyRenderer;
|
||||
|
||||
renderer->SetVSync = NGAGE_SetVSync;
|
||||
|
||||
renderer->name = NGAGE_RenderDriver.name;
|
||||
renderer->window = window;
|
||||
renderer->internal = phdata;
|
||||
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ARGB4444);
|
||||
SDL_SetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 256);
|
||||
SDL_SetHintWithPriority(SDL_HINT_RENDER_LINE_METHOD, "2", SDL_HINT_OVERRIDE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_RenderDriver NGAGE_RenderDriver = {
|
||||
NGAGE_CreateRenderer,
|
||||
"N-Gage"
|
||||
};
|
||||
|
||||
static void NGAGE_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static bool NGAGE_GetOutputSize(SDL_Renderer *renderer, int *w, int *h)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
|
||||
{
|
||||
switch (blendMode) {
|
||||
case SDL_BLENDMODE_NONE:
|
||||
case SDL_BLENDMODE_MOD:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool NGAGE_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props)
|
||||
{
|
||||
NGAGE_TextureData *data = (NGAGE_TextureData *)SDL_calloc(1, sizeof(*data));
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NGAGE_CreateTextureData(data, texture->w, texture->h)) {
|
||||
SDL_free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_Surface *surface = SDL_CreateSurface(texture->w, texture->h, texture->format);
|
||||
if (!surface) {
|
||||
SDL_free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
data->surface = surface;
|
||||
texture->internal = data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
if (!cmd->data.viewport.rect.w && !cmd->data.viewport.rect.h) {
|
||||
SDL_Rect viewport = { 0, 0, NGAGE_SCREEN_WIDTH, NGAGE_SCREEN_HEIGHT };
|
||||
SDL_SetRenderViewport(renderer, &viewport);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_QueueDrawVertices(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
|
||||
{
|
||||
NGAGE_Vertex *verts = (NGAGE_Vertex *)SDL_AllocateRenderVertices(renderer, count * sizeof(NGAGE_Vertex), 0, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
for (int i = 0; i < count; i++, points++) {
|
||||
int fixed_x = Real2Fix(points->x);
|
||||
int fixed_y = Real2Fix(points->y);
|
||||
|
||||
verts[i].x = Fix2Int(fixed_x);
|
||||
verts[i].y = Fix2Int(fixed_y);
|
||||
|
||||
Uint32 color = NGAGE_ConvertColor(cmd->data.draw.color.r, cmd->data.draw.color.g, cmd->data.draw.color.b, cmd->data.draw.color.a, cmd->data.draw.color_scale);
|
||||
|
||||
verts[i].color.a = (Uint8)(color >> 24);
|
||||
verts[i].color.b = (Uint8)(color >> 16);
|
||||
verts[i].color.g = (Uint8)(color >> 8);
|
||||
verts[i].color.r = (Uint8)color;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_QueueFillRects(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
|
||||
{
|
||||
NGAGE_Vertex *verts = (NGAGE_Vertex *)SDL_AllocateRenderVertices(renderer, count * 2 * sizeof(NGAGE_Vertex), 0, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
for (int i = 0; i < count; i++, rects++) {
|
||||
verts[i * 2].x = Real2Fix(rects->x);
|
||||
verts[i * 2].y = Real2Fix(rects->y);
|
||||
verts[i * 2 + 1].x = Real2Fix(rects->w);
|
||||
verts[i * 2 + 1].y = Real2Fix(rects->h);
|
||||
|
||||
verts[i * 2].x = Fix2Int(verts[i * 2].x);
|
||||
verts[i * 2].y = Fix2Int(verts[i * 2].y);
|
||||
verts[i * 2 + 1].x = Fix2Int(verts[i * 2 + 1].x);
|
||||
verts[i * 2 + 1].y = Fix2Int(verts[i * 2 + 1].y);
|
||||
|
||||
Uint32 color = NGAGE_ConvertColor(cmd->data.draw.color.r, cmd->data.draw.color.g, cmd->data.draw.color.b, cmd->data.draw.color.a, cmd->data.draw.color_scale);
|
||||
|
||||
verts[i * 2].color.a = (Uint8)(color >> 24);
|
||||
verts[i * 2].color.b = (Uint8)(color >> 16);
|
||||
verts[i * 2].color.g = (Uint8)(color >> 8);
|
||||
verts[i * 2].color.r = (Uint8)color;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_QueueCopy(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect)
|
||||
{
|
||||
SDL_Rect *verts = (SDL_Rect *)SDL_AllocateRenderVertices(renderer, 2 * sizeof(SDL_Rect), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
verts->x = (int)srcrect->x;
|
||||
verts->y = (int)srcrect->y;
|
||||
verts->w = (int)srcrect->w;
|
||||
verts->h = (int)srcrect->h;
|
||||
|
||||
verts++;
|
||||
|
||||
verts->x = (int)dstrect->x;
|
||||
verts->y = (int)dstrect->y;
|
||||
verts->w = (int)dstrect->w;
|
||||
verts->h = (int)dstrect->h;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_QueueCopyEx(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_FRect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y)
|
||||
{
|
||||
NGAGE_CopyExData *verts = (NGAGE_CopyExData *)SDL_AllocateRenderVertices(renderer, sizeof(NGAGE_CopyExData), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
verts->srcrect.x = (int)srcquad->x;
|
||||
verts->srcrect.y = (int)srcquad->y;
|
||||
verts->srcrect.w = (int)srcquad->w;
|
||||
verts->srcrect.h = (int)srcquad->h;
|
||||
verts->dstrect.x = (int)dstrect->x;
|
||||
verts->dstrect.y = (int)dstrect->y;
|
||||
verts->dstrect.w = (int)dstrect->w;
|
||||
verts->dstrect.h = (int)dstrect->h;
|
||||
|
||||
verts->angle = Real2Fix(angle);
|
||||
verts->center.x = Real2Fix(center->x);
|
||||
verts->center.y = Real2Fix(center->y);
|
||||
verts->scale_x = Real2Fix(scale_x);
|
||||
verts->scale_y = Real2Fix(scale_y);
|
||||
|
||||
verts->flip = flip;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const float *xy, int xy_stride, const SDL_FColor *color, int color_stride, const float *uv, int uv_stride, int num_vertices, const void *indices, int num_indices, int size_indices, float scale_x, float scale_y)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void NGAGE_InvalidateCachedState(SDL_Renderer *renderer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static bool NGAGE_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
||||
{
|
||||
NGAGE_RendererData *phdata = (NGAGE_RendererData *)renderer->internal;
|
||||
if (!phdata) {
|
||||
return false;
|
||||
}
|
||||
phdata->viewport = 0;
|
||||
|
||||
while (cmd) {
|
||||
switch (cmd->command) {
|
||||
case SDL_RENDERCMD_NO_OP:
|
||||
break;
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
phdata->viewport = &cmd->data.viewport.rect;
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_SETCLIPRECT:
|
||||
{
|
||||
const SDL_Rect *rect = &cmd->data.cliprect.rect;
|
||||
|
||||
if (cmd->data.cliprect.enabled) {
|
||||
NGAGE_SetClipRect(rect);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETDRAWCOLOR:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_CLEAR:
|
||||
{
|
||||
Uint32 color = NGAGE_ConvertColor(cmd->data.color.color.r, cmd->data.color.color.g, cmd->data.color.color.b, cmd->data.color.color.a, cmd->data.color.color_scale);
|
||||
|
||||
NGAGE_Clear(color);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_DRAW_POINTS:
|
||||
{
|
||||
NGAGE_Vertex *verts = (NGAGE_Vertex *)(((Uint8 *)vertices) + cmd->data.draw.first);
|
||||
const int count = cmd->data.draw.count;
|
||||
|
||||
// Apply viewport.
|
||||
if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
verts[i].x += phdata->viewport->x;
|
||||
verts[i].y += phdata->viewport->y;
|
||||
}
|
||||
}
|
||||
|
||||
NGAGE_DrawPoints(verts, count);
|
||||
break;
|
||||
}
|
||||
case SDL_RENDERCMD_DRAW_LINES:
|
||||
{
|
||||
NGAGE_Vertex *verts = (NGAGE_Vertex *)(((Uint8 *)vertices) + cmd->data.draw.first);
|
||||
const int count = cmd->data.draw.count;
|
||||
|
||||
// Apply viewport.
|
||||
if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
verts[i].x += phdata->viewport->x;
|
||||
verts[i].y += phdata->viewport->y;
|
||||
}
|
||||
}
|
||||
|
||||
NGAGE_DrawLines(verts, count);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_FILL_RECTS:
|
||||
{
|
||||
NGAGE_Vertex *verts = (NGAGE_Vertex *)(((Uint8 *)vertices) + cmd->data.draw.first);
|
||||
const int count = cmd->data.draw.count;
|
||||
|
||||
// Apply viewport.
|
||||
if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
verts[i].x += phdata->viewport->x;
|
||||
verts[i].y += phdata->viewport->y;
|
||||
}
|
||||
}
|
||||
|
||||
NGAGE_FillRects(verts, count);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY:
|
||||
{
|
||||
SDL_Rect *verts = (SDL_Rect *)(((Uint8 *)vertices) + cmd->data.draw.first);
|
||||
SDL_Rect *srcrect = verts;
|
||||
SDL_Rect *dstrect = verts + 1;
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
|
||||
// Apply viewport.
|
||||
if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) {
|
||||
dstrect->x += phdata->viewport->x;
|
||||
dstrect->y += phdata->viewport->y;
|
||||
}
|
||||
|
||||
NGAGE_Copy(renderer, texture, srcrect, dstrect);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX:
|
||||
{
|
||||
NGAGE_CopyExData *copydata = (NGAGE_CopyExData *)(((Uint8 *)vertices) + cmd->data.draw.first);
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
|
||||
// Apply viewport.
|
||||
if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) {
|
||||
copydata->dstrect.x += phdata->viewport->x;
|
||||
copydata->dstrect.y += phdata->viewport->y;
|
||||
}
|
||||
|
||||
NGAGE_CopyEx(renderer, texture, copydata);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_GEOMETRY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
cmd = cmd->next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
|
||||
{
|
||||
NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal;
|
||||
|
||||
SDL_Surface *surface = phdata->surface;
|
||||
Uint8 *src, *dst;
|
||||
int row;
|
||||
size_t length;
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
if (!SDL_LockSurface(surface)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
src = (Uint8 *)pixels;
|
||||
dst = (Uint8 *)surface->pixels +
|
||||
rect->y * surface->pitch +
|
||||
rect->x * surface->fmt->bytes_per_pixel;
|
||||
|
||||
length = (size_t)rect->w * surface->fmt->bytes_per_pixel;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += surface->pitch;
|
||||
}
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
|
||||
{
|
||||
NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal;
|
||||
SDL_Surface *surface = phdata->surface;
|
||||
|
||||
*pixels =
|
||||
(void *)((Uint8 *)surface->pixels + rect->y * surface->pitch +
|
||||
rect->x * surface->fmt->bytes_per_pixel);
|
||||
*pitch = surface->pitch;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void NGAGE_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
{
|
||||
}
|
||||
|
||||
static void NGAGE_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
|
||||
{
|
||||
}
|
||||
|
||||
static bool NGAGE_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static SDL_Surface *NGAGE_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||
{
|
||||
return (SDL_Surface *)0;
|
||||
}
|
||||
|
||||
static bool NGAGE_RenderPresent(SDL_Renderer *renderer)
|
||||
{
|
||||
NGAGE_Flip();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void NGAGE_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
{
|
||||
NGAGE_TextureData *data = (NGAGE_TextureData *)texture->internal;
|
||||
if (data) {
|
||||
SDL_DestroySurface(data->surface);
|
||||
NGAGE_DestroyTextureData(data);
|
||||
SDL_free(data);
|
||||
texture->internal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void NGAGE_DestroyRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
NGAGE_RendererData *phdata = (NGAGE_RendererData *)renderer->internal;
|
||||
if (phdata) {
|
||||
SDL_free(phdata);
|
||||
renderer->internal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool NGAGE_SetVSync(SDL_Renderer *renderer, int vsync)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_RENDER_NGAGE
|
744
src/render/ngage/SDL_render_ngage.cpp
Normal file
744
src/render/ngage/SDL_render_ngage.cpp
Normal file
|
@ -0,0 +1,744 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "SDL_internal.h"
|
||||
#include "SDL_render_ngage_c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_RENDER_NGAGE
|
||||
|
||||
#include "SDL_render_ngage_c.hpp"
|
||||
#include "SDL_render_ops.hpp"
|
||||
|
||||
const TUint32 WindowClientHandle = 0x571D0A;
|
||||
|
||||
extern CRenderer *gRenderer;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void NGAGE_Clear(const Uint32 color)
|
||||
{
|
||||
gRenderer->Clear(color);
|
||||
}
|
||||
|
||||
bool NGAGE_Copy(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Rect *srcrect, SDL_Rect *dstrect)
|
||||
{
|
||||
return gRenderer->Copy(renderer, texture, srcrect, dstrect);
|
||||
}
|
||||
|
||||
bool NGAGE_CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, NGAGE_CopyExData *copydata)
|
||||
{
|
||||
return gRenderer->CopyEx(renderer, texture, copydata);
|
||||
}
|
||||
|
||||
bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height)
|
||||
{
|
||||
return gRenderer->CreateTextureData(data, width, height);
|
||||
}
|
||||
|
||||
void NGAGE_DestroyTextureData(NGAGE_TextureData *data)
|
||||
{
|
||||
if (data) {
|
||||
delete data->bitmap;
|
||||
data->bitmap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count)
|
||||
{
|
||||
gRenderer->DrawLines(verts, count);
|
||||
}
|
||||
|
||||
void NGAGE_DrawPoints(NGAGE_Vertex *verts, const int count)
|
||||
{
|
||||
gRenderer->DrawPoints(verts, count);
|
||||
}
|
||||
|
||||
void NGAGE_FillRects(NGAGE_Vertex *verts, const int count)
|
||||
{
|
||||
gRenderer->FillRects(verts, count);
|
||||
}
|
||||
|
||||
void NGAGE_Flip()
|
||||
{
|
||||
gRenderer->Flip();
|
||||
}
|
||||
|
||||
void NGAGE_SetClipRect(const SDL_Rect *rect)
|
||||
{
|
||||
gRenderer->SetClipRect(rect->x, rect->y, rect->w, rect->h);
|
||||
}
|
||||
|
||||
void NGAGE_SetDrawColor(const Uint32 color)
|
||||
{
|
||||
if (gRenderer) {
|
||||
gRenderer->SetDrawColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
void NGAGE_PumpEventsInternal()
|
||||
{
|
||||
gRenderer->PumpEvents();
|
||||
}
|
||||
|
||||
void NGAGE_SuspendScreenSaverInternal(bool suspend)
|
||||
{
|
||||
gRenderer->SuspendScreenSaver(suspend);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
CRenderer *CRenderer::NewL()
|
||||
{
|
||||
CRenderer *self = new (ELeave) CRenderer();
|
||||
CleanupStack::PushL(self);
|
||||
self->ConstructL();
|
||||
CleanupStack::Pop(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
CRenderer::CRenderer() : iRenderer(0), iDirectScreen(0), iScreenGc(0), iWsSession(), iWsWindowGroup(), iWsWindowGroupID(0), iWsWindow(), iWsScreen(0), iWsEventStatus(), iWsEvent(), iShowFPS(EFalse), iFPS(0), iFont(0) {}
|
||||
|
||||
CRenderer::~CRenderer()
|
||||
{
|
||||
delete iRenderer;
|
||||
iRenderer = 0;
|
||||
}
|
||||
|
||||
void CRenderer::ConstructL()
|
||||
{
|
||||
TInt error = KErrNone;
|
||||
|
||||
error = iWsSession.Connect();
|
||||
if (error != KErrNone) {
|
||||
SDL_Log("Failed to connect to window server: %d", error);
|
||||
User::Leave(error);
|
||||
}
|
||||
|
||||
iWsScreen = new (ELeave) CWsScreenDevice(iWsSession);
|
||||
error = iWsScreen->Construct();
|
||||
if (error != KErrNone) {
|
||||
SDL_Log("Failed to construct screen device: %d", error);
|
||||
User::Leave(error);
|
||||
}
|
||||
|
||||
iWsWindowGroup = RWindowGroup(iWsSession);
|
||||
error = iWsWindowGroup.Construct(WindowClientHandle);
|
||||
if (error != KErrNone) {
|
||||
SDL_Log("Failed to construct window group: %d", error);
|
||||
User::Leave(error);
|
||||
}
|
||||
iWsWindowGroup.SetOrdinalPosition(0);
|
||||
|
||||
RProcess thisProcess;
|
||||
TParse exeName;
|
||||
exeName.Set(thisProcess.FileName(), NULL, NULL);
|
||||
TBuf<32> winGroupName;
|
||||
winGroupName.Append(0);
|
||||
winGroupName.Append(0);
|
||||
winGroupName.Append(0); // UID
|
||||
winGroupName.Append(0);
|
||||
winGroupName.Append(exeName.Name()); // Caption
|
||||
winGroupName.Append(0);
|
||||
winGroupName.Append(0); // DOC name
|
||||
iWsWindowGroup.SetName(winGroupName);
|
||||
|
||||
iWsWindow = RWindow(iWsSession);
|
||||
error = iWsWindow.Construct(iWsWindowGroup, WindowClientHandle - 1);
|
||||
if (error != KErrNone) {
|
||||
SDL_Log("Failed to construct window: %d", error);
|
||||
User::Leave(error);
|
||||
}
|
||||
iWsWindow.SetBackgroundColor(KRgbWhite);
|
||||
iWsWindow.SetRequiredDisplayMode(EColor4K);
|
||||
iWsWindow.Activate();
|
||||
iWsWindow.SetSize(iWsScreen->SizeInPixels());
|
||||
iWsWindow.SetVisible(ETrue);
|
||||
|
||||
iWsWindowGroupID = iWsWindowGroup.Identifier();
|
||||
|
||||
TRAPD(errc, iRenderer = iRenderer->NewL());
|
||||
if (errc != KErrNone) {
|
||||
SDL_Log("Failed to create renderer: %d", errc);
|
||||
return;
|
||||
}
|
||||
|
||||
iDirectScreen = CDirectScreenAccess::NewL(
|
||||
iWsSession,
|
||||
*(iWsScreen),
|
||||
iWsWindow, *this);
|
||||
|
||||
// Select font.
|
||||
TFontSpec fontSpec(_L("LatinBold12"), 12);
|
||||
TInt errd = iWsScreen->GetNearestFontInTwips((CFont *&)iFont, fontSpec);
|
||||
if (errd != KErrNone) {
|
||||
SDL_Log("Failed to get font: %d", errd);
|
||||
return;
|
||||
}
|
||||
|
||||
// Activate events.
|
||||
iWsEventStatus = KRequestPending;
|
||||
iWsSession.EventReady(&iWsEventStatus);
|
||||
|
||||
DisableKeyBlocking();
|
||||
|
||||
iIsFocused = ETrue;
|
||||
iShowFPS = EFalse;
|
||||
iSuspendScreenSaver = EFalse;
|
||||
|
||||
if (!iDirectScreen->IsActive()) {
|
||||
TRAPD(err, iDirectScreen->StartL());
|
||||
if (KErrNone != err) {
|
||||
return;
|
||||
}
|
||||
iDirectScreen->ScreenDevice()->SetAutoUpdate(ETrue);
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::Restart(RDirectScreenAccess::TTerminationReasons aReason)
|
||||
{
|
||||
if (!iDirectScreen->IsActive()) {
|
||||
TRAPD(err, iDirectScreen->StartL());
|
||||
if (KErrNone != err) {
|
||||
return;
|
||||
}
|
||||
iDirectScreen->ScreenDevice()->SetAutoUpdate(ETrue);
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::AbortNow(RDirectScreenAccess::TTerminationReasons aReason)
|
||||
{
|
||||
if (iDirectScreen->IsActive()) {
|
||||
iDirectScreen->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::Clear(TUint32 iColor)
|
||||
{
|
||||
if (iRenderer && iRenderer->Gc()) {
|
||||
iRenderer->Gc()->SetBrushColor(iColor);
|
||||
iRenderer->Gc()->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
Uint32 NGAGE_ConvertColor(float r, float g, float b, float a, float color_scale)
|
||||
{
|
||||
TFixed ff = 255 << 16; // 255.f
|
||||
|
||||
TFixed scalef = Real2Fix(color_scale);
|
||||
TFixed rf = Real2Fix(r);
|
||||
TFixed gf = Real2Fix(g);
|
||||
TFixed bf = Real2Fix(b);
|
||||
TFixed af = Real2Fix(a);
|
||||
|
||||
rf = FixMul(rf, scalef);
|
||||
gf = FixMul(gf, scalef);
|
||||
bf = FixMul(bf, scalef);
|
||||
|
||||
rf = SDL_clamp(rf, 0, ff);
|
||||
gf = SDL_clamp(gf, 0, ff);
|
||||
bf = SDL_clamp(bf, 0, ff);
|
||||
af = SDL_clamp(af, 0, ff);
|
||||
|
||||
rf = FixMul(rf, ff) >> 16;
|
||||
gf = FixMul(gf, ff) >> 16;
|
||||
bf = FixMul(bf, ff) >> 16;
|
||||
af = FixMul(af, ff) >> 16;
|
||||
|
||||
return (af << 24) | (bf << 16) | (gf << 8) | rf;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CRenderer::Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect)
|
||||
{
|
||||
if (!texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal;
|
||||
if (!phdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_FColor *c = &texture->color;
|
||||
int w = phdata->surface->w;
|
||||
int h = phdata->surface->h;
|
||||
int pitch = phdata->surface->pitch;
|
||||
void *source = phdata->surface->pixels;
|
||||
void *dest;
|
||||
|
||||
if (!source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void *pixel_buffer_a = SDL_calloc(1, pitch * h);
|
||||
if (!pixel_buffer_a) {
|
||||
return false;
|
||||
}
|
||||
dest = pixel_buffer_a;
|
||||
|
||||
void *pixel_buffer_b = SDL_calloc(1, pitch * h);
|
||||
if (!pixel_buffer_b) {
|
||||
SDL_free(pixel_buffer_a);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) {
|
||||
ApplyColorMod(dest, source, pitch, w, h, texture->color);
|
||||
|
||||
source = dest;
|
||||
}
|
||||
|
||||
float sx;
|
||||
float sy;
|
||||
SDL_GetRenderScale(renderer, &sx, &sy);
|
||||
|
||||
if (sx != 1.f || sy != 1.f) {
|
||||
TFixed scale_x = Real2Fix(sx);
|
||||
TFixed scale_y = Real2Fix(sy);
|
||||
TFixed center_x = Int2Fix(w / 2);
|
||||
TFixed center_y = Int2Fix(h / 2);
|
||||
|
||||
dest == pixel_buffer_a ? dest = pixel_buffer_b : dest = pixel_buffer_a;
|
||||
|
||||
ApplyScale(dest, source, pitch, w, h, center_x, center_y, scale_x, scale_y);
|
||||
|
||||
source = dest;
|
||||
}
|
||||
|
||||
Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h);
|
||||
SDL_free(pixel_buffer_a);
|
||||
SDL_free(pixel_buffer_b);
|
||||
|
||||
if (phdata->bitmap) {
|
||||
TRect aSource(TPoint(srcrect->x, srcrect->y), TSize(srcrect->w, srcrect->h));
|
||||
TPoint aDest(dstrect->x, dstrect->y);
|
||||
iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRenderer::CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE_CopyExData *copydata)
|
||||
{
|
||||
NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal;
|
||||
if (!phdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_FColor *c = &texture->color;
|
||||
int w = phdata->surface->w;
|
||||
int h = phdata->surface->h;
|
||||
int pitch = phdata->surface->pitch;
|
||||
void *source = phdata->surface->pixels;
|
||||
void *dest;
|
||||
|
||||
if (!source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void *pixel_buffer_a = SDL_calloc(1, pitch * h);
|
||||
if (!pixel_buffer_a) {
|
||||
return false;
|
||||
}
|
||||
dest = pixel_buffer_a;
|
||||
|
||||
void *pixel_buffer_b = SDL_calloc(1, pitch * h);
|
||||
if (!pixel_buffer_a) {
|
||||
SDL_free(pixel_buffer_a);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (copydata->flip) {
|
||||
ApplyFlip(dest, source, pitch, w, h, copydata->flip);
|
||||
source = dest;
|
||||
}
|
||||
|
||||
if (copydata->scale_x != 1.f || copydata->scale_y != 1.f) {
|
||||
dest == pixel_buffer_a ? dest = pixel_buffer_b : dest = pixel_buffer_a;
|
||||
ApplyScale(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->scale_x, copydata->scale_y);
|
||||
source = dest;
|
||||
}
|
||||
|
||||
if (copydata->angle) {
|
||||
dest == pixel_buffer_a ? dest = pixel_buffer_b : dest = pixel_buffer_a;
|
||||
ApplyRotation(dest, source, pitch, w, h, copydata->center.x, copydata->center.y, copydata->angle);
|
||||
source = dest;
|
||||
}
|
||||
|
||||
if (c->a != 1.f || c->r != 1.f || c->g != 1.f || c->b != 1.f) {
|
||||
dest == pixel_buffer_a ? dest = pixel_buffer_b : dest = pixel_buffer_a;
|
||||
ApplyColorMod(dest, source, pitch, w, h, texture->color);
|
||||
source = dest;
|
||||
}
|
||||
|
||||
Mem::Copy(phdata->bitmap->DataAddress(), source, pitch * h);
|
||||
SDL_free(pixel_buffer_a);
|
||||
SDL_free(pixel_buffer_b);
|
||||
|
||||
if (phdata->bitmap) {
|
||||
TRect aSource(TPoint(copydata->srcrect.x, copydata->srcrect.y), TSize(copydata->srcrect.w, copydata->srcrect.h));
|
||||
TPoint aDest(copydata->dstrect.x, copydata->dstrect.y);
|
||||
iRenderer->Gc()->BitBlt(aDest, phdata->bitmap, aSource);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRenderer::CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight)
|
||||
{
|
||||
if (!aTextureData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aTextureData->bitmap = new CFbsBitmap();
|
||||
if (!aTextureData->bitmap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TInt error = aTextureData->bitmap->Create(TSize(aWidth, aHeight), EColor4K);
|
||||
if (error != KErrNone) {
|
||||
delete aTextureData->bitmap;
|
||||
aTextureData->bitmap = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRenderer::DrawLines(NGAGE_Vertex *aVerts, const TInt aCount)
|
||||
{
|
||||
if (iRenderer && iRenderer->Gc()) {
|
||||
TPoint *aPoints = new TPoint[aCount];
|
||||
|
||||
for (TInt i = 0; i < aCount; i++) {
|
||||
aPoints[i] = TPoint(aVerts[i].x, aVerts[i].y);
|
||||
}
|
||||
|
||||
TUint32 aColor = (((TUint8)aVerts->color.a << 24) |
|
||||
((TUint8)aVerts->color.b << 16) |
|
||||
((TUint8)aVerts->color.g << 8) |
|
||||
(TUint8)aVerts->color.r);
|
||||
|
||||
iRenderer->Gc()->SetPenColor(aColor);
|
||||
iRenderer->Gc()->DrawPolyLineNoEndPoint(aPoints, aCount);
|
||||
|
||||
delete[] aPoints;
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount)
|
||||
{
|
||||
if (iRenderer && iRenderer->Gc()) {
|
||||
for (TInt i = 0; i < aCount; i++, aVerts++) {
|
||||
TUint32 aColor = (((TUint8)aVerts->color.a << 24) |
|
||||
((TUint8)aVerts->color.b << 16) |
|
||||
((TUint8)aVerts->color.g << 8) |
|
||||
(TUint8)aVerts->color.r);
|
||||
|
||||
iRenderer->Gc()->SetPenColor(aColor);
|
||||
iRenderer->Gc()->Plot(TPoint(aVerts->x, aVerts->y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::FillRects(NGAGE_Vertex *aVerts, const TInt aCount)
|
||||
{
|
||||
if (iRenderer && iRenderer->Gc()) {
|
||||
for (TInt i = 0; i < aCount; i++, aVerts++) {
|
||||
TPoint pos(aVerts[i].x, aVerts[i].y);
|
||||
TSize size(
|
||||
aVerts[i + 1].x,
|
||||
aVerts[i + 1].y);
|
||||
TRect rect(pos, size);
|
||||
|
||||
TUint32 aColor = (((TUint8)aVerts->color.a << 24) |
|
||||
((TUint8)aVerts->color.b << 16) |
|
||||
((TUint8)aVerts->color.g << 8) |
|
||||
(TUint8)aVerts->color.r);
|
||||
|
||||
iRenderer->Gc()->SetPenColor(aColor);
|
||||
iRenderer->Gc()->SetBrushColor(aColor);
|
||||
iRenderer->Gc()->DrawRect(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::Flip()
|
||||
{
|
||||
if (!iRenderer) {
|
||||
SDL_Log("iRenderer is NULL.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!iIsFocused) {
|
||||
return;
|
||||
}
|
||||
|
||||
iRenderer->Gc()->UseFont(iFont);
|
||||
|
||||
if (iShowFPS && iRenderer->Gc()) {
|
||||
UpdateFPS();
|
||||
|
||||
TBuf<64> info;
|
||||
|
||||
iRenderer->Gc()->SetPenStyle(CGraphicsContext::ESolidPen);
|
||||
iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ENullBrush);
|
||||
iRenderer->Gc()->SetPenColor(KRgbCyan);
|
||||
|
||||
TRect aTextRect(TPoint(3, 203 - iFont->HeightInPixels()), TSize(45, iFont->HeightInPixels() + 2));
|
||||
iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush);
|
||||
iRenderer->Gc()->SetBrushColor(KRgbBlack);
|
||||
iRenderer->Gc()->DrawRect(aTextRect);
|
||||
|
||||
// Draw messages.
|
||||
info.Format(_L("FPS: %d"), iFPS);
|
||||
iRenderer->Gc()->DrawText(info, TPoint(5, 203));
|
||||
} else {
|
||||
// This is a workaround that helps regulating the FPS.
|
||||
iRenderer->Gc()->DrawText(_L(""), TPoint(0, 0));
|
||||
}
|
||||
iRenderer->Gc()->DiscardFont();
|
||||
iRenderer->Flip(iDirectScreen);
|
||||
|
||||
// Keep the backlight on.
|
||||
if (iSuspendScreenSaver) {
|
||||
User::ResetInactivityTime();
|
||||
}
|
||||
// Suspend the current thread for a short while.
|
||||
// Give some time to other threads and active objects.
|
||||
User::After(0);
|
||||
}
|
||||
|
||||
void CRenderer::SetDrawColor(TUint32 iColor)
|
||||
{
|
||||
if (iRenderer && iRenderer->Gc()) {
|
||||
iRenderer->Gc()->SetPenColor(iColor);
|
||||
iRenderer->Gc()->SetBrushColor(iColor);
|
||||
iRenderer->Gc()->SetBrushStyle(CGraphicsContext::ESolidBrush);
|
||||
|
||||
TRAPD(err, iRenderer->SetCurrentColor(iColor));
|
||||
if (err != KErrNone) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::SetClipRect(TInt aX, TInt aY, TInt aWidth, TInt aHeight)
|
||||
{
|
||||
if (iRenderer && iRenderer->Gc()) {
|
||||
TRect viewportRect(aX, aY, aX + aWidth, aY + aHeight);
|
||||
iRenderer->Gc()->SetClippingRect(viewportRect);
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::UpdateFPS()
|
||||
{
|
||||
static TTime lastTime;
|
||||
static TInt frameCount = 0;
|
||||
TTime currentTime;
|
||||
const TUint KOneSecond = 1000000; // 1s in ms.
|
||||
|
||||
currentTime.HomeTime();
|
||||
++frameCount;
|
||||
|
||||
TTimeIntervalMicroSeconds timeDiff = currentTime.MicroSecondsFrom(lastTime);
|
||||
|
||||
if (timeDiff.Int64() >= KOneSecond) {
|
||||
// Calculate FPS.
|
||||
iFPS = frameCount;
|
||||
|
||||
// Reset frame count and last time.
|
||||
frameCount = 0;
|
||||
lastTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::SuspendScreenSaver(TBool aSuspend)
|
||||
{
|
||||
iSuspendScreenSaver = aSuspend;
|
||||
}
|
||||
|
||||
static SDL_Scancode ConvertScancode(int key)
|
||||
{
|
||||
SDL_Keycode keycode;
|
||||
|
||||
switch (key) {
|
||||
case EStdKeyBackspace: // Clear key
|
||||
keycode = SDLK_BACKSPACE;
|
||||
break;
|
||||
case 0x31: // 1
|
||||
keycode = SDLK_1;
|
||||
break;
|
||||
case 0x32: // 2
|
||||
keycode = SDLK_2;
|
||||
break;
|
||||
case 0x33: // 3
|
||||
keycode = SDLK_3;
|
||||
break;
|
||||
case 0x34: // 4
|
||||
keycode = SDLK_4;
|
||||
break;
|
||||
case 0x35: // 5
|
||||
keycode = SDLK_5;
|
||||
break;
|
||||
case 0x36: // 6
|
||||
keycode = SDLK_6;
|
||||
break;
|
||||
case 0x37: // 7
|
||||
keycode = SDLK_7;
|
||||
break;
|
||||
case 0x38: // 8
|
||||
keycode = SDLK_8;
|
||||
break;
|
||||
case 0x39: // 9
|
||||
keycode = SDLK_9;
|
||||
break;
|
||||
case 0x30: // 0
|
||||
keycode = SDLK_0;
|
||||
break;
|
||||
case 0x2a: // Asterisk
|
||||
keycode = SDLK_ASTERISK;
|
||||
break;
|
||||
case EStdKeyHash: // Hash
|
||||
keycode = SDLK_HASH;
|
||||
break;
|
||||
case EStdKeyDevice0: // Left softkey
|
||||
keycode = SDLK_SOFTLEFT;
|
||||
break;
|
||||
case EStdKeyDevice1: // Right softkey
|
||||
keycode = SDLK_SOFTRIGHT;
|
||||
break;
|
||||
case EStdKeyApplication0: // Call softkey
|
||||
keycode = SDLK_CALL;
|
||||
break;
|
||||
case EStdKeyApplication1: // End call softkey
|
||||
keycode = SDLK_ENDCALL;
|
||||
break;
|
||||
case EStdKeyDevice3: // Middle softkey
|
||||
keycode = SDLK_SELECT;
|
||||
break;
|
||||
case EStdKeyUpArrow: // Up arrow
|
||||
keycode = SDLK_UP;
|
||||
break;
|
||||
case EStdKeyDownArrow: // Down arrow
|
||||
keycode = SDLK_DOWN;
|
||||
break;
|
||||
case EStdKeyLeftArrow: // Left arrow
|
||||
keycode = SDLK_LEFT;
|
||||
break;
|
||||
case EStdKeyRightArrow: // Right arrow
|
||||
keycode = SDLK_RIGHT;
|
||||
break;
|
||||
default:
|
||||
keycode = SDLK_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return SDL_GetScancodeFromKey(keycode, NULL);
|
||||
}
|
||||
|
||||
void CRenderer::HandleEvent(const TWsEvent &aWsEvent)
|
||||
{
|
||||
Uint64 timestamp;
|
||||
|
||||
switch (aWsEvent.Type()) {
|
||||
case EEventKeyDown: /* Key events */
|
||||
timestamp = SDL_GetPerformanceCounter();
|
||||
SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), true);
|
||||
|
||||
if (aWsEvent.Key()->iScanCode == EStdKeyHash) {
|
||||
if (iShowFPS) {
|
||||
iShowFPS = EFalse;
|
||||
} else {
|
||||
iShowFPS = ETrue;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case EEventKeyUp: /* Key events */
|
||||
timestamp = SDL_GetPerformanceCounter();
|
||||
SDL_SendKeyboardKey(timestamp, 1, aWsEvent.Key()->iCode, ConvertScancode(aWsEvent.Key()->iScanCode), false);
|
||||
|
||||
case EEventFocusGained:
|
||||
DisableKeyBlocking();
|
||||
if (!iDirectScreen->IsActive()) {
|
||||
TRAPD(err, iDirectScreen->StartL());
|
||||
if (KErrNone != err) {
|
||||
return;
|
||||
}
|
||||
iDirectScreen->ScreenDevice()->SetAutoUpdate(ETrue);
|
||||
iIsFocused = ETrue;
|
||||
}
|
||||
Flip();
|
||||
break;
|
||||
case EEventFocusLost:
|
||||
{
|
||||
if (iDirectScreen->IsActive()) {
|
||||
iDirectScreen->Cancel();
|
||||
}
|
||||
|
||||
iIsFocused = EFalse;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderer::DisableKeyBlocking()
|
||||
{
|
||||
TRawEvent aEvent;
|
||||
|
||||
aEvent.Set((TRawEvent::TType) /*EDisableKeyBlock*/ 51);
|
||||
iWsSession.SimulateRawEvent(aEvent);
|
||||
}
|
||||
|
||||
void CRenderer::PumpEvents()
|
||||
{
|
||||
while (iWsEventStatus != KRequestPending) {
|
||||
iWsSession.GetEvent(iWsEvent);
|
||||
HandleEvent(iWsEvent);
|
||||
iWsEventStatus = KRequestPending;
|
||||
iWsSession.EventReady(&iWsEventStatus);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_RENDER_NGAGE
|
105
src/render/ngage/SDL_render_ngage_c.h
Normal file
105
src/render/ngage/SDL_render_ngage_c.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef ngage_video_render_ngage_c_h
|
||||
#define ngage_video_render_ngage_c_h
|
||||
|
||||
#define NGAGE_SCREEN_WIDTH 176
|
||||
#define NGAGE_SCREEN_HEIGHT 208
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../SDL_sysrender.h"
|
||||
|
||||
typedef struct NGAGE_RendererData
|
||||
{
|
||||
SDL_Rect *viewport;
|
||||
|
||||
} NGAGE_RendererData;
|
||||
|
||||
typedef struct NGAGE_Vertex
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
struct
|
||||
{
|
||||
Uint8 a;
|
||||
Uint8 r;
|
||||
Uint8 g;
|
||||
Uint8 b;
|
||||
|
||||
} color;
|
||||
|
||||
} NGAGE_Vertex;
|
||||
|
||||
typedef struct CFbsBitmap CFbsBitmap;
|
||||
|
||||
typedef struct NGAGE_TextureData
|
||||
{
|
||||
CFbsBitmap *bitmap;
|
||||
SDL_Surface *surface;
|
||||
|
||||
} NGAGE_TextureData;
|
||||
|
||||
typedef struct NGAGE_CopyExData
|
||||
{
|
||||
SDL_Rect srcrect;
|
||||
SDL_Rect dstrect;
|
||||
|
||||
int angle;
|
||||
|
||||
struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
} center;
|
||||
|
||||
SDL_FlipMode flip;
|
||||
|
||||
int scale_x;
|
||||
int scale_y;
|
||||
|
||||
} NGAGE_CopyExData;
|
||||
|
||||
void NGAGE_Clear(const Uint32 color);
|
||||
Uint32 NGAGE_ConvertColor(float r, float g, float b, float a, float color_scale);
|
||||
bool NGAGE_Copy(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Rect *srcrect, SDL_Rect *dstrect);
|
||||
bool NGAGE_CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, NGAGE_CopyExData *copydata);
|
||||
bool NGAGE_CreateTextureData(NGAGE_TextureData *data, const int width, const int height);
|
||||
void NGAGE_DestroyTextureData(NGAGE_TextureData *data);
|
||||
void NGAGE_DrawLines(NGAGE_Vertex *verts, const int count);
|
||||
void NGAGE_DrawPoints(NGAGE_Vertex *verts, const int count);
|
||||
void NGAGE_FillRects(NGAGE_Vertex *verts, const int count);
|
||||
void NGAGE_Flip(void);
|
||||
void NGAGE_SetClipRect(const SDL_Rect *rect);
|
||||
void NGAGE_SetDrawColor(const Uint32 color);
|
||||
void NGAGE_PumpEventsInternal(void);
|
||||
void NGAGE_SuspendScreenSaverInternal(bool suspend);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ngage_video_render_ngage_c_h
|
91
src/render/ngage/SDL_render_ngage_c.hpp
Normal file
91
src/render/ngage/SDL_render_ngage_c.hpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef ngage_video_render_ngage_c_hpp
|
||||
#define ngage_video_render_ngage_c_hpp
|
||||
|
||||
#include "SDL_render_ngage_c.h"
|
||||
#include <NRenderer.h>
|
||||
#include <e32std.h>
|
||||
#include <w32std.h>
|
||||
|
||||
class CRenderer : public MDirectScreenAccess
|
||||
{
|
||||
public:
|
||||
static CRenderer *NewL();
|
||||
virtual ~CRenderer();
|
||||
|
||||
// Rendering functions.
|
||||
void Clear(TUint32 iColor);
|
||||
bool Copy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect);
|
||||
bool CopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const NGAGE_CopyExData *copydata);
|
||||
bool CreateTextureData(NGAGE_TextureData *aTextureData, const TInt aWidth, const TInt aHeight);
|
||||
void DrawLines(NGAGE_Vertex *aVerts, const TInt aCount);
|
||||
void DrawPoints(NGAGE_Vertex *aVerts, const TInt aCount);
|
||||
void FillRects(NGAGE_Vertex *aVerts, const TInt aCount);
|
||||
void Flip();
|
||||
void SetDrawColor(TUint32 iColor);
|
||||
void SetClipRect(TInt aX, TInt aY, TInt aWidth, TInt aHeight);
|
||||
void UpdateFPS();
|
||||
void SuspendScreenSaver(TBool aSuspend);
|
||||
|
||||
// Event handling.
|
||||
void DisableKeyBlocking();
|
||||
void HandleEvent(const TWsEvent &aWsEvent);
|
||||
void PumpEvents();
|
||||
|
||||
private:
|
||||
CRenderer();
|
||||
void ConstructL(void);
|
||||
|
||||
// BackBuffer.
|
||||
CNRenderer *iRenderer;
|
||||
|
||||
// Direct screen access.
|
||||
CDirectScreenAccess *iDirectScreen;
|
||||
CFbsBitGc *iScreenGc;
|
||||
TBool iIsFocused;
|
||||
|
||||
// Window server session.
|
||||
RWsSession iWsSession;
|
||||
RWindowGroup iWsWindowGroup;
|
||||
TInt iWsWindowGroupID;
|
||||
RWindow iWsWindow;
|
||||
CWsScreenDevice *iWsScreen;
|
||||
|
||||
// Event handling.
|
||||
TRequestStatus iWsEventStatus;
|
||||
TWsEvent iWsEvent;
|
||||
|
||||
// MDirectScreenAccess functions.
|
||||
void Restart(RDirectScreenAccess::TTerminationReasons aReason);
|
||||
void AbortNow(RDirectScreenAccess::TTerminationReasons aReason);
|
||||
|
||||
// Frame per second.
|
||||
TBool iShowFPS;
|
||||
TUint iFPS;
|
||||
const CFont *iFont;
|
||||
|
||||
// Screen saver.
|
||||
TBool iSuspendScreenSaver;
|
||||
};
|
||||
|
||||
#endif // ngage_video_render_ngage_c_hpp
|
152
src/render/ngage/SDL_render_ops.cpp
Normal file
152
src/render/ngage/SDL_render_ops.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include <3dtypes.h>
|
||||
#include "SDL_render_ops.hpp"
|
||||
|
||||
void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color)
|
||||
{
|
||||
TUint16 *src_pixels = static_cast<TUint16 *>(source);
|
||||
TUint16 *dst_pixels = static_cast<TUint16 *>(dest);
|
||||
|
||||
TFixed rf = Real2Fix(color.r);
|
||||
TFixed gf = Real2Fix(color.g);
|
||||
TFixed bf = Real2Fix(color.b);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
TUint16 pixel = src_pixels[y * pitch / 2 + x];
|
||||
TUint8 r = (pixel & 0xF800) >> 8;
|
||||
TUint8 g = (pixel & 0x07E0) >> 3;
|
||||
TUint8 b = (pixel & 0x001F) << 3;
|
||||
r = FixMul(r, rf);
|
||||
g = FixMul(g, gf);
|
||||
b = FixMul(b, bf);
|
||||
dst_pixels[y * pitch / 2 + x] = (r << 8) | (g << 3) | (b >> 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyFlip(void* dest, void* source, int pitch, int width, int height, SDL_FlipMode flip)
|
||||
{
|
||||
TUint16* src_pixels = static_cast<TUint16*>(source);
|
||||
TUint16* dst_pixels = static_cast<TUint16*>(dest);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
int src_x = x;
|
||||
int src_y = y;
|
||||
|
||||
if (flip & SDL_FLIP_HORIZONTAL)
|
||||
{
|
||||
src_x = width - 1 - x;
|
||||
}
|
||||
|
||||
if (flip & SDL_FLIP_VERTICAL)
|
||||
{
|
||||
src_y = height - 1 - y;
|
||||
}
|
||||
|
||||
dst_pixels[y * pitch / 2 + x] = src_pixels[src_y * pitch / 2 + src_x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyRotation(void* dest, void* source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed angle)
|
||||
{
|
||||
TUint16* src_pixels = static_cast<TUint16*>(source);
|
||||
TUint16* dst_pixels = static_cast<TUint16*>(dest);
|
||||
|
||||
TFixed cos_angle = 0;
|
||||
TFixed sin_angle = 0;
|
||||
|
||||
if (angle != 0)
|
||||
{
|
||||
FixSinCos(angle, sin_angle, cos_angle);
|
||||
}
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
// Translate point to origin.
|
||||
TFixed translated_x = Int2Fix(x) - center_x;
|
||||
TFixed translated_y = Int2Fix(y) - center_y;
|
||||
|
||||
// Rotate point (clockwise).
|
||||
TFixed rotated_x = FixMul(translated_x, cos_angle) + FixMul(translated_y, sin_angle);
|
||||
TFixed rotated_y = FixMul(translated_y, cos_angle) - FixMul(translated_x, sin_angle);
|
||||
|
||||
// Translate point back.
|
||||
int final_x = Fix2Int(rotated_x + center_x);
|
||||
int final_y = Fix2Int(rotated_y + center_y);
|
||||
|
||||
// Check bounds.
|
||||
if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height)
|
||||
{
|
||||
dst_pixels[y * pitch / 2 + x] = src_pixels[final_y * pitch / 2 + final_x];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_pixels[y * pitch / 2 + x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyScale(void* dest, void* source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed scale_x, TFixed scale_y)
|
||||
{
|
||||
TUint16* src_pixels = static_cast<TUint16*>(source);
|
||||
TUint16* dst_pixels = static_cast<TUint16*>(dest);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
// Translate point to origin.
|
||||
TFixed translated_x = Int2Fix(x) - center_x;
|
||||
TFixed translated_y = Int2Fix(y) - center_y;
|
||||
|
||||
// Scale point.
|
||||
TFixed scaled_x = FixDiv(translated_x, scale_x);
|
||||
TFixed scaled_y = FixDiv(translated_y, scale_y);
|
||||
|
||||
// Translate point back.
|
||||
int final_x = Fix2Int(scaled_x + center_x);
|
||||
int final_y = Fix2Int(scaled_y + center_y);
|
||||
|
||||
// Check bounds.
|
||||
if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height)
|
||||
{
|
||||
dst_pixels[y * pitch / 2 + x] = src_pixels[final_y * pitch / 2 + final_x];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_pixels[y * pitch / 2 + x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
src/render/ngage/SDL_render_ops.hpp
Normal file
32
src/render/ngage/SDL_render_ops.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef ngage_video_render_ops_hpp
|
||||
#define ngage_video_render_ops_hpp
|
||||
|
||||
#include <3dtypes.h>
|
||||
|
||||
void ApplyColorMod(void* dest, void* source, int pitch, int width, int height, SDL_FColor color);
|
||||
void ApplyFlip(void* dest, void* source, int pitch, int width, int height, SDL_FlipMode flip);
|
||||
void ApplyRotation(void* dest, void* source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed angle);
|
||||
void ApplyScale(void* dest, void* source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed scale_x, TFixed scale_y);
|
||||
|
||||
#endif // ngage_video_render_ops_hpp
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
#if defined(__SIZEOF_WCHAR_T__)
|
||||
#define SDL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
#define SDL_SIZEOF_WCHAR_T 2
|
||||
#elif defined(SDL_PLATFORM_WINDOWS)
|
||||
#define SDL_SIZEOF_WCHAR_T 2
|
||||
#else // assume everything else is UTF-32 (add more tests if compiler-assert fails below!)
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
*/
|
||||
|
||||
// Do our best to make sure va_copy is working
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||
#if (defined(_MSC_VER) && _MSC_VER <= 1800) || defined(__SYMBIAN32__)
|
||||
// Visual Studio 2013 tries to link with _vacopy in the C runtime. Newer versions do an inline assignment
|
||||
#undef va_copy
|
||||
#define va_copy(dst, src) dst = src
|
||||
|
||||
#elif defined(__GNUC__) && (__GNUC__ < 3)
|
||||
#define va_copy(dst, src) __va_copy(dst, src)
|
||||
|
||||
#endif
|
||||
|
|
184
src/time/ngage/SDL_systime.cpp
Normal file
184
src/time/ngage/SDL_systime.cpp
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_TIME_NGAGE
|
||||
|
||||
#include <bautils.h>
|
||||
#include <e32base.h>
|
||||
#include <e32cons.h>
|
||||
#include <e32std.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static TTime UnixEpoch();
|
||||
|
||||
void SDL_GetSystemTimeLocalePreferences(SDL_DateFormat *df, SDL_TimeFormat *tf)
|
||||
{
|
||||
TLanguage language = User::Language();
|
||||
|
||||
switch (language) {
|
||||
case ELangFrench:
|
||||
case ELangSwissFrench:
|
||||
case ELangBelgianFrench:
|
||||
case ELangInternationalFrench:
|
||||
case ELangGerman:
|
||||
case ELangSwissGerman:
|
||||
case ELangAustrian:
|
||||
case ELangSpanish:
|
||||
case ELangInternationalSpanish:
|
||||
case ELangLatinAmericanSpanish:
|
||||
case ELangItalian:
|
||||
case ELangSwissItalian:
|
||||
case ELangSwedish:
|
||||
case ELangFinlandSwedish:
|
||||
case ELangDanish:
|
||||
case ELangNorwegian:
|
||||
case ELangNorwegianNynorsk:
|
||||
case ELangFinnish:
|
||||
case ELangPortuguese:
|
||||
case ELangBrazilianPortuguese:
|
||||
case ELangTurkish:
|
||||
case ELangCyprusTurkish:
|
||||
case ELangIcelandic:
|
||||
case ELangRussian:
|
||||
case ELangHungarian:
|
||||
case ELangDutch:
|
||||
case ELangBelgianFlemish:
|
||||
case ELangCzech:
|
||||
case ELangSlovak:
|
||||
case ELangPolish:
|
||||
case ELangSlovenian:
|
||||
case ELangTaiwanChinese:
|
||||
case ELangHongKongChinese:
|
||||
case ELangPrcChinese:
|
||||
case ELangJapanese:
|
||||
case ELangThai:
|
||||
case ELangAfrikaans:
|
||||
case ELangAlbanian:
|
||||
case ELangAmharic:
|
||||
case ELangArabic:
|
||||
case ELangArmenian:
|
||||
case ELangAzerbaijani:
|
||||
case ELangBelarussian:
|
||||
case ELangBengali:
|
||||
case ELangBulgarian:
|
||||
case ELangBurmese:
|
||||
case ELangCatalan:
|
||||
case ELangCroatian:
|
||||
case ELangEstonian:
|
||||
case ELangFarsi:
|
||||
case ELangScotsGaelic:
|
||||
case ELangGeorgian:
|
||||
case ELangGreek:
|
||||
case ELangCyprusGreek:
|
||||
case ELangGujarati:
|
||||
case ELangHebrew:
|
||||
case ELangHindi:
|
||||
case ELangIndonesian:
|
||||
case ELangIrish:
|
||||
case ELangKannada:
|
||||
case ELangKazakh:
|
||||
case ELangKhmer:
|
||||
case ELangKorean:
|
||||
case ELangLao:
|
||||
case ELangLatvian:
|
||||
case ELangLithuanian:
|
||||
case ELangMacedonian:
|
||||
case ELangMalay:
|
||||
case ELangMalayalam:
|
||||
case ELangMarathi:
|
||||
case ELangMoldavian:
|
||||
case ELangMongolian:
|
||||
case ELangPunjabi:
|
||||
case ELangRomanian:
|
||||
case ELangSerbian:
|
||||
case ELangSinhalese:
|
||||
case ELangSomali:
|
||||
case ELangSwahili:
|
||||
case ELangTajik:
|
||||
case ELangTamil:
|
||||
case ELangTelugu:
|
||||
case ELangTibetan:
|
||||
case ELangTigrinya:
|
||||
case ELangTurkmen:
|
||||
case ELangUkrainian:
|
||||
case ELangUrdu:
|
||||
case ELangUzbek:
|
||||
case ELangVietnamese:
|
||||
case ELangWelsh:
|
||||
case ELangZulu:
|
||||
*df = SDL_DATE_FORMAT_DDMMYYYY;
|
||||
*tf = SDL_TIME_FORMAT_24HR;
|
||||
break;
|
||||
case ELangAmerican:
|
||||
case ELangCanadianEnglish:
|
||||
case ELangInternationalEnglish:
|
||||
case ELangSouthAfricanEnglish:
|
||||
case ELangAustralian:
|
||||
case ELangNewZealand:
|
||||
case ELangCanadianFrench:
|
||||
*df = SDL_DATE_FORMAT_MMDDYYYY;
|
||||
*tf = SDL_TIME_FORMAT_12HR;
|
||||
break;
|
||||
case ELangEnglish:
|
||||
case ELangOther:
|
||||
default:
|
||||
*df = SDL_DATE_FORMAT_DDMMYYYY;
|
||||
*tf = SDL_TIME_FORMAT_24HR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SDL_GetCurrentTime(SDL_Time *ticks)
|
||||
{
|
||||
if (!ticks) {
|
||||
return SDL_InvalidParamError("ticks");
|
||||
}
|
||||
|
||||
TTime now;
|
||||
now.UniversalTime();
|
||||
|
||||
TTimeIntervalMicroSeconds interval = now.MicroSecondsFrom(UnixEpoch());
|
||||
TInt64 interval_ns = interval.Int64() * 1000;
|
||||
Uint32 ns_low = interval_ns.Low();
|
||||
Uint32 ns_high = interval_ns.High();
|
||||
|
||||
*ticks = ((Uint64)ns_high << 32) | ns_low;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static TTime UnixEpoch()
|
||||
{
|
||||
_LIT(KUnixEpoch, "19700101:000000.000000");
|
||||
TTime epochTime;
|
||||
epochTime.Set(KUnixEpoch);
|
||||
return epochTime;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDL_TIME_NGAGE
|
47
src/timer/ngage/SDL_systimer.cpp
Normal file
47
src/timer/ngage/SDL_systimer.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include <e32hal.h>
|
||||
#include <e32std.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
Uint64 SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
return (Uint64)User::TickCount();
|
||||
}
|
||||
|
||||
Uint64 SDL_GetPerformanceFrequency(void)
|
||||
{
|
||||
return (Uint64)1000000u;
|
||||
}
|
||||
|
||||
void SDL_SYS_DelayNS(Uint64 ns)
|
||||
{
|
||||
User::After(SDL_NS_TO_US(ns));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -530,6 +530,7 @@ extern VideoBootStrap PSP_bootstrap;
|
|||
extern VideoBootStrap VITA_bootstrap;
|
||||
extern VideoBootStrap RISCOS_bootstrap;
|
||||
extern VideoBootStrap N3DS_bootstrap;
|
||||
extern VideoBootStrap NGAGE_bootstrap;
|
||||
extern VideoBootStrap RPI_bootstrap;
|
||||
extern VideoBootStrap KMSDRM_bootstrap;
|
||||
extern VideoBootStrap DUMMY_bootstrap;
|
||||
|
|
|
@ -119,6 +119,9 @@ static VideoBootStrap *bootstrap[] = {
|
|||
#ifdef SDL_VIDEO_DRIVER_N3DS
|
||||
&N3DS_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_VIDEO_DRIVER_NGAGE
|
||||
&NGAGE_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM
|
||||
&KMSDRM_bootstrap,
|
||||
#endif
|
||||
|
|
175
src/video/ngage/SDL_ngagevideo.c
Normal file
175
src/video/ngage/SDL_ngagevideo.c
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_NGAGE
|
||||
|
||||
#include "SDL_ngagevideo.h"
|
||||
|
||||
#define NGAGE_VIDEO_DRIVER_NAME "N-Gage"
|
||||
|
||||
static void NGAGE_DeleteDevice(SDL_VideoDevice *device);
|
||||
static bool NGAGE_VideoInit(SDL_VideoDevice *device);
|
||||
static void NGAGE_VideoQuit(SDL_VideoDevice *device);
|
||||
|
||||
static bool NGAGE_GetDisplayBounds(SDL_VideoDevice *device, SDL_VideoDisplay *display, SDL_Rect *rect);
|
||||
static bool NGAGE_GetDisplayModes(SDL_VideoDevice *device, SDL_VideoDisplay *display);
|
||||
|
||||
static void NGAGE_PumpEvents(SDL_VideoDevice *device);
|
||||
|
||||
static bool NGAGE_SuspendScreenSaver(SDL_VideoDevice *device);
|
||||
|
||||
static SDL_VideoDevice *NGAGE_CreateDevice(void)
|
||||
{
|
||||
SDL_VideoDevice *device;
|
||||
SDL_VideoData *phdata;
|
||||
|
||||
// Initialize all variables that we clean on shutdown.
|
||||
device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (!device) {
|
||||
SDL_OutOfMemory();
|
||||
return (SDL_VideoDevice *)0;
|
||||
}
|
||||
|
||||
// Initialize internal N-Gage specific data.
|
||||
phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
|
||||
if (!phdata) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(device);
|
||||
return (SDL_VideoDevice *)0;
|
||||
}
|
||||
|
||||
device->internal = phdata;
|
||||
|
||||
device->name = "Nokia N-Gage";
|
||||
|
||||
device->VideoInit = NGAGE_VideoInit;
|
||||
device->VideoQuit = NGAGE_VideoQuit;
|
||||
|
||||
device->GetDisplayBounds = NGAGE_GetDisplayBounds;
|
||||
device->GetDisplayModes = NGAGE_GetDisplayModes;
|
||||
|
||||
device->PumpEvents = NGAGE_PumpEvents;
|
||||
|
||||
device->SuspendScreenSaver = NGAGE_SuspendScreenSaver;
|
||||
|
||||
device->free = NGAGE_DeleteDevice;
|
||||
|
||||
device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
VideoBootStrap NGAGE_bootstrap = {
|
||||
NGAGE_VIDEO_DRIVER_NAME,
|
||||
"N-Gage Video Driver",
|
||||
NGAGE_CreateDevice,
|
||||
0
|
||||
};
|
||||
|
||||
static void NGAGE_DeleteDevice(SDL_VideoDevice *device)
|
||||
{
|
||||
SDL_free(device->internal);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
static bool NGAGE_VideoInit(SDL_VideoDevice *device)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *)device->internal;
|
||||
|
||||
if (!phdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_zero(phdata->mode);
|
||||
SDL_zero(phdata->display);
|
||||
|
||||
phdata->mode.w = 176;
|
||||
phdata->mode.h = 208;
|
||||
phdata->mode.refresh_rate = 60.0f;
|
||||
phdata->mode.format = SDL_PIXELFORMAT_ARGB4444;
|
||||
|
||||
phdata->display.name = "N-Gage";
|
||||
phdata->display.desktop_mode = phdata->mode;
|
||||
|
||||
if (SDL_AddVideoDisplay(&phdata->display, false) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void NGAGE_VideoQuit(SDL_VideoDevice *device)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *)device->internal;
|
||||
|
||||
if (phdata) {
|
||||
SDL_zero(phdata->mode);
|
||||
SDL_zero(phdata->display);
|
||||
}
|
||||
}
|
||||
|
||||
static bool NGAGE_GetDisplayBounds(SDL_VideoDevice *device, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
{
|
||||
if (!display) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
rect->w = display->current_mode->w;
|
||||
rect->h = display->current_mode->h;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NGAGE_GetDisplayModes(SDL_VideoDevice *device, SDL_VideoDisplay *display)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *)device->internal;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
SDL_zero(mode);
|
||||
mode.w = phdata->mode.w;
|
||||
mode.h = phdata->mode.h;
|
||||
mode.refresh_rate = phdata->mode.refresh_rate;
|
||||
mode.format = phdata->mode.format;
|
||||
|
||||
if (!SDL_AddFullscreenDisplayMode(display, &mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "../../render/ngage/SDL_render_ngage_c.h"
|
||||
|
||||
static void NGAGE_PumpEvents(SDL_VideoDevice *device)
|
||||
{
|
||||
NGAGE_PumpEventsInternal();
|
||||
}
|
||||
|
||||
static bool NGAGE_SuspendScreenSaver(SDL_VideoDevice *device)
|
||||
{
|
||||
NGAGE_SuspendScreenSaverInternal(device->suspend_screensaver);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_NGAGE
|
39
src/video/ngage/SDL_ngagevideo.h
Normal file
39
src/video/ngage/SDL_ngagevideo.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_NGAGE
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#ifndef _SDL_ngagevideo_h
|
||||
#define _SDL_ngagevideo_h
|
||||
|
||||
typedef struct SDL_VideoData
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
SDL_VideoDisplay display;
|
||||
|
||||
} SDL_VideoData;
|
||||
|
||||
#endif // _SDL_ngagevideo_h
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_NGAGE
|
|
@ -32,8 +32,6 @@ if(NOT (MSVC AND SDL_CPU_ARM64))
|
|||
find_package(OpenGL)
|
||||
endif()
|
||||
|
||||
set(SDL_TEST_EXECUTABLES)
|
||||
|
||||
add_library(sdltests_utils OBJECT
|
||||
testutils.c
|
||||
)
|
||||
|
@ -101,7 +99,7 @@ define_property(TARGET PROPERTY SDL_NONINTERACTIVE BRIEF_DOCS "If true, target i
|
|||
define_property(TARGET PROPERTY SDL_NONINTERACTIVE_ARGUMENTS BRIEF_DOCS "Argument(s) to run executable in non-interactive mode." FULL_DOCS "Argument(s) to run executable in non-interactive mode.")
|
||||
define_property(TARGET PROPERTY SDL_NONINTERACTIVE_TIMEOUT BRIEF_DOCS "Timeout for noninteractive executable." FULL_DOCS "Timeout for noninteractive executable.")
|
||||
|
||||
macro(add_sdl_test_executable TARGET)
|
||||
function(add_sdl_test_executable TARGET)
|
||||
cmake_parse_arguments(AST "BUILD_DEPENDENT;NONINTERACTIVE;NEEDS_RESOURCES;TESTUTILS;THREADS;NO_C90;MAIN_CALLBACKS;NOTRACKMEM" "" "DEPENDS;DISABLE_THREADS_ARGS;NONINTERACTIVE_TIMEOUT;NONINTERACTIVE_ARGS;INSTALLED_ARGS;SOURCES" ${ARGN})
|
||||
if(AST_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unknown argument(s): ${AST_UNPARSED_ARGUMENTS}")
|
||||
|
@ -133,7 +131,8 @@ macro(add_sdl_test_executable TARGET)
|
|||
add_dependencies(${TARGET} ${AST_DEPENDS})
|
||||
endif()
|
||||
|
||||
list(APPEND SDL_TEST_EXECUTABLES ${TARGET})
|
||||
set_propertY(TARGET ${TARGET} PROPERTY SDL_INSTALL "1")
|
||||
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY SDL_TEST_EXECUTABLES "${TARGET}")
|
||||
set_property(TARGET ${TARGET} PROPERTY SDL_NOTRACKMEM ${AST_NOTRACKMEM})
|
||||
if(AST_NONINTERACTIVE)
|
||||
set_property(TARGET ${TARGET} PROPERTY SDL_NONINTERACTIVE 1)
|
||||
|
@ -192,6 +191,14 @@ macro(add_sdl_test_executable TARGET)
|
|||
target_link_options(${TARGET} PRIVATE "SHELL:--pre-js ${CMAKE_CURRENT_SOURCE_DIR}/emscripten/pre.js")
|
||||
target_link_options(${TARGET} PRIVATE "-sEXIT_RUNTIME=1")
|
||||
set_property(TARGET ${TARGET} APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/emscripten/pre.js")
|
||||
elseif(NGAGE)
|
||||
string(MD5 TARGET_MD5 "${TARGET}")
|
||||
string(SUBSTRING "${TARGET_MD5}" 0 8 TARGET_MD5_8)
|
||||
target_link_options(${TARGET} PRIVATE "SHELL:-s UID3=0x${TARGET_MD5_8}")
|
||||
if(NOT AST_MAIN_CALLBACKS)
|
||||
set_property(TARGET ${TARGET} PROPERTY "EXCLUDE_FROM_ALL" "1")
|
||||
set_propertY(TARGET ${TARGET} PROPERTY SDL_INSTALL "0")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENGL_FOUND)
|
||||
|
@ -200,10 +207,10 @@ macro(add_sdl_test_executable TARGET)
|
|||
|
||||
# FIXME: only add "${SDL3_BINARY_DIR}/include-config-$<LOWER_CASE:$<CONFIG>>" + include paths of external dependencies
|
||||
target_include_directories(${TARGET} PRIVATE "$<TARGET_PROPERTY:SDL3::${sdl_name_component},INCLUDE_DIRECTORIES>")
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
check_include_file(signal.h HAVE_SIGNAL_H)
|
||||
if(HAVE_SIGNAL_H)
|
||||
check_include_file(signal.h LIBC_HAS_SIGNAL_H)
|
||||
if(LIBC_HAS_SIGNAL_H)
|
||||
add_definitions(-DHAVE_SIGNAL_H)
|
||||
endif()
|
||||
|
||||
|
@ -425,6 +432,8 @@ add_sdl_test_executable(testprocess
|
|||
add_sdl_test_executable(childprocess SOURCES childprocess.c)
|
||||
add_dependencies(testprocess childprocess)
|
||||
|
||||
get_property(SDL_TEST_EXECUTABLES DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY SDL_TEST_EXECUTABLES)
|
||||
|
||||
if (HAVE_WAYLAND)
|
||||
# Set the GENERATED property on the protocol file, since it is first created at build time
|
||||
set_property(SOURCE ${SDL3_BINARY_DIR}/wayland-generated-protocols/xdg-shell-protocol.c PROPERTY GENERATED 1)
|
||||
|
@ -654,10 +663,15 @@ if(SDL_INSTALL_TESTS)
|
|||
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-tests/SDL3
|
||||
)
|
||||
else()
|
||||
install(
|
||||
TARGETS ${SDL_TEST_EXECUTABLES}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-tests/SDL3
|
||||
)
|
||||
foreach(test IN LISTS SDL_TEST_EXECUTABLES)
|
||||
get_property(install_target TARGET ${test} PROPERTY "SDL_INSTALL")
|
||||
if(install_target)
|
||||
install(
|
||||
TARGETS ${test}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-tests/SDL3
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
if(MSVC)
|
||||
foreach(test IN LISTS SDL_TEST_EXECUTABLES)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue