Compare commits

42 Commits

Author SHA1 Message Date
aap 4c8cab66bb Merge pull request #158 from withmorten/master
fix SDL3 fullscreen modes
2026-07-15 00:41:39 +02:00
withmorten d49da68af8 fix SDL3 fullscreen modes 2026-07-14 00:29:51 +02:00
aap 1252b90e03 more tex uniforms 2026-04-28 00:29:51 +02:00
aap 938330ffaa little cleanup and mousewheel support for skeleton 2026-04-06 01:03:14 +02:00
aap 373961bbce small stuff 2026-03-28 01:09:10 +01:00
aap 1499b9660c Merge pull request #147 from madebr/add-sdl3-support
Update imgui and add SDL3 support
2025-09-09 12:10:09 +02:00
Anonymous Maarten 6a1ec78cfb Add SDL3 backend 2025-09-04 22:01:07 +02:00
Anonymous Maarten 4495762b13 imgui/imguizmo: bump to latest 2025-09-04 21:50:46 +02:00
aap 169a45aa2f fixed embarrassingly wrong plugin order 2024-12-03 16:06:13 +01:00
aap 15cb2cbb53 Merge pull request #136 from Davilarek/patch-1
Fix conditional jump of unitialized value
2024-11-30 22:29:43 +01:00
Daniel d901d2db6f Fix conditional jump of unitialized value
Co-authored-by: Null7781 <nullzeron3310@gmail.com>
2024-11-30 21:20:42 +01:00
aap 895556fd81 Merge pull request #135 from madebr/update-202408
Get rid of conan, update imgui, and merge all workflows
2024-08-22 17:31:04 +02:00
Anonymous Maarten a85292e799 ci: don't use conan for ci 2024-08-16 18:54:20 +02:00
Anonymous Maarten e40a19be72 cmake: don't require SDL2main 2024-08-16 18:54:20 +02:00
Anonymous Maarten 0155539316 cmake: give priority to SDL2 config 2024-08-16 17:58:58 +02:00
Anonymous Maarten d53e325b72 cmake: don't check LIBRW_GL3_GFXLIB when platform is not GL3 2024-08-16 15:20:20 +02:00
Anonymous Maarten a565c5bb80 cmake: make option choices part of doc string (for CMakeCache.txt) 2024-08-16 15:20:20 +02:00
Anonymous Maarten 72253f751d imgui/imguizmo: bump to latest 2024-08-16 15:20:20 +02:00
Anonymous Maarten 8fa4885a1b gl3/sdl2: implement subsystems 2024-08-16 14:36:55 +02:00
aap a6139bc44d moved d3d9 device reset to a hopefully better spot 2024-02-09 13:14:05 +01:00
aap 05db81b92f small changes 2023-02-21 01:24:42 +01:00
aap 8271c23a9e add an ADC flag hack for instancing 2022-05-20 00:12:46 +02:00
aap 25e735048f Merge pull request #109 from kaalkuul/master
Add support for CMake source dependency on GLFW
2022-12-14 19:23:43 +01:00
Emmanuel Boutin 1059d79d73 Add support for CMake source dependency on librw 2022-12-14 14:35:23 +01:00
aap 0bc9c77c81 tiny fix 2022-11-13 21:51:57 +01:00
aap f7e7841e1c hacked lighting into im3d 2022-09-22 17:59:20 +02:00
aap d2f54a2471 Merge pull request #107 from Pirulax/patch-1
Add include to `cerrno` to fix build
2022-08-30 14:23:26 +02:00
Pirulax d4b67d366a Add include to cerrno to fix build 2022-08-30 14:22:08 +02:00
aap 841325cea5 Merge pull request #106 from sr-tream/geomfix
Fix double-free materials
2022-07-08 19:35:53 +02:00
SR_team ed2e1ddb37 Fix double-free materials 2022-07-08 19:30:52 +03:00
aap a6d659d1b5 Merge pull request #102 from sr-tream/master
Fix deprecated enum operation
2022-06-18 23:34:36 +02:00
SR_team 6052e159c6 Use C-style casts 2022-06-18 20:46:22 +03:00
SR_team df5664b4c1 Fix deprecated enum operation 2022-06-18 16:47:04 +03:00
aap b4be832434 Merge pull request #101 from madebr/conan-fix
Small pr to fix CI
2022-05-15 09:18:46 +02:00
Anonymous Maarten 9b986f12e3 bump conan dependencies 2022-05-14 22:09:20 +02:00
aap 8dbe79bcd2 Merge pull request #91 from madebr/sdl2_imgui_percounter
skeleton: use SDL_GetPerformanceCounter instead of SDL_GetTicks
2022-05-14 21:00:17 +02:00
aap ac99c20d0c more fanciness for hopalong 2021-11-26 17:20:17 +01:00
aap 50c8f9ec7f hopalong orbit viewer; also bezier patches in playground 2021-11-25 14:17:44 +01:00
aap 7dd7ec184d tiny fix 2021-11-23 14:43:52 +01:00
aap c60d7a791c remove stupidity 2021-10-23 12:21:08 +02:00
aap 453ae4b9ee changes and fixes for ps2 2021-10-14 13:31:30 +02:00
Anonymous Maarten 711298e274 skeleton: use SDL_GetPerformanceCounter insted of SDL_GetTicks 2021-08-19 16:11:54 +02:00
71 changed files with 33521 additions and 13441 deletions
-60
View File
@@ -1,60 +0,0 @@
name: Conan
on:
pull_request:
push:
release:
types: published
jobs:
build-cmake:
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
platform: ['null', 'gl3', 'd3d9']
gl3_gfxlib: ['glfw', 'sdl2']
exclude:
- os: ubuntu-latest
platform: d3d9
- os: macos-latest
platform: d3d9
- platform: 'null'
gl3_gfxlib: sdl2
- platform: d3d9
gl3_gfxlib: sdl2
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: "Setup conan"
run: |
python -m pip install conan
conan config init
conan config set log.print_run_commands=True
conan config set general.revisions_enabled=1
conan remote add bincrafters https://bincrafters.jfrog.io/artifactory/api/conan/public-conan
- name: "Create host profile"
shell: bash
run: |
cp ~/.conan/profiles/default host_profile
- name: "Download/build dependencies (conan install)"
run: |
conan install ${{ github.workspace }} librw/master@ -if build -o librw:platform=${{ matrix.platform }} -o librw:gl3_gfxlib=${{ matrix.gl3_gfxlib }} --build missing -pr:h ./host_profile -pr:b default
env:
CONAN_SYSREQUIRES_MODE: enabled
- name: "Build librw (conan build)"
run: |
conan build ${{ github.workspace }} -if build -bf build -pf package
- name: "Package librw (conan package)"
run: |
conan package ${{ github.workspace }} -if build -bf build -pf package
- name: "Create binary package (cpack)"
working-directory: ./build
run: |
cpack
- name: "Archive binary package (github artifacts)"
uses: actions/upload-artifact@v2
with:
name: "${{ matrix.os }}-${{ matrix.platform }}"
path: build/*.tar.xz
if-no-files-found: error
-29
View File
@@ -1,29 +0,0 @@
name: Playstation 2 (by ps2dev)
on:
pull_request:
push:
release:
types: published
jobs:
build-playstation-2:
runs-on: ubuntu-latest
container: ps2dev/ps2dev
steps:
- uses: actions/checkout@v2
- name: "Install dependencies"
run: |
apk add build-base cmake
- name: "Build files"
run: |
cmake -S. -Bbuild -DLIBRW_INSTALL=ON -DLIBRW_PLATFORM=PS2 -DCMAKE_TOOLCHAIN_FILE=cmake/ps2/cmaketoolchain/toolchain_ps2_ee.cmake
cmake --build build --parallel
- name: "Create binary package (cpack)"
working-directory: ./build
run: |
cpack
- name: "Archive binary package (github artifacts)"
uses: actions/upload-artifact@v2
with:
name: "ps2"
path: build/*.tar.xz
if-no-files-found: error
-26
View File
@@ -1,26 +0,0 @@
name: Nintendo Switch (by devkitPro)
on:
pull_request:
push:
release:
types: published
jobs:
build-nintendo-switch:
runs-on: ubuntu-latest
container: devkitpro/devkita64:latest
steps:
- uses: actions/checkout@v2
- name: "Build files"
run: |
/opt/devkitpro/portlibs/switch/bin/aarch64-none-elf-cmake -S. -Bbuild -DLIBRW_PLATFORM=GL3 -DLIBRW_GL3_GFXLIB=GLFW -DLIBRW_INSTALL=True
cmake --build build --parallel
- name: "Create binary package (cpack)"
working-directory: ./build
run: |
cpack
- name: "Archive binary package (github artifacts)"
uses: actions/upload-artifact@v2
with:
name: "switch-gl3"
path: build/*.tar.xz
if-no-files-found: error
+79
View File
@@ -0,0 +1,79 @@
name: Build
on:
pull_request:
push:
release:
types: published
jobs:
build-cmake:
name: ${{ matrix.case.name }}
runs-on: ${{ matrix.case.os }}
container: ${{ matrix.case.container }}
strategy:
fail-fast: false
matrix:
case:
- { name: 'Windows (DirectX 9)', os: 'windows-latest', platform: 'D3D9' }
- { name: 'Windows (GL3, glfw)', os: 'windows-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
- { name: 'Windows (GL3, SDL2)', os: 'windows-latest', platform: 'GL3', gl3_gfxlib: 'SDL2', sdl-version: '2-latest' }
- { name: 'Windows (GL3, SDL3)', os: 'windows-latest', platform: 'GL3', gl3_gfxlib: 'SDL3', sdl-version: '3-latest' }
- { name: 'Windows (null)', os: 'windows-latest', platform: 'NULL' }
- { name: 'macOS (GL3, glfw)', os: 'macos-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
- { name: 'macOS (GL3, SDL2)', os: 'macos-latest', platform: 'GL3', gl3_gfxlib: 'SDL2', sdl-version: '2-latest' }
- { name: 'macOS (GL3, SDL3)', os: 'macos-latest', platform: 'GL3', gl3_gfxlib: 'SDL3', sdl-version: '3-latest' }
- { name: 'macOS (null)', os: 'macos-latest', platform: 'NULL' }
- { name: 'Ubuntu (GL3, glfw)', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
- { name: 'Ubuntu (GL3, SDL2)', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'SDL2', sdl-version: '2-latest' }
- { name: 'Ubuntu (null)', os: 'ubuntu-latest', platform: 'NULL' }
- { name: 'PlayStation 2', os: 'ubuntu-latest', platform: 'PS2', ps2: true, container: 'ps2dev/ps2dev:latest', cmake-toolchain-file: 'cmake/ps2/cmaketoolchain/toolchain_ps2_ee.cmake' }
- { name: 'Nintendo Switch', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'GLFW', glfw-nobuild: true, container: 'devkitpro/devkita64:latest', cmake-toolchain-file: '/opt/devkitpro/cmake/Switch.cmake' }
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: 'Install PS2 dependencies'
if: ${{ matrix.case.ps2 }}
run: |
apk add cmake gmp mpc1 mpfr4 make pkgconf git
- name: 'Setup SDL'
if: ${{ !!matrix.case.sdl-version }}
uses: libsdl-org/setup-sdl@main
with:
version: ${{ matrix.case.sdl-version }}
install-linux-dependencies: true
cmake-toolchain-file: ${{ matrix.case.cmake-toolchain-file }}
- name: 'Setup GLFW'
if: ${{ matrix.case.gl3_gfxlib == 'GLFW' && !matrix.case.glfw-nobuild }}
shell: sh
run: |
${{ (runner.os == 'Linux' && 'sudo apt-get update -y && sudo apt-get install -y libwayland-dev libxkbcommon-dev xorg-dev') || '' }}
git clone "https://github.com/glfw/glfw.git" glfw-source --depth 1
cmake -S glfw-source -B glfw-build -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF -DGLFW_BUILD_DOCS=OFF -DGLFW_INSTALL=ON -DCMAKE_INSTALL_PREFIX=glfw-prefix -DCMAKE_TOOLCHAIN_FILE="${{ matrix.case.cmake-toolchain-file }}" -DCMAKE_BUILD_TYPE=Release
cmake --build glfw-build --config Release
cmake --install glfw-build --config Release
echo "glfw3_ROOT=${{ github.workspace}}/glfw-prefix" >${GITHUB_ENV}
- name: 'Configure (CMake)'
shell: sh
run: |
cmake -S . -B build \
-DLIBRW_PLATFORM=${{ matrix.case.platform }} \
-DLIBRW_GL3_GFXLIB=${{ matrix.case.gl3_gfxlib }} \
-DCMAKE_TOOLCHAIN_FILE=${{ matrix.case.cmake-toolchain-file }} \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POLICY_DEFAULT_CMP0074=NEW
- name: 'Build (CMake)'
run: |
cmake --build build --config Release --verbose
- name: 'Create binary package (CPack)'
run: |
cd build
cpack . -C Release
- name: 'Archive binary package (GitHub artifacts)'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.case.os }}-${{ matrix.case.platform }}${{ (matrix.case.gl3_gfxlib != '' && format('-{0}', matrix.case.gl3_gfxlib)) || '' }}
path: build/*.tar.xz
if-no-files-found: error
+14 -9
View File
@@ -30,7 +30,7 @@ else()
set(LIBRW_PLATFORM_GL3_REQUIRES_OPENGL ON)
endif()
list(GET LIBRW_PLATFORMS 0 LIBRW_PLATFORM_DEFAULT)
set(LIBRW_PLATFORM "${LIBRW_PLATFORM_DEFAULT}" CACHE STRING "Platform")
set(LIBRW_PLATFORM "${LIBRW_PLATFORM_DEFAULT}" CACHE STRING "Platform (choices=${LIBRW_PLATFORMS})")
set_property(CACHE LIBRW_PLATFORM PROPERTY STRINGS ${LIBRW_PLATFORMS})
message(STATUS "LIBRW_PLATFORM = ${LIBRW_PLATFORM} (choices=${LIBRW_PLATFORMS})")
set("LIBRW_PLATFORM_${LIBRW_PLATFORM}" ON)
@@ -38,14 +38,16 @@ if(NOT LIBRW_PLATFORM IN_LIST LIBRW_PLATFORMS)
message(FATAL_ERROR "Illegal LIBRW_PLATFORM=${LIBRW_PLATFORM}")
endif()
set(LIBRW_GL3_GFXLIBS "GLFW" "SDL2")
set(LIBRW_GL3_GFXLIB "GLFW" CACHE STRING "gfxlib for gl3")
set_property(CACHE LIBRW_GL3_GFXLIB PROPERTY STRINGS ${LIBRW_GL3_GFXLIBS})
if(LIBRW_PLATFORM_GL3)
message(STATUS "LIBRW_GL3_GFXLIB = ${LIBRW_GL3_GFXLIB} (choices=${LIBRW_GL3_GFXLIBS})")
endif()
if(NOT LIBRW_GL3_GFXLIB IN_LIST LIBRW_GL3_GFXLIBS)
message(FATAL_ERROR "Illegal LIBRW_GL3_GFXLIB=${LIBRW_GL3_GFXLIB}")
set(LIBRW_GL3_GFXLIBS "GLFW" "SDL2" "SDL3")
set(LIBRW_GL3_GFXLIB "GLFW" CACHE STRING "gfxlib for gl3 (choices=${LIBRW_GL3_GFXLIBS})")
set_property(CACHE LIBRW_GL3_GFXLIB PROPERTY STRINGS ${LIBRW_GL3_GFXLIBS})
if(LIBRW_PLATFORM_GL3)
message(STATUS "LIBRW_GL3_GFXLIB = ${LIBRW_GL3_GFXLIB} (choices=${LIBRW_GL3_GFXLIBS})")
endif()
if(NOT LIBRW_GL3_GFXLIB IN_LIST LIBRW_GL3_GFXLIBS)
message(FATAL_ERROR "Illegal LIBRW_GL3_GFXLIB=${LIBRW_GL3_GFXLIB}")
endif()
endif()
if(LIBRW_PLATFORM_PS2)
@@ -89,6 +91,7 @@ if(LIBRW_INSTALL)
EXPORT librw-targets NAMESPACE librw::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
export(TARGETS librw NAMESPACE librw:: FILE librw-targets.cmake)
if(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
install(
@@ -124,8 +127,10 @@ if(LIBRW_INSTALL)
elseif(LIBRW_PLATFORM_GL3)
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
set(platform "-gl3-glfw")
else()
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
set(platform "-gl3-sdl2")
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL3")
set(platform "-gl3-sdl3")
endif()
elseif(LIBRW_PLATFORM_D3D9)
set(platform "-d3d9")
+14 -2
View File
@@ -14,9 +14,21 @@ if(LIBRW_PLATFORM_GL3)
message(FATAL_ERROR "find_package(OpenGL) failed: no target was created")
endif()
include(CMakeFindDependencyMacro)
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
find_package(glfw3 REQUIRED)
if (NOT TARGET glfw)
find_dependency(glfw3 REQUIRED)
endif()
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
find_package(SDL2 REQUIRED)
if (NOT TARGET SDL2::SDL2)
find_dependency(SDL2 CONFIG)
if (NOT TARGET SDL2::SDL2)
find_dependency(SDL2 MODULE REQUIRED)
endif()
endif()
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL3")
if (NOT TARGET SDL3::SDL3)
find_dependency(SDL3 CONFIG REQUIRED)
endif()
endif()
endif()
-12
View File
@@ -1,12 +0,0 @@
[settings]
os=Playstation2
arch=mips
compiler=gcc
compiler.version=3.2
compiler.libcxx=libstdc++
build_type=Release
[options]
librw:platform=ps2
[build_requires]
ps2dev-ps2toolchain/unknown@madebr/testing
[env]
-136
View File
@@ -1,136 +0,0 @@
from conans import ConanFile, CMake, tools
from conans.errors import ConanException, ConanInvalidConfiguration
import os
import shutil
import textwrap
class LibrwConan(ConanFile):
name = "librw"
version = "master"
license = "MIT"
settings = "os", "arch", "compiler", "build_type"
generators = "cmake", "cmake_find_package"
options = {
"platform": ["null", "gl3", "d3d9", "ps2"],
"gl3_gfxlib": ["glfw", "sdl2"],
}
default_options = {
"platform": "gl3",
"gl3_gfxlib": "glfw",
"openal:with_external_libs": False,
"sdl2:vulkan": False,
"sdl2:opengl": True,
"sdl2:sdl2main": True,
}
no_copy_source = True
@property
def _os_is_playstation2(self):
try:
return self.settings.os == "Playstation2"
except ConanException:
return False
def config_options(self):
if self._os_is_playstation2:
self.options.platform = "ps2"
if self.settings.os == "Windows":
self.options.platform = "d3d9"
self.options["sdl2"].directx = False
def configure(self):
if self.options.platform != "gl3":
del self.options.gl3_gfxlib
def validate(self):
if self.options.platform == "d3d9" and self.settings.os != "Windows":
raise ConanInvalidConfiguration("platform=d3d9 can only be built for os=Windows")
if self._os_is_playstation2:
if self.options.platform not in ("null", "ps2"):
raise ConanInvalidConfiguration("os=Playstation2 only supports platform=(null,ps2)")
def requirements(self):
if self.options.platform == "gl3":
if self.options.gl3_gfxlib == "glfw":
self.requires("glfw/3.3.2")
elif self.options.gl3_gfxlib == "sdl2":
self.requires("sdl2/2.0.12@bincrafters/stable")
elif self.options.platform == "ps2":
self.requires("ps2dev-ps2sdk/unknown@madebr/testing")
if self._os_is_playstation2:
self.requires("ps2dev-cmaketoolchain/{}".format(self.version))
def export_sources(self):
for d in ("cmake", "skeleton", "src", "tools"):
shutil.copytree(src=d, dst=os.path.join(self.export_sources_folder, d))
self.copy("args.h")
self.copy("rw.h")
self.copy("CMakeLists.txt")
self.copy("LICENSE")
@property
def _librw_platform(self):
return {
"null": "NULL",
"gl3": "GL3",
"d3d9": "D3D9",
"ps2": "PS2",
}[str(self.options.platform)]
def build(self):
if self.source_folder == self.build_folder:
raise Exception("cannot build with source_folder == build_folder")
if self.options.platform == "gl3" and self.options.gl3_gfxlib == "glfw":
tools.save("Findglfw3.cmake",
textwrap.dedent(
"""
if(NOT TARGET glfw)
message(STATUS "Creating glfw TARGET")
add_library(glfw INTERFACE IMPORTED)
set_target_properties(glfw PROPERTIES
INTERFACE_LINK_LIBRARIES CONAN_PKG::glfw)
endif()
"""), append=True)
tools.save("CMakeLists.txt",
textwrap.dedent(
"""
cmake_minimum_required(VERSION 3.0)
project(cmake_wrapper)
include("{}/conanbuildinfo.cmake")
conan_basic_setup(TARGETS)
add_subdirectory("{}" librw)
""").format(self.install_folder.replace("\\", "/"),
self.source_folder.replace("\\", "/")))
cmake = CMake(self)
env = {}
cmake.definitions["LIBRW_PLATFORM"] = self._librw_platform
cmake.definitions["LIBRW_INSTALL"] = True
cmake.definitions["LIBRW_TOOLS"] = True
if self.options.platform == "gl3":
cmake.definitions["LIBRW_GL3_GFXLIB"] = str(self.options.gl3_gfxlib).upper()
if self._os_is_playstation2:
env["PS2SDK"] = self.deps_cpp_info["ps2dev-ps2sdk"].rootpath
with tools.environment_append(env):
cmake.configure(source_folder=self.build_folder)
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
def package_info(self):
self.cpp_info.includedirs.append(os.path.join("include", "librw"))
self.cpp_info.libs = ["librw" if self.settings.compiler == "Visual Studio" else "rw"]
if self.options.platform == "null":
self.cpp_info.defines.append("RW_NULL")
elif self.options.platform == "gl3":
self.cpp_info.defines.append("RW_GL3")
if self.options.gl3_gfxlib == "sdl2":
self.cpp_info.defines.append("LIBRW_SDL2")
elif self.options.platform == "d3d9":
self.cpp_info.defines.append("RW_D3D9")
elif self.options.platform == "ps2":
self.cpp_info.defines.append("RW_PS2")
+30 -3
View File
@@ -6,6 +6,7 @@ newoption {
allowed = {
{ "glfw", "GLFW" },
{ "sdl2", "SDL2" },
{ "sdl3", "SDL3" },
},
}
@@ -27,7 +28,14 @@ newoption {
trigger = "sdl2dir",
value = "PATH",
description = "Directory of sdl2",
default = "../SDL2-2.0.14",
default = "../SDL2-2.32.10",
}
newoption {
trigger = "sdl3dir",
value = "PATH",
description = "Directory of sdl3",
default = "../SDL3-3.2.22",
}
workspace "librw"
@@ -64,6 +72,10 @@ workspace "librw"
defines { "RW_GL3" }
if _OPTIONS["gfxlib"] == "sdl2" then
defines { "LIBRW_SDL2" }
elseif _OPTIONS["gfxlib"] == "sdl3" then
defines { "LIBRW_SDL3" }
elseif _OPTIONS["gfxlib"] == "glfw" then
defines { "LIBRW_GLFW" }
end
filter { "platforms:*d3d9" }
defines { "RW_D3D9" }
@@ -131,21 +143,27 @@ function findlibs()
links { "GL" }
if _OPTIONS["gfxlib"] == "glfw" then
links { "glfw" }
else
elseif _OPTIONS["gfxlib"] == "sdl2" then
links { "SDL2" }
elseif _OPTIONS["gfxlib"] == "sdl3" then
links { "SDL3" }
end
filter { "platforms:win-amd64-gl3" }
libdirs { path.join(_OPTIONS["glfwdir64"], "lib-vc2015") }
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x64") }
libdirs { path.join(_OPTIONS["sdl3dir"], "lib/x64") }
filter { "platforms:win-x86-gl3" }
libdirs { path.join(_OPTIONS["glfwdir32"], "lib-vc2015") }
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x86") }
libdirs { path.join(_OPTIONS["sdl3dir"], "lib/x86") }
filter { "platforms:win*gl3" }
links { "opengl32" }
if _OPTIONS["gfxlib"] == "glfw" then
links { "glfw3" }
else
elseif _OPTIONS["gfxlib"] == "sdl2" then
links { "SDL2" }
elseif _OPTIONS["gfxlib"] == "sdl3" then
links { "SDL3" }
end
filter { "platforms:*d3d9" }
links { "gdi32", "d3d9" }
@@ -275,3 +293,12 @@ project "ps2test"
-- includedirs { "." }
-- libdirs { Libdir }
-- links { "librw" }
project "hopalong"
kind "WindowedApp"
characterset ("MBCS")
skeltool("hopalong")
entrypoint("WinMainCRTStartup")
removeplatforms { "*null" }
removeplatforms { "ps2" }
+6
View File
@@ -1,6 +1,7 @@
add_library(librw_skeleton
glfw.cpp
sdl2.cpp
sdl3.cpp
skeleton.cpp
skeleton.h
win.cpp
@@ -24,6 +25,7 @@ add_library(librw_skeleton
imgui/ImGuizmo.h
)
add_library(librw::skeleton ALIAS librw_skeleton)
target_compile_features(librw_skeleton PUBLIC cxx_std_11)
set_target_properties(librw_skeleton
PROPERTIES
@@ -37,6 +39,10 @@ target_link_libraries(librw_skeleton
librw
)
if (LIBRW_GL3_GFXLIB MATCHES "SDL[23]")
target_compile_definitions(librw_skeleton PRIVATE SDL_MAIN_HANDLED)
endif()
target_include_directories(librw_skeleton
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+11 -2
View File
@@ -1,4 +1,4 @@
#ifndef LIBRW_SDL2
#ifdef LIBRW_GLFW
#include <rw.h>
#include "skeleton.h"
@@ -182,7 +182,7 @@ mousebtn(GLFWwindow *window, int button, int action, int mods)
{
static int buttons = 0;
sk::MouseState ms;
switch(button){
case GLFW_MOUSE_BUTTON_LEFT:
if(action == GLFW_PRESS)
@@ -208,6 +208,14 @@ mousebtn(GLFWwindow *window, int button, int action, int mods)
EventHandler(MOUSEBTN, &ms);
}
static void
mousewheel(GLFWwindow *window, double x, double y)
{
sk::MouseState ms;
ms.wheelDelta = y;
EventHandler(MOUSEWHEEL, &ms);
}
int
main(int argc, char *argv[])
{
@@ -231,6 +239,7 @@ main(int argc, char *argv[])
glfwSetWindowSizeCallback(window, resize);
glfwSetCursorPosCallback(window, mousemove);
glfwSetMouseButtonCallback(window, mousebtn);
glfwSetScrollCallback(window, mousewheel);
float lastTime = glfwGetTime()*1000;
while(!sk::globals.quit && !glfwWindowShouldClose(window)){
File diff suppressed because it is too large Load Diff
+103 -10
View File
@@ -1,20 +1,20 @@
// https://github.com/CedricGuillemet/ImGuizmo
// v 1.61 WIP
// v1.91.3 WIP
//
// The MIT License(MIT)
//
//
// Copyright(c) 2021 Cedric Guillemet
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
@@ -39,9 +39,9 @@
// - display rotation/translation/scale infos in local/world space and not only local
// - finish local/world matrix application
// - OPERATION as bitmask
//
//
// -------------------------------------------------------------------------------------------
// Example
// Example
#if 0
void EditTransform(const Camera& camera, matrix_t& matrix)
{
@@ -111,7 +111,13 @@ void EditTransform(const Camera& camera, matrix_t& matrix)
#define IMGUI_API
#endif
namespace ImGuizmo
#ifndef IMGUIZMO_NAMESPACE
#define IMGUIZMO_NAMESPACE ImGuizmo
#endif
struct ImGuiWindow;
namespace IMGUIZMO_NAMESPACE
{
// call inside your own window and before Manipulate() in order to draw gizmo to that window.
// Or pass a specific ImDrawList to draw to (e.g. ImGui::GetForegroundDrawList()).
@@ -132,6 +138,14 @@ namespace ImGuizmo
// return true if mouse IsOver or if the gizmo is in moving state
IMGUI_API bool IsUsing();
// return true if the view gizmo is in moving state
IMGUI_API bool IsUsingViewManipulate();
// only check if your mouse is over the view manipulator - no matter whether it's active or not
IMGUI_API bool IsViewManipulateHovered();
// return true if any gizmo is in moving state
IMGUI_API bool IsUsingAny();
// enable/disable the gizmo. Stay in the state until next call to Enable.
// gizmo is rendered with gray half transparent color when disabled
IMGUI_API void Enable(bool enable);
@@ -160,7 +174,7 @@ namespace ImGuizmo
IMGUI_API void DrawGrid(const float* view, const float* projection, const float* matrix, const float gridSize);
// call it when you want a gizmo
// Needs view and projection matrices.
// Needs view and projection matrices.
// matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional
// translation is applied in world space
enum OPERATION
@@ -176,9 +190,15 @@ namespace ImGuizmo
SCALE_Y = (1u << 8),
SCALE_Z = (1u << 9),
BOUNDS = (1u << 10),
SCALE_XU = (1u << 11),
SCALE_YU = (1u << 12),
SCALE_ZU = (1u << 13),
TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z,
ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN,
SCALE = SCALE_X | SCALE_Y | SCALE_Z
SCALE = SCALE_X | SCALE_Y | SCALE_Z,
SCALEU = SCALE_XU | SCALE_YU | SCALE_ZU, // universal
UNIVERSAL = TRANSLATE | ROTATE | SCALEU
};
inline OPERATION operator|(OPERATION lhs, OPERATION rhs)
@@ -200,8 +220,34 @@ namespace ImGuizmo
//
IMGUI_API void ViewManipulate(float* view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
// use this version if you did not call Manipulate before and you are just using ViewManipulate
IMGUI_API void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
IMGUI_API void SetAlternativeWindow(ImGuiWindow* window);
[[deprecated("Use PushID/PopID instead.")]]
IMGUI_API void SetID(int id);
// ID stack/scopes
// Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui.
// - Those questions are answered and impacted by understanding of the ID stack system:
// - "Q: Why is my widget not reacting when I click on it?"
// - "Q: How can I have widgets with an empty label?"
// - "Q: How can I have multiple widgets with the same label?"
// - Short version: ID are hashes of the entire ID stack. If you are creating widgets in a loop you most likely
// want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them.
// - You can also use the "Label##foobar" syntax within widget label to distinguish them from each others.
// - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID,
// whereas "str_id" denote a string that is only used as an ID and not normally displayed.
IMGUI_API void PushID(const char* str_id); // push string into the ID stack (will hash string).
IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string).
IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer).
IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer).
IMGUI_API void PopID(); // pop from the ID stack.
IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself
IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end);
IMGUI_API ImGuiID GetID(const void* ptr_id);
// return true if the cursor is over the operation's gizmo
IMGUI_API bool IsOver(OPERATION op);
IMGUI_API void SetGizmoSizeClipSpace(float value);
@@ -210,4 +256,51 @@ namespace ImGuizmo
// When true (default), the guizmo axis flip for better visibility
// When false, they always stay along the positive world/local axis
IMGUI_API void AllowAxisFlip(bool value);
// Configure the limit where axis are hidden
IMGUI_API void SetAxisLimit(float value);
// Set an axis mask to permanently hide a given axis (true -> hidden, false -> shown)
IMGUI_API void SetAxisMask(bool x, bool y, bool z);
// Configure the limit where planes are hiden
IMGUI_API void SetPlaneLimit(float value);
// from a x,y,z point in space and using Manipulation view/projection matrix, check if mouse is in pixel radius distance of that projected point
IMGUI_API bool IsOver(float* position, float pixelRadius);
enum COLOR
{
DIRECTION_X, // directionColor[0]
DIRECTION_Y, // directionColor[1]
DIRECTION_Z, // directionColor[2]
PLANE_X, // planeColor[0]
PLANE_Y, // planeColor[1]
PLANE_Z, // planeColor[2]
SELECTION, // selectionColor
INACTIVE, // inactiveColor
TRANSLATION_LINE, // translationLineColor
SCALE_LINE,
ROTATION_USING_BORDER,
ROTATION_USING_FILL,
HATCHED_AXIS_LINES,
TEXT,
TEXT_SHADOW,
COUNT
};
struct Style
{
IMGUI_API Style();
float TranslationLineThickness; // Thickness of lines for translation gizmo
float TranslationLineArrowSize; // Size of arrow at the end of lines for translation gizmo
float RotationLineThickness; // Thickness of lines for rotation gizmo
float RotationOuterLineThickness; // Thickness of line surrounding the rotation gizmo
float ScaleLineThickness; // Thickness of lines for scale gizmo
float ScaleLineCircleSize; // Size of circle at the end of lines for scale gizmo
float HatchedAxisLineThickness; // Thickness of hatched axis lines
float CenterCircleSize; // Size of circle at the center of the translate/scale gizmo
ImVec4 Colors[COLOR::COUNT];
};
IMGUI_API Style& GetStyle();
}
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2021 Omar Cornut
Copyright (c) 2014-2025 Omar Cornut
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+54 -30
View File
@@ -1,5 +1,5 @@
//-----------------------------------------------------------------------------
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
// DEAR IMGUI COMPILE-TIME OPTIONS
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//-----------------------------------------------------------------------------
@@ -9,7 +9,7 @@
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//-----------------------------------------------------------------------------
#pragma once
@@ -21,56 +21,79 @@
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
//#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport )
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Disable all of Dear ImGui or don't implement standard windows.
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger window: ShowMetricsWindow() will be empty.
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
//---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. (imm32.lib/.a)
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
//---- Enable Test Engine / Automation features.
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
//---- Include imgui_user.h at the end of imgui.h as a convenience
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
//#define IMGUI_INCLUDE_IMGUI_USER_H
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
//#define IMGUI_USE_BGRA_PACKED_COLOR
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
//#define IMGUI_USE_LEGACY_CRC32_ADLER
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
//#define IMGUI_USE_WCHAR32
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
// #define IMGUI_USE_STB_SPRINTF
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
//#define IMGUI_USE_STB_SPRINTF
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
// On Windows you may use vcpkg with 'vcpkg install freetype' + 'vcpkg integrate install'.
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
//#define IMGUI_ENABLE_FREETYPE
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
// Only works in combination with IMGUI_ENABLE_FREETYPE.
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
//---- Use stb_truetype to build and rasterize the font atlas (default)
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
//#define IMGUI_ENABLE_STB_TRUETYPE
@@ -78,14 +101,16 @@
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
/*
#define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
#define IM_VEC2_CLASS_EXTRA \
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
operator MyVec2() const { return MyVec2(x,y); }
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
#define IM_VEC4_CLASS_EXTRA \
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/
//---- ...Or use Dear ImGui's own very basic math operators.
//#define IMGUI_DEFINE_MATH_OPERATORS
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
@@ -99,23 +124,22 @@
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback
//---- Debug Tools: Macro to break in Debugger
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
//#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak()
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
// This adds a small runtime cost which is why it is not enabled by default.
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
//---- Debug Tools: Enable highlight ID conflicts _before_ hovering items. When io.ConfigDebugHighlightIdConflicts is set.
// (THIS WILL SLOW DOWN DEAR IMGUI. Only use occasionally and disable after use)
//#define IMGUI_DEBUG_HIGHLIGHT_ALL_ID_CONFLICTS
//---- Debug Tools: Enable slower asserts
//#define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
void MyFunction(const char* name, MyMatrix44* mtx);
}
*/
+10432 -4144
View File
File diff suppressed because it is too large Load Diff
+2440 -1157
View File
File diff suppressed because it is too large Load Diff
+5332 -2220
View File
File diff suppressed because it is too large Load Diff
+3401 -1249
View File
File diff suppressed because it is too large Load Diff
+138 -33
View File
@@ -1,3 +1,4 @@
#define WITH_D3D
#include <rw.h>
#include <skeleton.h>
#include <assert.h>
@@ -11,6 +12,35 @@ static rw::Texture *g_FontTexture;
static Im2DVertex *g_vertbuf;
static int g_vertbufSize;
// TODO: scissor from librw itself
static void
SetClip(const ImVec4 &clip)
{
ImGuiIO &io = ImGui::GetIO();
float x1 = clip.x; float y1 = clip.y;
float x2 = clip.z; float y2 = clip.w;
#ifdef RW_OPENGL
glScissor(x1, io.DisplaySize.y-y2, x2-x1, y2-y1);
glEnable(GL_SCISSOR_TEST);
#endif
#ifdef RW_D3D9
rw::d3d::d3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, 1);
RECT r = { (LONG)x1, (LONG)y1, (LONG)x2, (LONG)y2 };
rw::d3d::d3ddevice->SetScissorRect(&r);
#endif
}
static void
DisableClip(void)
{
#ifdef RW_OPENGL
glDisable(GL_SCISSOR_TEST);
#endif
#ifdef RW_D3D9
rw::d3d::d3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, 0);
#endif
}
void
ImGui_ImplRW_RenderDrawLists(ImDrawData* draw_data)
{
@@ -80,7 +110,7 @@ ImGui_ImplRW_RenderDrawLists(ImDrawData* draw_data)
if(pcmd->UserCallback)
pcmd->UserCallback(cmd_list, pcmd);
else{
rw::Texture *tex = (rw::Texture*)pcmd->TextureId;
rw::Texture *tex = (rw::Texture*)pcmd->GetTexID();
if(tex && tex->raster){
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
rw::SetRenderState(rw::TEXTUREADDRESSU, tex->getAddressU());
@@ -88,9 +118,12 @@ ImGui_ImplRW_RenderDrawLists(ImDrawData* draw_data)
rw::SetRenderState(rw::TEXTUREFILTER, tex->getFilter());
}else
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
SetClip(pcmd->ClipRect);
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
g_vertbuf+vtx_offset, cmd_list->VtxBuffer.Size,
cmd_list->IdxBuffer.Data+idx_offset, pcmd->ElemCount);
DisableClip();
}
idx_offset += pcmd->ElemCount;
}
@@ -116,26 +149,6 @@ ImGui_ImplRW_Init(void)
ImGui::CreateContext();
ImGuiIO &io = ImGui::GetIO();
io.KeyMap[ImGuiKey_Tab] = KEY_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = KEY_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = KEY_UP;
io.KeyMap[ImGuiKey_DownArrow] = KEY_DOWN;
io.KeyMap[ImGuiKey_PageUp] = KEY_PGUP;
io.KeyMap[ImGuiKey_PageDown] = KEY_PGDN;
io.KeyMap[ImGuiKey_Home] = KEY_HOME;
io.KeyMap[ImGuiKey_End] = KEY_END;
io.KeyMap[ImGuiKey_Delete] = KEY_DEL;
io.KeyMap[ImGuiKey_Backspace] = KEY_BACKSP;
io.KeyMap[ImGuiKey_Enter] = KEY_ENTER;
io.KeyMap[ImGuiKey_Escape] = KEY_ESC;
io.KeyMap[ImGuiKey_A] = 'A';
io.KeyMap[ImGuiKey_C] = 'C';
io.KeyMap[ImGuiKey_V] = 'V';
io.KeyMap[ImGuiKey_X] = 'X';
io.KeyMap[ImGuiKey_Y] = 'Y';
io.KeyMap[ImGuiKey_Z] = 'Z';
return true;
}
@@ -161,7 +174,7 @@ ImGui_ImplRW_CreateFontsTexture()
g_FontTexture = rw::Texture::create(rw::Raster::createFromImage(image));
g_FontTexture->setFilter(rw::Texture::LINEAR);
image->destroy();
// Store our identifier
io.Fonts->TexID = (void*)g_FontTexture;
@@ -171,8 +184,6 @@ ImGui_ImplRW_CreateFontsTexture()
bool
ImGui_ImplRW_CreateDeviceObjects()
{
// if(!g_pd3dDevice)
// return false;
if(!ImGui_ImplRW_CreateFontsTexture())
return false;
return true;
@@ -189,9 +200,9 @@ ImGui_ImplRW_NewFrame(float timeDelta)
io.DisplaySize = ImVec2(sk::globals.width, sk::globals.height);
io.DeltaTime = timeDelta;
io.KeyCtrl = io.KeysDown[sk::KEY_LCTRL] || io.KeysDown[sk::KEY_RCTRL];
io.KeyShift = io.KeysDown[sk::KEY_LSHIFT] || io.KeysDown[sk::KEY_RSHIFT];
io.KeyAlt = io.KeysDown[sk::KEY_LALT] || io.KeysDown[sk::KEY_RALT];
io.KeyCtrl = ImGui::IsKeyPressed(ImGuiKey_LeftCtrl) || ImGui::IsKeyPressed(ImGuiKey_RightCtrl);
io.KeyShift = ImGui::IsKeyPressed(ImGuiKey_LeftShift) || ImGui::IsKeyPressed(ImGuiKey_RightShift);
io.KeyAlt = ImGui::IsKeyPressed(ImGuiKey_LeftAlt) || ImGui::IsKeyPressed(ImGuiKey_RightAlt);
io.KeySuper = false;
if(io.WantSetMousePos)
@@ -200,6 +211,100 @@ ImGui_ImplRW_NewFrame(float timeDelta)
ImGui::NewFrame();
}
static ImGuiKey SkKeyToImGuiKey(int keycode)
{
switch (keycode) {
case ' ': return ImGuiKey_Space;
case '\'': return ImGuiKey_Apostrophe;
case '-': return ImGuiKey_Minus;
case '.': return ImGuiKey_Period;
case '/': return ImGuiKey_Slash;
case '0': return ImGuiKey_0;
case '1': return ImGuiKey_1;
case '2': return ImGuiKey_2;
case '3': return ImGuiKey_3;
case '4': return ImGuiKey_4;
case '5': return ImGuiKey_5;
case '6': return ImGuiKey_6;
case '7': return ImGuiKey_7;
case '8': return ImGuiKey_8;
case '9': return ImGuiKey_9;
case ';': return ImGuiKey_Semicolon;
case '=': return ImGuiKey_Equal;
case 'A': return ImGuiKey_A;
case 'B': return ImGuiKey_B;
case 'C': return ImGuiKey_C;
case 'D': return ImGuiKey_D;
case 'E': return ImGuiKey_E;
case 'F': return ImGuiKey_F;
case 'G': return ImGuiKey_G;
case 'H': return ImGuiKey_H;
case 'I': return ImGuiKey_I;
case 'J': return ImGuiKey_J;
case 'K': return ImGuiKey_K;
case 'L': return ImGuiKey_L;
case 'M': return ImGuiKey_M;
case 'N': return ImGuiKey_N;
case 'O': return ImGuiKey_O;
case 'P': return ImGuiKey_P;
case 'Q': return ImGuiKey_Q;
case 'R': return ImGuiKey_R;
case 'S': return ImGuiKey_S;
case 'T': return ImGuiKey_T;
case 'U': return ImGuiKey_U;
case 'V': return ImGuiKey_V;
case 'W': return ImGuiKey_W;
case 'X': return ImGuiKey_X;
case 'Y': return ImGuiKey_Y;
case 'Z': return ImGuiKey_Z;
case '[': return ImGuiKey_LeftBracket;
case '\\': return ImGuiKey_Backslash;
case ']': return ImGuiKey_RightBracket;
case '`': return ImGuiKey_GraveAccent;
case sk::KEY_ESC: return ImGuiKey_Escape;
case sk::KEY_ENTER: return ImGuiKey_Enter;
case sk::KEY_TAB: return ImGuiKey_Tab;
case sk::KEY_BACKSP: return ImGuiKey_Backspace;
case sk::KEY_INS: return ImGuiKey_Insert;
case sk::KEY_DEL: return ImGuiKey_Delete;
case sk::KEY_RIGHT: return ImGuiKey_RightArrow;
case sk::KEY_LEFT: return ImGuiKey_LeftArrow;
case sk::KEY_DOWN: return ImGuiKey_DownArrow;
case sk::KEY_UP: return ImGuiKey_UpArrow;
case sk::KEY_PGUP: return ImGuiKey_PageUp;
case sk::KEY_PGDN: return ImGuiKey_PageDown;
case sk::KEY_HOME: return ImGuiKey_Home;
case sk::KEY_END: return ImGuiKey_End;
case sk::KEY_CAPSLK: return ImGuiKey_CapsLock;
case sk::KEY_F1: return ImGuiKey_F1;
case sk::KEY_F2: return ImGuiKey_F2;
case sk::KEY_F3: return ImGuiKey_F3;
case sk::KEY_F4: return ImGuiKey_F4;
case sk::KEY_F5: return ImGuiKey_F5;
case sk::KEY_F6: return ImGuiKey_F6;
case sk::KEY_F7: return ImGuiKey_F7;
case sk::KEY_F8: return ImGuiKey_F8;
case sk::KEY_F9: return ImGuiKey_F9;
case sk::KEY_F10: return ImGuiKey_F10;
case sk::KEY_F11: return ImGuiKey_F11;
case sk::KEY_F12: return ImGuiKey_F12;
case sk::KEY_LSHIFT: return ImGuiKey_LeftShift;
case sk::KEY_LCTRL: return ImGuiKey_LeftCtrl;
case sk::KEY_LALT: return ImGuiKey_LeftAlt;
case sk::KEY_RSHIFT: return ImGuiKey_RightShift;
case sk::KEY_RCTRL: return ImGuiKey_RightCtrl;
case sk::KEY_RALT: return ImGuiKey_RightAlt;
case sk::KEY_NULL: return ImGuiKey_None;
}
return ImGuiKey_None;
}
sk::EventStatus
ImGuiEventHandler(sk::Event e, void *param)
{
@@ -211,14 +316,10 @@ ImGuiEventHandler(sk::Event e, void *param)
switch(e){
case KEYDOWN:
c = *(int*)param;
if(c < 256)
io.KeysDown[c] = 1;
io.AddKeyEvent(SkKeyToImGuiKey(*(int*)param), true);
return EVENTPROCESSED;
case KEYUP:
c = *(int*)param;
if(c < 256)
io.KeysDown[c] = 0;
io.AddKeyEvent(SkKeyToImGuiKey(*(int*)param), false);
return EVENTPROCESSED;
case CHARINPUT:
c = (uint)(uintptr)param;
@@ -235,6 +336,10 @@ ImGuiEventHandler(sk::Event e, void *param)
io.MouseDown[2] = !!(ms->buttons & 2);
io.MouseDown[1] = !!(ms->buttons & 4);
return EVENTPROCESSED;
case MOUSEWHEEL:
ms = (MouseState*)param;
io.MouseWheel += ms->wheelDelta;
return EVENTPROCESSED;
}
return EVENTPROCESSED;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+41 -53
View File
@@ -1,15 +1,19 @@
// [DEAR IMGUI]
// This is a slightly modified version of stb_rect_pack.h 1.00.
// Those changes would need to be pushed into nothings/stb:
// - Added STBRP__CDECL
// This is a slightly modified version of stb_rect_pack.h 1.01.
// Grep for [DEAR IMGUI] to find the changes.
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
//
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation.
//
// Before #including,
//
// #define STB_RECT_PACK_IMPLEMENTATION
//
// in the file that you want to have the implementation.
//
// Not necessarily the awesomest packing method, but better than
// the totally naive one in stb_truetype (which is primarily what
// this is meant to replace).
@@ -34,13 +38,14 @@
// Minor features
// Martins Mozeiko
// github:IntellectualKitty
//
//
// Bugfixes / warning fixes
// Jeremy Jaussaud
// Fabian Giesen
//
// Version history:
//
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
// 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result
@@ -81,11 +86,10 @@ typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
#ifdef STBRP_LARGE_RECTS
typedef int stbrp_coord;
#else
typedef unsigned short stbrp_coord;
#endif
#define STBRP__MAXVAL 0x7fffffff
// Mostly for internal use, but this is the maximum supported coordinate value.
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
// Assign packed locations to rectangles. The rectangles are of type
@@ -213,10 +217,9 @@ struct stbrp_context
#define STBRP_ASSERT assert
#endif
// [DEAR IMGUI] Added STBRP__CDECL
#ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v)
#define STBRP__CDECL __cdecl
#define STBRP__CDECL __cdecl
#else
#define STBRP__NOTUSED(v) (void)sizeof(v)
#define STBRP__CDECL
@@ -262,9 +265,6 @@ STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_ou
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{
int i;
#ifndef STBRP_LARGE_RECTS
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
#endif
for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1];
@@ -283,11 +283,7 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width;
#ifdef STBRP_LARGE_RECTS
context->extra[1].y = (1<<30);
#else
context->extra[1].y = 65535;
#endif
context->extra[1].next = NULL;
}
@@ -433,7 +429,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
if (y <= best_y) {
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
best_x = xpos;
STBRP_ASSERT(y <= best_y);
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
best_y = y;
best_waste = waste;
best = prev;
@@ -441,7 +437,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
}
}
tail = tail->next;
}
}
}
fr.prev_link = best;
@@ -529,7 +525,6 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
return res;
}
// [DEAR IMGUI] Added STBRP__CDECL
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
@@ -541,7 +536,6 @@ static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
return (p->w > q->w) ? -1 : (p->w < q->w);
}
// [DEAR IMGUI] Added STBRP__CDECL
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
@@ -549,12 +543,6 @@ static int STBRP__CDECL rect_original_order(const void *a, const void *b)
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
}
#ifdef STBRP_LARGE_RECTS
#define STBRP__MAXVAL 0xffffffff
#else
#define STBRP__MAXVAL 0xffff
#endif
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
int i, all_rects_packed = 1;
@@ -602,38 +590,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/
+227 -186
View File
@@ -1,10 +1,14 @@
// [DEAR IMGUI]
// This is a slightly modified version of stb_textedit.h 1.13.
// This is a slightly modified version of stb_textedit.h 1.14.
// Those changes would need to be pushed into nothings/stb:
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
// - Added name to struct or it may be forward declared in our code.
// - Added UTF-8 support (see https://github.com/nothings/stb/issues/188 + https://github.com/ocornut/imgui/pull/7925)
// Grep for [DEAR IMGUI] to find the changes.
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
// stb_textedit.h - v1.13 - public domain - Sean Barrett
// stb_textedit.h - v1.14 - public domain - Sean Barrett
// Development of this library was sponsored by RAD Game Tools
//
// This C header file implements the guts of a multi-line text-editing
@@ -19,7 +23,7 @@
// texts, as its performance does not scale and it has limited undo).
//
// Non-trivial behaviors are modelled after Windows text controls.
//
//
//
// LICENSE
//
@@ -29,16 +33,17 @@
// DEPENDENCIES
//
// Uses the C runtime function 'memmove', which you can override
// by defining STB_TEXTEDIT_memmove before the implementation.
// by defining IMSTB_TEXTEDIT_memmove before the implementation.
// Uses no other functions. Performs no runtime allocations.
//
//
// VERSION HISTORY
//
// 1.14 (2021-07-11) page up/down, various fixes
// 1.13 (2019-02-07) fix bug in undo size management
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
// 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual
// 1.10 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
// 1.9 (2016-08-27) customizable move-by-word
// 1.8 (2016-04-02) better keyboard handling when mouse button is down
// 1.7 (2015-09-13) change y range handling in case baseline is non-0
@@ -58,6 +63,7 @@
// Ulf Winklemann: move-by-word in 1.1
// Fabian Giesen: secondary key inputs in 1.5
// Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6
// Louis Schnellbach: page up/down in 1.14
//
// Bugfixes:
// Scott Graham
@@ -93,8 +99,8 @@
// moderate sizes. The undo system does no memory allocations, so
// it grows STB_TexteditState by the worst-case storage which is (in bytes):
//
// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT
// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT
// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATECOUNT
// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHARCOUNT
//
//
// Implementation mode:
@@ -135,6 +141,7 @@
// with previous char)
// STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character
// (return type is int, -1 means not valid to insert)
// (not supported if you want to use UTF-8, see below)
// STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based
// STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize
// as manually wordwrapping for end-of-line positioning
@@ -172,6 +179,13 @@
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
//
// To support UTF-8:
//
// STB_TEXTEDIT_GETPREVCHARINDEX returns index of previous character
// STB_TEXTEDIT_GETNEXTCHARINDEX returns index of next character
// Do NOT define STB_TEXTEDIT_KEYTOTEXT.
// Instead, call stb_textedit_text() directly for text contents.
//
// Keyboard input must be encoded as a single integer value; e.g. a character code
// and some bitflags that represent shift states. to simplify the interface, SHIFT must
// be a bitflag, so we can test the shifted state of cursor movements to allow selection,
@@ -205,6 +219,7 @@
// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key)
// void stb_textedit_text(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int text_len)
//
// Each of these functions potentially updates the string and updates the
// state.
@@ -217,20 +232,20 @@
// call this with the mouse x,y on a mouse down; it will update the cursor
// and reset the selection start/end to the cursor point. the x,y must
// be relative to the text widget, with (0,0) being the top left.
//
//
// drag:
// call this with the mouse x,y on a mouse drag/up; it will update the
// cursor and the selection end point
//
//
// cut:
// call this to delete the current selection; returns true if there was
// one. you should FIRST copy the current selection to the system paste buffer.
// (To copy, just copy the current selection out of the string yourself.)
//
//
// paste:
// call this to paste text at the current cursor point or over the current
// selection if there is one.
//
//
// key:
// call this for keyboard inputs sent to the textfield. you can use it
// for "key down" events or for "translated" key events. if you need to
@@ -239,9 +254,16 @@
// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit
// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
// anything other type you wante before including.
// anything other type you want before including.
// if the STB_TEXTEDIT_KEYTOTEXT function is defined, selected keys are
// transformed into text and stb_textedit_text() is automatically called.
//
// text: (added 2025)
// call this to directly send text input the textfield, which is required
// for UTF-8 support, because stb_textedit_key() + STB_TEXTEDIT_KEYTOTEXT()
// cannot infer text length.
//
//
//
// When rendering, you can read the cursor position and selection state from
// the STB_TexteditState.
//
@@ -271,8 +293,8 @@
////
////
#ifndef INCLUDE_STB_TEXTEDIT_H
#define INCLUDE_STB_TEXTEDIT_H
#ifndef INCLUDE_IMSTB_TEXTEDIT_H
#define INCLUDE_IMSTB_TEXTEDIT_H
////////////////////////////////////////////////////////////////////////
//
@@ -283,38 +305,38 @@
// and undo state.
//
#ifndef STB_TEXTEDIT_UNDOSTATECOUNT
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
#ifndef IMSTB_TEXTEDIT_UNDOSTATECOUNT
#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99
#endif
#ifndef STB_TEXTEDIT_UNDOCHARCOUNT
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
#ifndef IMSTB_TEXTEDIT_UNDOCHARCOUNT
#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999
#endif
#ifndef STB_TEXTEDIT_CHARTYPE
#define STB_TEXTEDIT_CHARTYPE int
#ifndef IMSTB_TEXTEDIT_CHARTYPE
#define IMSTB_TEXTEDIT_CHARTYPE int
#endif
#ifndef STB_TEXTEDIT_POSITIONTYPE
#define STB_TEXTEDIT_POSITIONTYPE int
#ifndef IMSTB_TEXTEDIT_POSITIONTYPE
#define IMSTB_TEXTEDIT_POSITIONTYPE int
#endif
typedef struct
{
// private data
STB_TEXTEDIT_POSITIONTYPE where;
STB_TEXTEDIT_POSITIONTYPE insert_length;
STB_TEXTEDIT_POSITIONTYPE delete_length;
IMSTB_TEXTEDIT_POSITIONTYPE where;
IMSTB_TEXTEDIT_POSITIONTYPE insert_length;
IMSTB_TEXTEDIT_POSITIONTYPE delete_length;
int char_storage;
} StbUndoRecord;
typedef struct
{
// private data
StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
StbUndoRecord undo_rec [IMSTB_TEXTEDIT_UNDOSTATECOUNT];
IMSTB_TEXTEDIT_CHARTYPE undo_char[IMSTB_TEXTEDIT_UNDOCHARCOUNT];
short undo_point, redo_point;
int undo_char_point, redo_char_point;
} StbUndoState;
typedef struct
typedef struct STB_TexteditState
{
/////////////////////
//
@@ -368,7 +390,7 @@ typedef struct
float ymin,ymax; // height of row above and below baseline
int num_chars;
} StbTexteditRow;
#endif //INCLUDE_STB_TEXTEDIT_H
#endif //INCLUDE_IMSTB_TEXTEDIT_H
////////////////////////////////////////////////////////////////////////////
@@ -381,13 +403,23 @@ typedef struct
// implementation isn't include-guarded, since it might have indirectly
// included just the "header" portion
#ifdef STB_TEXTEDIT_IMPLEMENTATION
#ifdef IMSTB_TEXTEDIT_IMPLEMENTATION
#ifndef STB_TEXTEDIT_memmove
#ifndef IMSTB_TEXTEDIT_memmove
#include <string.h>
#define STB_TEXTEDIT_memmove memmove
#define IMSTB_TEXTEDIT_memmove memmove
#endif
// [DEAR IMGUI]
// Functions must be implemented for UTF8 support
// Code in this file that uses those functions is modified for [DEAR IMGUI] and deviates from the original stb_textedit.
// There is not necessarily a '[DEAR IMGUI]' at the usage sites.
#ifndef IMSTB_TEXTEDIT_GETPREVCHARINDEX
#define IMSTB_TEXTEDIT_GETPREVCHARINDEX(OBJ, IDX) ((IDX) - 1)
#endif
#ifndef IMSTB_TEXTEDIT_GETNEXTCHARINDEX
#define IMSTB_TEXTEDIT_GETNEXTCHARINDEX(OBJ, IDX) ((IDX) + 1)
#endif
/////////////////////////////////////////////////////////////////////////////
//
@@ -395,7 +427,7 @@ typedef struct
//
// traverse the layout to locate the nearest character to a display position
static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
{
StbTexteditRow r;
int n = STB_TEXTEDIT_STRINGLEN(str);
@@ -434,13 +466,13 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
if (x < r.x1) {
// search characters in row for one that straddles 'x'
prev_x = r.x0;
for (k=0; k < r.num_chars; ++k) {
for (k=0; k < r.num_chars; k = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k) - i) {
float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
if (x < prev_x+w) {
if (x < prev_x+w/2)
return k+i;
else
return k+i+1;
return IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k);
}
prev_x += w;
}
@@ -455,7 +487,7 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
}
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
{
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
// goes off the top or bottom of the text
@@ -473,7 +505,7 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
}
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
{
int p = 0;
@@ -499,11 +531,11 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
//
// forward declarations
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
typedef struct
{
@@ -515,36 +547,21 @@ typedef struct
// find the x/y location of a character, and remember info about the previous row in
// case we get a move-up event (for page up, we'll have to rescan)
static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING *str, int n, int single_line)
{
StbTexteditRow r;
int prev_start = 0;
int z = STB_TEXTEDIT_STRINGLEN(str);
int i=0, first;
if (n == z) {
// if it's at the end, then find the last line -- simpler than trying to
// explicitly handle this case in the regular code
if (single_line) {
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
find->y = 0;
find->first_char = 0;
find->length = z;
find->height = r.ymax - r.ymin;
find->x = r.x1;
} else {
find->y = 0;
find->x = 0;
find->height = 1;
while (i < z) {
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
prev_start = i;
i += r.num_chars;
}
find->first_char = i;
find->length = 0;
find->prev_first = prev_start;
}
if (n == z && single_line) {
// special case if it's at the end (may not be needed?)
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
find->y = 0;
find->first_char = 0;
find->length = z;
find->height = r.ymax - r.ymin;
find->x = r.x1;
return;
}
@@ -555,9 +572,16 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
if (n < i + r.num_chars)
break;
if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line
break; // [DEAR IMGUI]
prev_start = i;
i += r.num_chars;
find->y += r.baseline_y_delta;
if (i == z) // [DEAR IMGUI]
{
r.num_chars = 0; // [DEAR IMGUI]
break; // [DEAR IMGUI]
}
}
find->first_char = first = i;
@@ -567,14 +591,14 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
// now scan to find xpos
find->x = r.x0;
for (i=0; first+i < n; ++i)
for (i=0; first+i < n; i = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, first + i) - first)
find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
}
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
// make the selection/cursor state valid if client altered the string
static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
static void stb_textedit_clamp(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{
int n = STB_TEXTEDIT_STRINGLEN(str);
if (STB_TEXT_HAS_SELECTION(state)) {
@@ -588,7 +612,7 @@ static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
}
// delete characters while updating undo
static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
static void stb_textedit_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
{
stb_text_makeundo_delete(str, state, where, len);
STB_TEXTEDIT_DELETECHARS(str, where, len);
@@ -596,7 +620,7 @@ static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *sta
}
// delete the section
static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
static void stb_textedit_delete_selection(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{
stb_textedit_clamp(str, state);
if (STB_TEXT_HAS_SELECTION(state)) {
@@ -633,7 +657,7 @@ static void stb_textedit_move_to_first(STB_TexteditState *state)
}
// move cursor to last character of selection
static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{
if (STB_TEXT_HAS_SELECTION(state)) {
stb_textedit_sortselection(state);
@@ -645,17 +669,17 @@ static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditStat
}
#ifdef STB_TEXTEDIT_IS_SPACE
static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
{
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
}
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c )
{
--c; // always move at least one character
while( c >= 0 && !is_word_boundary( str, c ) )
--c;
c = IMSTB_TEXTEDIT_GETPREVCHARINDEX( str, c ); // always move at least one character
while (c >= 0 && !is_word_boundary(str, c))
c = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, c);
if( c < 0 )
c = 0;
@@ -666,12 +690,12 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
#endif
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c )
{
const int len = STB_TEXTEDIT_STRINGLEN(str);
++c; // always move at least one character
c = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, c); // always move at least one character
while( c < len && !is_word_boundary( str, c ) )
++c;
c = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, c);
if( c > len )
c = len;
@@ -693,7 +717,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
}
// API cut: delete selection
static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
static int stb_textedit_cut(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{
if (STB_TEXT_HAS_SELECTION(state)) {
stb_textedit_delete_selection(str,state); // implicitly clamps
@@ -704,7 +728,7 @@ static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
}
// API paste: replace existing selection with passed-in text
static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE *text, int len)
{
// if there's a selection, the paste should delete it
stb_textedit_clamp(str, state);
@@ -716,9 +740,7 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
state->has_preferred_x = 0;
return 1;
}
// remove the undo since we didn't actually insert the characters
if (state->undostate.undo_point)
--state->undostate.undo_point;
// note: paste failure will leave deleted selection, may be restored with an undo (see https://github.com/nothings/stb/issues/734 for details)
return 0;
}
@@ -726,36 +748,45 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
#define STB_TEXTEDIT_KEYTYPE int
#endif
// API key: process text input
// [DEAR IMGUI] Added stb_textedit_text(), extracted out and called by stb_textedit_key() for backward compatibility.
static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len)
{
// can't add newline in single-line mode
if (text[0] == '\n' && state->single_line)
return;
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
state->cursor += text_len;
state->has_preferred_x = 0;
}
} else {
stb_textedit_delete_selection(str, state); // implicitly clamps
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
stb_text_makeundo_insert(state, state->cursor, text_len);
state->cursor += text_len;
state->has_preferred_x = 0;
}
}
}
// API key: process a keyboard input
static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
{
retry:
switch (key) {
default: {
#ifdef STB_TEXTEDIT_KEYTOTEXT
// This is not suitable for UTF-8 support.
int c = STB_TEXTEDIT_KEYTOTEXT(key);
if (c > 0) {
STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
// can't add newline in single-line mode
if (c == '\n' && state->single_line)
break;
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
++state->cursor;
state->has_preferred_x = 0;
}
} else {
stb_textedit_delete_selection(str,state); // implicitly clamps
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
stb_text_makeundo_insert(state, state->cursor, 1);
++state->cursor;
state->has_preferred_x = 0;
}
}
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE)c;
stb_textedit_text(str, state, &ch, 1);
}
#endif
break;
}
@@ -764,7 +795,7 @@ retry:
state->insert_mode = !state->insert_mode;
break;
#endif
case STB_TEXTEDIT_K_UNDO:
stb_text_undo(str, state);
state->has_preferred_x = 0;
@@ -779,9 +810,9 @@ retry:
// if currently there's a selection, move cursor to start of selection
if (STB_TEXT_HAS_SELECTION(state))
stb_textedit_move_to_first(state);
else
else
if (state->cursor > 0)
--state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
state->has_preferred_x = 0;
break;
@@ -790,7 +821,7 @@ retry:
if (STB_TEXT_HAS_SELECTION(state))
stb_textedit_move_to_last(str, state);
else
++state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
stb_textedit_clamp(str, state);
state->has_preferred_x = 0;
break;
@@ -800,7 +831,7 @@ retry:
stb_textedit_prep_selection_at_cursor(state);
// move selection left
if (state->select_end > 0)
--state->select_end;
state->select_end = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->select_end);
state->cursor = state->select_end;
state->has_preferred_x = 0;
break;
@@ -828,7 +859,7 @@ retry:
#ifdef STB_TEXTEDIT_MOVEWORDRIGHT
case STB_TEXTEDIT_K_WORDRIGHT:
if (STB_TEXT_HAS_SELECTION(state))
if (STB_TEXT_HAS_SELECTION(state))
stb_textedit_move_to_last(str, state);
else {
state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
@@ -850,7 +881,7 @@ retry:
case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT:
stb_textedit_prep_selection_at_cursor(state);
// move selection right
++state->select_end;
state->select_end = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->select_end);
stb_textedit_clamp(str, state);
state->cursor = state->select_end;
state->has_preferred_x = 0;
@@ -897,16 +928,18 @@ retry:
state->cursor = start;
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
x = row.x0;
for (i=0; i < row.num_chars; ++i) {
for (i=0; i < row.num_chars; ) {
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
int next = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
break;
#endif
x += dx;
if (x > goal_x)
break;
++state->cursor;
i += next - state->cursor;
state->cursor = next;
}
stb_textedit_clamp(str, state);
@@ -922,7 +955,7 @@ retry:
}
break;
}
case STB_TEXTEDIT_K_UP:
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT:
case STB_TEXTEDIT_K_PGUP:
@@ -959,16 +992,18 @@ retry:
state->cursor = find.prev_first;
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
x = row.x0;
for (i=0; i < row.num_chars; ++i) {
for (i=0; i < row.num_chars; ) {
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
int next = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
break;
#endif
x += dx;
if (x > goal_x)
break;
++state->cursor;
i += next - state->cursor;
state->cursor = next;
}
stb_textedit_clamp(str, state);
@@ -981,8 +1016,13 @@ retry:
// go to previous line
// (we need to scan previous line the hard way. maybe we could expose this as a new API function?)
prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0;
while (prev_scan > 0 && STB_TEXTEDIT_GETCHAR(str, prev_scan - 1) != STB_TEXTEDIT_NEWLINE)
--prev_scan;
while (prev_scan > 0)
{
int prev = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, prev_scan);
if (STB_TEXTEDIT_GETCHAR(str, prev) == STB_TEXTEDIT_NEWLINE)
break;
prev_scan = prev;
}
find.first_char = find.prev_first;
find.prev_first = prev_scan;
}
@@ -996,7 +1036,7 @@ retry:
else {
int n = STB_TEXTEDIT_STRINGLEN(str);
if (state->cursor < n)
stb_textedit_delete(str, state, state->cursor, 1);
stb_textedit_delete(str, state, state->cursor, IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor) - state->cursor);
}
state->has_preferred_x = 0;
break;
@@ -1008,13 +1048,14 @@ retry:
else {
stb_textedit_clamp(str, state);
if (state->cursor > 0) {
stb_textedit_delete(str, state, state->cursor-1, 1);
--state->cursor;
int prev = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
stb_textedit_delete(str, state, prev, state->cursor - prev);
state->cursor = prev;
}
}
state->has_preferred_x = 0;
break;
#ifdef STB_TEXTEDIT_K_TEXTSTART2
case STB_TEXTEDIT_K_TEXTSTART2:
#endif
@@ -1031,7 +1072,7 @@ retry:
state->select_start = state->select_end = 0;
state->has_preferred_x = 0;
break;
#ifdef STB_TEXTEDIT_K_TEXTSTART2
case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
#endif
@@ -1060,7 +1101,7 @@ retry:
if (state->single_line)
state->cursor = 0;
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
--state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
state->has_preferred_x = 0;
break;
@@ -1072,9 +1113,9 @@ retry:
stb_textedit_clamp(str, state);
stb_textedit_move_to_first(state);
if (state->single_line)
state->cursor = n;
state->cursor = n;
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
++state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
state->has_preferred_x = 0;
break;
}
@@ -1088,7 +1129,7 @@ retry:
if (state->single_line)
state->cursor = 0;
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
--state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
state->select_end = state->cursor;
state->has_preferred_x = 0;
break;
@@ -1103,7 +1144,7 @@ retry:
if (state->single_line)
state->cursor = n;
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
++state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
state->select_end = state->cursor;
state->has_preferred_x = 0;
break;
@@ -1119,8 +1160,8 @@ retry:
static void stb_textedit_flush_redo(StbUndoState *state)
{
state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
state->redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
state->redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
}
// discard the oldest entry in the undo list
@@ -1132,13 +1173,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
int n = state->undo_rec[0].insert_length, i;
// delete n characters from all other records
state->undo_char_point -= n;
STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
IMSTB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
for (i=0; i < state->undo_point; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
}
--state->undo_point;
STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
IMSTB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
}
}
@@ -1148,7 +1189,7 @@ static void stb_textedit_discard_undo(StbUndoState *state)
// fill up even though the undo buffer didn't
static void stb_textedit_discard_redo(StbUndoState *state)
{
int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
int k = IMSTB_TEXTEDIT_UNDOSTATECOUNT-1;
if (state->redo_point <= k) {
// if the k'th undo state has characters, clean those up
@@ -1156,7 +1197,7 @@ static void stb_textedit_discard_redo(StbUndoState *state)
int n = state->undo_rec[k].insert_length, i;
// move the remaining redo character data to the end of the buffer
state->redo_char_point += n;
STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
IMSTB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((IMSTB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
// adjust the position of all the other records to account for above memmove
for (i=state->redo_point; i < k; ++i)
if (state->undo_rec[i].char_storage >= 0)
@@ -1164,12 +1205,12 @@ static void stb_textedit_discard_redo(StbUndoState *state)
}
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
// [DEAR IMGUI]
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
size_t move_size = (size_t)((IMSTB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
IMSTB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
// now move redo_point to point to the new one
++state->redo_point;
@@ -1183,32 +1224,32 @@ static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numch
// if we have no free records, we have to make room, by sliding the
// existing records down
if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
if (state->undo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
stb_textedit_discard_undo(state);
// if the characters to store won't possibly fit in the buffer, we can't undo
if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
if (numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
state->undo_point = 0;
state->undo_char_point = 0;
return NULL;
}
// if we don't have enough free characters in the buffer, we have to make room
while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
while (state->undo_char_point + numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT)
stb_textedit_discard_undo(state);
return &state->undo_rec[state->undo_point++];
}
static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
static IMSTB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
{
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
if (r == NULL)
return NULL;
r->where = pos;
r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
r->insert_length = (IMSTB_TEXTEDIT_POSITIONTYPE) insert_len;
r->delete_length = (IMSTB_TEXTEDIT_POSITIONTYPE) delete_len;
if (insert_len == 0) {
r->char_storage = -1;
@@ -1220,7 +1261,7 @@ static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos,
}
}
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{
StbUndoState *s = &state->undostate;
StbUndoRecord u, *r;
@@ -1247,7 +1288,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
// characters stored for *undoing* don't leave room for redo
// if the last is true, we have to bail
if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
if (s->undo_char_point + u.delete_length >= IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
// the undo records take up too much character space; there's no space to store the redo characters
r->insert_length = 0;
} else {
@@ -1256,7 +1297,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
// there's definitely room to store the characters eventually
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
// should never happen:
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
return;
// there's currently not enough room, so discard a redo record
stb_textedit_discard_redo(s);
@@ -1288,11 +1329,11 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
s->redo_point--;
}
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{
StbUndoState *s = &state->undostate;
StbUndoRecord *u, r;
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
return;
// we need to do two things: apply the redo record, and create an undo record
@@ -1344,20 +1385,20 @@ static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int le
stb_text_createundo(&state->undostate, where, 0, length);
}
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
{
int i;
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
if (p) {
for (i=0; i < length; ++i)
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
}
}
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
{
int i;
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
if (p) {
for (i=0; i < old_length; ++i)
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
@@ -1369,8 +1410,8 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
{
state->undostate.undo_point = 0;
state->undostate.undo_char_point = 0;
state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
state->undostate.redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
state->undostate.redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
state->select_end = state->select_start = 0;
state->cursor = 0;
state->has_preferred_x = 0;
@@ -1393,16 +1434,16 @@ static void stb_textedit_initialize_state(STB_TexteditState *state, int is_singl
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
static int stb_textedit_paste(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE const *ctext, int len)
{
return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
return stb_textedit_paste_internal(str, state, (IMSTB_TEXTEDIT_CHARTYPE *) ctext, len);
}
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
#endif//STB_TEXTEDIT_IMPLEMENTATION
#endif//IMSTB_TEXTEDIT_IMPLEMENTATION
/*
------------------------------------------------------------------------------
@@ -1410,38 +1451,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/
File diff suppressed because it is too large Load Diff
+5 -4
View File
@@ -224,7 +224,8 @@ main(int argc, char *argv[])
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
return 0;
float lastTime = SDL_GetTicks();
Uint64 lastTicks = SDL_GetPerformanceCounter();
const float tickPeriod = 1.f / SDL_GetPerformanceFrequency();
SDL_Event event;
int mouseButtons = 0;
@@ -297,12 +298,12 @@ main(int argc, char *argv[])
}
}
}
float currTime = SDL_GetTicks();
float timeDelta = (currTime - lastTime) * 0.001f;
Uint64 currTicks = SDL_GetPerformanceCounter();
float timeDelta = (currTicks - lastTicks) * tickPeriod;
EventHandler(IDLE, &timeDelta);
lastTime = currTime;
lastTicks = currTicks;
}
SDL_StopTextInput();
+323
View File
@@ -0,0 +1,323 @@
#ifdef LIBRW_SDL3
#include <rw.h>
#include "skeleton.h"
using namespace sk;
using namespace rw;
#ifdef RW_OPENGL
SDL_Window *window;
static int keyCodeToSkKey(SDL_Keycode keycode) {
switch (keycode) {
case SDLK_SPACE: return ' ';
case SDLK_APOSTROPHE: return '\'';
case SDLK_COMMA: return ',';
case SDLK_MINUS: return '-';
case SDLK_PERIOD: return '.';
case SDLK_SLASH: return '/';
case SDLK_0: return '0';
case SDLK_1: return '1';
case SDLK_2: return '2';
case SDLK_3: return '3';
case SDLK_4: return '4';
case SDLK_5: return '5';
case SDLK_6: return '6';
case SDLK_7: return '7';
case SDLK_8: return '8';
case SDLK_9: return '9';
case SDLK_SEMICOLON: return ';';
case SDLK_EQUALS: return '=';
case SDLK_A: return 'A';
case SDLK_B: return 'B';
case SDLK_C: return 'C';
case SDLK_D: return 'D';
case SDLK_E: return 'E';
case SDLK_F: return 'F';
case SDLK_G: return 'G';
case SDLK_H: return 'H';
case SDLK_I: return 'I';
case SDLK_J: return 'J';
case SDLK_K: return 'K';
case SDLK_L: return 'L';
case SDLK_M: return 'M';
case SDLK_N: return 'N';
case SDLK_O: return 'O';
case SDLK_P: return 'P';
case SDLK_Q: return 'Q';
case SDLK_R: return 'R';
case SDLK_S: return 'S';
case SDLK_T: return 'T';
case SDLK_U: return 'U';
case SDLK_V: return 'V';
case SDLK_W: return 'W';
case SDLK_X: return 'X';
case SDLK_Y: return 'Y';
case SDLK_Z: return 'Z';
case SDLK_LEFTBRACKET: return '[';
case SDLK_BACKSLASH: return '\\';
case SDLK_RIGHTBRACKET: return ']';
case SDLK_GRAVE: return '`';
case SDLK_ESCAPE: return KEY_ESC;
case SDLK_RETURN: return KEY_ENTER;
case SDLK_TAB: return KEY_TAB;
case SDLK_BACKSPACE: return KEY_BACKSP;
case SDLK_INSERT: return KEY_INS;
case SDLK_DELETE: return KEY_DEL;
case SDLK_RIGHT: return KEY_RIGHT;
case SDLK_LEFT: return KEY_LEFT;
case SDLK_DOWN: return KEY_DOWN;
case SDLK_UP: return KEY_UP;
case SDLK_PAGEUP: return KEY_PGUP;
case SDLK_PAGEDOWN: return KEY_PGDN;
case SDLK_HOME: return KEY_HOME;
case SDLK_END: return KEY_END;
case SDLK_CAPSLOCK: return KEY_CAPSLK;
case SDLK_SCROLLLOCK: return KEY_NULL;
case SDLK_NUMLOCKCLEAR: return KEY_NULL;
case SDLK_PRINTSCREEN: return KEY_NULL;
case SDLK_PAUSE: return KEY_NULL;
case SDLK_F1: return KEY_F1;
case SDLK_F2: return KEY_F2;
case SDLK_F3: return KEY_F3;
case SDLK_F4: return KEY_F4;
case SDLK_F5: return KEY_F5;
case SDLK_F6: return KEY_F6;
case SDLK_F7: return KEY_F7;
case SDLK_F8: return KEY_F8;
case SDLK_F9: return KEY_F9;
case SDLK_F10: return KEY_F10;
case SDLK_F11: return KEY_F11;
case SDLK_F12: return KEY_F12;
case SDLK_F13: return KEY_NULL;
case SDLK_F14: return KEY_NULL;
case SDLK_F15: return KEY_NULL;
case SDLK_F16: return KEY_NULL;
case SDLK_F17: return KEY_NULL;
case SDLK_F18: return KEY_NULL;
case SDLK_F19: return KEY_NULL;
case SDLK_F20: return KEY_NULL;
case SDLK_F21: return KEY_NULL;
case SDLK_F22: return KEY_NULL;
case SDLK_F23: return KEY_NULL;
case SDLK_F24: return KEY_NULL;
case SDLK_KP_0: return KEY_NULL;
case SDLK_KP_1: return KEY_NULL;
case SDLK_KP_2: return KEY_NULL;
case SDLK_KP_3: return KEY_NULL;
case SDLK_KP_4: return KEY_NULL;
case SDLK_KP_5: return KEY_NULL;
case SDLK_KP_6: return KEY_NULL;
case SDLK_KP_7: return KEY_NULL;
case SDLK_KP_8: return KEY_NULL;
case SDLK_KP_9: return KEY_NULL;
case SDLK_KP_DECIMAL: return KEY_NULL;
case SDLK_KP_DIVIDE: return KEY_NULL;
case SDLK_KP_MULTIPLY: return KEY_NULL;
case SDLK_KP_MINUS: return KEY_NULL;
case SDLK_KP_PLUS: return KEY_NULL;
case SDLK_KP_ENTER: return KEY_NULL;
case SDLK_KP_EQUALS: return KEY_NULL;
case SDLK_LSHIFT: return KEY_LSHIFT;
case SDLK_LCTRL: return KEY_LCTRL;
case SDLK_LALT: return KEY_LALT;
case SDLK_LGUI: return KEY_NULL;
case SDLK_RSHIFT: return KEY_RSHIFT;
case SDLK_RCTRL: return KEY_RCTRL;
case SDLK_RALT: return KEY_RALT;
case SDLK_RGUI: return KEY_NULL;
case SDLK_MENU: return KEY_NULL;
}
return KEY_NULL;
}
#if 0
static void
keypress(SDL_Window *window, int key, int scancode, int action, int mods)
{
if(key >= 0 && key <= GLFW_KEY_LAST){
if(action == GLFW_RELEASE) KeyUp(keymap[key]);
else if(action == GLFW_PRESS) KeyDown(keymap[key]);
else if(action == GLFW_REPEAT) KeyDown(keymap[key]);
}
}
static void
charinput(GLFWwindow *window, unsigned int c)
{
EventHandler(CHARINPUT, (void*)(uintptr)c);
}
static void
resize(GLFWwindow *window, int w, int h)
{
rw::Rect r;
r.x = 0;
r.y = 0;
r.w = w;
r.h = h;
EventHandler(RESIZE, &r);
}
static void
mousebtn(GLFWwindow *window, int button, int action, int mods)
{
static int buttons = 0;
sk::MouseState ms;
switch(button){
case GLFW_MOUSE_BUTTON_LEFT:
if(action == GLFW_PRESS)
buttons |= 1;
else
buttons &= ~1;
break;
case GLFW_MOUSE_BUTTON_MIDDLE:
if(action == GLFW_PRESS)
buttons |= 2;
else
buttons &= ~2;
break;
case GLFW_MOUSE_BUTTON_RIGHT:
if(action == GLFW_PRESS)
buttons |= 4;
else
buttons &= ~4;
break;
}
sk::MouseState ms;
ms.buttons = buttons;
EventHandler(MOUSEBTN, &ms);
}
#endif
enum mousebutton {
BUTTON_LEFT = 0x1,
BUTTON_MIDDLE = 0x2,
BUTTON_RIGHT = 0x4,
};
int
main(int argc, char *argv[])
{
args.argc = argc;
args.argv = argv;
if(EventHandler(INITIALIZE, nil) == EVENTERROR)
return 0;
engineOpenParams.width = sk::globals.width;
engineOpenParams.height = sk::globals.height;
engineOpenParams.windowtitle = sk::globals.windowtitle;
engineOpenParams.window = &window;
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
return 0;
Uint64 lastTicks = SDL_GetPerformanceCounter();
const float tickPeriod = 1.f / SDL_GetPerformanceFrequency();
SDL_Event event;
int mouseButtons = 0;
SDL_StartTextInput(window);
while(!sk::globals.quit){
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_EVENT_QUIT:
sk::globals.quit = true;
break;
case SDL_EVENT_WINDOW_RESIZED: {
rw::Rect r;
SDL_GetWindowPosition(window, &r.x, &r.y);
r.w = event.window.data1;
r.h = event.window.data2;
EventHandler(RESIZE, &r);
break;
}
case SDL_EVENT_KEY_UP: {
int c = keyCodeToSkKey(event.key.key);
EventHandler(KEYUP, &c);
break;
}
case SDL_EVENT_KEY_DOWN: {
int c = keyCodeToSkKey(event.key.key);
EventHandler(KEYDOWN, &c);
break;
}
case SDL_EVENT_TEXT_INPUT: {
const char *c = event.text.text;
while (int ci = *c) {
EventHandler(CHARINPUT, (void*)(uintptr)ci);
++c;
}
break;
}
case SDL_EVENT_MOUSE_MOTION: {
sk::MouseState ms;
ms.posx = event.motion.x;
ms.posy = event.motion.y;
EventHandler(MOUSEMOVE, &ms);
break;
}
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
switch (event.button.button) {
case SDL_BUTTON_LEFT: mouseButtons |= BUTTON_LEFT; break;
case SDL_BUTTON_MIDDLE: mouseButtons |= BUTTON_MIDDLE; break;
case SDL_BUTTON_RIGHT: mouseButtons |= BUTTON_RIGHT; break;
}
sk::MouseState ms;
ms.buttons = mouseButtons;
EventHandler(MOUSEBTN, &ms);
break;
}
case SDL_EVENT_MOUSE_BUTTON_UP: {
switch (event.button.button) {
case SDL_BUTTON_LEFT: mouseButtons &= ~BUTTON_LEFT; break;
case SDL_BUTTON_MIDDLE: mouseButtons &= ~BUTTON_MIDDLE; break;
case SDL_BUTTON_RIGHT: mouseButtons &= ~BUTTON_RIGHT; break;
}
sk::MouseState ms;
ms.buttons = mouseButtons;
EventHandler(MOUSEBTN, &ms);
break;
}
}
}
Uint64 currTicks = SDL_GetPerformanceCounter();
float timeDelta = (currTicks - lastTicks) * tickPeriod;
EventHandler(IDLE, &timeDelta);
lastTicks = currTicks;
}
SDL_StopTextInput(window);
EventHandler(RWTERMINATE, nil);
return 0;
}
namespace sk {
void
SetMousePosition(int x, int y)
{
SDL_WarpMouseInWindow(*engineOpenParams.window, x, y);
}
}
#endif
#endif
+2 -2
View File
@@ -23,7 +23,7 @@ InitRW(void)
n = Engine::getNumSubSystems();
for(i = 0; i < n; i++)
if(Engine::getSubSystemInfo(&info, i))
printf("subsystem: %s\n", info.name);
;//printf("subsystem: %s\n", info.name);
Engine::setSubSystem(n-1);
int want = -1;
@@ -34,7 +34,7 @@ InitRW(void)
// if(mode.width == 640 && mode.height == 480 && mode.depth == 32)
if(mode.width == 1920 && mode.height == 1080 && mode.depth == 32)
want = i;
printf("mode: %dx%dx%d %d\n", mode.width, mode.height, mode.depth, mode.flags);
//printf("mode: %dx%dx%d %d\n", mode.width, mode.height, mode.depth, mode.flags);
}
// if(want >= 0) Engine::setVideoMode(want);
Engine::getVideoModeInfo(&mode, Engine::getCurrentVideoMode());
+2
View File
@@ -72,6 +72,7 @@ enum Event
CHARINPUT,
MOUSEMOVE,
MOUSEBTN,
MOUSEWHEEL,
RESIZE,
IDLE,
QUIT
@@ -91,6 +92,7 @@ struct MouseState
{
int posx, posy;
int buttons; // bits 0-2 are left, middle, right button down
float wheelDelta;
};
struct Args
+4
View File
@@ -135,6 +135,10 @@ WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
ms.buttons = buttons;
EventHandler(MOUSEBTN, &ms);
break;
case WM_MOUSEWHEEL:
ms.wheelDelta = (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
EventHandler(MOUSEWHEEL, &ms);
break;
case WM_SIZE:
rw::Rect r;
+17 -2
View File
@@ -150,18 +150,33 @@ set_target_properties(librw
if(LIBRW_PLATFORM_GL3)
if (LIBRW_GL3_GFXLIB STREQUAL "GLFW")
find_package(glfw3 REQUIRED)
if (NOT TARGET glfw)
find_package(glfw3 REQUIRED)
endif()
target_compile_definitions(librw PUBLIC LIBRW_GLFW)
target_link_libraries(librw
PUBLIC
glfw
)
elseif (LIBRW_GL3_GFXLIB STREQUAL "SDL2")
find_package(SDL2 REQUIRED)
if (NOT TARGET SDL2::SDL2)
find_package(SDL2 CONFIG)
if (NOT TARGET SDL2::SDL2)
find_package(SDL2 MODULE REQUIRED)
endif()
endif()
target_compile_definitions(librw PUBLIC LIBRW_SDL2)
target_link_libraries(librw
PUBLIC
SDL2::SDL2
)
elseif (LIBRW_GL3_GFXLIB STREQUAL "SDL3")
find_package(SDL3 CONFIG REQUIRED)
target_compile_definitions(librw PUBLIC LIBRW_SDL3)
target_link_libraries(librw
PUBLIC
SDL3::SDL3
)
endif()
set(OpenGL_GL_PREFERENCE GLVND)
+15 -13
View File
@@ -587,6 +587,7 @@ Matrix::makeRotation(Matrix *dst, const V3d *axis, float32 angle)
dst->pos.y = 0.0;
dst->pos.z = 0.0;
dst->flags = TYPEORTHONORMAL;
dst->pad1 = dst->pad2 = dst->pad3 = 0;
}
/* q must be normalized */
@@ -616,6 +617,7 @@ Matrix::makeRotation(Matrix *dst, const Quat &q)
dst->pos.y = 0.0;
dst->pos.z = 0.0;
dst->flags = TYPEORTHONORMAL;
dst->pad1 = dst->pad2 = dst->pad3 = 0;
}
float32
@@ -999,7 +1001,7 @@ StreamFile*
StreamFile::open(const char *path, const char *mode)
{
assert(this->file == nil);
this->file = fopen(path, mode);
this->file = engine->filefuncs.rwfopen(path, mode);
if(this->file == nil){
RWERROR((ERR_FILE, path));
return nil;
@@ -1011,38 +1013,38 @@ void
StreamFile::close(void)
{
assert(this->file);
fclose(this->file);
engine->filefuncs.rwfclose(this->file);
this->file = nil;
}
uint32
StreamFile::write8(const void *data, uint32 length)
{
return (uint32)fwrite(data, 1, length, this->file);
return (uint32)engine->filefuncs.rwfwrite(data, 1, length, this->file);
}
uint32
StreamFile::read8(void *data, uint32 length)
{
return (uint32)fread(data, 1, length, this->file);
return (uint32)engine->filefuncs.rwfread(data, 1, length, this->file);
}
void
StreamFile::seek(int32 offset, int32 whence)
{
fseek(this->file, offset, whence);
engine->filefuncs.rwfseek(this->file, offset, whence);
}
uint32
StreamFile::tell(void)
{
return ftell(this->file);
return engine->filefuncs.rwftell(this->file);
}
bool
StreamFile::eof(void)
{
return ( feof(this->file) != 0 );
return engine->filefuncs.rwfeof(this->file) != 0;
}
bool
@@ -1106,15 +1108,15 @@ findPointer(void *p, void **list, int32 num)
uint8*
getFileContents(const char *name, uint32 *len)
{
FILE *cf = fopen(name, "rb");
void *cf = engine->filefuncs.rwfopen(name, "rb");
if(cf == nil)
return nil;
fseek(cf, 0, SEEK_END);
*len = ftell(cf);
fseek(cf, 0, SEEK_SET);
engine->filefuncs.rwfseek(cf, 0, SEEK_END);
*len = engine->filefuncs.rwftell(cf);
engine->filefuncs.rwfseek(cf, 0, SEEK_SET);
uint8 *data = rwNewT(uint8, *len, MEMDUR_EVENT);
fread(data, 1, *len, cf);
fclose(cf);
engine->filefuncs.rwfread(data, 1, *len, cf);
engine->filefuncs.rwfclose(cf);
return data;
}
+99 -100
View File
@@ -985,97 +985,6 @@ setViewport(Raster *fb)
vp.Height = fb->height;
d3ddevice->SetViewport(&vp);
}
static void
beginUpdate(Camera *cam)
{
float view[16], proj[16];
// View Matrix
Matrix inv;
Matrix::invert(&inv, cam->getFrame()->getLTM());
// Since we're looking into positive Z,
// flip X to ge a left handed view space.
view[0] = -inv.right.x;
view[1] = inv.right.y;
view[2] = inv.right.z;
view[3] = 0.0f;
view[4] = -inv.up.x;
view[5] = inv.up.y;
view[6] = inv.up.z;
view[7] = 0.0f;
view[8] = -inv.at.x;
view[9] = inv.at.y;
view[10] = inv.at.z;
view[11] = 0.0f;
view[12] = -inv.pos.x;
view[13] = inv.pos.y;
view[14] = inv.pos.z;
view[15] = 1.0f;
memcpy(&cam->devView, view, sizeof(RawMatrix));
// d3ddevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)view);
// Projection Matrix
float32 invwx = 1.0f/cam->viewWindow.x;
float32 invwy = 1.0f/cam->viewWindow.y;
float32 invz = 1.0f/(cam->farPlane-cam->nearPlane);
proj[0] = invwx;
proj[1] = 0.0f;
proj[2] = 0.0f;
proj[3] = 0.0f;
proj[4] = 0.0f;
proj[5] = invwy;
proj[6] = 0.0f;
proj[7] = 0.0f;
proj[8] = cam->viewOffset.x*invwx;
proj[9] = cam->viewOffset.y*invwy;
proj[12] = -proj[8];
proj[13] = -proj[9];
if(cam->projection == Camera::PERSPECTIVE){
proj[10] = cam->farPlane*invz;
proj[11] = 1.0f;
proj[15] = 0.0f;
}else{
proj[10] = invz;
proj[11] = 0.0f;
proj[15] = 1.0f;
}
proj[14] = -cam->nearPlane*proj[10];
memcpy(&cam->devProj, proj, sizeof(RawMatrix));
// d3ddevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)proj);
// TODO: figure out where this is really done
// setRenderState(D3DRS_FOGSTART, *(uint32*)&cam->fogPlane);
// setRenderState(D3DRS_FOGEND, *(uint32*)&cam->farPlane);
d3dShaderState.fogData.start = cam->fogPlane;
d3dShaderState.fogData.end = cam->farPlane;
d3dShaderState.fogData.range = 1.0f/(cam->fogPlane - cam->farPlane);
// TODO: not quite sure this is the right place to do this...
d3dShaderState.fogData.disable = rwStateCache.fogenable ? 0.0f : 1.0f;
d3dShaderState.fogDisable.start = 0.0f;
d3dShaderState.fogDisable.end = 0.0f;
d3dShaderState.fogDisable.range = 0.0f;
d3dShaderState.fogDisable.disable = 1.0f;
d3dShaderState.fogDirty = true;
setRenderSurfaces(cam);
setViewport(cam->frameBuffer);
d3ddevice->BeginScene();
}
static void
endUpdate(Camera *cam)
{
d3ddevice->EndScene();
}
// Manage video memory
void
@@ -1310,16 +1219,81 @@ restoreVideoMemory(void)
}
static void
clearCamera(Camera *cam, RGBA *col, uint32 mode)
beginUpdate(Camera *cam)
{
int flags = 0;
if(mode & Camera::CLEARIMAGE)
mode |= D3DCLEAR_TARGET;
if(mode & Camera::CLEARZ)
mode |= D3DCLEAR_ZBUFFER;
if(mode & Camera::CLEARSTENCIL)
mode |= D3DCLEAR_STENCIL;
D3DCOLOR c = D3DCOLOR_RGBA(col->red, col->green, col->blue, col->alpha);
float view[16], proj[16];
// View Matrix
Matrix inv;
Matrix::invert(&inv, cam->getFrame()->getLTM());
// Since we're looking into positive Z,
// flip X to ge a left handed view space.
view[0] = -inv.right.x;
view[1] = inv.right.y;
view[2] = inv.right.z;
view[3] = 0.0f;
view[4] = -inv.up.x;
view[5] = inv.up.y;
view[6] = inv.up.z;
view[7] = 0.0f;
view[8] = -inv.at.x;
view[9] = inv.at.y;
view[10] = inv.at.z;
view[11] = 0.0f;
view[12] = -inv.pos.x;
view[13] = inv.pos.y;
view[14] = inv.pos.z;
view[15] = 1.0f;
memcpy(&cam->devView, view, sizeof(RawMatrix));
// d3ddevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)view);
// Projection Matrix
float32 invwx = 1.0f/cam->viewWindow.x;
float32 invwy = 1.0f/cam->viewWindow.y;
float32 invz = 1.0f/(cam->farPlane-cam->nearPlane);
proj[0] = invwx;
proj[1] = 0.0f;
proj[2] = 0.0f;
proj[3] = 0.0f;
proj[4] = 0.0f;
proj[5] = invwy;
proj[6] = 0.0f;
proj[7] = 0.0f;
proj[8] = cam->viewOffset.x*invwx;
proj[9] = cam->viewOffset.y*invwy;
proj[12] = -proj[8];
proj[13] = -proj[9];
if(cam->projection == Camera::PERSPECTIVE){
proj[10] = cam->farPlane*invz;
proj[11] = 1.0f;
proj[15] = 0.0f;
}else{
proj[10] = invz;
proj[11] = 0.0f;
proj[15] = 1.0f;
}
proj[14] = -cam->nearPlane*proj[10];
memcpy(&cam->devProj, proj, sizeof(RawMatrix));
// d3ddevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)proj);
// TODO: figure out where this is really done
// setRenderState(D3DRS_FOGSTART, *(uint32*)&cam->fogPlane);
// setRenderState(D3DRS_FOGEND, *(uint32*)&cam->farPlane);
d3dShaderState.fogData.start = cam->fogPlane;
d3dShaderState.fogData.end = cam->farPlane;
d3dShaderState.fogData.range = 1.0f/(cam->fogPlane - cam->farPlane);
// TODO: not quite sure this is the right place to do this...
d3dShaderState.fogData.disable = rwStateCache.fogenable ? 0.0f : 1.0f;
d3dShaderState.fogDisable.start = 0.0f;
d3dShaderState.fogDisable.end = 0.0f;
d3dShaderState.fogDisable.range = 0.0f;
d3dShaderState.fogDisable.disable = 1.0f;
d3dShaderState.fogDirty = true;
RECT r;
GetClientRect(d3d9Globals.window, &r);
@@ -1337,6 +1311,31 @@ clearCamera(Camera *cam, RGBA *col, uint32 mode)
setRenderSurfaces(cam);
setViewport(cam->frameBuffer);
d3ddevice->BeginScene();
}
static void
endUpdate(Camera *cam)
{
d3ddevice->EndScene();
}
static void
clearCamera(Camera *cam, RGBA *col, uint32 mode)
{
int flags = 0;
if(mode & Camera::CLEARIMAGE)
mode |= D3DCLEAR_TARGET;
if(mode & Camera::CLEARZ)
mode |= D3DCLEAR_ZBUFFER;
if(mode & Camera::CLEARSTENCIL)
mode |= D3DCLEAR_STENCIL;
D3DCOLOR c = D3DCOLOR_RGBA(col->red, col->green, col->blue, col->alpha);
setRenderSurfaces(cam);
setViewport(cam->frameBuffer); // need to set this for the clear to work correctly
d3ddevice->Clear(0, nil, mode, c, 1.0f, 0);
}
+23 -5
View File
@@ -236,8 +236,9 @@ static int32 num3DVertices;
void
openIm3D(void)
{
D3DVERTEXELEMENT9 elements[4] = {
D3DVERTEXELEMENT9 elements[5] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, offsetof(Im3DVertex, normal), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, offsetof(Im3DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, offsetof(Im3DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
@@ -273,6 +274,10 @@ closeIm3D(void)
im3dindbuf = nil;
}
// settable by user - TOOD: make this less shit
RGBA im3dMaterialColor = { 255, 255, 255, 255 };
SurfaceProperties im3dSurfaceProps = { 1.0f, 1.0f, 1.0f };
void
im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
{
@@ -284,9 +289,22 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
if((flags & im3d::VERTEXUV) == 0)
SetRenderStatePtr(TEXTURERASTER, nil);
static RGBA white = { 255, 255, 255, 255 };
static SurfaceProperties surfprops = { 0.0f, 0.0f, 0.0f };
setMaterial(white, surfprops);
void *shader = default_amb_VS;
if(flags & im3d::LIGHTING){
setMaterial(im3dMaterialColor, im3dSurfaceProps);
int32 vsBits = lightingCB_Shader();
// Pick a shader
if((vsBits & VSLIGHT_MASK) == 0)
shader = default_amb_VS;
else if((vsBits & VSLIGHT_MASK) == VSLIGHT_DIRECT)
shader = default_amb_dir_VS;
else
shader = default_all_VS;
}else{
static RGBA white = { 255, 255, 255, 255 };
static SurfaceProperties surfprops = { 0.0f, 0.0f, 0.0f };
setMaterial(white, surfprops);
}
uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_DISCARD);
memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex));
@@ -295,7 +313,7 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
setStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex));
setVertexDeclaration(im3ddecl);
setVertexShader(default_amb_VS);
setVertexShader(shader);
num3DVertices = numVertices;
}
+16 -5
View File
@@ -357,11 +357,6 @@ lightingCB_Shader(Atomic *atomic)
if(atomic->geometry->flags & rw::Geometry::LIGHT){
((World*)engine->currentWorld)->enumerateLights(atomic, &lightData);
setAmbient(lightData.ambient);
if((atomic->geometry->flags & rw::Geometry::NORMALS) == 0){
// Get rid of lights that need normals when we don't have any
lightData.numDirectionals = 0;
lightData.numLocals = 0;
}
return uploadLights(&lightData);
}else{
static const RGBAf black = { 0.0f, 0.0f, 0.0f, 0.0f };
@@ -371,6 +366,22 @@ lightingCB_Shader(Atomic *atomic)
}
}
int32
lightingCB_Shader(void)
{
WorldLights lightData;
Light *directionals[8];
Light *locals[8];
lightData.directionals = directionals;
lightData.numDirectionals = 8;
lightData.locals = locals;
lightData.numLocals = 8;
((World*)engine->currentWorld)->enumerateLights(&lightData);
setAmbient(lightData.ambient);
return uploadLights(&lightData);
}
static RawMatrix identityXform = {
{ 1.0f, 0.0f, 0.0f }, 0.0f,
{ 0.0f, 1.0f, 0.0f }, 0.0f,
+10
View File
@@ -42,12 +42,16 @@ void setD3dMaterial(D3DMATERIAL9 *mat9);
struct Im3DVertex
{
V3d position;
V3d normal; // librw extension
uint32 color;
float32 u, v;
void setX(float32 x) { this->position.x = x; }
void setY(float32 y) { this->position.y = y; }
void setZ(float32 z) { this->position.z = z; }
void setNormalX(float32 x) { this->normal.x = x; }
void setNormalY(float32 y) { this->normal.y = y; }
void setNormalZ(float32 z) { this->normal.z = z; }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = COLOR_ARGB(a, r, g, b); }
void setU(float32 u) { this->u = u; }
void setV(float32 v) { this->v = v; }
@@ -55,11 +59,16 @@ struct Im3DVertex
float getX(void) { return this->position.x; }
float getY(void) { return this->position.y; }
float getZ(void) { return this->position.z; }
float getNormalX(void) { return this->normal.x; }
float getNormalY(void) { return this->normal.y; }
float getNormalZ(void) { return this->normal.z; }
RGBA getColor(void) { return makeRGBA(this->color>>16 & 0xFF, this->color>>8 & 0xFF,
this->color & 0xFF, this->color>>24 & 0xFF); }
float getU(void) { return this->u; }
float getV(void) { return this->v; }
};
extern RGBA im3dMaterialColor;
extern SurfaceProperties im3dSurfaceProps;
struct Im2DVertex
{
@@ -386,6 +395,7 @@ enum
void lightingCB_Fix(Atomic *atomic);
int32 lightingCB_Shader(Atomic *atomic);
int32 lightingCB_Shader(void);
// for VS
void uploadMatrices(void); // no world transform
void uploadMatrices(Matrix *worldMat);
+7
View File
@@ -254,6 +254,13 @@ Engine::open(EngineOpenParams *p)
engine = (Engine*)rwNew(Engine::s_plglist.size, MEMDUR_GLOBAL);
engine->currentCamera = nil;
engine->currentWorld = nil;
engine->filefuncs.rwfopen = (void *(*)(const char*, const char*))fopen;
engine->filefuncs.rwfclose = (int (*)(void*))fclose;
engine->filefuncs.rwfseek = (int (*)(void*, long, int))fseek;
engine->filefuncs.rwftell = (long (*)(void*))ftell;
engine->filefuncs.rwfread = (size_t (*)(void*, size_t, size_t, void*))fread;
engine->filefuncs.rwfwrite = (size_t (*)(const void*, size_t, size_t, void*))fwrite;
engine->filefuncs.rwfeof = (int (*)(void*))feof;
// Initialize device
// Device and possibly OS specific!
+7
View File
@@ -275,6 +275,13 @@ Frame::rotate(const V3d *axis, float32 angle, CombineOp op)
updateObjects();
}
void
Frame::rotate(const Quat *q, CombineOp op)
{
this->matrix.rotate(*q, op);
updateObjects();
}
void
Frame::translate(const V3d *trans, CombineOp op)
{
+1
View File
@@ -727,6 +727,7 @@ MaterialList::deinit(void)
for(int32 i = 0; i < this->numMaterials; i++)
this->materials[i]->destroy();
rwFree(this->materials);
this->materials = nil;
}
}
+318 -14
View File
@@ -923,6 +923,7 @@ resetRenderState(void)
rwStateCache.alphaFunc = ALPHAGREATEREQUAL;
alphaFunc = 0;
alphaRef = 10.0f/255.0f;
uniformStateDirty[RWGL_ALPHAREF] = true;
uniformState.fogDisable = 1.0f;
uniformState.fogStart = 0.0f;
uniformState.fogEnd = 0.0f;
@@ -1109,7 +1110,7 @@ flushCache(void)
uniformState.fogRange = 1.0f/(rwStateCache.fogStart - rwStateCache.fogEnd);
if(uniformStateDirty[RWGL_ALPHAFUNC] || uniformStateDirty[RWGL_ALPHAREF]){
float alphaTest[4];
float alphaTest[4] = {};
switch(alphaFunc){
case ALPHAALWAYS:
default:
@@ -1245,8 +1246,12 @@ getFramebufferRect(Raster *frameBuffer)
if(fb->type == Raster::CAMERA){
#ifdef LIBRW_SDL2
SDL_GetWindowSize(glGlobals.window, &r.w, &r.h);
#else
#elif defined(LIBRW_SDL3)
SDL_GetWindowSize(glGlobals.window, &r.w, &r.h);
#elif defined(LIBRW_GLFW)
glfwGetFramebufferSize(glGlobals.window, &r.w, &r.h);
#else
missing implementation
#endif
}else{
r.w = fb->width;
@@ -1411,12 +1416,20 @@ showRaster(Raster *raster, uint32 flags)
else
SDL_GL_SetSwapInterval(0);
SDL_GL_SwapWindow(glGlobals.window);
#else
#elif defined(LIBRW_SDL3)
if(flags & Raster::FLIPWAITVSYNCH)
SDL_GL_SetSwapInterval(1);
else
SDL_GL_SetSwapInterval(0);
SDL_GL_SwapWindow(glGlobals.window);
#elif defined(LIBRW_GLFW)
if(flags & Raster::FLIPWAITVSYNCH)
glfwSwapInterval(1);
else
glfwSwapInterval(0);
glfwSwapBuffers(glGlobals.window);
#else
not implemented
#endif
}
@@ -1512,7 +1525,10 @@ openSDL2(EngineOpenParams *openparams)
return 0;
}
makeVideoModeList(0);
glGlobals.currentDisplay = 0;
glGlobals.numDisplays = SDL_GetNumVideoDisplays();
makeVideoModeList(glGlobals.currentDisplay);
return 1;
}
@@ -1580,7 +1596,7 @@ startSDL2(void)
return 0;
}
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
// printf("OpenGL version: %s\n", glGetString(GL_VERSION));
glGlobals.window = win;
glGlobals.glcontext = ctx;
@@ -1599,7 +1615,178 @@ stopSDL2(void)
SDL_DestroyWindow(glGlobals.window);
return 1;
}
#else
#elif defined(LIBRW_SDL3)
static void
addVideoMode(const SDL_DisplayMode *mode)
{
int i;
for(i = 1; i < glGlobals.numModes; i++){
if(glGlobals.modes[i].mode.w == mode->w &&
glGlobals.modes[i].mode.h == mode->h &&
glGlobals.modes[i].mode.format == mode->format){
// had this mode already, remember highest refresh rate
if(mode->refresh_rate > glGlobals.modes[i].mode.refresh_rate)
glGlobals.modes[i].mode.refresh_rate = mode->refresh_rate;
return;
}
}
// none found, add
glGlobals.modes[glGlobals.numModes].mode = *mode;
glGlobals.modes[glGlobals.numModes].flags = VIDEOMODEEXCLUSIVE;
glGlobals.numModes++;
}
static void
makeVideoModeList(SDL_DisplayID displayIndex, SDL_DisplayID *displays)
{
int i, num, depth;
const SDL_DisplayMode *currentMode;
SDL_DisplayMode **modes;
currentMode = SDL_GetCurrentDisplayMode(displays[displayIndex]);
modes = SDL_GetFullscreenDisplayModes(displays[displayIndex], &num);
rwFree(glGlobals.modes);
glGlobals.modes = rwNewT(DisplayMode, num+(currentMode != NULL ? 1 : 0), ID_DRIVER | MEMDUR_EVENT);
if (currentMode) {
glGlobals.modes[0].mode = *currentMode;
glGlobals.modes[0].flags = 0;
glGlobals.numModes = 1;
}
for(i = 0; i < num; i++)
addVideoMode(modes[i]);
for(i = 0; i < glGlobals.numModes; i++){
depth = SDL_BITSPERPIXEL(glGlobals.modes[i].mode.format);
// set depth to power of two
for(glGlobals.modes[i].depth = 1; glGlobals.modes[i].depth < depth; glGlobals.modes[i].depth <<= 1);
}
SDL_free(modes);
}
static int
openSDL3(EngineOpenParams *openparams)
{
glGlobals.winWidth = openparams->width;
glGlobals.winHeight = openparams->height;
glGlobals.winTitle = openparams->windowtitle;
glGlobals.pWindow = openparams->window;
memset(&gl3Caps, 0, sizeof(gl3Caps));
/* Init SDL */
if (!SDL_InitSubSystem(SDL_INIT_VIDEO)){
RWERROR((ERR_GENERAL, SDL_GetError()));
return 0;
}
glGlobals.currentDisplay = 0;
SDL_DisplayID *displays = SDL_GetDisplays(&glGlobals.numDisplays);
if (glGlobals.currentDisplay >= glGlobals.numDisplays) {
RWERROR((ERR_GENERAL, SDL_GetError()));
return 0;
}
makeVideoModeList(glGlobals.currentDisplay, displays);
SDL_free(displays);
return 1;
}
static int
closeSDL3(void)
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return 1;
}
static struct {
int gl;
int major, minor;
} profiles[] = {
{ SDL_GL_CONTEXT_PROFILE_CORE, 3, 3 },
{ SDL_GL_CONTEXT_PROFILE_CORE, 2, 1 },
{ SDL_GL_CONTEXT_PROFILE_ES, 3, 1 },
{ SDL_GL_CONTEXT_PROFILE_ES, 2, 0 },
{ 0, 0, 0 },
};
static int
startSDL3(void)
{
SDL_Window *win;
SDL_GLContext ctx;
DisplayMode *mode;
mode = &glGlobals.modes[glGlobals.currentMode];
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, glGlobals.numSamples);
int i;
for(i = 0; profiles[i].gl; i++){
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profiles[i].gl);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, profiles[i].major);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, profiles[i].minor);
if(mode->flags & VIDEOMODEEXCLUSIVE) {
win = SDL_CreateWindow(glGlobals.winTitle, mode->mode.w, mode->mode.h, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
// This is the recommended way for SDL3.
if (win) {
SDL_SetWindowFullscreenMode(win, &mode->mode);
SDL_SetWindowFullscreen(win, true);
}
} else {
win = SDL_CreateWindow(glGlobals.winTitle, glGlobals.winWidth, glGlobals.winHeight, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
if (win)
SDL_SetWindowFullscreenMode(win, NULL);
}
if(win){
gl3Caps.gles = profiles[i].gl == SDL_GL_CONTEXT_PROFILE_ES;
gl3Caps.glversion = profiles[i].major*10 + profiles[i].minor;
break;
}
}
if(win == nil){
RWERROR((ERR_GENERAL, SDL_GetError()));
return 0;
}
ctx = SDL_GL_CreateContext(win);
if (!((gl3Caps.gles ? gladLoadGLES2Loader : gladLoadGLLoader) ((GLADloadproc) SDL_GL_GetProcAddress, gl3Caps.glversion)) ) {
RWERROR((ERR_GENERAL, "gladLoadGLLoader failed"));
SDL_GL_DestroyContext(ctx);
SDL_DestroyWindow(win);
return 0;
}
// printf("OpenGL version: %s\n", glGetString(GL_VERSION));
glGlobals.window = win;
glGlobals.glcontext = ctx;
*glGlobals.pWindow = win;
glGlobals.presentWidth = 0;
glGlobals.presentHeight = 0;
glGlobals.presentOffX = 0;
glGlobals.presentOffY = 0;
return 1;
}
static int
stopSDL3(void)
{
SDL_GL_DestroyContext(glGlobals.glcontext);
SDL_DestroyWindow(glGlobals.window);
return 1;
}
#elif defined(LIBRW_GLFW)
static void
addVideoMode(const GLFWvidmode *mode)
@@ -1626,16 +1813,16 @@ addVideoMode(const GLFWvidmode *mode)
}
static void
makeVideoModeList(void)
makeVideoModeList(GLFWmonitor *monitor)
{
int i, num;
const GLFWvidmode *modes;
modes = glfwGetVideoModes(glGlobals.monitor, &num);
modes = glfwGetVideoModes(monitor, &num);
rwFree(glGlobals.modes);
glGlobals.modes = rwNewT(DisplayMode, num+1, ID_DRIVER | MEMDUR_EVENT);
glGlobals.modes[0].mode = *glfwGetVideoMode(glGlobals.monitor);
glGlobals.modes[0].mode = *glfwGetVideoMode(monitor);
glGlobals.modes[0].flags = 0;
glGlobals.numModes = 1;
@@ -1669,7 +1856,7 @@ openGLFW(EngineOpenParams *openparams)
glGlobals.monitor = glfwGetMonitors(&glGlobals.numMonitors)[0];
makeVideoModeList();
makeVideoModeList(glGlobals.monitor);
return 1;
}
@@ -1746,7 +1933,7 @@ startGLFW(void)
return 0;
}
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
// printf("OpenGL version: %s\n", glGetString(GL_VERSION));
glGlobals.window = win;
*glGlobals.pWindow = win;
@@ -1763,6 +1950,8 @@ stopGLFW(void)
glfwDestroyWindow(glGlobals.window);
return 1;
}
#else
not implemented
#endif
static int
@@ -1939,7 +2128,27 @@ deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
case DEVICEFINALIZE:
return finalizeOpenGL();
// TODO: implement subsystems
case DEVICEGETNUMSUBSYSTEMS:
return glGlobals.numDisplays;
case DEVICEGETCURRENTSUBSYSTEM:
return glGlobals.currentDisplay;
case DEVICESETSUBSYSTEM:
if (n >= SDL_GetNumVideoDisplays())
return 0;
glGlobals.currentDisplay = n;
return 1;
case DEVICEGETSUBSSYSTEMINFO: {
const char *display_name = SDL_GetDisplayName(n);
if (display_name == nil)
return 0;
strncpy(((SubSystemInfo*)arg)->name, display_name, sizeof(SubSystemInfo::name));
return 1;
}
case DEVICEGETNUMVIDEOMODES:
return glGlobals.numModes;
@@ -1983,7 +2192,94 @@ deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
return 1;
}
#else
#elif defined(LIBRW_SDL3)
static int
deviceSystemSDL3(DeviceReq req, void *arg, int32 n)
{
VideoMode *rwmode;
switch(req){
case DEVICEOPEN:
return openSDL3((EngineOpenParams*)arg);
case DEVICECLOSE:
return closeSDL3();
case DEVICEINIT:
return startSDL3() && initOpenGL();
case DEVICETERM:
return termOpenGL() && stopSDL3();
case DEVICEFINALIZE:
return finalizeOpenGL();
case DEVICEGETNUMSUBSYSTEMS:
return glGlobals.numDisplays;
case DEVICEGETCURRENTSUBSYSTEM:
return glGlobals.currentDisplay;
case DEVICESETSUBSYSTEM:
if (n >= glGlobals.numDisplays)
return 0;
glGlobals.currentDisplay = n;
return 1;
case DEVICEGETSUBSSYSTEMINFO: {
const char *display_name = SDL_GetDisplayName(n);
if (display_name == nil)
return 0;
strncpy(((SubSystemInfo*)arg)->name, display_name, sizeof(SubSystemInfo::name));
return 1;
}
case DEVICEGETNUMVIDEOMODES:
return glGlobals.numModes;
case DEVICEGETCURRENTVIDEOMODE:
return glGlobals.currentMode;
case DEVICESETVIDEOMODE:
if(n >= glGlobals.numModes)
return 0;
glGlobals.currentMode = n;
return 1;
case DEVICEGETVIDEOMODEINFO:
if (n < 0)
return 0;
rwmode = (VideoMode*)arg;
rwmode->width = glGlobals.modes[n].mode.w;
rwmode->height = glGlobals.modes[n].mode.h;
rwmode->depth = glGlobals.modes[n].depth;
rwmode->flags = glGlobals.modes[n].flags;
return 1;
case DEVICEGETMAXMULTISAMPLINGLEVELS:
{
GLint maxSamples;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
if(maxSamples == 0)
return 1;
return maxSamples;
}
case DEVICEGETMULTISAMPLINGLEVELS:
if(glGlobals.numSamples == 0)
return 1;
return glGlobals.numSamples;
case DEVICESETMULTISAMPLINGLEVELS:
glGlobals.numSamples = (uint32)n;
return 1;
default:
assert(0 && "not implemented");
return 0;
}
return 1;
}
#elif defined(LIBRW_GLFW)
static int
deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
@@ -2070,6 +2366,10 @@ deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
return 1;
}
#else
not implemented
#endif
Device renderdevice = {
@@ -2091,8 +2391,12 @@ Device renderdevice = {
gl3::im3DEnd,
#ifdef LIBRW_SDL2
gl3::deviceSystemSDL2
#else
#elif defined(LIBRW_SDL3)
gl3::deviceSystemSDL3
#elif defined(LIBRW_GLFW)
gl3::deviceSystemGLFW
#else
not implemented
#endif
};
+16 -5
View File
@@ -193,9 +193,11 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
static Shader *im3dShader;
static AttribDesc im3dattribDesc[3] = {
static AttribDesc im3dattribDesc[4] = {
{ ATTRIB_POS, GL_FLOAT, GL_FALSE, 3,
sizeof(Im3DVertex), 0 },
{ ATTRIB_NORMAL, GL_FLOAT, GL_FALSE, 3,
sizeof(Im3DVertex), offsetof(Im3DVertex, normal) },
{ ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
sizeof(Im3DVertex), offsetof(Im3DVertex, r) },
{ ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
@@ -228,7 +230,7 @@ openIm3D(void)
#ifdef RW_GL_USE_VAOS
glGenVertexArrays(1, &im3DVao);
glBindVertexArray(im3DVao);
setAttribPointers(im3dattribDesc, 3);
setAttribPointers(im3dattribDesc, 4);
#endif
}
@@ -244,6 +246,10 @@ closeIm3D(void)
im3dShader = nil;
}
// settable by user - TOOD: make this less shit
RGBA im3dMaterialColor = { 255, 255, 255, 255 };
SurfaceProperties im3dSurfaceProps = { 1.0f, 1.0f, 1.0f };
void
im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
{
@@ -253,7 +259,12 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
world = &ident;
}
setWorldMatrix(world);
im3dShader->use();
if(flags & im3d::LIGHTING){
setMaterial(im3dMaterialColor, im3dSurfaceProps);
int32 vsBits = lightingCB();
defaultShader_fullLight->use();
}else
im3dShader->use();
if((flags & im3d::VERTEXUV) == 0)
SetRenderStatePtr(TEXTURERASTER, nil);
@@ -266,7 +277,7 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im3DVertex), nil, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im3DVertex), vertices);
#ifndef RW_GL_USE_VAOS
setAttribPointers(im3dattribDesc, 3);
setAttribPointers(im3dattribDesc, 4);
#endif
num3DVertices = numVertices;
}
@@ -296,7 +307,7 @@ void
im3DEnd(void)
{
#ifndef RW_GL_USE_VAOS
disableAttribPointers(im3dattribDesc, 3);
disableAttribPointers(im3dattribDesc, 4);
#endif
}
+19 -10
View File
@@ -121,20 +121,29 @@ lightingCB(Atomic *atomic)
lightData.locals = locals;
lightData.numLocals = 8;
if(atomic->geometry->flags & rw::Geometry::LIGHT){
if(atomic->geometry->flags & rw::Geometry::LIGHT)
((World*)engine->currentWorld)->enumerateLights(atomic, &lightData);
if((atomic->geometry->flags & rw::Geometry::NORMALS) == 0){
// Get rid of lights that need normals when we don't have any
lightData.numDirectionals = 0;
lightData.numLocals = 0;
}
return setLights(&lightData);
}else{
else
memset(&lightData, 0, sizeof(lightData));
return setLights(&lightData);
}
return setLights(&lightData);
}
int32
lightingCB(void)
{
WorldLights lightData;
Light *directionals[8];
Light *locals[8];
lightData.directionals = directionals;
lightData.numDirectionals = 8;
lightData.locals = locals;
lightData.numLocals = 8;
((World*)engine->currentWorld)->enumerateLights(&lightData);
return setLights(&lightData);
}
void
defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
{
+8
View File
@@ -45,6 +45,8 @@ registerUniform(const char *name, UniformType type, int32 num)
{
int i;
i = findUniform(name);
if(type == UNIFORM_NA)
num = 0;
if(i >= 0){
Uniform *u = &uniformRegistry.uniforms[i];
assert(u->type == type);
@@ -222,6 +224,12 @@ linkprogram(GLint vs, GLint fs, GLuint *program)
glBindAttribLocation(prog, ATTRIB_INDICES, "in_indices");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS0, "in_tex0");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS1, "in_tex1");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS2, "in_tex2");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS3, "in_tex3");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS4, "in_tex4");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS5, "in_tex5");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS6, "in_tex6");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS7, "in_tex7");
}
glAttachShader(prog, vs);
+21 -2
View File
@@ -2,8 +2,12 @@
#include "glad/glad.h"
#ifdef LIBRW_SDL2
#include <SDL.h>
#else
#elif defined(LIBRW_SDL3)
#include <SDL3/SDL.h>
#elif defined(LIBRW_GLFW)
#include <GLFW/glfw3.h>
#else
not implemented
#endif
#endif
@@ -15,8 +19,13 @@ struct EngineOpenParams
#ifdef LIBRW_SDL2
SDL_Window **window;
bool32 fullscreen;
#else
#elif defined(LIBRW_SDL3)
SDL_Window **window;
bool32 fullscreen;
#elif defined(LIBRW_GLFW)
GLFWwindow **window;
#else
not implemented
#endif
int width, height;
const char *windowtitle;
@@ -103,12 +112,16 @@ extern Shader *defaultShader_fullLight, *defaultShader_fullLight_noAT;
struct Im3DVertex
{
V3d position;
V3d normal; // librw extension
uint8 r, g, b, a;
float32 u, v;
void setX(float32 x) { this->position.x = x; }
void setY(float32 y) { this->position.y = y; }
void setZ(float32 z) { this->position.z = z; }
void setNormalX(float32 x) { this->normal.x = x; }
void setNormalY(float32 y) { this->normal.y = y; }
void setNormalZ(float32 z) { this->normal.z = z; }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) {
this->r = r; this->g = g; this->b = b; this->a = a; }
void setU(float32 u) { this->u = u; }
@@ -117,10 +130,15 @@ struct Im3DVertex
float getX(void) { return this->position.x; }
float getY(void) { return this->position.y; }
float getZ(void) { return this->position.z; }
float getNormalX(void) { return this->normal.x; }
float getNormalY(void) { return this->normal.y; }
float getNormalZ(void) { return this->normal.z; }
RGBA getColor(void) { return makeRGBA(this->r, this->g, this->b, this->a); }
float getU(void) { return this->u; }
float getV(void) { return this->v; }
};
extern RGBA im3dMaterialColor;
extern SurfaceProperties im3dSurfaceProps;
struct Im2DVertex
{
@@ -221,6 +239,7 @@ void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinsta
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
int32 lightingCB(Atomic *atomic);
int32 lightingCB(void);
void drawInst_simple(InstanceDataHeader *header, InstanceData *inst);
// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer
+18 -2
View File
@@ -26,8 +26,12 @@ struct DisplayMode
{
#ifdef LIBRW_SDL2
SDL_DisplayMode mode;
#else
#elif defined(LIBRW_SDL3)
SDL_DisplayMode mode;
#elif defined(LIBRW_GLFW)
GLFWvidmode mode;
#else
not implemented
#endif
int32 depth;
uint32 flags;
@@ -39,13 +43,25 @@ struct GlGlobals
SDL_Window **pWindow;
SDL_Window *window;
SDL_GLContext glcontext;
#else
int numDisplays;
int currentDisplay;
#elif defined(LIBRW_SDL3)
SDL_Window **pWindow;
SDL_Window *window;
SDL_GLContext glcontext;
int numDisplays;
int currentDisplay;
#elif defined(LIBRW_GLFW)
GLFWwindow **pWindow;
GLFWwindow *window;
GLFWmonitor *monitor;
int numMonitors;
int currentMonitor;
#else
not implemented
#endif
DisplayMode *modes;
+1 -2
View File
@@ -8,8 +8,7 @@ void
main(void)
{
vec4 Vertex = u_world * vec4(in_pos, 1.0);
vec4 CamVertex = u_view * Vertex;
gl_Position = u_proj * CamVertex;
gl_Position = u_proj * u_view * Vertex;
v_color = in_color;
v_tex0 = in_tex0;
v_fog = DoFog(gl_Position.w);
+1 -2
View File
@@ -9,8 +9,7 @@ const char *im3d_vert_src =
"main(void)\n"
"{\n"
" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n"
" vec4 CamVertex = u_view * Vertex;\n"
" gl_Position = u_proj * CamVertex;\n"
" gl_Position = u_proj * u_view * Vertex;\n"
" v_color = in_color;\n"
" v_tex0 = in_tex0;\n"
" v_fog = DoFog(gl_Position.w);\n"
-1
View File
@@ -12,4 +12,3 @@ main(void)
DoAlphaTest(color.a);
FRAGCOLOR(color);
}
+7 -7
View File
@@ -931,16 +931,16 @@ char*
Image::getFilename(const char *name)
{
ImageGlobals *g = PLUGINOFFSET(ImageGlobals, engine, imageModuleOffset);
FILE *f;
void *f;
char *s, *p = g->searchPaths;
size_t len = strlen(name)+1;
if(g->numSearchPaths == 0){
s = rwStrdup(name, MEMDUR_EVENT);
makePath(s);
f = fopen(s, "rb");
f = engine->filefuncs.rwfopen(s, "rb");
if(f){
fclose(f);
printf("found %s\n", s);
engine->filefuncs.rwfclose(f);
// printf("found %s\n", s);
return s;
}
rwFree(s);
@@ -955,10 +955,10 @@ Image::getFilename(const char *name)
strcpy(s, p);
strcat(s, name);
makePath(s);
f = fopen(s, "r");
f = engine->filefuncs.rwfopen(s, "r");
if(f){
fclose(f);
printf("found %s\n", name);
engine->filefuncs.rwfclose(f);
// printf("found %s\n", name);
return s;
}
rwFree(s);
+2 -2
View File
@@ -185,8 +185,8 @@ PluginList::registerPlugin(int32 size, uint32 id,
p->rightsCallback = nil;
p->alwaysCallback = nil;
p->parentList = this;
this->plugins.add(&p->inParentList);
allPlugins.add(&p->inGlobalList);
this->plugins.append(&p->inParentList);
allPlugins.append(&p->inGlobalList);
return p->offset;
}
+16 -6
View File
@@ -21,6 +21,8 @@
namespace rw {
namespace ps2 {
bool adcHack = false;
#define ALIGNPTR(p,a) ((uint8*)(((uintptr)(p)+a-1) & ~(uintptr)(a-1)))
static void*
@@ -706,13 +708,21 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
for(uint i = 0; i < nelem(this->attribs); i++)
if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){
if(rw::version >= 0x35000)
*p++ = VIF_NOP;
else
*p++ = VIF_MARK | markcnt++;
*p++ = VIF_STMOD;
uint32 mask;
if(adcHack && a == &attribXYZ){
*p++ = VIF_STMASK;
*p++ = 1 << 6; // write w field with VIF1_R3
mask = 0x10000000;
}else{
if(rw::version >= 0x35000)
*p++ = VIF_NOP;
else
*p++ = VIF_MARK | markcnt++;
*p++ = VIF_STMOD;
mask = 0x00000000;
}
*p++ = VIF_STCYCL1 | this->inputStride;
*p++ = (a->attrib&0xFF004000)
*p++ = (a->attrib&0xFF004000) | mask
| 0x8000 | nverts << 16 | i; // UNPACK
if(a == &attribXYZ)
+4 -4
View File
@@ -1219,7 +1219,7 @@ rasterCreateTexture(Raster *raster)
// this obviously only works with 32 bit pointers, but it's only needed on the PS2 anyway
*xferchain++ = (uint32)(uintptr)p - 0x50;
*xferchain++ = 0; // VIF nop
*xferchain++ = 0x50000000 | sz+5; // VIF DIRECT 2 qwords
*xferchain++ = 0x50000000 | sz+5; // VIF DIRECT
}else{
// Add to existing transfer
xferchain[-4] = 0x30000000 | (xferchain[-4]&0xFFFF) + sz+5; // last DMAref
@@ -1243,7 +1243,7 @@ rasterCreateTexture(Raster *raster)
*p++ = 0;
// TRXPOS
*(uint64*)p = paltrxpos;
*(uint64*)p = (uint64)paltrxpos<<32;
p += 2;
*p++ = 0x51;
*p++ = 0;
@@ -1291,10 +1291,10 @@ rasterCreateTexture(Raster *raster)
xferchain[1] = xferchain[-15];
xferchain[2] = xferchain[-14];
xferchain[3] = xferchain[-13];
xferchain += 4;
// Add to last transfer
xferchain[-16] = 0x30000000 | (xferchain[-16]&0xFFFF) + sz+5; // last DMAref
xferchain[-13] = 0x50000000 | (xferchain[-13]&0xFFFF) + sz+5; // last DIRECT
xferchain += 4;
pp->numTransfers--;
}
@@ -1302,7 +1302,7 @@ rasterCreateTexture(Raster *raster)
// this obviously only works with 32 bit pointers, but it's only needed on the PS2 anyway
*xferchain++ = (uint32)(uintptr)p - 0x50;
*xferchain++ = 0; // VIF nop
*xferchain++ = 0x50000000 | sz+5; // VIF DIRECT 2 qwords
*xferchain++ = 0x50000000 | sz+5; // VIF DIRECT
}
}
raster->originalPixels = raster->pixels;
+24 -1
View File
@@ -15,8 +15,8 @@ extern Device renderdevice;
struct Im2DVertex
{
float32 x, y, z, w;
uint32 r, g, b, a;
float32 u, v, q, PAD;
uint32 r, g, b, a;
void setScreenX(float32 x) { this->x = x; }
void setScreenY(float32 y) { this->y = y; }
@@ -38,6 +38,28 @@ struct Im2DVertex
float getV(void) { return this->v; }
};
struct Im3DVertex
{
V3d position;
uint8 r, g, b, a;
float32 u, v;
void setX(float32 x) { this->position.x = x; }
void setY(float32 y) { this->position.y = y; }
void setZ(float32 z) { this->position.z = z; }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) {
this->r = r; this->g = g; this->b = b; this->a = a; }
void setU(float32 u) { this->u = u; }
void setV(float32 v) { this->v = v; }
float getX(void) { return this->position.x; }
float getY(void) { return this->position.y; }
float getZ(void) { return this->position.z; }
RGBA getColor(void) { return makeRGBA(this->r, this->g, this->b, this->a); }
float getU(void) { return this->u; }
float getV(void) { return this->v; }
};
struct InstanceData
{
@@ -99,6 +121,7 @@ struct PipeAttribute
uint32 attrib;
};
extern bool adcHack; // use MASK write to initialize ADC field in vertex cluster
extern PipeAttribute attribXYZ;
extern PipeAttribute attribXYZW;
extern PipeAttribute attribUV;
+12 -9
View File
@@ -70,9 +70,13 @@ typedef int32 bool32;
typedef uint8 byte;
typedef uint32 uint;
#ifndef nil
#define nil NULL
#endif
#ifndef nelem
#define nelem(A) (sizeof(A) / sizeof A[0])
#endif
#ifdef __GNUC__
#define RWALIGN(n) __attribute__ ((aligned (n)))
@@ -151,7 +155,7 @@ struct RGBA
uint8 blue;
uint8 alpha;
};
inline RGBA makeRGBA(uint8 r, uint8 g, uint8 b, uint8 a) { RGBA c = { r, g, b, a }; return c; }
inline RGBA makeRGBA(uint8 r, uint8 g, uint8 b, uint8 a) { RGBA c; c.red = r; c.green = g; c.blue = b; c.alpha = a; return c; }
inline bool32 equal(const RGBA &c1, const RGBA &c2) { return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue && c1.alpha == c2.alpha; }
#define RWRGBAINT(r, g, b, a) ((uint32)((((a)&0xff)<<24)|(((b)&0xff)<<16)|(((g)&0xff)<<8)|((r)&0xff)))
@@ -162,7 +166,7 @@ struct RGBAf
float32 blue;
float32 alpha;
};
inline RGBAf makeRGBAf(float32 r, float32 g, float32 b, float32 a) { RGBAf c = { r, g, b, a }; return c; }
inline RGBAf makeRGBAf(float32 r, float32 g, float32 b, float32 a) { RGBAf c; c.red = r; c.green = g; c.blue = b; c.alpha = a; return c; }
inline bool32 equal(const RGBAf &c1, const RGBAf &c2) { return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue && c1.alpha == c2.alpha; }
inline RGBAf add(const RGBAf &a, const RGBAf &b) { return makeRGBAf(a.red+b.red, a.green+b.green, a.blue+b.blue, a.alpha+b.alpha); }
inline RGBAf modulate(const RGBAf &a, const RGBAf &b) { return makeRGBAf(a.red*b.red, a.green*b.green, a.blue*b.blue, a.alpha*b.alpha); }
@@ -215,7 +219,7 @@ struct V2d
this->x = x; this->y = y; }
};
inline V2d makeV2d(float32 x, float32 y) { V2d v = { x, y }; return v; }
inline V2d makeV2d(float32 x, float32 y) { V2d v; v.x = x; v.y = y; return v; }
inline bool32 equal(const V2d &v1, const V2d &v2) { return v1.x == v2.x && v1.y == v2.y; }
inline V2d neg(const V2d &a) { return makeV2d(-a.x, -a.y); }
inline V2d add(const V2d &a, const V2d &b) { return makeV2d(a.x+b.x, a.y+b.y); }
@@ -233,7 +237,7 @@ struct V3d
static void transformVectors(V3d *out, const V3d *in, int32 n, const Matrix *m);
};
inline V3d makeV3d(float32 x, float32 y, float32 z) { V3d v = { x, y, z }; return v; }
inline V3d makeV3d(float32 x, float32 y, float32 z) { V3d v; v.x = x; v.y = y; v.z = z; return v; }
inline bool32 equal(const V3d &v1, const V3d &v2) { return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z; }
inline V3d neg(const V3d &a) { return makeV3d(-a.x, -a.y, -a.z); }
inline V3d add(const V3d &a, const V3d &b) { return makeV3d(a.x+b.x, a.y+b.y, a.z+b.z); }
@@ -281,8 +285,8 @@ struct Quat
Quat *rotate(const V3d *axis, float32 angle, CombineOp op = rw::COMBINEPOSTCONCAT);
};
inline Quat makeQuat(float32 w, float32 x, float32 y, float32 z) { Quat q = { x, y, z, w }; return q; }
inline Quat makeQuat(float32 w, const V3d &vec) { Quat q = { vec.x, vec.y, vec.z, w }; return q; }
inline Quat makeQuat(float32 w, float32 x, float32 y, float32 z) { Quat q; q.x = x; q.y = y; q.z = z; q.w = w; return q; }
inline Quat makeQuat(float32 w, const V3d &vec) { return makeQuat(w, vec.x, vec.y, vec.z); }
inline Quat add(const Quat &q, const Quat &p) { return makeQuat(q.w+p.w, q.x+p.x, q.y+p.y, q.z+p.z); }
inline Quat sub(const Quat &q, const Quat &p) { return makeQuat(q.w-p.w, q.x-p.x, q.y-p.y, q.z-p.z); }
inline Quat negate(const Quat &q) { return makeQuat(-q.w, -q.x, -q.y, -q.z); }
@@ -343,7 +347,7 @@ struct Matrix
void destroy(void);
void setIdentity(void);
void optimize(Tolerance *tolerance = nil);
void update(void) { flags &= ~(IDENTITY|TYPEMASK); }
void update(void) { flags &= ~(int(IDENTITY) | int(TYPEMASK)); }
static Matrix *mult(Matrix *dst, const Matrix *src1, const Matrix *src2);
static Matrix *invert(Matrix *dst, const Matrix *src);
static Matrix *transpose(Matrix *dst, const Matrix *src);
@@ -510,8 +514,7 @@ public:
class StreamFile : public Stream
{
public:
FILE *file;
void *file;
StreamFile(void) { file = nil; }
void close(void);
uint32 write8(const void *data, uint32 length);
+12
View File
@@ -121,6 +121,17 @@ struct MemoryFunctions
void *(*rwmustrealloc)(void *p, size_t sz, uint32 hint);
};
struct FileFunctions
{
void *(*rwfopen)(const char *path, const char *mode);
int (*rwfclose)(void *fp);
int (*rwfseek)(void *fp, long offset, int whence);
long (*rwftell)(void *fp);
size_t (*rwfread)(void *ptr, size_t size, size_t nmemb, void *fp);
size_t (*rwfwrite)(const void *ptr, size_t size, size_t nmemb, void *fp);
int (*rwfeof)(void *fp);
};
struct SubSystemInfo
{
char name[80];
@@ -155,6 +166,7 @@ struct Engine
Camera *currentCamera;
World *currentWorld;
LinkList frameDirtyList;
FileFunctions filefuncs;
// Dynamically allocated because of plugins
Driver *driver[NUM_PLATFORMS];
+2
View File
@@ -71,6 +71,7 @@ struct Frame
return !!(this->root->object.privateFlags & HIERARCHYSYNC); }
Matrix *getLTM(void);
void rotate(const V3d *axis, float32 angle, CombineOp op = rw::COMBINEPOSTCONCAT);
void rotate(const Quat *q, CombineOp op = rw::COMBINEPOSTCONCAT);
void translate(const V3d *trans, CombineOp op = rw::COMBINEPOSTCONCAT);
void scale(const V3d *scale, CombineOp op = rw::COMBINEPOSTCONCAT);
void transform(const Matrix *mat, CombineOp op = rw::COMBINEPOSTCONCAT);
@@ -872,6 +873,7 @@ struct World
void removeClump(Clump *clump);
void render(void);
void enumerateLights(Atomic *atomic, WorldLights *lightData);
void enumerateLights(WorldLights *lightData);
};
struct TexDictionary
+1
View File
@@ -123,6 +123,7 @@ enum TransformFlags
NOCLIP = 4, // don't frustum clip
VERTEXXYZ = 8, // has position
VERTEXRGBA = 16, // has color
LIGHTING = 32, // do lighting, assumes normals (librw extension)
EVERYTHING = VERTEXUV|VERTEXXYZ|VERTEXRGBA
};
+1 -1
View File
@@ -73,7 +73,7 @@ textureClose(void *object, int32 offset, int32 size)
FORLIST(lnk, TEXTUREGLOBAL(textures)){
Texture *tex = LLLinkGetData(lnk, Texture, inGlobalList);
printf("Tex still allocated: %d %s %s\n", tex->refCount, tex->name, tex->mask);
// printf("Tex still allocated: %d %s %s\n", tex->refCount, tex->name, tex->mask);
assert(tex->dict == nil);
tex->destroy();
}
+40
View File
@@ -195,4 +195,44 @@ World::enumerateLights(Atomic *atomic, WorldLights *lightData)
}
}
// Find all lights, for im3d lighting extension
// missing flags and bounding spheres so more primitive than above
void
World::enumerateLights(WorldLights *lightData)
{
int32 maxDirectionals, maxLocals;
maxDirectionals = lightData->numDirectionals;
maxLocals = lightData->numLocals;
lightData->numDirectionals = 0;
lightData->numLocals = 0;
lightData->numAmbients = 0;
lightData->ambient.red = 0.0f;
lightData->ambient.green = 0.0f;
lightData->ambient.blue = 0.0f;
lightData->ambient.alpha = 1.0f;
FORLIST(lnk, this->globalLights){
Light *l = Light::fromWorld(lnk);
if(l->getType() == Light::AMBIENT){
lightData->ambient.red += l->color.red;
lightData->ambient.green += l->color.green;
lightData->ambient.blue += l->color.blue;
lightData->numAmbients++;
}else if(l->getType() == Light::DIRECTIONAL){
if(lightData->numDirectionals < maxDirectionals)
lightData->directionals[lightData->numDirectionals++] = l;
}
}
FORLIST(lnk, this->localLights){
if(lightData->numLocals >= maxLocals)
return;
Light *l = Light::fromWorld(lnk);
lightData->locals[lightData->numLocals++] = l;
}
}
}
+4
View File
@@ -7,6 +7,10 @@ target_link_libraries(dumprwtree
librw::librw
)
if(LIBRW_GL3_GFXLIB MATCHES "SDL[23]")
target_compile_definitions(dumprwtree PRIVATE SDL_MAIN_HANDLED)
endif()
if(LIBRW_INSTALL)
install(TARGETS dumprwtree
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+469
View File
@@ -0,0 +1,469 @@
#include <rw.h>
#include <skeleton.h>
#include <assert.h>
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
struct SceneGlobals {
rw::World *world;
rw::Camera *camera;
} Scene;
rw::EngineOpenParams engineOpenParams;
rw::Texture *ParticleTex;
rw::Raster *ParticleRaster;
static rw::RWDEVICE::Im2DVertex im2dVerts[1024];
static int numImVerts;
static rw::uint16 imIndices[1024*2];
static int numImIndices;
static rw::PrimitiveType imPrim;
void
BeginIm2D(rw::PrimitiveType prim)
{
numImVerts = 0;
numImIndices = 0;
imPrim = prim;
}
void
EndIm2D(void)
{
rw::im2d::RenderIndexedPrimitive(imPrim, &im2dVerts, numImVerts, &imIndices, numImIndices);
}
void
RenderParticle(float x, float y, float sz, rw::RGBA col)
{
using namespace rw;
using namespace RWDEVICE;
if(numImVerts+4 > nelem(im2dVerts) ||
numImIndices+6 > nelem(imIndices)){
EndIm2D();
numImVerts = 0;
numImIndices = 0;
}
float recipZ = 1.0f/Scene.camera->nearPlane;
rw::RWDEVICE::Im2DVertex *verts = &im2dVerts[numImVerts];
x += sk::globals.width/2;
y += sk::globals.height/2;
verts[0].setScreenX(x-sz);
verts[0].setScreenY(y-sz);
verts[0].setScreenZ(rw::im2d::GetNearZ());
verts[0].setCameraZ(Scene.camera->nearPlane);
verts[0].setRecipCameraZ(recipZ);
verts[0].setColor(col.red, col.green, col.blue, col.alpha);
verts[0].setU(0.0f, recipZ);
verts[0].setV(0.0f, recipZ);
verts[1].setScreenX(x+sz);
verts[1].setScreenY(y-sz);
verts[1].setScreenZ(rw::im2d::GetNearZ());
verts[1].setCameraZ(Scene.camera->nearPlane);
verts[1].setRecipCameraZ(recipZ);
verts[1].setColor(col.red, col.green, col.blue, col.alpha);
verts[1].setU(1.0f, recipZ);
verts[1].setV(0.0f, recipZ);
verts[2].setScreenX(x+sz);
verts[2].setScreenY(y+sz);
verts[2].setScreenZ(rw::im2d::GetNearZ());
verts[2].setCameraZ(Scene.camera->nearPlane);
verts[2].setRecipCameraZ(recipZ);
verts[2].setColor(col.red, col.green, col.blue, col.alpha);
verts[2].setU(1.0f, recipZ);
verts[2].setV(1.0f, recipZ);
verts[3].setScreenX(x-sz);
verts[3].setScreenY(y+sz);
verts[3].setScreenZ(rw::im2d::GetNearZ());
verts[3].setCameraZ(Scene.camera->nearPlane);
verts[3].setRecipCameraZ(recipZ);
verts[3].setColor(col.red, col.green, col.blue, col.alpha);
verts[3].setU(0.0f, recipZ);
verts[3].setV(1.0f, recipZ);
imIndices[numImIndices+0] = numImVerts+0;
imIndices[numImIndices+1] = numImVerts+1;
imIndices[numImIndices+2] = numImVerts+2;
imIndices[numImIndices+3] = numImVerts+0;
imIndices[numImIndices+4] = numImVerts+2;
imIndices[numImIndices+5] = numImVerts+3;
numImVerts += 4;
numImIndices += 6;
}
float sgn(float f) { return f < 0.0f ? -1.0f : f > 0.0f ? 1.0f : 0.0f; }
struct Orbit
{
ImVec4 color;
float StartX;
float StartY;
float PointSz;
int numIterations;
bool used;
};
Orbit orbits[100];
int curOrbit = 0;
float A = 0.0f;
float B = 0.0f;
float C = 0.0f;
float D = 0.0f;
float E = 0.0f;
float Exp = 0.25f;
float Scale = 50.0f;
int type;
bool textured = true;
bool animateX;
bool animateY;
bool animateA;
bool animateB;
bool animateC;
void
ResetOrbit(Orbit *o)
{
o->color = ImVec4(1.0f, 0.0f, 0.0f, 1.00f);
o->StartX = 1.0f;
o->StartY = 0.0f;
o->PointSz = 3.0f;
o->numIterations = 1000;
o->used = false;
}
void
RenderOrbit(Orbit *o)
{
rw::RGBA red = { 0xFF, 0, 0, 0xFF };
rw::RGBA color = rw::makeRGBA(o->color.x*255, o->color.y*255, o->color.z*255, o->color.w*255);
float x1, y1;
float x0 = o->StartX;
float y0 = o->StartY;
int n = o->numIterations;
if(textured){
rw::SetRenderStatePtr(rw::TEXTURERASTER, ParticleRaster);
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::LINEAR);
}else
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
BeginIm2D(rw::PRIMTYPETRILIST);
while(n--){
switch(type){
case 0:
default:
x1 = y0 - sgn(x0)*(D + sqrtf(fabs(B*x0 - C)));
break;
case 1:
x1 = y0 - sgn(x0)*(D + powf(fabs(B*x0 - C), Exp));
break;
case 2:
x1 = y0 - sgn(x0)*(D + logf(2.0f + sqrtf(fabs(B*x0 - C))));
break;
}
y1 = A - x0;
x1 += E;
RenderParticle(x1*Scale, y1*Scale, o->PointSz, color);
x0 = x1;
y0 = y1;
}
EndIm2D();
}
void
RenderHopalong(void)
{
int i;
for(i = 0; i < nelem(orbits); i++)
if(orbits[i].used)
RenderOrbit(&orbits[i]);
}
void
Init(void)
{
sk::globals.windowtitle = "Hopalong map";
sk::globals.width = 1280;
sk::globals.height = 800;
sk::globals.quit = 0;
}
bool
attachPlugins(void)
{
rw::ps2::registerPDSPlugin(40);
rw::ps2::registerPluginPDSPipes();
rw::registerMeshPlugin();
rw::registerNativeDataPlugin();
rw::registerAtomicRightsPlugin();
rw::registerMaterialRightsPlugin();
rw::xbox::registerVertexFormatPlugin();
rw::registerSkinPlugin();
rw::registerUserDataPlugin();
rw::registerHAnimPlugin();
rw::registerMatFXPlugin();
rw::registerUVAnimPlugin();
rw::ps2::registerADCPlugin();
return true;
}
#include "particle.inc"
#include "vfs.h"
VFS_file files[] = {
{ "particle.png", particle_png, particle_png_len }
};
VFS vfs = {
files, nelem(files)
};
bool
InitRW(void)
{
if(!sk::InitRW())
return false;
installVFS(&vfs);
Scene.world = rw::World::create();
ParticleTex = rw::Texture::read("particle", nil);
if(ParticleTex)
ParticleRaster = ParticleTex->raster;
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
ambient->setColor(0.2f, 0.2f, 0.2f);
Scene.world->addLight(ambient);
rw::V3d xaxis = { 1.0f, 0.0f, 0.0f };
rw::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
direct->setColor(0.8f, 0.8f, 0.8f);
direct->setFrame(rw::Frame::create());
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
Scene.world->addLight(direct);
Scene.camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
Scene.world->addCamera(Scene.camera);
for(int i = 0; i < nelem(orbits); i++)
ResetOrbit(&orbits[i]);
orbits[0].used = true;
ImGui_ImplRW_Init();
ImGui::StyleColorsClassic();
return true;
}
void
orbitGUI(Orbit *o)
{
ImGui::SliderFloat("x0", &o->StartX, -10.0f, 10.0f);
ImGui::SliderFloat("y0", &o->StartY, -10.0f, 10.0f);
ImGui::SliderFloat("Point Size", &o->PointSz, 0.5f, 10.0f);
ImGui::SliderInt("NumPoints", &o->numIterations, 1, 10000);
ImGui::ColorEdit3("color", (float*)&o->color);
/*
ImGui::Checkbox("Textured", &textured);
ImGui::Checkbox("AnimateX", &animateX);
ImGui::Checkbox("AnimateY", &animateY);
ImGui::Checkbox("AnimateA", &animateA);
ImGui::Checkbox("AnimateB", &animateB);
ImGui::Checkbox("AnimateC", &animateC);
*/
}
void
hopalongGUI(void)
{
int i;
static char tmp[128];
if(curOrbit >= 0)
orbitGUI(&orbits[curOrbit]);
ImGui::SliderFloat("A", &A, -10.0f, 10.0f);
ImGui::SliderFloat("B", &B, -10.0f, 10.0f);
ImGui::SliderFloat("C", &C, -10.0f, 10.0f);
ImGui::SliderFloat("D", &D, -10.0f, 10.0f);
ImGui::SliderFloat("E", &E, -10.0f, 10.0f);
ImGui::SliderFloat("exp", &Exp, 0.001f, 4.0f);
ImGui::RadioButton("sqrt", &type, 0);
ImGui::RadioButton("^exp", &type, 1);
ImGui::RadioButton("log", &type, 2);
ImGui::SliderFloat("Scale", &Scale, 1.0f, 100.0f);
for(i = 0; i < nelem(orbits); i++){
if(orbits[i].used){
sprintf(tmp, "Orbit %d\n", i);
if(ImGui::Button(tmp))
curOrbit = i;
}
}
if( ImGui::Button("Add Orbit"))
for(i = 0; i < nelem(orbits); i++)
if(!orbits[i].used){
ResetOrbit(&orbits[i]);
orbits[i].used = true;
curOrbit = i;
break;
}
if(curOrbit >= 0 && ImGui::Button("Remove Orbit")){
orbits[curOrbit].used = false;
curOrbit = -1;
for(i = 0; i < nelem(orbits); i++)
if(orbits[i].used){
curOrbit = i;
break;
}
}
}
#ifdef __unix__
#include <unistd.h>
#endif
void
Draw(float timeDelta)
{
static bool show_demo_window = false;
rw::RGBA clearcol = { 0, 0, 0, 255 };
Scene.camera->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
Scene.camera->beginUpdate();
ImGui_ImplRW_NewFrame(timeDelta);
RenderHopalong();
/*
if(animateX) StartX += timeDelta/10000.0f;
if(animateY) StartY += timeDelta/10000.0f;
if(animateA) A += timeDelta/10000.0f;
if(animateB) B += timeDelta/10000.0f;
if(animateC) C += timeDelta/10000.0f;
*/
hopalongGUI();
if(show_demo_window){
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver);
ImGui::ShowDemoWindow(&show_demo_window);
}
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplRW_RenderDrawLists(ImGui::GetDrawData());
Scene.camera->endUpdate();
Scene.camera->showRaster(0);
#ifdef __unix__
usleep(10000);
#endif
}
void
KeyUp(int key)
{
}
void
KeyDown(int key)
{
switch(key){
case sk::KEY_ESC:
sk::globals.quit = 1;
break;
}
}
int MouseX, MouseY;
int MouseDeltaX, MouseDeltaY;
int MouseButtons;
void
MouseBtn(sk::MouseState *mouse)
{
MouseButtons = mouse->buttons;
}
void
MouseMove(sk::MouseState *mouse)
{
MouseDeltaX = mouse->posx - MouseX;
MouseDeltaY = mouse->posy - MouseY;
MouseX = mouse->posx;
MouseY = mouse->posy;
if(MouseButtons&1){
int mx = MouseX - sk::globals.width/2;
int my = MouseY - sk::globals.height/2;
if(curOrbit >= 0){
orbits[curOrbit].StartX = mx/Scale;
orbits[curOrbit].StartY = my/Scale;
}
}
}
sk::EventStatus
AppEventHandler(sk::Event e, void *param)
{
using namespace sk;
Rect *r;
MouseState *ms;
ImGuiEventHandler(e, param);
ImGuiIO &io = ImGui::GetIO();
switch(e){
case INITIALIZE:
Init();
return EVENTPROCESSED;
case RWINITIALIZE:
return ::InitRW() ? EVENTPROCESSED : EVENTERROR;
case PLUGINATTACH:
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
case KEYDOWN:
KeyDown(*(int*)param);
return EVENTPROCESSED;
case KEYUP:
KeyUp(*(int*)param);
return EVENTPROCESSED;
case MOUSEBTN:
if(!io.WantCaptureMouse){
ms = (MouseState*)param;
MouseBtn(ms);
}else
MouseButtons = 0;
return EVENTPROCESSED;
case MOUSEMOVE:
MouseMove((MouseState*)param);
return EVENTPROCESSED;
case RESIZE:
r = (Rect*)param;
// TODO: register when we're minimized
if(r->w == 0) r->w = 1;
if(r->h == 0) r->h = 1;
sk::globals.width = r->w;
sk::globals.height = r->h;
// TODO: set aspect ratio
if(Scene.camera)
sk::CameraSize(Scene.camera, r);
break;
case IDLE:
Draw(*(float*)param);
return EVENTPROCESSED;
}
return sk::EVENTNOTPROCESSED;
}
+467
View File
@@ -0,0 +1,467 @@
unsigned char particle_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x08, 0x03, 0x00, 0x00, 0x00, 0x6b, 0xac, 0x58, 0x54, 0x00, 0x00, 0x02,
0xfd, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x52, 0x92, 0xc4, 0x9b, 0x00, 0x00, 0x00, 0xfe, 0x74, 0x52,
0x4e, 0x53, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82,
0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
0xfb, 0xfc, 0xfd, 0xfe, 0x86, 0xe3, 0x51, 0x9e, 0x00, 0x00, 0x11, 0x70,
0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xec, 0x96, 0x81, 0x6a, 0xeb, 0x30,
0x0c, 0x00, 0xad, 0xfe, 0xff, 0x37, 0xd7, 0x0f, 0x26, 0x38, 0xb4, 0x1e,
0x26, 0xb3, 0xeb, 0xd0, 0xb4, 0xaf, 0x8e, 0x23, 0x6b, 0x2b, 0x60, 0xee,
0xa2, 0x58, 0x89, 0xf6, 0x9f, 0x8f, 0xaf, 0x80, 0xaf, 0x80, 0xaf, 0x80,
0x6b, 0x6c, 0xdc, 0x3f, 0x54, 0xc0, 0xc2, 0x76, 0xfd, 0x33, 0x05, 0x84,
0x73, 0xa3, 0x2b, 0xff, 0x10, 0x01, 0x51, 0x56, 0x32, 0xe3, 0x2b, 0xeb,
0x9f, 0x20, 0x20, 0xb4, 0x90, 0x88, 0x9f, 0x44, 0xcb, 0x9b, 0x0a, 0x88,
0x41, 0xd4, 0xae, 0x42, 0x56, 0x7c, 0x27, 0x01, 0xa6, 0x0f, 0x92, 0xe1,
0x9e, 0x62, 0xef, 0x25, 0x21, 0xbe, 0x8f, 0x80, 0x10, 0x7c, 0x91, 0x30,
0x68, 0x83, 0x82, 0xe7, 0x26, 0xbc, 0x83, 0x00, 0x81, 0xdb, 0x81, 0xcf,
0xc4, 0xce, 0xaa, 0x5b, 0x22, 0x2e, 0x2e, 0x00, 0x7c, 0xe8, 0x99, 0xae,
0x82, 0x4c, 0xa0, 0x82, 0xb1, 0x6b, 0xe6, 0x92, 0xeb, 0x95, 0x05, 0x0c,
0xb0, 0x65, 0x20, 0xea, 0xe6, 0x50, 0x75, 0xf1, 0x0f, 0x54, 0x5c, 0x52,
0x80, 0xca, 0xbe, 0x06, 0x4c, 0xa0, 0xa7, 0x6e, 0x0d, 0x15, 0x88, 0xf0,
0xe7, 0x42, 0xc0, 0xd0, 0x25, 0x05, 0x40, 0x57, 0xc1, 0x49, 0x55, 0x07,
0x75, 0xb8, 0xf6, 0xa1, 0xaf, 0xe9, 0x19, 0x65, 0x10, 0xe7, 0xe0, 0xfb,
0x92, 0x02, 0x57, 0x80, 0xf0, 0x7d, 0xed, 0x57, 0x10, 0x3b, 0xf1, 0xa1,
0x84, 0x98, 0x04, 0x7e, 0x1b, 0x78, 0xe0, 0xc7, 0x00, 0xd0, 0x24, 0xb8,
0xd9, 0xa8, 0x20, 0x76, 0xe3, 0x17, 0x5e, 0x56, 0xc2, 0x1f, 0x05, 0x80,
0x4d, 0xa8, 0x22, 0xac, 0xe0, 0xb5, 0x02, 0x54, 0xf9, 0x20, 0x93, 0x57,
0x09, 0x2d, 0x83, 0xba, 0x00, 0xf4, 0xa0, 0xd6, 0xc9, 0x7f, 0xfc, 0x2e,
0xbc, 0x54, 0x80, 0xf0, 0x2b, 0x39, 0x37, 0x0a, 0xb8, 0x28, 0x01, 0x7d,
0x00, 0x70, 0x01, 0xce, 0x8d, 0x87, 0xad, 0x0a, 0x62, 0x2b, 0x3e, 0xe0,
0x0a, 0xb3, 0x02, 0xa0, 0x26, 0x20, 0xc2, 0x0a, 0x5e, 0x28, 0x40, 0xa5,
0x0f, 0x35, 0xab, 0x05, 0xd4, 0x77, 0x00, 0x7e, 0x70, 0x24, 0xe0, 0x61,
0xf5, 0xab, 0xf0, 0x32, 0x01, 0xb0, 0x04, 0x13, 0x60, 0x46, 0xe1, 0x9f,
0x10, 0x50, 0x0c, 0xd4, 0xd1, 0x58, 0xb0, 0x90, 0xf3, 0x35, 0x02, 0x6a,
0xed, 0x8b, 0xbb, 0xf0, 0xaf, 0x0b, 0xc8, 0xa0, 0x81, 0x9c, 0x0d, 0x45,
0x10, 0x67, 0xe1, 0xdf, 0xc0, 0xcf, 0x38, 0x2d, 0x20, 0x6f, 0x14, 0xdc,
0x4f, 0x52, 0x10, 0xcf, 0xf1, 0x43, 0x6f, 0x76, 0xbf, 0x05, 0x2d, 0x0e,
0x05, 0x80, 0xef, 0xfa, 0xc7, 0x82, 0x1d, 0x3c, 0x63, 0x20, 0xb6, 0x3c,
0xfe, 0x4a, 0x6f, 0x03, 0x14, 0x80, 0x3f, 0x04, 0x46, 0x9f, 0x01, 0xd0,
0x89, 0xbf, 0x3a, 0xd8, 0x51, 0x04, 0xf1, 0x0c, 0x3f, 0x15, 0x0e, 0xf3,
0x2d, 0xb3, 0x0c, 0x16, 0xc0, 0x35, 0x12, 0xe0, 0x26, 0x50, 0xf1, 0x33,
0xdc, 0xf9, 0xb3, 0xe1, 0xc0, 0x06, 0xce, 0x14, 0x90, 0x08, 0x70, 0x81,
0x9e, 0xf8, 0x56, 0xd0, 0x42, 0x02, 0x30, 0x50, 0xf9, 0x25, 0xa0, 0x37,
0xe1, 0xa3, 0x80, 0x4a, 0x48, 0x53, 0xa9, 0xef, 0x7c, 0x01, 0x7e, 0xfc,
0x95, 0xbf, 0x18, 0x20, 0xc2, 0x3f, 0x27, 0x00, 0x03, 0xe0, 0x57, 0xfe,
0x6a, 0xe0, 0xc9, 0x22, 0x88, 0x75, 0xfe, 0x68, 0x82, 0xc7, 0x00, 0xbf,
0x34, 0x2c, 0xe4, 0xfc, 0x9b, 0x80, 0x9c, 0x39, 0x1a, 0xa8, 0xf0, 0x4b,
0x42, 0xeb, 0xcb, 0x06, 0x62, 0x85, 0xdf, 0x4f, 0xff, 0x26, 0x03, 0x8c,
0x83, 0x3e, 0x78, 0xd0, 0x05, 0x19, 0xe6, 0xbf, 0xbb, 0x0a, 0x30, 0x70,
0x9a, 0x00, 0x9f, 0xfd, 0x89, 0x2d, 0x03, 0x19, 0x76, 0x08, 0x00, 0x5f,
0xfc, 0x99, 0xba, 0x1f, 0x9c, 0x28, 0x00, 0xfe, 0x14, 0x70, 0x43, 0xc0,
0x6f, 0x03, 0xdc, 0xe2, 0xff, 0x93, 0x80, 0x62, 0x40, 0x1d, 0xb0, 0xf2,
0x23, 0xe0, 0x9e, 0x02, 0x96, 0x0c, 0xc4, 0x12, 0x3f, 0x83, 0x87, 0x2f,
0x03, 0x19, 0xe0, 0x1f, 0x08, 0x68, 0xd1, 0x7a, 0x1b, 0x08, 0xc8, 0x00,
0xbe, 0xf9, 0x29, 0x03, 0x06, 0x06, 0xce, 0x11, 0x30, 0xaa, 0xfe, 0xc2,
0xaf, 0x46, 0x00, 0xff, 0x8a, 0x80, 0x8c, 0x6a, 0x01, 0xc5, 0xc0, 0xe8,
0x3d, 0xd8, 0x2f, 0xc0, 0xc7, 0x1f, 0xf8, 0x19, 0x6d, 0x60, 0xf4, 0x35,
0x8c, 0x83, 0x32, 0xa0, 0x1f, 0x7e, 0x07, 0x9b, 0x3f, 0x03, 0x0a, 0x16,
0x8f, 0xc2, 0x98, 0xe5, 0xe7, 0xed, 0x07, 0x3f, 0xe7, 0x81, 0x01, 0xf5,
0x41, 0x0b, 0x70, 0x17, 0x1c, 0xf2, 0x63, 0xa0, 0x28, 0xe0, 0x24, 0x98,
0x33, 0x10, 0x2b, 0xfc, 0xe0, 0x3f, 0x18, 0x18, 0x36, 0x02, 0x7d, 0x0d,
0x6b, 0x67, 0x7d, 0x06, 0x54, 0x03, 0x6a, 0x01, 0x0f, 0xfc, 0x28, 0x58,
0x30, 0x10, 0x93, 0xfc, 0xd1, 0xc0, 0xff, 0xa1, 0x47, 0x41, 0x06, 0x19,
0x80, 0x7f, 0x5a, 0x00, 0x06, 0xc4, 0x9f, 0xc8, 0xe0, 0xff, 0x04, 0x14,
0xb4, 0x3e, 0x67, 0x20, 0x66, 0xf8, 0x19, 0xbf, 0xe9, 0xf5, 0x1a, 0x60,
0x20, 0xe3, 0xb8, 0x0d, 0x30, 0x46, 0x4d, 0x20, 0xc9, 0xe1, 0x57, 0xf9,
0x3f, 0x38, 0x60, 0x60, 0x60, 0x9f, 0x00, 0xf8, 0xeb, 0xe3, 0x2f, 0x1a,
0x64, 0x40, 0xc7, 0xe0, 0x8c, 0x00, 0x1f, 0x81, 0xe2, 0x2f, 0xe8, 0xb5,
0x08, 0x30, 0xb0, 0x53, 0x80, 0xf8, 0x13, 0xb9, 0x2a, 0x38, 0x68, 0x04,
0x6a, 0x03, 0x6c, 0x0d, 0xbf, 0x9a, 0xc0, 0x41, 0x0b, 0x28, 0xf8, 0xb9,
0xac, 0x19, 0x88, 0x55, 0x7e, 0xe0, 0xd3, 0x86, 0x0d, 0x1c, 0x9f, 0x82,
0x33, 0x67, 0xa0, 0xf8, 0xa9, 0x7e, 0xe2, 0x9a, 0x81, 0x58, 0xe0, 0x47,
0x80, 0x14, 0xfc, 0x63, 0xdd, 0x8e, 0x76, 0xe4, 0xb6, 0x62, 0x18, 0x0c,
0xe3, 0xcc, 0xbc, 0xff, 0x23, 0x4f, 0x50, 0x60, 0x4a, 0x44, 0x10, 0x3e,
0x2f, 0xed, 0x62, 0xeb, 0x38, 0xf6, 0xf6, 0x52, 0x7f, 0x25, 0x92, 0x3a,
0xde, 0x68, 0x04, 0xaa, 0xa0, 0x33, 0xe0, 0x26, 0x60, 0x0c, 0xd4, 0x02,
0x28, 0x3f, 0x54, 0x20, 0xf0, 0x5b, 0x00, 0xa5, 0x7e, 0x67, 0xe0, 0x27,
0x19, 0x54, 0x05, 0xf9, 0x36, 0xa8, 0x06, 0xfe, 0x24, 0x81, 0x4c, 0xc0,
0x6f, 0x08, 0x9c, 0x87, 0xf5, 0x8f, 0xfd, 0x6d, 0x00, 0x78, 0xc1, 0x7d,
0x16, 0x8a, 0x08, 0xf0, 0x65, 0x28, 0x08, 0xee, 0x52, 0x10, 0xfa, 0xbf,
0x01, 0x8c, 0x1d, 0x76, 0x02, 0x00, 0xe8, 0xf5, 0x27, 0xfe, 0x58, 0xfb,
0x42, 0xd0, 0x09, 0x44, 0x05, 0x6d, 0x81, 0xd5, 0x00, 0xd1, 0xc0, 0x5e,
0xff, 0x2a, 0x5f, 0x0a, 0x89, 0x44, 0x85, 0xc0, 0x63, 0x00, 0x73, 0xf8,
0x67, 0xfd, 0xca, 0x00, 0x32, 0x98, 0x87, 0x2a, 0xe8, 0x3a, 0xbc, 0x25,
0x80, 0x14, 0x84, 0x04, 0x22, 0x00, 0x12, 0xc8, 0x51, 0xe1, 0x2f, 0x01,
0xa4, 0xfe, 0xc9, 0xbe, 0xef, 0x2b, 0x04, 0x74, 0x40, 0x15, 0x81, 0x92,
0x03, 0x8a, 0x04, 0xd0, 0x01, 0x57, 0xe5, 0x7f, 0x26, 0x19, 0x87, 0xc0,
0x73, 0x00, 0x5d, 0x00, 0x5f, 0x27, 0xf2, 0xb7, 0x00, 0x20, 0x03, 0xc1,
0x74, 0x5e, 0x8e, 0x40, 0xdd, 0x86, 0xd6, 0x04, 0x28, 0x01, 0xb1, 0x80,
0x10, 0x98, 0x16, 0x10, 0x40, 0xa4, 0x30, 0x04, 0xee, 0x87, 0xe0, 0xdc,
0xd6, 0xbf, 0xe4, 0x7f, 0x01, 0x78, 0x8f, 0x08, 0x60, 0x85, 0x73, 0x3b,
0x03, 0xdd, 0x06, 0x4d, 0x01, 0x73, 0x63, 0x81, 0xf9, 0xe1, 0x33, 0x00,
0xb6, 0x19, 0x74, 0x02, 0x00, 0xe8, 0xf5, 0x9f, 0x94, 0xbd, 0x5e, 0xa9,
0x5d, 0x2b, 0x44, 0x07, 0x4b, 0x12, 0x2a, 0x39, 0x68, 0x14, 0x50, 0x0b,
0xcc, 0x2b, 0x95, 0xe7, 0x45, 0x24, 0xea, 0x04, 0x3a, 0x00, 0xf5, 0x3f,
0x95, 0x33, 0x08, 0xc7, 0x9d, 0x20, 0xb7, 0x33, 0xd0, 0x5d, 0xc0, 0x09,
0x48, 0xfd, 0xee, 0x00, 0x36, 0x7f, 0x9e, 0x7a, 0x41, 0x07, 0xd0, 0x1b,
0x20, 0x00, 0xfe, 0xea, 0xdf, 0x9b, 0xfa, 0xcd, 0x43, 0x1a, 0x21, 0xdb,
0x40, 0x92, 0xc0, 0xa4, 0x00, 0x37, 0x01, 0x4c, 0xd0, 0x04, 0xb4, 0x08,
0xe4, 0x11, 0x25, 0x0c, 0x80, 0xda, 0x02, 0x02, 0xa0, 0xfe, 0xdd, 0xff,
0x6f, 0x01, 0x6c, 0x04, 0xcf, 0x67, 0x00, 0x0d, 0x78, 0x3e, 0x01, 0xbb,
0x7c, 0x01, 0x7c, 0xf6, 0x14, 0x74, 0x02, 0x1d, 0x40, 0xae, 0x94, 0x2f,
0x80, 0x37, 0x2a, 0x50, 0x67, 0xe0, 0xb9, 0x06, 0xdc, 0x4f, 0x40, 0x5e,
0x29, 0x1a, 0x00, 0x41, 0x90, 0xab, 0x03, 0xa8, 0x02, 0xb0, 0xfd, 0x2f,
0x00, 0xa6, 0x7e, 0x47, 0xa0, 0xce, 0x40, 0xee, 0xa6, 0x01, 0xb9, 0xcb,
0x04, 0x38, 0x02, 0x43, 0x20, 0x7f, 0xb7, 0x1b, 0x56, 0x19, 0x38, 0x7d,
0x00, 0xec, 0xff, 0xbc, 0x8a, 0x10, 0xd2, 0x01, 0xaf, 0x16, 0x05, 0x6b,
0x10, 0xfc, 0x43, 0x07, 0xdc, 0x09, 0xe0, 0xc7, 0x29, 0x28, 0x43, 0x50,
0x00, 0x60, 0x80, 0xef, 0xb9, 0x9b, 0x10, 0x0e, 0x81, 0x40, 0x70, 0x04,
0x4a, 0x0e, 0xa0, 0x01, 0x58, 0x84, 0x55, 0x00, 0xda, 0x3f, 0x37, 0x66,
0x78, 0x0f, 0x80, 0x01, 0x58, 0x06, 0xf8, 0xde, 0xb7, 0x00, 0xcc, 0xc3,
0xaa, 0x60, 0x1f, 0x01, 0x35, 0xd0, 0x3d, 0xa8, 0x0b, 0xe0, 0xdc, 0xcb,
0x0c, 0xcb, 0x10, 0x9c, 0x87, 0x03, 0xf0, 0xb6, 0x05, 0x10, 0x42, 0x09,
0x14, 0x15, 0xd4, 0x06, 0x9b, 0x06, 0x52, 0x3f, 0x02, 0x48, 0x03, 0x7c,
0x9e, 0x0d, 0xc1, 0xa9, 0x03, 0xc0, 0xff, 0x7f, 0x01, 0xbc, 0x9f, 0x47,
0x01, 0x17, 0xe2, 0x5c, 0x2e, 0xc3, 0xcf, 0x43, 0xc0, 0x47, 0x00, 0xf4,
0x40, 0x1b, 0x82, 0x53, 0x1b, 0x60, 0x04, 0x70, 0xca, 0x57, 0x08, 0x7a,
0x14, 0x08, 0xc7, 0xf5, 0x81, 0x90, 0x11, 0x40, 0x02, 0xf2, 0x7b, 0x11,
0x2d, 0x04, 0x94, 0xf1, 0xcf, 0x63, 0x7a, 0x80, 0x16, 0xe8, 0x00, 0xd6,
0x0a, 0xbc, 0xcb, 0x2f, 0x00, 0x20, 0x40, 0x07, 0xe0, 0x83, 0xb6, 0x40,
0x6e, 0x3a, 0x60, 0xd5, 0x5f, 0x01, 0xac, 0xc7, 0x1a, 0x82, 0x0a, 0x40,
0x05, 0xdc, 0x02, 0x68, 0x0b, 0x0c, 0x00, 0x09, 0x28, 0x02, 0xaf, 0xcc,
0x14, 0xeb, 0xa0, 0xcb, 0x60, 0x3a, 0x36, 0xad, 0xeb, 0x51, 0xd8, 0xad,
0xfe, 0xe5, 0xb1, 0x85, 0x50, 0x1d, 0x14, 0x80, 0x03, 0xb0, 0xea, 0x97,
0x81, 0x00, 0xba, 0x08, 0xd8, 0x01, 0xe4, 0x80, 0xdc, 0x4d, 0x02, 0x3a,
0x80, 0x3c, 0x16, 0x81, 0x36, 0x04, 0xe7, 0x56, 0x01, 0x53, 0xb6, 0x0c,
0xb0, 0x02, 0x0f, 0xc7, 0xae, 0x93, 0x40, 0x89, 0xc2, 0xd7, 0x29, 0xc0,
0x83, 0x30, 0x0d, 0xc0, 0xea, 0x83, 0x04, 0x1d, 0x04, 0x40, 0x57, 0x40,
0x8a, 0x57, 0x09, 0xf3, 0x1c, 0x02, 0x24, 0x01, 0x82, 0x00, 0x36, 0x48,
0x0c, 0xa0, 0x01, 0x76, 0xfd, 0x18, 0x40, 0x6e, 0x20, 0x14, 0x1d, 0x2c,
0x00, 0xe6, 0x0c, 0x28, 0x45, 0xcb, 0x40, 0x00, 0x35, 0x0e, 0x97, 0x28,
0x58, 0x82, 0x60, 0x89, 0xc1, 0x02, 0xa0, 0xfa, 0xfc, 0xe7, 0x9c, 0x0f,
0x15, 0x00, 0x34, 0x80, 0x02, 0xb0, 0x28, 0xe4, 0x1e, 0x00, 0x10, 0xe0,
0x70, 0x38, 0x5c, 0xab, 0x0b, 0x8c, 0x09, 0x72, 0x1c, 0x4c, 0xfd, 0x03,
0x20, 0x37, 0xb5, 0x23, 0x03, 0x57, 0x2d, 0x70, 0x6a, 0x03, 0x5c, 0xd7,
0xdf, 0xcc, 0xd0, 0x16, 0x30, 0x0c, 0x8f, 0x08, 0x28, 0x01, 0x06, 0x61,
0x1b, 0xa0, 0x18, 0xe0, 0x35, 0x81, 0xd6, 0x02, 0xe7, 0xb6, 0x01, 0xfe,
0xd6, 0x5c, 0xbd, 0xa0, 0xb4, 0x00, 0x33, 0x50, 0x92, 0x20, 0x13, 0x50,
0x1a, 0xa0, 0xea, 0xff, 0xfc, 0x60, 0x0b, 0x08, 0xa0, 0x37, 0xc0, 0xaa,
0x1f, 0x06, 0xbd, 0x05, 0xcc, 0x82, 0x6e, 0x43, 0xee, 0x42, 0xe6, 0xc0,
0xdb, 0x06, 0xc8, 0x03, 0x02, 0xb7, 0x2d, 0x70, 0x7a, 0x03, 0x4c, 0xe9,
0x45, 0x08, 0x24, 0xc0, 0x0c, 0x70, 0x2a, 0xa8, 0x08, 0x7a, 0x22, 0xe8,
0x04, 0x50, 0x7f, 0x19, 0xff, 0x79, 0xd4, 0x16, 0x38, 0x37, 0x0d, 0x00,
0x81, 0xd5, 0x00, 0xbd, 0x05, 0xf0, 0x81, 0x10, 0x28, 0x23, 0x90, 0xfa,
0xf1, 0x80, 0xda, 0x00, 0xbb, 0x05, 0xa8, 0x9f, 0x16, 0xe8, 0x00, 0x76,
0x03, 0xa4, 0x60, 0x06, 0xa1, 0x0c, 0x01, 0x22, 0xa0, 0x06, 0x98, 0x03,
0x9a, 0x0b, 0x0a, 0xa0, 0x0f, 0xc0, 0xbc, 0xf2, 0xde, 0x2d, 0x20, 0x80,
0xde, 0x00, 0x9b, 0x40, 0x71, 0x82, 0x3c, 0xcf, 0xab, 0x02, 0x30, 0x0a,
0x12, 0x04, 0x1b, 0x80, 0x3c, 0x89, 0x00, 0x36, 0xff, 0xbc, 0x7b, 0x0b,
0x1c, 0x1a, 0x00, 0x05, 0x5c, 0xc5, 0x17, 0x19, 0xf8, 0xbe, 0xe3, 0x1d,
0x45, 0x05, 0xab, 0x06, 0x74, 0x0d, 0x4c, 0x21, 0x29, 0x1f, 0x01, 0xb0,
0xf9, 0x73, 0x0f, 0x01, 0x5b, 0xe0, 0xb8, 0x06, 0xbe, 0xce, 0x5f, 0x0b,
0x84, 0x40, 0x49, 0x03, 0xb9, 0x04, 0x90, 0x24, 0x14, 0x05, 0x20, 0x09,
0x91, 0x83, 0xf2, 0x48, 0x0e, 0x02, 0x40, 0xae, 0x92, 0x00, 0xa8, 0xff,
0x5f, 0x00, 0x5f, 0x4d, 0x65, 0x29, 0x04, 0x40, 0x1a, 0x60, 0x00, 0xd8,
0x06, 0x79, 0x15, 0x02, 0x27, 0xeb, 0xc0, 0x02, 0x10, 0x02, 0x02, 0x70,
0x15, 0x58, 0x00, 0xe6, 0x73, 0x40, 0xa9, 0x5f, 0xf9, 0xcb, 0x1d, 0x00,
0xd3, 0x02, 0x02, 0xd0, 0x03, 0xf3, 0x7b, 0x00, 0xa9, 0xbb, 0x0c, 0x02,
0x04, 0x3a, 0x00, 0xa2, 0x60, 0xd6, 0x61, 0x82, 0x60, 0x07, 0x40, 0xfd,
0xa5, 0xf9, 0xf3, 0xca, 0xef, 0x0d, 0xe0, 0x84, 0x01, 0x80, 0x04, 0xbe,
0xce, 0x12, 0x00, 0x21, 0x48, 0x20, 0x0f, 0x36, 0xe2, 0x0a, 0x20, 0x2e,
0xd0, 0x01, 0x78, 0x16, 0x62, 0x08, 0x2c, 0xff, 0xf3, 0x73, 0xe7, 0x43,
0x09, 0x2d, 0x00, 0x80, 0x59, 0x83, 0x57, 0xe9, 0x95, 0x00, 0xc7, 0x02,
0x24, 0x81, 0x0d, 0xe0, 0xc7, 0x24, 0xb8, 0x01, 0x90, 0x02, 0x38, 0x08,
0xe8, 0xf5, 0xaf, 0x57, 0xd6, 0x62, 0x01, 0x28, 0x81, 0x73, 0x10, 0x5e,
0x09, 0x10, 0x06, 0x54, 0xc1, 0xff, 0x0b, 0x80, 0x1a, 0x48, 0x04, 0xe8,
0xf5, 0xcf, 0x21, 0x39, 0x32, 0x78, 0xae, 0x25, 0x70, 0x03, 0x78, 0x42,
0x20, 0x0f, 0x44, 0x00, 0x1b, 0x70, 0x1d, 0x9c, 0x18, 0x80, 0x09, 0x20,
0x01, 0x8c, 0x40, 0xad, 0x7f, 0x01, 0x50, 0x06, 0x01, 0x70, 0x22, 0x81,
0xe7, 0x5b, 0x54, 0x27, 0xc0, 0x5e, 0x18, 0x06, 0x84, 0x41, 0x82, 0x40,
0xd1, 0x00, 0x62, 0x00, 0x31, 0x90, 0x2d, 0x20, 0x8f, 0x52, 0x7f, 0x7a,
0xe1, 0xab, 0x83, 0xa6, 0xc1, 0x43, 0x03, 0xa0, 0x00, 0x0c, 0xc2, 0x78,
0x61, 0xda, 0xa0, 0xce, 0x80, 0x61, 0xb8, 0xb8, 0x80, 0x41, 0xf8, 0x66,
0x02, 0x42, 0x20, 0x4d, 0x60, 0xf3, 0xa3, 0x02, 0x21, 0xbc, 0x01, 0x38,
0x01, 0x01, 0x40, 0x0b, 0x28, 0x83, 0x38, 0x21, 0x3e, 0x00, 0x80, 0x92,
0x03, 0x00, 0x80, 0x07, 0xe0, 0x81, 0x48, 0x20, 0x7f, 0x03, 0xc0, 0x19,
0x08, 0x00, 0x26, 0x20, 0x21, 0x68, 0x00, 0xa8, 0x87, 0x12, 0x18, 0x23,
0x38, 0xaf, 0x6d, 0x03, 0x1c, 0x0a, 0x25, 0x0a, 0x6f, 0x00, 0x89, 0xc2,
0x21, 0xe0, 0x61, 0x48, 0xb2, 0xcc, 0x58, 0x80, 0xf5, 0xab, 0x7c, 0xf3,
0x48, 0x18, 0x72, 0x06, 0xce, 0xb5, 0x07, 0xa4, 0x4e, 0x1e, 0x4d, 0x06,
0x54, 0x41, 0x6d, 0x60, 0x54, 0xd0, 0x5d, 0x60, 0x34, 0x10, 0x13, 0x50,
0x03, 0xef, 0x05, 0x00, 0x00, 0x1f, 0x7d, 0x00, 0x00, 0x07, 0x0f, 0xb4,
0x05, 0x5c, 0x0a, 0x88, 0x02, 0x97, 0x49, 0x20, 0x97, 0xdb, 0x90, 0xbb,
0x50, 0x2e, 0x53, 0x00, 0x21, 0xc0, 0x15, 0xc0, 0x06, 0xc8, 0xd3, 0x19,
0x10, 0xc0, 0x9a, 0x00, 0x00, 0x30, 0x04, 0x8a, 0x00, 0x22, 0xc8, 0x08,
0xf8, 0x61, 0xc0, 0xcf, 0x02, 0x8c, 0x40, 0x6e, 0x1b, 0xa0, 0x0c, 0x00,
0x00, 0x66, 0x06, 0x04, 0x30, 0x12, 0xf0, 0xda, 0x13, 0xb0, 0x9f, 0xb6,
0x80, 0x4e, 0x38, 0x17, 0x61, 0xb8, 0x1c, 0x09, 0x79, 0x20, 0x44, 0x10,
0xde, 0x97, 0x5b, 0xd0, 0xd5, 0xf4, 0xaf, 0xe7, 0xa4, 0xc1, 0x25, 0x02,
0x07, 0x13, 0xa4, 0x01, 0x16, 0x80, 0xda, 0x02, 0x79, 0x74, 0x1b, 0xe8,
0x23, 0xd0, 0x4d, 0x20, 0xc5, 0xf7, 0x06, 0xd8, 0x00, 0x6c, 0x81, 0xcc,
0x80, 0x00, 0x66, 0x0f, 0x4a, 0x89, 0x02, 0xe8, 0x2a, 0xe0, 0x46, 0x88,
0x0d, 0x70, 0x26, 0xb6, 0x5a, 0x20, 0xb7, 0x26, 0xe0, 0x26, 0xd8, 0x14,
0x00, 0x00, 0x79, 0x65, 0x23, 0x12, 0x00, 0x26, 0x48, 0xfd, 0x02, 0xd0,
0x08, 0x52, 0xbf, 0x2a, 0x68, 0x07, 0x78, 0x24, 0x86, 0x04, 0x14, 0x0d,
0xcc, 0x53, 0x0b, 0x00, 0x00, 0x04, 0x34, 0xc2, 0x0d, 0x20, 0x26, 0xf8,
0xad, 0x8a, 0xfa, 0x01, 0x50, 0x64, 0xb0, 0xf8, 0x60, 0x08, 0x20, 0x82,
0xa9, 0xbf, 0xb9, 0x60, 0x91, 0x40, 0x00, 0x40, 0x20, 0x61, 0x31, 0x47,
0x4c, 0x02, 0xd0, 0x04, 0x53, 0x6c, 0xde, 0x1d, 0x40, 0x4f, 0x02, 0xb9,
0x1f, 0x75, 0x00, 0x41, 0xb8, 0xa6, 0x80, 0x0e, 0x20, 0xaf, 0xbc, 0x31,
0xc2, 0x01, 0xa0, 0x04, 0xa4, 0x5e, 0xea, 0x6f, 0x00, 0xf0, 0x01, 0x46,
0xe0, 0x95, 0x20, 0x54, 0x35, 0xe0, 0xfb, 0xf8, 0xc3, 0x08, 0xe0, 0x01,
0x05, 0x00, 0x04, 0xf2, 0x83, 0x22, 0x00, 0x80, 0x0c, 0x2f, 0xe5, 0x33,
0x06, 0xb9, 0xd7, 0x4a, 0x74, 0xbb, 0x0f, 0xe1, 0x83, 0xae, 0xc3, 0x61,
0x70, 0xbf, 0x09, 0xa5, 0x74, 0x32, 0xe0, 0x22, 0x00, 0x82, 0x8b, 0x24,
0x70, 0x4c, 0x01, 0x23, 0x01, 0x9b, 0x43, 0xd1, 0x41, 0xbf, 0x11, 0x1d,
0x5b, 0xc0, 0x24, 0xd4, 0x76, 0x21, 0x77, 0x61, 0xbf, 0x07, 0x15, 0x05,
0xdc, 0x95, 0x8f, 0x08, 0x90, 0x04, 0x8e, 0x29, 0x00, 0x09, 0x6c, 0x53,
0x30, 0x7f, 0x3c, 0x13, 0x98, 0x33, 0x11, 0xb3, 0x30, 0xcb, 0x50, 0xfe,
0xe4, 0xe2, 0x34, 0xc4, 0xb3, 0x80, 0xf9, 0x53, 0xfa, 0x1f, 0x19, 0x24,
0x09, 0x1c, 0x35, 0xf0, 0xbd, 0x47, 0xc0, 0x2e, 0x98, 0xbf, 0x00, 0xc8,
0x63, 0x00, 0xf8, 0x5b, 0x12, 0xaa, 0xe0, 0xd2, 0x40, 0x7f, 0x37, 0x62,
0x01, 0x48, 0x0b, 0x08, 0x00, 0x02, 0xeb, 0x87, 0xfc, 0x98, 0x30, 0x58,
0x00, 0xbc, 0xce, 0x7b, 0x3a, 0x80, 0x2e, 0xa0, 0xfe, 0x66, 0x84, 0xfa,
0xa0, 0x59, 0xb8, 0x26, 0x61, 0x5c, 0xb0, 0x9b, 0xe0, 0xfc, 0xcd, 0x0b,
0x06, 0xf3, 0x1b, 0x33, 0x97, 0x00, 0x30, 0x41, 0x39, 0xe4, 0x6d, 0x1e,
0x26, 0x0d, 0x13, 0x86, 0x89, 0x82, 0x00, 0x20, 0x08, 0x2e, 0x09, 0xb0,
0x01, 0x4c, 0xc1, 0xca, 0x9f, 0x33, 0x80, 0x0a, 0x1e, 0x35, 0x30, 0xd5,
0x59, 0xbc, 0x4e, 0xe0, 0x46, 0xa4, 0x0a, 0x0a, 0xa0, 0x88, 0xa0, 0x00,
0xd4, 0x40, 0xf7, 0x20, 0x1d, 0x40, 0x08, 0x61, 0x84, 0x0a, 0x9e, 0x9d,
0x03, 0xbf, 0x17, 0xa5, 0xd3, 0x04, 0x6d, 0x06, 0x0c, 0xc3, 0xbf, 0x07,
0x40, 0x10, 0xee, 0x13, 0x90, 0x37, 0x18, 0xe2, 0x83, 0x2b, 0x0b, 0x1e,
0x4d, 0x60, 0x6a, 0x2d, 0x3a, 0xd8, 0x8c, 0xd0, 0x7d, 0x28, 0xf7, 0x7f,
0x01, 0x90, 0x9b, 0x18, 0xd8, 0x4d, 0x50, 0x05, 0xdc, 0x20, 0xb4, 0x81,
0xa3, 0x09, 0xd8, 0x01, 0xca, 0xe0, 0xd4, 0xdf, 0x17, 0x42, 0xfe, 0x1d,
0x2d, 0xeb, 0x20, 0xcb, 0xa0, 0xff, 0x5a, 0xb6, 0xaf, 0x82, 0xb9, 0x8d,
0xc0, 0x76, 0x00, 0x36, 0x00, 0x80, 0xd7, 0x41, 0x02, 0x40, 0x61, 0x16,
0x82, 0x80, 0x0b, 0x71, 0x08, 0x3c, 0x74, 0x81, 0xd4, 0xef, 0x32, 0x6c,
0xfd, 0xa4, 0x20, 0xca, 0x46, 0x04, 0xb6, 0x0d, 0x1c, 0x83, 0xb0, 0x55,
0x17, 0x27, 0xbc, 0x55, 0x41, 0x92, 0x60, 0x07, 0x40, 0x12, 0xbc, 0xd3,
0xc0, 0xea, 0x81, 0xb2, 0x20, 0x0c, 0x0b, 0x80, 0xb2, 0x89, 0x45, 0x79,
0x60, 0x84, 0x8c, 0x40, 0xcd, 0xc2, 0x49, 0x42, 0x7c, 0x1a, 0x34, 0x09,
0x2b, 0x01, 0x98, 0xa0, 0x1d, 0x00, 0x07, 0x7c, 0x10, 0x00, 0xaf, 0xc3,
0x2a, 0x08, 0x86, 0x22, 0x02, 0x20, 0xa8, 0x67, 0x42, 0x17, 0x51, 0xb8,
0x9e, 0x07, 0x51, 0xbe, 0x12, 0xa0, 0x07, 0xd8, 0x06, 0xe3, 0x83, 0x1b,
0xc0, 0xc4, 0x80, 0x77, 0x46, 0xa0, 0x0a, 0xa1, 0x1d, 0xc0, 0xd9, 0xf8,
0x71, 0x1f, 0xdc, 0xfb, 0xf0, 0x10, 0x48, 0xfd, 0xd7, 0xdb, 0x70, 0xee,
0xfd, 0x4d, 0xa4, 0x74, 0x40, 0x11, 0xc0, 0x8c, 0xc0, 0x67, 0x07, 0x81,
0x43, 0x0c, 0x98, 0x8a, 0x25, 0xd1, 0x64, 0x50, 0x23, 0x4c, 0xfd, 0xbb,
0x01, 0xfa, 0x2e, 0xe0, 0xa1, 0x78, 0x6e, 0x4d, 0xb0, 0x4a, 0xe0, 0xd4,
0xed, 0x08, 0xec, 0x20, 0x10, 0x00, 0xf9, 0x28, 0xc4, 0x61, 0x80, 0x10,
0xfa, 0x0c, 0xf8, 0x7d, 0x4c, 0x17, 0xa8, 0x39, 0x40, 0x17, 0xf0, 0xab,
0x58, 0x9f, 0x00, 0x8b, 0xe7, 0x48, 0x20, 0x9f, 0x87, 0x16, 0x80, 0xef,
0x65, 0x03, 0x6c, 0x12, 0x25, 0x0a, 0x05, 0x01, 0x1a, 0xf0, 0xfb, 0x0e,
0x50, 0x03, 0x52, 0x7e, 0x8f, 0x41, 0xb9, 0x4c, 0x85, 0x93, 0x84, 0x02,
0xa0, 0xe4, 0xa0, 0xe2, 0x03, 0x35, 0x0c, 0x33, 0x03, 0xee, 0xc3, 0x76,
0x80, 0xdb, 0x30, 0x13, 0xd0, 0x83, 0x70, 0xf1, 0x80, 0x92, 0x84, 0x0a,
0x80, 0xa6, 0x02, 0x10, 0x70, 0x1f, 0xf4, 0xdb, 0xc8, 0xce, 0xc2, 0xb9,
0x67, 0x19, 0x4c, 0xf9, 0xed, 0xab, 0x88, 0xbb, 0x20, 0x31, 0xa0, 0x14,
0xff, 0x08, 0xc0, 0x5b, 0x02, 0x3d, 0x0a, 0xf5, 0x28, 0x68, 0x12, 0xba,
0x0f, 0x42, 0xe6, 0xa0, 0x1e, 0x04, 0x7b, 0x0c, 0xa2, 0xfe, 0x0f, 0x00,
0x48, 0xc2, 0x0d, 0xc1, 0x22, 0x90, 0x1b, 0x17, 0x28, 0x9f, 0x07, 0xef,
0x45, 0xb0, 0x7c, 0x18, 0xd4, 0x05, 0x72, 0xaf, 0xfa, 0x5b, 0xf9, 0x66,
0xe1, 0xe3, 0x79, 0x90, 0xea, 0x27, 0x82, 0x7b, 0x0d, 0xd0, 0x05, 0x0c,
0x42, 0x93, 0x04, 0x09, 0x42, 0xba, 0xc0, 0xbd, 0x06, 0x58, 0xbe, 0x5a,
0xc8, 0x99, 0x90, 0x00, 0x2c, 0xf6, 0x19, 0x80, 0xfd, 0x79, 0x2c, 0x3e,
0x58, 0x34, 0x00, 0x17, 0x68, 0x1a, 0xf0, 0x7d, 0xae, 0xcf, 0x62, 0x0d,
0x40, 0x71, 0x81, 0x0e, 0xe0, 0x7b, 0x75, 0x07, 0xf0, 0x58, 0x0c, 0x1f,
0xcc, 0xf3, 0x08, 0x80, 0x73, 0x71, 0x4e, 0xc5, 0xcb, 0xa1, 0xb8, 0xbb,
0x50, 0x10, 0x70, 0x1c, 0x56, 0x9c, 0x60, 0x7d, 0x22, 0xfe, 0x87, 0xbd,
0x3b, 0xba, 0x81, 0x30, 0x84, 0x61, 0x18, 0xbc, 0xff, 0xd6, 0x4c, 0x60,
0x21, 0xf5, 0x35, 0xdf, 0x0a, 0x48, 0x77, 0x3f, 0xb4, 0x89, 0xfd, 0x3f,
0x80, 0x1e, 0x0d, 0xe5, 0x73, 0x30, 0x06, 0xe3, 0x87, 0x03, 0xa8, 0xa1,
0x78, 0x3c, 0x06, 0x63, 0x10, 0x14, 0x07, 0xe0, 0x00, 0xfc, 0x04, 0xfc,
0x09, 0xfa, 0x0c, 0xba, 0x08, 0xb9, 0x0a, 0x7b, 0x0c, 0x79, 0x0e, 0x1b,
0x88, 0x18, 0x89, 0x19, 0x8a, 0x1a, 0x8b, 0x8f, 0x2e, 0x46, 0xac, 0xc6,
0x2c, 0x47, 0xad, 0xc7, 0x05, 0x24, 0x44, 0x64, 0x84, 0xa4, 0xc4, 0xe4,
0x04, 0x25, 0x45, 0x65, 0x85, 0xa5, 0xc5, 0xe5, 0x15, 0x26, 0x54, 0x66,
0x94, 0xa6, 0xd4, 0xe6, 0x14, 0x27, 0x55, 0x67, 0x95, 0xa7, 0xf7, 0xea,
0xf3, 0x00, 0x0a, 0x10, 0x1a, 0x20, 0x2a, 0x30, 0x3a, 0x40, 0x4a, 0x50,
0x5a, 0x60, 0x6a, 0x70, 0x7a, 0x80, 0x8a, 0x90, 0x9a, 0xa0, 0xaa, 0xb0,
0xba, 0xc0, 0xca, 0xd0, 0xda, 0xe0, 0xea, 0xf0, 0xfa, 0x04, 0x0b, 0x14,
0x1b, 0x24, 0x2b, 0x34, 0x3b, 0x44, 0x4b, 0xd3, 0xaa, 0x2d, 0xb2, 0x35,
0xba, 0x3d, 0xc2, 0x45, 0xca, 0x4d, 0xd2, 0x55, 0xda, 0x5d, 0xe2, 0x65,
0xea, 0x6d, 0xf2, 0x75, 0xfa, 0xfd, 0xd7, 0x9e, 0x1d, 0xe8, 0x26, 0xb2,
0x03, 0x41, 0x14, 0xf5, 0xfc, 0xff, 0x47, 0xb3, 0x92, 0x66, 0x1b, 0x2a,
0x3a, 0x56, 0x7b, 0x14, 0x6b, 0x04, 0x48, 0xd9, 0x85, 0x09, 0x49, 0xde,
0x5b, 0x74, 0x2f, 0x76, 0x55, 0x1b, 0xc6, 0x31, 0x62, 0x13, 0xc4, 0x12,
0x98, 0x17, 0x40, 0x76, 0x20, 0x11, 0x40, 0x09, 0x34, 0x35, 0x68, 0x0d,
0x18, 0x02, 0xd9, 0x84, 0xd3, 0x2a, 0x78, 0x69, 0xc8, 0x0d, 0x70, 0x49,
0x00, 0x39, 0x98, 0x41, 0xb8, 0xcc, 0x3f, 0xf9, 0x1d, 0x84, 0x3d, 0x0b,
0x0d, 0x4f, 0x43, 0x0e, 0xc3, 0x1a, 0x58, 0x27, 0x61, 0x04, 0x60, 0x26,
0xa0, 0xa0, 0x8d, 0x81, 0x5c, 0x03, 0xab, 0xed, 0x4f, 0x04, 0xb8, 0x02,
0x1c, 0x04, 0x97, 0xa3, 0xe0, 0x8b, 0xdf, 0x10, 0x58, 0x04, 0x41, 0xbe,
0xfe, 0xf2, 0x23, 0x60, 0xbd, 0x09, 0x8a, 0xdc, 0xed, 0xdf, 0x8f, 0xc1,
0x7e, 0x28, 0xd2, 0xcd, 0x01, 0x7e, 0x38, 0xd2, 0x8f, 0xc3, 0x04, 0x41,
0x7d, 0x61, 0x03, 0x5c, 0x12, 0xe0, 0x26, 0x38, 0x31, 0x6a, 0x0d, 0xb0,
0xfd, 0xc1, 0x6f, 0x22, 0xd0, 0x16, 0x74, 0x0b, 0xb8, 0x04, 0x8c, 0x41,
0x14, 0x10, 0x04, 0xf5, 0xfa, 0x9f, 0xea, 0x9a, 0x0d, 0x80, 0x00, 0x0c,
0x64, 0x15, 0x24, 0xbc, 0x01, 0xf8, 0xe2, 0xb7, 0x04, 0xcd, 0xc0, 0xf9,
0x28, 0x4c, 0x0a, 0x5a, 0x84, 0x2f, 0x03, 0x06, 0x61, 0x4a, 0xc8, 0x02,
0x90, 0xff, 0xb2, 0x80, 0x91, 0x31, 0xa0, 0x80, 0x7e, 0x08, 0x9a, 0x67,
0x20, 0xfc, 0x61, 0xa0, 0x49, 0xc1, 0x7e, 0x18, 0x52, 0x40, 0x06, 0xc0,
0x58, 0x0b, 0x58, 0xc6, 0xc0, 0x09, 0x57, 0xec, 0x0a, 0xe8, 0x87, 0x00,
0xdf, 0x11, 0xb4, 0x06, 0x7d, 0x57, 0x70, 0x3d, 0x0a, 0x20, 0xa0, 0x2e,
0xa7, 0x24, 0x03, 0xe0, 0xba, 0x00, 0x63, 0xa0, 0x76, 0x41, 0x1f, 0x80,
0xee, 0x00, 0xb7, 0x40, 0x9f, 0x01, 0x6e, 0x01, 0xf7, 0x40, 0x1f, 0x84,
0x59, 0x80, 0x7d, 0x00, 0xac, 0x05, 0x50, 0x86, 0x6e, 0xff, 0x4c, 0x80,
0x7e, 0x07, 0xac, 0x33, 0xe0, 0xfa, 0x1e, 0xc8, 0x14, 0x20, 0x08, 0x28,
0xc0, 0xdf, 0x09, 0xd0, 0x40, 0xcd, 0x84, 0xb9, 0x16, 0x0e, 0x12, 0xe0,
0xbc, 0x84, 0x02, 0x0c, 0x34, 0x73, 0x00, 0xfc, 0x81, 0x7f, 0xf2, 0x93,
0x02, 0x8f, 0x7c, 0xdd, 0x6b, 0xfe, 0x83, 0x7f, 0x25, 0x60, 0x6d, 0x20,
0xdb, 0xd0, 0x3f, 0x47, 0xdd, 0xf3, 0x43, 0xe1, 0xa6, 0x04, 0x3c, 0x0d,
0xf6, 0x35, 0x10, 0x1f, 0x13, 0x17, 0xfe, 0x34, 0x08, 0xb3, 0xff, 0xe4,
0xbf, 0x2e, 0xc0, 0x18, 0x38, 0x0a, 0x0d, 0x01, 0x9e, 0x02, 0x32, 0x04,
0xeb, 0x3a, 0xda, 0x41, 0xd0, 0x51, 0xb0, 0x2c, 0xc4, 0x91, 0x70, 0x7a,
0x22, 0x50, 0x40, 0x69, 0x7a, 0x64, 0x00, 0xec, 0x08, 0x28, 0x03, 0x91,
0x84, 0x73, 0x7c, 0xf9, 0x0b, 0xbf, 0x1b, 0x04, 0x47, 0x3b, 0x0a, 0x96,
0x02, 0x0d, 0xcc, 0x14, 0x64, 0xfe, 0x15, 0xff, 0x5a, 0xc0, 0xd2, 0x80,
0x5d, 0x60, 0xfe, 0xf5, 0xe7, 0xa0, 0x30, 0xb0, 0x6e, 0x81, 0xe4, 0xef,
0x4f, 0x44, 0x26, 0xa1, 0xf9, 0x2f, 0xff, 0x45, 0x01, 0xc4, 0xc0, 0xf8,
0x4f, 0x54, 0xd4, 0x04, 0x40, 0xc7, 0xef, 0x51, 0xe8, 0x18, 0x29, 0xe0,
0xbc, 0x78, 0x1c, 0x6a, 0x0c, 0x10, 0x03, 0xe5, 0xe2, 0xff, 0x7f, 0x3d,
0x2a, 0x00, 0x36, 0x04, 0x10, 0x84, 0x59, 0x06, 0x4e, 0x40, 0x69, 0xa0,
0x89, 0x00, 0x16, 0x40, 0x2c, 0x81, 0x3e, 0x04, 0x92, 0xdf, 0x79, 0x28,
0xe3, 0x9f, 0x00, 0xec, 0xe8, 0xb6, 0x0c, 0x1c, 0xd3, 0x0a, 0x24, 0x02,
0xc2, 0xc0, 0xb2, 0x06, 0x93, 0x9f, 0x10, 0xb0, 0x0a, 0xeb, 0xda, 0xf3,
0x6f, 0x09, 0xd0, 0xc0, 0x21, 0xbe, 0x11, 0x98, 0xf8, 0xfd, 0x1c, 0xd4,
0x4e, 0x42, 0xa5, 0xc0, 0x18, 0x54, 0xc1, 0x43, 0xfe, 0x3d, 0x01, 0x8d,
0x81, 0xcc, 0xbf, 0x9e, 0xdf, 0x93, 0x40, 0x23, 0x80, 0xd3, 0xc0, 0xca,
0x40, 0x26, 0xa1, 0xfc, 0xdb, 0x02, 0x1a, 0x03, 0x87, 0x67, 0x80, 0x86,
0xdf, 0x08, 0x60, 0x0e, 0x30, 0x04, 0x1a, 0x03, 0x9e, 0x09, 0x1e, 0x3d,
0xff, 0xbe, 0x80, 0x34, 0xf0, 0x14, 0x70, 0xb0, 0x03, 0x8c, 0x40, 0x33,
0xb0, 0x11, 0x60, 0x0a, 0x1a, 0x83, 0xec, 0x81, 0xc7, 0x53, 0x40, 0xf2,
0x8f, 0x7d, 0x01, 0x1a, 0xa8, 0x3a, 0x2c, 0x54, 0x02, 0x90, 0x08, 0x34,
0x03, 0x8d, 0x00, 0x43, 0x20, 0xf8, 0x8d, 0xc1, 0x0c, 0xc2, 0xa0, 0xaf,
0xfa, 0x83, 0x7f, 0x43, 0x80, 0x06, 0x4e, 0x94, 0x52, 0x10, 0xf8, 0x56,
0xc0, 0xf5, 0x0c, 0xbc, 0x96, 0x82, 0x14, 0x41, 0x28, 0x28, 0xfc, 0xf3,
0x7f, 0x83, 0x7f, 0x57, 0x80, 0x06, 0x42, 0x41, 0xf0, 0xaf, 0xa7, 0x20,
0xcf, 0x42, 0x9e, 0x86, 0xfa, 0x59, 0xc8, 0x20, 0x0c, 0x7c, 0xf9, 0xf7,
0x05, 0x68, 0x60, 0x54, 0x0e, 0x84, 0x82, 0x65, 0x05, 0x58, 0x02, 0x0a,
0xa0, 0x06, 0x96, 0x45, 0xf0, 0xc2, 0x8f, 0xd3, 0xaf, 0xfc, 0xfb, 0x02,
0x3c, 0x17, 0xfc, 0x54, 0x20, 0xbf, 0x63, 0xa0, 0x19, 0x98, 0x6f, 0x8b,
0x4f, 0x53, 0x90, 0x61, 0x50, 0x03, 0x3f, 0xf1, 0x9d, 0xff, 0xf7, 0x05,
0x68, 0xa0, 0x04, 0x44, 0x23, 0x96, 0x81, 0x52, 0xe2, 0x18, 0xf8, 0x3b,
0x01, 0x0c, 0x83, 0x85, 0x5b, 0xfc, 0xd1, 0x7d, 0x25, 0x00, 0xfe, 0x4d,
0x01, 0x1a, 0x20, 0x09, 0xe4, 0x77, 0x0c, 0x54, 0x00, 0xc7, 0x61, 0x05,
0x38, 0x0c, 0x6a, 0x80, 0xdd, 0x2f, 0xff, 0xbe, 0x00, 0x0d, 0xb8, 0x0f,
0xa6, 0x15, 0xa8, 0x81, 0x4b, 0x02, 0xe4, 0x9f, 0x56, 0xa1, 0xab, 0xbf,
0xf8, 0xef, 0x11, 0x60, 0x14, 0xe2, 0x80, 0x08, 0xdc, 0x10, 0xd0, 0xc6,
0x20, 0xf4, 0xc6, 0xdf, 0x4d, 0x02, 0xca, 0x40, 0x11, 0x95, 0x00, 0xf8,
0xeb, 0x37, 0x63, 0xde, 0x82, 0x53, 0x01, 0xf3, 0x1e, 0x1c, 0x85, 0x89,
0x81, 0x12, 0x50, 0xbe, 0x8a, 0xff, 0x0e, 0x01, 0x1a, 0x70, 0x15, 0x50,
0x01, 0xc5, 0x5e, 0x97, 0x71, 0x4d, 0x40, 0xf6, 0x60, 0x59, 0xa0, 0x08,
0x7c, 0xf5, 0xe5, 0xbf, 0x4b, 0x40, 0x15, 0x79, 0xae, 0x82, 0x02, 0xb7,
0x02, 0xb2, 0x04, 0xae, 0x0b, 0x48, 0x7e, 0x8a, 0xe0, 0x07, 0x7f, 0xc9,
0x1a, 0x6e, 0xff, 0xbb, 0x04, 0xb8, 0x08, 0x46, 0xf1, 0xae, 0x23, 0xd0,
0xf7, 0x44, 0x7d, 0x57, 0x74, 0x19, 0x83, 0xf5, 0xed, 0xf0, 0xe5, 0xbf,
0x53, 0x80, 0x06, 0xd8, 0x08, 0x36, 0xa0, 0x2d, 0xb8, 0x10, 0x60, 0x0f,
0xda, 0x85, 0x2e, 0x7e, 0xf9, 0xef, 0x14, 0xe0, 0x22, 0x18, 0x38, 0xd0,
0xc0, 0x98, 0x8f, 0x01, 0xf3, 0x41, 0x60, 0xc6, 0x0f, 0xfd, 0xf0, 0xe5,
0xbf, 0x57, 0x80, 0x06, 0x70, 0x80, 0x85, 0xb1, 0x6a, 0xc1, 0x65, 0x0f,
0x0e, 0xd8, 0xa1, 0x97, 0x7f, 0x5f, 0xc0, 0xbe, 0x02, 0x23, 0xf0, 0xba,
0x00, 0xa7, 0xe1, 0x25, 0xfe, 0x1b, 0x04, 0x14, 0x48, 0xd1, 0x9d, 0xac,
0x9a, 0x18, 0x1b, 0x02, 0x86, 0xdc, 0x85, 0x1e, 0x93, 0x8f, 0xfc, 0xb7,
0x0b, 0x70, 0x11, 0x84, 0x82, 0x51, 0xe4, 0x94, 0xc0, 0x65, 0x01, 0xc9,
0x9f, 0x5f, 0x03, 0x9f, 0x97, 0xff, 0x2d, 0x02, 0x0a, 0xa7, 0x14, 0x14,
0x2d, 0x17, 0xc7, 0x00, 0x3f, 0x19, 0x9a, 0xf5, 0x20, 0x97, 0xc0, 0x2f,
0x65, 0xef, 0x14, 0xa0, 0x82, 0x17, 0x6e, 0xde, 0x7f, 0x27, 0x60, 0x3c,
0xa1, 0xe3, 0x5b, 0xf0, 0xdf, 0x2a, 0x40, 0x05, 0xe3, 0x48, 0x0f, 0x79,
0x9b, 0x8f, 0x01, 0x0e, 0x02, 0x85, 0x98, 0xb7, 0xf8, 0x09, 0xf8, 0xef,
0x17, 0x30, 0x8e, 0x91, 0x0a, 0x0a, 0x35, 0xb9, 0x8d, 0x00, 0x3e, 0x1b,
0x24, 0x04, 0xf2, 0x52, 0x5f, 0x13, 0x1f, 0xfe, 0x37, 0x09, 0x50, 0xc1,
0x93, 0x96, 0x07, 0x17, 0x05, 0x3c, 0x0d, 0xf0, 0x00, 0xfc, 0xb7, 0x0b,
0x50, 0xc1, 0x38, 0x9a, 0xbf, 0xf2, 0x6b, 0x20, 0xa3, 0xc0, 0xbf, 0xe0,
0x7f, 0x86, 0x00, 0x15, 0x04, 0x35, 0xf8, 0x3c, 0x6f, 0x39, 0x40, 0x41,
0x90, 0x83, 0xff, 0x19, 0x02, 0x54, 0x50, 0x1a, 0xe2, 0x92, 0x5e, 0x88,
0x40, 0x46, 0x81, 0x22, 0x2d, 0xf0, 0xbc, 0x80, 0xff, 0x59, 0x02, 0x92,
0x3f, 0x6e, 0xf9, 0xb0, 0xee, 0xb6, 0x40, 0xf2, 0x85, 0x81, 0xb8, 0x41,
0xff, 0x81, 0x02, 0xa2, 0xe1, 0x55, 0xe1, 0x00, 0x50, 0x6f, 0x88, 0x30,
0x0e, 0x88, 0x1d, 0xbf, 0xfe, 0x4c, 0x01, 0x2a, 0x48, 0x07, 0xdc, 0x6d,
0x81, 0xa0, 0x8f, 0x7b, 0x3c, 0xac, 0xcb, 0x07, 0x0b, 0xd0, 0x01, 0xe4,
0x2c, 0xff, 0xc1, 0x36, 0xc0, 0x41, 0x5c, 0x3e, 0x5a, 0x00, 0xff, 0x32,
0x12, 0x4c, 0x3f, 0x2c, 0x20, 0x21, 0x7f, 0xf6, 0x1d, 0x02, 0x74, 0xc0,
0xd5, 0x67, 0x65, 0x11, 0x78, 0xfd, 0x46, 0x01, 0x22, 0x67, 0xfa, 0x89,
0xaf, 0x07, 0xe1, 0xbf, 0x4e, 0xc0, 0x20, 0xf5, 0xe2, 0x91, 0x06, 0xc8,
0xc4, 0xf1, 0xdd, 0x02, 0x78, 0x22, 0x1e, 0xab, 0xc0, 0xc7, 0x5f, 0x25,
0x60, 0xff, 0xe9, 0x44, 0xff, 0x7e, 0x01, 0xfd, 0x13, 0x8b, 0xfd, 0x25,
0x02, 0xbe, 0xff, 0xcf, 0x9f, 0x80, 0x3f, 0x01, 0x7f, 0x02, 0xfe, 0x01,
0x75, 0xe2, 0x8b, 0x93, 0x95, 0x3a, 0x44, 0x8f, 0x00, 0x00, 0x00, 0x00,
0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
unsigned int particle_png_len = 5564;
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

+133
View File
@@ -0,0 +1,133 @@
#include <rw.h>
#include <string.h>
#include "vfs.h"
struct FILE_VFS
{
int used;
rw::uint8 *data;
int pos;
int size;
};
FILE_VFS vfsfiles[64];
VFS *globalVFS;
void*
vfs_fopen(const char *path, const char *mode)
{
int flags = 0;
int i, j;
char *r, *w, *plus;
// printf("trying to open <%s> mode <%s>\n", path, mode);
const char *file = strrchr((char*)path, '/');
if(file)
file++;
else
file = path;
for(i = 0; i < nelem(vfsfiles); i++){
if(!vfsfiles[i].used)
goto found;
}
// no file pointer available
return nil;
found:
// why can't we pass const char*? urghhh....
r = strchr((char*)mode, 'r');
w = strchr((char*)mode, 'w');
plus = strchr((char*)mode, '+');
// cannot write files
if(w || plus)
return nil;
for(j = 0; j < globalVFS->numFiles; j++){
if(strcmp(globalVFS->files[j].name, file) == 0)
goto found2;
}
// file not found
return nil;
found2:
vfsfiles[i].used = 1;
vfsfiles[i].data = globalVFS->files[j].data;
vfsfiles[i].pos = 0;
vfsfiles[i].size = globalVFS->files[j].length;
return &vfsfiles[i];
}
int
vfs_fclose(void *fp)
{
FILE_VFS *f = (FILE_VFS*)fp;
if(!f->used)
return EOF;
f->used = 0;
f->data = nil;
return 0;
}
int
vfs_fseek(void *fp, long offset, int whence)
{
FILE_VFS *f = (FILE_VFS*)fp;
switch(whence){
case 0:
f->pos = offset;
break;
case 1:
f->pos += offset;
break;
case 2:
f->pos = f->size - offset;
break;
}
if(f->pos > f->size) f->pos = f->size;
return f->pos;
}
long
vfs_ftell(void *fp)
{
FILE_VFS *f = (FILE_VFS*)fp;
return f->pos;
}
size_t
vfs_fread(void *ptr, size_t size, size_t nmemb, void *fp)
{
FILE_VFS *f = (FILE_VFS*)fp;
size_t sz = size*nmemb;
if(sz > f->size-f->pos)
sz = f->size-f->pos;
memcpy(ptr, f->data+f->pos, sz);
f->pos += sz;
return sz/size;
}
size_t
vfs_fwrite(const void *ptr, size_t size, size_t nmemb, void *fp)
{
return 0;
}
int
vfs_feof(void *fp)
{
FILE_VFS *f = (FILE_VFS*)fp;
return f->pos >= f->size;
}
void
installVFS(VFS *vfs)
{
globalVFS = vfs;
rw::engine->filefuncs.rwfopen = vfs_fopen;
rw::engine->filefuncs.rwfclose = vfs_fclose;
rw::engine->filefuncs.rwfseek = vfs_fseek;
rw::engine->filefuncs.rwftell = vfs_ftell;
rw::engine->filefuncs.rwfread = vfs_fread;
rw::engine->filefuncs.rwfwrite = vfs_fwrite;
rw::engine->filefuncs.rwfeof = vfs_feof;
}
+15
View File
@@ -0,0 +1,15 @@
struct VFS_file
{
const char *name;
rw::uint8 *data;
rw::uint32 length;
};
struct VFS
{
// TODO: directories?
VFS_file *files;
int numFiles;
};
void installVFS(VFS *vfs);
+1 -1
View File
@@ -377,7 +377,7 @@ DrawDirectLight(void)
void
DrawCurrentLight(void)
{
rw::SetRenderState(rw::TEXTURERASTER, nil);
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::SetRenderState(rw::CULLMODE, rw::CULLBACK);
rw::SetRenderState(rw::ZTESTENABLE, 1);
+5 -5
View File
@@ -302,8 +302,8 @@ InitRW(void)
camera->m_aspectRatio = 640.0f/448.0f;
// camera->m_near = 0.5f;
camera->m_near = 1.5f;
// camera->m_far = 450.0f;
camera->m_far = 15.0f;
camera->m_far = 450.0f;
// camera->m_far = 15.0f;
camera->m_target.set(0.0f, 0.0f, 0.0f);
camera->m_position.set(0.0f, -10.0f, 0.0f);
// camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
@@ -497,7 +497,7 @@ Draw(float timeDelta)
getFrontBuffer();
rw::SetRenderState(rw::FOGCOLOR, 0xFF0000FF);
rw::SetRenderState(rw::FOGENABLE, 1);
// rw::SetRenderState(rw::FOGENABLE, 1);
camera->m_rwcam->fogPlane = camera->m_rwcam->nearPlane;
static rw::RGBA clearcol = { 161, 161, 161, 0xFF };
@@ -517,7 +517,7 @@ extern void endSoftras(void);
endSoftras();
}
//im2dtest();
im2dtest2();
//im2dtest2();
// Scene.clump->render();
// im3dtest();
@@ -525,7 +525,7 @@ extern void endSoftras(void);
// testfont->print("foo ABC", 200, 200, true);
// rendersplines();
rendersplines();
camera->m_rwcam->endUpdate();
+240 -10
View File
@@ -59,6 +59,20 @@ AddVertex(const rw::V3d &vert)
float epsilon = 0.000001;
class BezierSurf
{
public:
// hardcoded 4x4 for now
V3d verts[16];
void mirrorX(void);
void mirrorY(void);
V3d eval(float u, float v);
void drawHull(void);
void drawShaded(void);
};
class RBCurve
{
public:
@@ -126,6 +140,113 @@ evalBasisFast(int i, int d, float u, float knots[])
return tmp[0];
}
void
BezierSurf::mirrorX(void)
{
int i;
for(i = 0; i < 16; i++)
verts[i].x = -verts[i].x;
}
void
BezierSurf::mirrorY(void)
{
int i;
for(i = 0; i < 16; i++)
verts[i].y = -verts[i].y;
}
V3d
BezierSurf::eval(float u, float v)
{
int i, j;
V3d out = { 0.0f, 0.0f, 0.0f };
float us[4], vs[4];
float iu = 1.0f-u;
float iv = 1.0f-v;
us[0] = iu*iu*iu;
us[1] = 3.0f*u*iu*iu;
us[2] = 3.0f*u*u*iu;
us[3] = u*u*u;
vs[0] = iv*iv*iv;
vs[1] = 3.0f*v*iv*iv;
vs[2] = 3.0f*v*v*iv;
vs[3] = v*v*v;
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++)
out = add(out, scale(verts[j+i*4],us[j]*vs[i]));
return out;
}
void
BezierSurf::drawHull(void)
{
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::SetRenderState(rw::FOGENABLE, 0);
imVert.setU(0.0f);
imVert.setV(0.0f);
imVert.setColor(138, 72, 51, 255);
// imVert.setColor(228, 172, 121, 255);
int iu, iv;
for(iv = 0; iv < 4; iv++){
BeginIm3D(rw::PRIMTYPEPOLYLINE);
for(iu = 0; iu < 4; iu++)
AddVertex(verts[iu + iv*4]);
EndIm3D();
}
for(iu = 0; iu < 4; iu++){
BeginIm3D(rw::PRIMTYPEPOLYLINE);
for(iv = 0; iv < 4; iv++)
AddVertex(verts[iu + iv*4]);
EndIm3D();
}
}
void
BezierSurf::drawShaded(void)
{
V3d vert;
int iu, iv;
float u, v;
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::SetRenderState(rw::FOGENABLE, 0);
imVert.setU(0.0f);
imVert.setV(0.0f);
imVert.setColor(0, 128, 240, 255);
float endu = 1.0f - epsilon;
float endv = 1.0f - epsilon;
float uinc = (endu-0.0f)/40.0f;
float vinc = (endv-0.0f)/40.0f;
float vnext;
for(v = 0.0f;; v = vnext){
if(v > endv)
v = endv;
vnext = v + vinc;
BeginIm3D(rw::PRIMTYPETRISTRIP);
for(u = 0.0f;; u += uinc){
if(u > endu)
u = endu;
AddVertex(eval(u, v));
AddVertex(eval(u, vnext));
if(u >= endu)
break;
}
EndIm3D();
if(vnext >= endv)
break;
}
}
V3d
RBCurve::eval(float u)
{
@@ -153,7 +274,7 @@ RBCurve::drawHull(void)
{
int i;
rw::SetRenderState(rw::TEXTURERASTER, nil);
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::SetRenderState(rw::FOGENABLE, 0);
BeginIm3D(rw::PRIMTYPEPOLYLINE);
@@ -173,7 +294,7 @@ RBCurve::drawSpline(void)
float u, endu;
V3d vert;
rw::SetRenderState(rw::TEXTURERASTER, nil);
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::SetRenderState(rw::FOGENABLE, 0);
BeginIm3D(rw::PRIMTYPEPOLYLINE);
imVert.setU(0.0f);
@@ -238,7 +359,7 @@ RBSurf::eval(float u, float v)
void
RBSurf::drawHull(void)
{
rw::SetRenderState(rw::TEXTURERASTER, nil);
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::SetRenderState(rw::FOGENABLE, 0);
imVert.setU(0.0f);
@@ -269,7 +390,7 @@ RBSurf::drawIsoparms(void)
int iu, iv;
float u, v;
rw::SetRenderState(rw::TEXTURERASTER, nil);
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::SetRenderState(rw::FOGENABLE, 0);
imVert.setU(0.0f);
@@ -323,7 +444,7 @@ RBSurf::drawShaded(void)
int iu, iv;
float u, v;
rw::SetRenderState(rw::TEXTURERASTER, nil);
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::SetRenderState(rw::FOGENABLE, 0);
imVert.setU(0.0f);
@@ -362,6 +483,92 @@ RBSurf::drawShaded(void)
RBCurve testspline1, testspline2;
RBSurf testsurf;
V3d teapotVerts[] = {
{ 0.2000, 0.0000, 2.70000 }, { 0.2000, -0.1120, 2.70000 },
{ 0.1120, -0.2000, 2.70000 }, { 0.0000, -0.2000, 2.70000 },
{ 1.3375, 0.0000, 2.53125 }, { 1.3375, -0.7490, 2.53125 },
{ 0.7490, -1.3375, 2.53125 }, { 0.0000, -1.3375, 2.53125 },
{ 1.4375, 0.0000, 2.53125 }, { 1.4375, -0.8050, 2.53125 },
{ 0.8050, -1.4375, 2.53125 }, { 0.0000, -1.4375, 2.53125 },
{ 1.5000, 0.0000, 2.40000 }, { 1.5000, -0.8400, 2.40000 },
{ 0.8400, -1.5000, 2.40000 }, { 0.0000, -1.5000, 2.40000 },
{ 1.7500, 0.0000, 1.87500 }, { 1.7500, -0.9800, 1.87500 },
{ 0.9800, -1.7500, 1.87500 }, { 0.0000, -1.7500, 1.87500 },
{ 2.0000, 0.0000, 1.35000 }, { 2.0000, -1.1200, 1.35000 },
{ 1.1200, -2.0000, 1.35000 }, { 0.0000, -2.0000, 1.35000 },
{ 2.0000, 0.0000, 0.90000 }, { 2.0000, -1.1200, 0.90000 },
{ 1.1200, -2.0000, 0.90000 }, { 0.0000, -2.0000, 0.90000 },
{ -2.0000, 0.0000, 0.90000 }, { 2.0000, 0.0000, 0.45000 },
{ 2.0000, -1.1200, 0.45000 }, { 1.1200, -2.0000, 0.45000 },
{ 0.0000, -2.0000, 0.45000 }, { 1.5000, 0.0000, 0.22500 },
{ 1.5000, -0.8400, 0.22500 }, { 0.8400, -1.5000, 0.22500 },
{ 0.0000, -1.5000, 0.22500 }, { 1.5000, 0.0000, 0.15000 },
{ 1.5000, -0.8400, 0.15000 }, { 0.8400, -1.5000, 0.15000 },
{ 0.0000, -1.5000, 0.15000 }, { -1.6000, 0.0000, 2.02500 },
{ -1.6000, -0.3000, 2.02500 }, { -1.5000, -0.3000, 2.25000 },
{ -1.5000, 0.0000, 2.25000 }, { -2.3000, 0.0000, 2.02500 },
{ -2.3000, -0.3000, 2.02500 }, { -2.5000, -0.3000, 2.25000 },
{ -2.5000, 0.0000, 2.25000 }, { -2.7000, 0.0000, 2.02500 },
{ -2.7000, -0.3000, 2.02500 }, { -3.0000, -0.3000, 2.25000 },
{ -3.0000, 0.0000, 2.25000 }, { -2.7000, 0.0000, 1.80000 },
{ -2.7000, -0.3000, 1.80000 }, { -3.0000, -0.3000, 1.80000 },
{ -3.0000, 0.0000, 1.80000 }, { -2.7000, 0.0000, 1.57500 },
{ -2.7000, -0.3000, 1.57500 }, { -3.0000, -0.3000, 1.35000 },
{ -3.0000, 0.0000, 1.35000 }, { -2.5000, 0.0000, 1.12500 },
{ -2.5000, -0.3000, 1.12500 }, { -2.6500, -0.3000, 0.93750 },
{ -2.6500, 0.0000, 0.93750 }, { -2.0000, -0.3000, 0.90000 },
{ -1.9000, -0.3000, 0.60000 }, { -1.9000, 0.0000, 0.60000 },
{ 1.7000, 0.0000, 1.42500 }, { 1.7000, -0.6600, 1.42500 },
{ 1.7000, -0.6600, 0.60000 }, { 1.7000, 0.0000, 0.60000 },
{ 2.6000, 0.0000, 1.42500 }, { 2.6000, -0.6600, 1.42500 },
{ 3.1000, -0.6600, 0.82500 }, { 3.1000, 0.0000, 0.82500 },
{ 2.3000, 0.0000, 2.10000 }, { 2.3000, -0.2500, 2.10000 },
{ 2.4000, -0.2500, 2.02500 }, { 2.4000, 0.0000, 2.02500 },
{ 2.7000, 0.0000, 2.40000 }, { 2.7000, -0.2500, 2.40000 },
{ 3.3000, -0.2500, 2.40000 }, { 3.3000, 0.0000, 2.40000 },
{ 2.8000, 0.0000, 2.47500 }, { 2.8000, -0.2500, 2.47500 },
{ 3.5250, -0.2500, 2.49375 }, { 3.5250, 0.0000, 2.49375 },
{ 2.9000, 0.0000, 2.47500 }, { 2.9000, -0.1500, 2.47500 },
{ 3.4500, -0.1500, 2.51250 }, { 3.4500, 0.0000, 2.51250 },
{ 2.8000, 0.0000, 2.40000 }, { 2.8000, -0.1500, 2.40000 },
{ 3.2000, -0.1500, 2.40000 }, { 3.2000, 0.0000, 2.40000 },
{ 0.0000, 0.0000, 3.15000 }, { 0.8000, 0.0000, 3.15000 },
{ 0.8000, -0.4500, 3.15000 }, { 0.4500, -0.8000, 3.15000 },
{ 0.0000, -0.8000, 3.15000 }, { 0.0000, 0.0000, 2.85000 },
{ 1.4000, 0.0000, 2.40000 }, { 1.4000, -0.7840, 2.40000 },
{ 0.7840, -1.4000, 2.40000 }, { 0.0000, -1.4000, 2.40000 },
{ 0.4000, 0.0000, 2.55000 }, { 0.4000, -0.2240, 2.55000 },
{ 0.2240, -0.4000, 2.55000 }, { 0.0000, -0.4000, 2.55000 },
{ 1.3000, 0.0000, 2.55000 }, { 1.3000, -0.7280, 2.55000 },
{ 0.7280, -1.3000, 2.55000 }, { 0.0000, -1.3000, 2.55000 },
{ 1.3000, 0.0000, 2.40000 }, { 1.3000, -0.7280, 2.40000 },
{ 0.7280, -1.3000, 2.40000 }, { 0.0000, -1.3000, 2.40000 }
};
int teapotPatches[10][16] = {
{ 118, 118, 118, 118, 124, 122, 119, 121,
123, 126, 125, 120, 40, 39, 38, 37 },
{ 102, 103, 104, 105, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15 },
{ 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27 },
{ 24, 25, 26, 27, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40 },
{ 96, 96, 96, 96, 97, 98, 99, 100,
101, 101, 101, 101, 0, 1, 2, 3 },
{ 0, 1, 2, 3, 106, 107, 108, 109,
110, 111, 112, 113, 114, 115, 116, 117 },
{ 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56 },
{ 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 28, 65, 66, 67 },
{ 68, 69, 70, 71, 72, 73, 74, 75,
76, 77, 78, 79, 80, 81, 82, 83 },
{ 80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95 },
};
BezierSurf teapotSurfs[32];
void
initsplines(void)
{
@@ -412,6 +619,7 @@ initsplines(void)
V(-61.9913, 9.158239, 0);
V(-32.32231, 27.23371, 0);
V(25.80961, -4.820126, 0);
#undef V
testspline2.knots.clear();
testspline2.knots.push_back(0);
testspline2.knots.push_back(0);
@@ -479,6 +687,7 @@ initsplines(void)
V(25.75483, 70.07219, 31.27717);
V(56.61724, 70.07219, -2.498198);
V(86.35364, 70.07219, 12.53265);
#undef V
testsurf.knotsU.clear();
testsurf.knotsU.push_back(0);
testsurf.knotsU.push_back(0);
@@ -503,18 +712,39 @@ initsplines(void)
testsurf.knotsV.push_back(1);
testsurf.update();
int i, j;
for(i = 0; i < 10; i++)
for(j = 0; j < 16; j++)
teapotSurfs[i].verts[j] = teapotVerts[teapotPatches[i][j]];
for(i = 0; i < 10; i++){
teapotSurfs[i+10] = teapotSurfs[i];
teapotSurfs[i+10].mirrorY();
}
for(i = 0; i < 6; i++){
teapotSurfs[i+20] = teapotSurfs[i];
teapotSurfs[i+20].mirrorX();
teapotSurfs[i+20+6] = teapotSurfs[i+10];
teapotSurfs[i+20+6].mirrorX();
}
}
void
rendersplines(void)
{
testspline1.drawHull();
testspline1.drawSpline();
// testspline1.drawHull();
// testspline1.drawSpline();
// testspline2.drawHull();
// testspline2.drawSpline();
testsurf.drawHull();
testsurf.drawShaded();
testsurf.drawIsoparms();
// testsurf.drawHull();
// testsurf.drawShaded();
// testsurf.drawIsoparms();
int i;
for(i = 0; i < 32; i++){
teapotSurfs[i].drawHull();
teapotSurfs[i].drawShaded();
}
}
+1
View File
@@ -1,5 +1,6 @@
#include <cstdio>
#include <cassert>
#include <cerrno>
#define PAL
+5 -1
View File
@@ -7,10 +7,14 @@ target_link_libraries(ska2anm
librw::librw
)
librw_platform_target(ska2anm INSTALL)
if(LIBRW_GL3_GFXLIB MATCHES "SDL[23]")
target_compile_definitions(ska2anm PRIVATE SDL_MAIN_HANDLED)
endif()
if(LIBRW_INSTALL)
install(TARGETS ska2anm
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
endif()
librw_platform_target(ska2anm INSTALL)