Initial commit

This commit is contained in:
Shinovon 2026-04-22 07:30:27 +05:00
commit 77cdaaf97e
827 changed files with 418745 additions and 0 deletions

32
vendor/librw/.appveyor.yml vendored Normal file
View file

@ -0,0 +1,32 @@
image: Visual Studio 2017
configuration: Release
environment:
GLFW_BASE: glfw-3.3.4.bin.WIN64
GLFW_URL: https://github.com/glfw/glfw/releases/download/3.3.4/%GLFW_BASE%.zip
SDL2_BASE: SDL2-devel-2.0.14-VC
SDL2_URL: https://www.libsdl.org/release/%SDL2_BASE%.zip
SDL2_DIRAME: SDL2-2.0.14
PREMAKE5_URL: https://github.com/premake/premake-core/releases/download/v5.0.0-alpha16/premake-5.0.0-alpha16-windows.zip
matrix:
- PLATFORM: win-amd64-null
- PLATFORM: win-amd64-gl3
PREMAKE5_EXTRA_ARGS: --gfxlib=glfw
- PLATFORM: win-amd64-gl3
PREMAKE5_EXTRA_ARGS: --gfxlib=sdl2
- PLATFORM: win-amd64-d3d9
install:
- appveyor DownloadFile %GLFW_URL% -FileName "%APPVEYOR_BUILD_FOLDER%/%GLFW_BASE%.zip"
- 7z x "%APPVEYOR_BUILD_FOLDER%/%GLFW_BASE%.zip"
- appveyor DownloadFile %SDL2_URL% -FileName "%APPVEYOR_BUILD_FOLDER%/%SDL2_BASE%.zip"
- 7z x "%APPVEYOR_BUILD_FOLDER%/%SDL2_BASE%.zip"
- appveyor DownloadFile %PREMAKE5_URL% -FileName "%APPVEYOR_BUILD_FOLDER%/premake5.zip"
- mkdir "%APPVEYOR_BUILD_FOLDER%/bin" && cd "%APPVEYOR_BUILD_FOLDER%/bin" && 7z x "%APPVEYOR_BUILD_FOLDER%/premake5.zip"
- set PATH=%APPVEYOR_BUILD_FOLDER%/bin;%PATH%
before_build:
- mkdir "%APPVEYOR_BUILD_FOLDER%/build"
- cd "%APPVEYOR_BUILD_FOLDER%"
- premake5 vs2017 --glfwdir64=%APPVEYOR_BUILD_FOLDER%/%GLFW_BASE% --sdl2dir=%APPVEYOR_BUILD_FOLDER%/%SDL2_DIRAME% %PREMAKE5_EXTRA_ARGS%
build:
project: c:\projects\librw\build\librw.sln
verbosity: minimal

View file

@ -0,0 +1,60 @@
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

View file

@ -0,0 +1,29 @@
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

View file

@ -0,0 +1,26 @@
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

10
vendor/librw/.gitignore vendored Normal file
View file

@ -0,0 +1,10 @@
/bin
/build
/obj
/lib
/output
/.vs
librw.vcxproj.user
librw.VC.db
librw.VC.VC.opendb
imgui.ini

46
vendor/librw/.travis.yml vendored Normal file
View file

@ -0,0 +1,46 @@
language: cpp
matrix:
include:
- os: linux
env: TARGET=release_linux-amd64-null
script:
- mkdir -p "$TRAVIS_BUILD_DIR/build"
#- docker build -t librw "$TRAVIS_BUILD_DIR"
#- docker run -v "$TRAVIS_BUILD_DIR:/librw:rw,z" --name librw_instance -d librw sleep infinity
- docker pull librw/librw
- docker run -v "$TRAVIS_BUILD_DIR:/librw:rw,z" -v "$TRAVIS_BUILD_DIR/build:/build:rw,z" --name librw_instance -d librw/librw sleep infinity
- docker exec -u builder librw_instance /bin/bash -c "cd /librw && premake5 gmake && cd /librw/build && make config=$TARGET verbose=1"
- os: linux
env: TARGET=release_linux-amd64-gl3 GFXLIB=glfw
services: docker
script:
- mkdir -p "$TRAVIS_BUILD_DIR/build"
#- docker build -t librw "$TRAVIS_BUILD_DIR"
#- docker run -v "$TRAVIS_BUILD_DIR:/librw:rw,z" --name librw_instance -d librw sleep infinity
- docker pull librw/librw
- docker run -v "$TRAVIS_BUILD_DIR:/librw:rw,z" -v "$TRAVIS_BUILD_DIR/build:/build:rw,z" --name librw_instance -d librw/librw sleep infinity
- docker exec -u builder librw_instance /bin/bash -c "cd /librw && premake5 --gfxlib=$GFXLIB gmake && cd /librw/build && make config=$TARGET verbose=1"
- os: linux
env: TARGET=release_linux-amd64-gl3 GFXLIB=sdl2
services: docker
script:
- mkdir -p "$TRAVIS_BUILD_DIR/build"
#- docker build -t librw "$TRAVIS_BUILD_DIR"
#- docker run -v "$TRAVIS_BUILD_DIR:/librw:rw,z" --name librw_instance -d librw sleep infinity
- docker pull librw/librw
- docker run -v "$TRAVIS_BUILD_DIR:/librw:rw,z" -v "$TRAVIS_BUILD_DIR/build:/build:rw,z" --name librw_instance -d librw/librw sleep infinity
- docker exec -u builder librw_instance /bin/bash -c "cd /librw && premake5 --gfxlib=$GFXLIB gmake && cd /librw/build && make config=$TARGET verbose=1"
- name: "ps2"
os: linux
env: TARGET=release_ps2
services: docker
script:
- mkdir -p "$TRAVIS_BUILD_DIR/build"
#- docker build -t librw "$TRAVIS_BUILD_DIR"
#- docker run -v "$TRAVIS_BUILD_DIR:/librw:rw,z" --name librw_instance -d librw sleep infinity
- docker pull librw/librw
- docker run -v "$TRAVIS_BUILD_DIR:/librw:rw,z" -v "$TRAVIS_BUILD_DIR/build:/build:rw,z" --name librw_instance -d librw/librw sleep infinity
- docker exec -u builder librw_instance /bin/bash -c "cd /librw && premake5 gmake && cd /librw/build && make config=$TARGET verbose=1"
allow_failures:
- name: "ps2"

174
vendor/librw/ARCHITECTURE.MD vendored Normal file
View file

@ -0,0 +1,174 @@
This document gives an overview of the architecture of librw.
Disclaimer: Some of these design decision were taken over from original RW,
some are my own. I only take partial responsibility.
Differently from original RW, librw has no neat separation into modules.
Some things could be made optional, but in particular RW's RpWorld
plugin is integrated with everything else.
# Plugins
To extend structs with custom data,
RW (and librw) provides a plugin mechanism
for certain structs.
This can be used to tack more data onto a struct
and register custom streaming functions.
Plugins must be registered before any instance
of that struct is allocated.
# Pipelines
RW's pipeline architecture was designed for very flexible data flow.
Unfortunately for RW most of the rendering pipeline moved into the GPU
causing RW's pipeline architecture to be severely overengineered.
librw's pipeline architecture is therefore much simplified
and only implements what is actually needed,
but the name *pipeline* is retained.
Three pipelines are implemented in librw itself:
Default, Skin, MatFX (only env map so far).
Others can be implemented by applications using librw.
# RW Objects
## Frame
A Frame is an orientation in space, arranged in a hierarchy.
Camera, Lights and Atomics can be attached to it.
It has two matrices: a (so called) model matrix,
which is relative to its parent,
and a local transformation matrix (LTM) which is relative to the world.
The LTM is updated automatically as needed whenever the hierarchy gets dirty.
## Camera
A Camera is attached to a Frame to position it in space
and has a framebuffer and a z-buffer attached to render to.
Rendering is started by `beginUpdate` and ended by `endUpdate`.
This sets up things like framebuffers and matrices
so that the Camera's raster can be rendered to.
## Light
Lights are attached to a Frame to position it in space.
They are used to light Atomics for rendering.
Different types of light are possible.
## Geometry
A Geometry contains the raw geometry data that can be rendered.
It has a list of materials that are applied to its triangles.
The latter are sorted by materials into meshes for easier instancing.
## Atomic
An Atomic is attached to a Frame to position it in space
and references a Geometry.
Atomics are the objects that are rendered by pipelines.
## Clump
A Clump is a container of Atomics, Lights and Cameras.
Clumps can be read from and written to DFF files.
Rendering a Clump will be render all of its Atomics.
# Engine
Due to the versatility of librw,
there are three levels of code:
Platform indpendent code,
platform specific code,
and render device specific code.
The second category does not exist in original RW,
but because librw is supposed to be able to
convert between all sorts of platform specific files,
the code for that has to be available no matter
the render platform used.
The common interface for all device-independent
platform code is the `Driver` struct.
The `Engine` struct has an array with one for each platform.
The render device specific code
is used for actually rendering something to the screen.
The common interface for the device-dependent
code is the `Device` struct and the `Engine`
struct only has a single one, as there can only be one render device
(i.e. you cannot select D3D or OpenGL at runtime).
Thus when implementing a new backend
you have to implement the `Driver` and `Device` interfaces.
But do note that the `Driver` can be extended with plugins!
# Driver
The driver is mostly concerned with conversion
between platform independent data to platform dependent one, and vice versa.
This concerns the following two cases.
## Raster, Images
Images contain platform independent uncompressed pixel data.
Rasters contain platform dependent (and possibly compressed) pixel data.
A driver has to be able to convert an image to a raster for the purposes of loading textures
from files or having them converted from foreign rasters.
Converting from rasters to images is not absolutely necessary but it's needed e.g. for taking screenshots.
librw has a set of default raster formats that the platform is
expected to implement for the most part, however not all have to be supported necessarily.
A driver is also free to implement its own formats;
this is done for texture compression.
Rasters have different types,
`TEXTURE` and `CAMERATEXTURE` rasters can be used as textures,
`CAMERA` and `CAMERATEXTURE` can be used as render targets,
`ZBUFFER` is used as a depth-buffer.
## Pipelines
A librw ObjPipeline implements essentially
an instance stage which converts platform independent geometry
to a format that can efficiently be rendered,
and a render stage that actually renders it.
(There is also an uninstance function,
but this is only used to convert platform specific geometry back to the generic format
and hence is not necessary.)
# Device
The device implements everything that is actually needed for rendering.
This includes starting, handling and closing the rendering device,
setting render states,
allocating and destroying buffers and textures,
im2d and im3d rendering,
and the render functions of the pipelines.
## System
The `system` function implements certain device requests
from the engine (why these aren't separate functions I don't know, RW design).
The `Engine` is started in different stages, at various points of which
the render device gets different requests.
At the end the device is initialized and ready for rendering.
A similar but reverse sequence happens on shutdown.
Subsystems (screens) and video modes are queried through
the `system` by the application before the device is started.
## Immediate mode
Im2d and im3d are immediate-mode style rendering interface.
## Pipelines
For instancing the typical job is to allocate and fill
a struct to hold some data about an atomic,
an array of structs for all the meshes,
and vertex and index buffers to hold geometry for rendering.
The render function will render the previously instanced
data by doing a per-object setup and then iterating over
and rendering all the meshes.

160
vendor/librw/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,160 @@
set(librw_MAINPROJECT ON)
if(DEFINED PROJECT_NAME)
set(librw_MAINPROJECT OFF)
endif()
cmake_minimum_required(VERSION 3.8)
project(librw
VERSION 0.0.1
LANGUAGES C CXX
)
set(librw_AUTHOR aap)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
if(WIN32)
set(LIBRW_PLATFORMS "NULL" "GL3" "D3D9")
set(LIBRW_PLATFORM_GL3_REQUIRES_OPENGL ON)
elseif(NINTENDO_SWITCH)
set(LIBRW_PLATFORMS "NULL" "GL3")
set(LIBRW_PLATFORM_GL3_REQUIRES_OPENGL OFF)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/nx")
include(NXFunctions)
elseif(PS2)
set(LIBRW_PLATFORMS "PS2")
set(LIBRW_PLATFORM_GL3_REQUIRES_OPENGL OFF)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ps2")
include(PS2Functions)
else()
set(LIBRW_PLATFORMS "NULL" "GL3")
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_property(CACHE LIBRW_PLATFORM PROPERTY STRINGS ${LIBRW_PLATFORMS})
message(STATUS "LIBRW_PLATFORM = ${LIBRW_PLATFORM} (choices=${LIBRW_PLATFORMS})")
set("LIBRW_PLATFORM_${LIBRW_PLATFORM}" ON)
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}")
endif()
if(LIBRW_PLATFORM_PS2)
enable_language(DSM)
endif()
if(NOT COMMAND librw_platform_target)
function(librw_platform_target)
endfunction()
endif()
include(CMakeDependentOption)
option(LIBRW_TOOLS "Build librw tools" ${librw_MAINPROJECT})
option(LIBRW_INSTALL "Install librw files" ${librw_MAINPROJECT})
cmake_dependent_option(LIBRW_EXAMPLES "Build librw examples" ON "LIBRW_TOOLS;NOT LIBRW_PLATFORM_NULL" OFF)
if(LIBRW_INSTALL)
include(GNUInstallDirs)
set(LIBRW_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/librw")
endif()
add_subdirectory(src)
if(LIBRW_TOOLS AND NOT LIBRW_PLATFORM_PS2 AND NOT LIBRW_PLATFORM_NULL)
add_subdirectory(skeleton)
endif()
add_subdirectory(tools)
if(LIBRW_INSTALL)
include(CMakePackageConfigHelpers)
configure_package_config_file(cmake/librw-config.cmake.in librw-config.cmake
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}"
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/librw-config.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(
EXPORT librw-targets NAMESPACE librw::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
if(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
install(
FILES "${CMAKE_CURRENT_LIST_DIR}/cmake/FindSDL2.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake"
)
endif()
string(REPLACE "." ";" cmake_c_compiler_version_list "${CMAKE_C_COMPILER_VERSION}")
list(GET cmake_c_compiler_version_list 0 cmake_c_compiler_version_major)
string(TOLOWER "${LIBRW_PLATFORM}" librw_platform)
set(compiler)
set(os)
if(NOT LIBRW_PLATFORM STREQUAL "PS2")
if(MSVC)
set(compiler "-msvc${MSVC_VERSION}")
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(compiler "-gcc${cmake_c_compiler_version_major}")
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(compiler "-clang${cmake_c_compiler_version_major}")
elseif(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(compiler "-appleclang${cmake_c_compiler_version_major}")
else()
set(compiler "-UNK")
message(WARNING "Unknown compiler. Created cpack package will be wrong. (override using cpack -P)")
endif()
endif()
if(LIBRW_PLATFORM_NULL)
set(platform "-null")
elseif(LIBRW_PLATFORM_PS2)
set(platform "-ps2")
elseif(LIBRW_PLATFORM_GL3)
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
set(platform "-gl3-glfw")
else()
set(platform "-gl3-sdl2")
endif()
elseif(LIBRW_PLATFORM_D3D9)
set(platform "-d3d9")
endif()
if(NOT LIBRW_PLATFORM_PS2)
if(WIN32)
set(os "-win")
elseif(NINTENDO_SWITCH)
set(os "-switch")
elseif(PS2)
set(os "-ps2")
elseif(APPLE)
set(os "-apple")
elseif(UNIX)
set(os "-linux")
else()
set(compiler "-UNK")
message(WARNING "Unknown os. Created cpack package will be wrong. (override using cpack -P)")
endif()
endif()
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}${platform}${os}${compiler}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A (partial) re-implementation of RenderWare Graphics")
set(CPACK_PACKAGE_VENDOR "aap")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_GENERATOR "TXZ")
include(CPack)
endif()

60
vendor/librw/Dockerfile vendored Normal file
View file

@ -0,0 +1,60 @@
FROM ubuntu:rolling
ENV PS2DEV /ps2dev
ENV PS2SDK $PS2DEV/ps2sdk
ENV PATH $PATH:$PS2DEV/bin:$PS2DEV/ee/bin:$PS2DEV/iop/bin:$PS2DEV/dvp/bin:$PS2SDK/bin
ENV DEBIAN_FRONTEND noninteractive
ENV TOOLCHAIN_GIT_URL git://github.com/ps2dev/ps2toolchain.git
ENV TOOLCHAIN_GIT_BRANCH master
ENV PREMAKE5_URL=https://github.com/premake/premake-core/releases/download/v5.0.0-alpha12/premake-5.0.0-alpha12-linux.tar.gz
RUN mkdir -p "$PS2DEV" "$PS2SDK" \
&& apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y \
build-essential \
cmake \
autoconf \
bzip2 \
gcc \
git \
libucl-dev \
make \
patch \
vim \
wget \
zip \
zlib1g-dev \
libglfw3-dev \
libsdl2-dev \
&& git clone -b $TOOLCHAIN_GIT_BRANCH $TOOLCHAIN_GIT_URL /toolchain \
&& cd /toolchain \
&& ./toolchain.sh \
&& git clone git://github.com/ps2dev/ps2eth.git /ps2dev/ps2eth \
&& make -C /ps2dev/ps2eth \
&& git clone git://github.com/ps2dev/ps2-packer.git /ps2-packer \
&& make install -C /ps2-packer \
&& rm -rf \
/ps2-packer \
/ps2dev/ps2eth/.git \
/ps2dev/ps2sdk/test.tmp \
/ps2dev/test.tmp \
/toolchain \
&& rm -rf /var/lib/apt/lists/* \
&& wget "$PREMAKE5_URL" -O /tmp/premake5.tar.gz \
&& tar xf /tmp/premake5.tar.gz -C /usr/bin/ \
&& rm /tmp/premake5.tar.gz \
&& groupadd 1000 -g 1000 \
&& groupadd 1001 -g 1001 \
&& groupadd 2000 -g 2000 \
&& groupadd 999 -g 999 \
&& useradd -ms /bin/bash builder -g 1001 -G 1000,2000,999 \
&& printf "builder:builder" | chpasswd \
&& adduser builder sudo \
&& printf "builder ALL= NOPASSWD: ALL\\n" >> /etc/sudoers
USER builder
WORKDIR /home/builder

22
vendor/librw/LICENSE vendored Normal file
View file

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014 aap
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
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.

9
vendor/librw/README.cmake vendored Normal file
View file

@ -0,0 +1,9 @@
Build with cmake
================
Linux
mkdir build
cd build
cmake .. -DLIBRW_PLATFORM=GL3 -DLIBRW_GL3_GFXLIB=SDL2
make

26
vendor/librw/README.md vendored Normal file
View file

@ -0,0 +1,26 @@
librw
=====
This library is supposed to be a re-implementation of RenderWare graphics,
or a good part of it anyway.
It is intended to be cross-platform in two senses:
support rendering on different platforms similar to RW;
supporting all file formats for all platforms at all times and provide
way to convert to all other platforms.
Supported file formats are DFF and TXD for PS2, D3D8, D3D9 and Xbox.
Not all pre-instanced PS2 DFFs are supported.
BSP is not supported at all.
For rendering we have D3D9 and OpenGL (>=2.1, ES >= 2.0) backends.
Rendering some things on the PS2 is working as a test only.
# Uses
librw can be used for rendering [GTA](https://github.com/gtamodding/re3).
# Building
Get premake5. Generate a config, e.g. with ``premake5 gmake``,
and look in the build directory.

24
vendor/librw/TODO vendored Normal file
View file

@ -0,0 +1,24 @@
TODO:
- tristrips
- examples
skeleton + interface
camtex
matfx1 (more new shaders)
hanim1
fog
imlight?
patch?
- morphing
- Pipelines (PDS, Xbox, PC)
- bsp
driver
- metrics
ps2
- rendering!
- ADC conversion
BUGS:
- fseek with negative offset on ps2 over ps2link messes up the current position

24
vendor/librw/args.h vendored Normal file
View file

@ -0,0 +1,24 @@
extern char *argv0;
#define USED(x) ((void)x)
#define SET(x) ((x)=0)
#define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\
argv[0] && argv[0][0]=='-' && argv[0][1];\
argc--, argv++) {\
char *_args, *_argt;\
char _argc;\
_args = &argv[0][1];\
if(_args[0]=='-' && _args[1]==0){\
argc--; argv++; break;\
}\
_argc = 0;\
while(*_args && (_argc = *_args++))\
switch(_argc)
#define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc);
#define ARGF() (_argt=_args, _args=(char*)"",\
(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
#define EARGF(x) (_argt=_args, _args=(char*)"",\
(*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
#define ARGC() _argc

38
vendor/librw/cmake/FindSDL2.cmake vendored Normal file
View file

@ -0,0 +1,38 @@
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(SDL2 IMPORTED_TARGET "sdl2")
if(TARGET PkgConfig::SDL2 AND NOT TARGET SDL2::SDL2)
add_library(SDL2::SDL2 INTERFACE IMPORTED)
set_property(TARGET SDL2::SDL2 PROPERTY INTERFACE_LINK_LIBRARIES PkgConfig::SDL2)
endif()
endif()
find_library(SDL2main_LIBRARY SDL2main)
if(NOT SDL2_FOUND)
find_path(SDL2_INCLUDE_DIR sdl2.h)
find_library(SDL2_LIBRARY SDL2 SDL2d)
find_library(SDL2main_LIBRARY SDL2main)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(libuv
REQUIRED_VARS SDL2_INCLUDE_DIR SDL2_LIBRARY
)
if(NOT TARGET SDL2::SDL2)
add_library(SDL2::SDL2 UNKNOWN IMPORTED)
set_target_properties(SDL2::SDL2 PROPERTIES
IMPORTED_LOCATION "${SDL2_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
)
endif()
endif()
if(SDL2main_LIBRARY AND NOT TARGET SDL2::SDL2main)
add_library(SDL2::SDL2main UNKNOWN IMPORTED)
set_target_properties(SDL2::SDL2main PROPERTIES
IMPORTED_LOCATION "${SDL2main_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
)
endif()

View file

@ -0,0 +1,22 @@
include("${CMAKE_CURRENT_LIST_DIR}/librw-targets.cmake")
set(LIBRW_PLATFORM "@LIBRW_PLATFORM@")
set(LIBRW_PLATFORMS "@LIBRW_PLATFORMS@")
set(LIBRW_PLATFORM_@LIBRW_PLATFORM@ ON)
if(LIBRW_PLATFORM_GL3)
set(LIBRW_GL3_GFXLIB "@LIBRW_GL3_GFXLIB@")
set(LIBRW_GL3_GFXLIBS "@LIBRW_GL3_GFXLIBS@")
set(OpenGL_GL_PREFERENCE GLVND)
find_package(OpenGL)
if(NOT TARGET OpenGL::OpenGL AND NOT TARGET OpenGL::EGL AND NOT TARGET OpenGL::GL)
message(FATAL_ERROR "find_package(OpenGL) failed: no target was created")
endif()
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
find_package(glfw3 REQUIRED)
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
find_package(SDL2 REQUIRED)
endif()
endif()

37
vendor/librw/cmake/nx/NXFunctions.cmake vendored Normal file
View file

@ -0,0 +1,37 @@
if(NOT COMMAND nx_generate_nacp)
message(FATAL_ERROR "The `nx_generate_nacp` cmake command is not available. Please use an appropriate Nintendo Switch toolchain.")
endif()
if(NOT COMMAND nx_create_nro)
message(FATAL_ERROR "The `nx_create_nro` cmake command is not available. Please use an appropriate Nintendo Switch toolchain.")
endif()
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
function(librw_platform_target TARGET)
cmake_parse_arguments(LPT "INSTALL" "" "" ${ARGN})
get_target_property(TARGET_TYPE "${TARGET}" TYPE)
if(TARGET_TYPE STREQUAL "EXECUTABLE")
nx_generate_nacp(${TARGET}.nacp
NAME "${TARGET}"
AUTHOR "${librw_AUTHOR}"
VERSION "${librw_VERSION}"
)
nx_create_nro(${TARGET}
NACP ${TARGET}.nacp
)
if(LIBRW_INSTALL AND LPT_INSTALL)
get_target_property(TARGET_OUTPUT_NAME ${TARGET} OUTPUT_NAME)
if(NOT TARGET_OUTPUT_NAME)
set(TARGET_OUTPUT_NAME "${TARGET}")
endif()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_OUTPUT_NAME}.nro"
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
endif()
endif()
endfunction()

View file

@ -0,0 +1,18 @@
if(NOT COMMAND add_erl_executable)
message(FATAL_ERROR "The `add_erl_executable` cmake command is not available. Please use an appropriate Playstation 2 toolchain.")
endif()
function(librw_platform_target TARGET)
cmake_parse_arguments(LPT "INSTALL" "" "" ${ARGN})
get_target_property(TARGET_TYPE "${TARGET}" TYPE)
if(TARGET_TYPE STREQUAL "EXECUTABLE")
add_erl_executable(${TARGET} OUTPUT_VAR ERL_FILE)
if(LIBRW_INSTALL AND LPT_INSTALL)
install(FILES "${ERL_FILE}"
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
endif()
endif()
endfunction()

View file

@ -0,0 +1,16 @@
set(CMAKE_DSM_COMPILER "@_CMAKE_DSM_COMPILER@")
set(CMAKE_DSM_COMPILER_ARG1 "@_CMAKE_DSM_COMPILER_ARG1@")
set(CMAKE_DSM_COMPILER_AR "@_CMAKE_DSM_COMPILER_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
set(CMAKE_DSM_COMPILER_RANLIB "@_CMAKE_DSM_COMPILER_RANLIB@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
set(CMAKE_DSM_COMPILER_LOADED 1)
set(CMAKE_DSM_COMPILER_ID "@_CMAKE_DSM_COMPILER_ID@")
set(CMAKE_DSM_COMPILER_VERSION "@_CMAKE_DSM_COMPILER_VERSION@")
set(CMAKE_DSM_COMPILER_ENV_VAR "@_CMAKE_DSM_COMPILER_ENV_VAR@")
@_SET_CMAKE_DSM_COMPILER_ARCHITECTURE_ID@
set(CMAKE_DSM_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_DSM_LINKER_PREFERENCE 0)
@CMAKE_DSM_COMPILER_CUSTOM_CODE@

View file

@ -0,0 +1,79 @@
if(UNIX)
set(CMAKE_DSM_OUTPUT_EXTENSION .o)
else()
set(CMAKE_DSM_OUTPUT_EXTENSION .obj)
endif()
set(CMAKE_INCLUDE_FLAG_DSM "-I")
set(CMAKE_DSM_FLAGS_INIT "$ENV{DSMFLAGS} ${CMAKE_DSM_FLAGS_INIT}")
# replace for CMake >= 3.11
foreach(c "" _DEBUG _RELEASE _MINSIZEREL _RELWITHDEBINFO)
string(STRIP "${CMAKE_DSM_FLAGS${c}_INIT}" CMAKE_DSM_FLAGS${c}_INIT)
endforeach()
set (CMAKE_DSM_FLAGS "${CMAKE_DSM_FLAGS_INIT}" CACHE STRING
"Flags used by the assembler during all build types.")
if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
get_property(_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
# default build type is none
if(NOT _GENERATOR_IS_MULTI_CONFIG AND NOT CMAKE_NO_BUILD_TYPE)
set (CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE_INIT} CACHE STRING
"Choose the type of build, options are: None, Debug Release RelWithDebInfo MinSizeRel.")
endif()
unset(_GENERATOR_IS_MULTI_CONFIG)
set (CMAKE_DSM_FLAGS_DEBUG "${CMAKE_DSM_FLAGS_DEBUG_INIT}" CACHE STRING
"Flags used by the assembler during debug builds.")
set (CMAKE_DSM_FLAGS_MINSIZEREL "${CMAKE_DSM_FLAGS_MINSIZEREL_INIT}" CACHE STRING
"Flags used by the assembler during release minsize builds.")
set (CMAKE_DSM_FLAGS_RELEASE "${CMAKE_DSM_FLAGS_RELEASE_INIT}" CACHE STRING
"Flags used by the assembler during release builds.")
set (CMAKE_DSM_FLAGS_RELWITHDEBINFO "${CMAKE_DSM_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
"Flags used by the assembler during Release with Debug Info builds.")
endif()
mark_as_advanced(CMAKE_DSM_FLAGS
CMAKE_DSM_FLAGS_DEBUG
CMAKE_DSM_FLAGS_MINSIZEREL
CMAKE_DSM_FLAGS_RELEASE
CMAKE_DSM_FLAGS_RELWITHDEBINFO
)
# WITH: cmake_initialize_per_config_variable(CMAKE_DSM_FLAGS "Flags used by the DSM compiler")
if(NOT CMAKE_DSM_COMPILE_OBJECT)
set(CMAKE_DSM_COMPILE_OBJECT "<CMAKE_DSM_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
endif()
if(NOT CMAKE_DSM_CREATE_STATIC_LIBRARY)
set(CMAKE_DSM_CREATE_STATIC_LIBRARY
"<CMAKE_DSM_COMPILER_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS> "
"<CMAKE_DSM_COMPILER_RANLIB> <TARGET>")
endif()
if(NOT CMAKE_DSM_LINK_EXECUTABLE)
set(CMAKE_DSM_LINK_EXECUTABLE
"<CMAKE_DSM_COMPILER> <FLAGS> <CMAKE_DSM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_EXECUTABLE_RUNTIME_DSM_FLAG)
set(CMAKE_EXECUTABLE_RUNTIME_DSM_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_DSM_FLAG})
endif()
if(NOT CMAKE_EXECUTABLE_RUNTIME_DSM_FLAG_SEP)
set(CMAKE_EXECUTABLE_RUNTIME_DSM_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_DSM_FLAG_SEP})
endif()
if(NOT CMAKE_EXECUTABLE_RPATH_LINK_DSM_FLAG)
set(CMAKE_EXECUTABLE_RPATH_LINK_DSM_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_DSM_FLAG})
endif()
# to be done
if(NOT CMAKE_DSM_CREATE_SHARED_LIBRARY)
set(CMAKE_DSM_CREATE_SHARED_LIBRARY)
endif()
if(NOT CMAKE_DSM_CREATE_SHARED_MODULE)
set(CMAKE_DSM_CREATE_SHARED_MODULE)
endif()

View file

@ -0,0 +1,87 @@
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
if (NOT CMAKE_DSM_COMPILER)
message(FATAL_ERROR "Need CMAKE_DSM_COMPILER set")
endif()
_cmake_find_compiler_path(DSM)
mark_as_advanced(CMAKE_DSM_COMPILER)
if (NOT CMAKE_DSM_COMPILER_ID)
# Table of per-vendor compiler id flags with expected output.
list(APPEND CMAKE_DSM_COMPILER_ID_VENDORS GNU )
set(CMAKE_DSM_COMPILER_ID_VENDOR_FLAGS_GNU "--version")
set(CMAKE_DSM_COMPILER_ID_VENDOR_REGEX_GNU "(GNU assembler)|(GCC)|(Free Software Foundation)")
include(CMakeDetermineCompilerId)
cmake_determine_compiler_id_vendor(DSM "")
endif()
if (NOT _CMAKE_TOOLCHAIN_LOCATION)
get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_DSM_COMPILER}" PATH)
endif()
if (CMAKE_DSM_COMPILER_ID)
if (CMAKE_DSM_COMPILER_VERSION)
set(_version " ${CMAKE_DSM_COMPILER_VERSION}")
else()
set(_version "")
endif()
message(STATUS "The DSM compiler identification is ${CMAKE_DSM_COMPILER_ID}${_version}")
unset(_version)
else()
message(STATUS "The DSM compiler identification is unknown")
endif()
if (NOT _CMAKE_TOOLCHAIN_PREFIX)
get_filename_component(COMPILER_BASENAME "${CMAKE_DSM_COMPILER}" NAME)
if (COMPILER_BASENAME MATCHES "^(.+1)g?as(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
endif()
endif()
set(_CMAKE_PROCESSING_LANGUAGE "DSM")
find_program(CMAKE_DSM_COMPILER_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_DSM_COMPILER_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_DSM_COMPILER_STRIP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}strip HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_DSM_COMPILER_NM NAMES ${_CMAKE_TOOLCHAIN_PREFIX}nm HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_DSM_COMPILER_OBJDUMP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objdump HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_DSM_COMPILER_OBJCOPY NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objcopy HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
unset(_CMAKE_PROCESSING_LANGUAGE)
set(CMAKE_DSM_COMPILER_ENV_VAR "DSM")
if (CMAKE_DSM_COMPILER)
message(STATUS "Found DSM assembler: ${CMAKE_DSM_COMPILER}")
else()
message(STATUS "Didn't find assembler")
endif()
foreach(_var
COMPILER
COMPILER_ID
COMPILER_ARG1
COMPILER_ENV_VAR
COMPILER_AR
COMPILER_RANLIB
COMPILER_VERSION
)
set(_CMAKE_DSM_${_var} "${CMAKE_DSM_${_var}}")
endforeach()
configure_file("${CMAKE_CURRENT_LIST_DIR}/CMakeDSMCompiler.cmake.in"
"${CMAKE_PLATFORM_INFO_DIR}/CMakeDSMCompiler.cmake" @ONLY)
foreach(_var
COMPILER
COMPILER_ID
COMPILER_ARG1
COMPILER_ENV_VAR
COMPILER_AR
COMPILER_VERSION
)
unset(_CMAKE_DSM_${_var})
endforeach()

View file

@ -0,0 +1,7 @@
set(_ASM_COMPILER_WORKS 0)
if(CMAKE_DSM_COMPILER)
set(_DSM_COMPILER_WORKS)
endif()
set(CMAKE_DSM_COMPILER_WORKS ${_DSM_COMPILER_WORKS} CACHE INTERNAL "")

View file

@ -0,0 +1 @@
set(CMAKE_EXECUTABLE_SUFFIX ".elf")

View file

@ -0,0 +1,24 @@
from conans import ConanFile
import os
import shutil
class Ps2devCMakeToolchainConan(ConanFile):
name = "ps2dev-cmaketoolchain"
description = "CMake toolchain script for ps2dev"
topics = "ps2", "sdk", "library", "sony", "playstation", "ps2"
def export_sources(self):
self.copy("*.cmake*", dst="cmake")
self.copy("Platform", dst="cmake")
def package(self):
shutil.copytree(os.path.join(self.source_folder, "cmake"),
os.path.join(self.package_folder, "cmake"))
def package_info(self):
self.user_info.cmake_dir = os.path.join(self.package_folder, "cmake").replace("\\", "/")
cmake_toolchain_file = os.path.join(self.package_folder, "cmake", "toolchain_ps2_ee.cmake").replace("\\", "/")
self.user_info.cmake_toolchain_file = cmake_toolchain_file
self.cpp_info.CONAN_CMAKE_TOOLCHAIN_FILE = cmake_toolchain_file

View file

@ -0,0 +1,92 @@
cmake_minimum_required(VERSION 3.7)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
set(CMAKE_SYSTEM_NAME "PlayStation2")
set(CMAKE_SYSTEM_PROCESSOR "mips64r5900el")
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_NO_SYSTEM_FROM_IMPORTED ON)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
if(NOT DEFINED ENV{PS2DEV})
message(FATAL_ERROR "Need environment variable PS2DEV set")
endif()
if(NOT DEFINED ENV{PS2SDK})
message(FATAL_ERROR "Need environment variable PS2SDK set")
endif()
if(NOT DEFINED ENV{GSKIT})
message(FATAL_ERROR "Need environment variable PS2SDK set")
endif()
set(PS2DEV "$ENV{PS2DEV}")
set(PS2SDK "$ENV{PS2SDK}")
set(GSKIT "$ENV{GSKIT}")
if(NOT IS_DIRECTORY "${PS2DEV}")
message(FATAL_ERROR "PS2DEV must be a folder path (${PS2DEV})")
endif()
if(NOT IS_DIRECTORY "${PS2SDK}")
message(FATAL_ERROR "PS2SDK must be a folder path (${PS2SDK})")
endif()
if(NOT IS_DIRECTORY "${GSKIT}")
message(FATAL_ERROR "GSKIT must be a folder path (${GSKIT})")
endif()
set(CMAKE_DSM_SOURCE_FILE_EXTENSIONS "dsm")
set(CMAKE_C_COMPILER "${PS2DEV}/ee/bin/mips64r5900el-ps2-elf-gcc" CACHE FILEPATH "C compiler")
set(CMAKE_CXX_COMPILER "${PS2DEV}/ee/bin/mips64r5900el-ps2-elf-g++" CACHE FILEPATH "CXX compiler")
set(CMAKE_ASM_COMPILER "${PS2DEV}/ee/bin/mips64r5900el-ps2-elf-g++" CACHE FILEPATH "ASM assembler")
set(CMAKE_DSM_COMPILER "${PS2DEV}/dvp/bin/dvp-as" CACHE FILEPATH "DSM assembler")
set(CMAKE_AR "${PS2DEV}/ee/bin/mips64r5900el-ps2-elf-ar" CACHE FILEPATH "archiver")
set(CMAKE_LINKER "${PS2DEV}/ee/bin/mips64r5900el-ps2-elf-ld" CACHE FILEPATH "Linker")
set(CMAKE_RANLIB "${PS2DEV}/ee/bin/mips64r5900el-ps2-elf-ranlib" CACHE FILEPATH "ranlib")
set(CMAKE_STRIP "${PS2DEV}/ee/bin/mips64r5900el-ps2-elf-strip" CACHE FILEPATH "strip")
set(CMAKE_ASM_FLAGS_INIT "-G0 -I\"${PS2SDK}/ee/include\" -I\"${PS2SDK}/common/include\" -D_EE")
set(CMAKE_C_FLAGS_INIT "-G0 -fno-common -I\"${PS2SDK}/ee/include\" -I\"${PS2SDK}/common/include\" -D_EE")
set(CMAKE_CXX_FLAGS_INIT "-G0 -fno-common -I\"${PS2SDK}/ee/include\" -I\"${PS2SDK}/common/include\" -D_EE")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-G0 -L\"${PS2SDK}/ee/lib\" -Wl,-r -Wl,-d")
set(CMAKE_FIND_ROOT_PATH "${PS2DEV}/ee" "${PS2SDK}/ee" "${GSKIT}")
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(PS2 1)
set(EE 1)
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
function(add_erl_executable TARGET)
cmake_parse_arguments("AEE" "" "OUTPUT_VAR" "" ${ARGN})
get_target_property(output_dir "${TARGET}" RUNTIME_OUTPUT_DIRECTORY)
if(NOT output_dir)
set(output_dir ${CMAKE_CURRENT_BINARY_DIR})
endif()
get_target_property(output_name ${TARGET} OUTPUT_NAME)
if(NOT output_name)
set(output_name ${TARGET})
endif()
set(outfile "${output_dir}/${output_name}.erl")
add_custom_command(OUTPUT "${outfile}"
COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:${TARGET}>" "${outfile}"
COMMAND "${CMAKE_STRIP}" --strip-unneeded -R .mdebug.eabi64 -R .reginfo -R .comment "${outfile}"
DEPENDS ${TARGET}
)
add_custom_target("${TARGET}_erl" ALL
DEPENDS "${outfile}"
)
if(AEE_OUTPUT_VAR)
set("${AEE_OUTPUT_VAR}" "${outfile}" PARENT_SCOPE)
endif()
endfunction()

12
vendor/librw/conan/playstation2 vendored Normal file
View file

@ -0,0 +1,12 @@
[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
vendor/librw/conanfile.py vendored Normal file
View file

@ -0,0 +1,136 @@
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")

22
vendor/librw/docker_rebuild_ps2.sh vendored Normal file
View file

@ -0,0 +1,22 @@
#!/bin/bash
TARGET=release_ps2
set -e
LIBRWDIR=$(dirname "$(readlink -f "$0")")
echo "LIBRWDIR is $LIBRWDIR"
cd "$LIBRWDIR"
premake5 gmake
docker rm librw_instance -f >/dev/null 2>&1 || true
docker stop librw_instance -t 0 >/dev/null 2>&1 || true
docker pull librw/librw
docker run -v "$LIBRWDIR:/librw:rw,z" --name librw_instance -d librw/librw sleep infinity
docker exec -u builder librw_instance /bin/bash -c "cd /librw/build && make clean config=$TARGET && make config=$TARGET verbose=1"
docker rm librw_instance -f >/dev/null 2>&1 || true
docker stop librw_instance -t 0 >/dev/null 2>&1 || true

1
vendor/librw/premake-vs2019.cmd vendored Normal file
View file

@ -0,0 +1 @@
premake5 vs2019

BIN
vendor/librw/premake5.exe vendored Normal file

Binary file not shown.

277
vendor/librw/premake5.lua vendored Normal file
View file

@ -0,0 +1,277 @@
newoption {
trigger = "gfxlib",
value = "LIBRARY",
description = "Choose a particular development library",
default = "glfw",
allowed = {
{ "glfw", "GLFW" },
{ "sdl2", "SDL2" },
},
}
newoption {
trigger = "glfwdir64",
value = "PATH",
description = "Directory of glfw",
default = "../glfw-3.3.4.bin.WIN64",
}
newoption {
trigger = "glfwdir32",
value = "PATH",
description = "Directory of glfw",
default = "../glfw-3.3.4.bin.WIN32",
}
newoption {
trigger = "sdl2dir",
value = "PATH",
description = "Directory of sdl2",
default = "../SDL2-2.0.14",
}
workspace "librw"
location "build"
language "C++"
configurations { "Release", "Debug" }
filter { "system:windows" }
configurations { "ReleaseStatic" }
platforms { "win-x86-null", "win-x86-gl3", "win-x86-d3d9",
"win-amd64-null", "win-amd64-gl3", "win-amd64-d3d9" }
filter { "system:linux" }
platforms { "linux-x86-null", "linux-x86-gl3",
"linux-amd64-null", "linux-amd64-gl3",
"linux-arm-null", "linux-arm-gl3",
"ps2" }
if _OPTIONS["gfxlib"] == "sdl2" then
includedirs { "/usr/include/SDL2" }
end
filter {}
filter "configurations:Debug"
defines { "DEBUG" }
symbols "On"
filter "configurations:Release*"
defines { "NDEBUG" }
optimize "On"
filter "configurations:ReleaseStatic"
staticruntime("On")
filter { "platforms:*null" }
defines { "RW_NULL" }
filter { "platforms:*gl3" }
defines { "RW_GL3" }
if _OPTIONS["gfxlib"] == "sdl2" then
defines { "LIBRW_SDL2" }
end
filter { "platforms:*d3d9" }
defines { "RW_D3D9" }
filter { "platforms:ps2" }
defines { "RW_PS2" }
toolset "gcc"
gccprefix 'ee-'
buildoptions { "-nostdlib", "-fno-common" }
includedirs { "$(PS2SDK)/ee/include", "$(PS2SDK)/common/include" }
optimize "Off"
filter { "platforms:*amd64*" }
architecture "x86_64"
filter { "platforms:*x86*" }
architecture "x86"
filter { "platforms:*arm*" }
architecture "ARM"
filter { "platforms:win*" }
system "windows"
filter { "platforms:linux*" }
system "linux"
filter { "platforms:win*gl3" }
includedirs { path.join(_OPTIONS["sdl2dir"], "include") }
filter { "platforms:win-x86-gl3" }
includedirs { path.join(_OPTIONS["glfwdir32"], "include") }
filter { "platforms:win-amd64-gl3" }
includedirs { path.join(_OPTIONS["glfwdir64"], "include") }
filter "action:vs*"
buildoptions { "/wd4996", "/wd4244" }
filter { "platforms:win*gl3", "action:not vs*" }
if _OPTIONS["gfxlib"] == "sdl2" then
includedirs { "/mingw/include/SDL2" } -- TODO: Detect this properly
end
filter {}
Libdir = "lib/%{cfg.platform}/%{cfg.buildcfg}"
Bindir = "bin/%{cfg.platform}/%{cfg.buildcfg}"
project "librw"
kind "StaticLib"
targetname "rw"
targetdir (Libdir)
defines { "LODEPNG_NO_COMPILE_CPP" }
files { "src/*.*" }
files { "src/*/*.*" }
filter { "platforms:*gl3" }
files { "src/gl/glad/*.*" }
project "dumprwtree"
kind "ConsoleApp"
targetdir (Bindir)
removeplatforms { "*gl3", "*d3d9", "ps2" }
files { "tools/dumprwtree/*" }
includedirs { "." }
libdirs { Libdir }
links { "librw" }
function findlibs()
filter { "platforms:linux*gl3" }
links { "GL" }
if _OPTIONS["gfxlib"] == "glfw" then
links { "glfw" }
else
links { "SDL2" }
end
filter { "platforms:win-amd64-gl3" }
libdirs { path.join(_OPTIONS["glfwdir64"], "lib-vc2015") }
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x64") }
filter { "platforms:win-x86-gl3" }
libdirs { path.join(_OPTIONS["glfwdir32"], "lib-vc2015") }
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x86") }
filter { "platforms:win*gl3" }
links { "opengl32" }
if _OPTIONS["gfxlib"] == "glfw" then
links { "glfw3" }
else
links { "SDL2" }
end
filter { "platforms:*d3d9" }
links { "gdi32", "d3d9" }
filter { "platforms:*d3d9", "action:vs*" }
links { "Xinput9_1_0" }
filter {}
end
function skeleton()
files { "skeleton/*.cpp", "skeleton/*.h" }
files { "skeleton/imgui/*.cpp", "skeleton/imgui/*.h" }
includedirs { "skeleton" }
end
function skeltool(dir)
targetdir (Bindir)
files { path.join("tools", dir, "*.cpp"),
path.join("tools", dir, "*.h") }
vpaths {
{["src"] = { path.join("tools", dir, "*") }},
{["skeleton"] = { "skeleton/*" }},
}
skeleton()
debugdir ( path.join("tools", dir) )
includedirs { "." }
libdirs { Libdir }
links { "librw" }
findlibs()
end
function vucode()
filter "files:**.dsm"
buildcommands {
'cpp "%{file.relpath}" | dvp-as -o "%{cfg.objdir}/%{file.basename}.o"'
}
buildoutputs { '%{cfg.objdir}/%{file.basename}.o' }
filter {}
end
project "playground"
kind "WindowedApp"
characterset ("MBCS")
skeltool("playground")
entrypoint("WinMainCRTStartup")
removeplatforms { "*null" }
removeplatforms { "ps2" } -- for now
project "imguitest"
kind "WindowedApp"
characterset ("MBCS")
skeltool("imguitest")
entrypoint("WinMainCRTStartup")
removeplatforms { "*null" }
removeplatforms { "ps2" }
project "lights"
kind "WindowedApp"
characterset ("MBCS")
skeltool("lights")
entrypoint("WinMainCRTStartup")
removeplatforms { "*null" }
removeplatforms { "ps2" }
project "subrast"
kind "WindowedApp"
characterset ("MBCS")
skeltool("subrast")
entrypoint("WinMainCRTStartup")
removeplatforms { "*null" }
removeplatforms { "ps2" }
project "camera"
kind "WindowedApp"
characterset ("MBCS")
skeltool("camera")
entrypoint("WinMainCRTStartup")
removeplatforms { "*null" }
removeplatforms { "ps2" }
project "im2d"
kind "WindowedApp"
characterset ("MBCS")
skeltool("im2d")
entrypoint("WinMainCRTStartup")
removeplatforms { "*null" }
removeplatforms { "ps2" }
project "im3d"
kind "WindowedApp"
characterset ("MBCS")
skeltool("im3d")
entrypoint("WinMainCRTStartup")
removeplatforms { "*null" }
removeplatforms { "ps2" }
project "ska2anm"
kind "ConsoleApp"
characterset ("MBCS")
targetdir (Bindir)
files { path.join("tools/ska2anm", "*.cpp"),
path.join("tools/ska2anm", "*.h") }
debugdir ( path.join("tools/ska2nm") )
includedirs { "." }
libdirs { Libdir }
links { "librw" }
findlibs()
removeplatforms { "*gl3", "*d3d9", "*ps2" }
project "ps2test"
kind "ConsoleApp"
targetdir (Bindir)
vucode()
removeplatforms { "*gl3", "*d3d9", "*null" }
targetextension '.elf'
includedirs { "." }
files { "tools/ps2test/*.cpp",
"tools/ps2test/vu/*.dsm",
"tools/ps2test/*.h" }
libdirs { "$(PS2SDK)/ee/lib" }
links { "librw" }
--project "ps2rastertest"
-- kind "ConsoleApp"
-- targetdir (Bindir)
-- removeplatforms { "*gl3", "*d3d9" }
-- files { "tools/ps2rastertest/*.cpp" }
-- includedirs { "." }
-- libdirs { Libdir }
-- links { "librw" }

25
vendor/librw/rw.h vendored Normal file
View file

@ -0,0 +1,25 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "src/rwbase.h"
#include "src/rwerror.h"
#include "src/rwplg.h"
#include "src/rwrender.h"
#include "src/rwengine.h"
#include "src/rwpipeline.h"
#include "src/rwobjects.h"
#include "src/rwanim.h"
#include "src/rwplugins.h"
#include "src/rwuserdata.h"
#include "src/rwcharset.h"
#include "src/ps2/rwps2.h"
#include "src/ps2/rwps2plg.h"
#include "src/d3d/rwxbox.h"
#include "src/d3d/rwd3d.h"
#include "src/d3d/rwd3d8.h"
#include "src/d3d/rwd3d9.h"
#include "src/gl/rwwdgl.h"
#include "src/gl/rwgl3.h"
#include "src/gl/rwgl3shader.h"
#include "src/gl/rwgl3plg.h"

80
vendor/librw/skeleton/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,80 @@
add_library(librw_skeleton
glfw.cpp
sdl2.cpp
skeleton.cpp
skeleton.h
win.cpp
imgui/imgui_impl_rw.cpp
imgui/imgui_impl_rw.h
imgui/imconfig.h
imgui/imgui.cpp
imgui/imgui.h
imgui/imgui_demo.cpp
imgui/imgui_draw.cpp
imgui/imgui_internal.h
imgui/imgui_tables.cpp
imgui/imgui_widgets.cpp
imgui/imstb_rectpack.h
imgui/imstb_textedit.h
imgui/imstb_truetype.h
imgui/ImGuizmo.cpp
imgui/ImGuizmo.h
)
add_library(librw::skeleton ALIAS librw_skeleton)
set_target_properties(librw_skeleton
PROPERTIES
PREFIX ""
EXPORT_NAME skeleton
CXX_STANDARD 11
)
target_link_libraries(librw_skeleton
PRIVATE
librw
)
target_include_directories(librw_skeleton
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${LIBRW_INSTALL_INCLUDEDIR}/skeleton>
)
if(LIBRW_INSTALL)
install(
FILES
skeleton.h
DESTINATION "${LIBRW_INSTALL_INCLUDEDIR}/skeleton"
)
install(
FILES
imgui/imconfig.h
imgui/imgui.h
imgui/imgui_impl_rw.h
imgui/imgui_internal.h
imgui/ImGuizmo.h
imgui/imstb_rectpack.h
imgui/imstb_textedit.h
imgui/imstb_truetype.h
DESTINATION "${LIBRW_INSTALL_INCLUDEDIR}/skeleton/imgui"
)
install(
FILES
imgui/LICENSE_imgui.txt
imgui/LICENSE_imguizmo.txt
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
)
install(
TARGETS librw_skeleton
EXPORT librw-targets
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
endif()

262
vendor/librw/skeleton/glfw.cpp vendored Normal file
View file

@ -0,0 +1,262 @@
#ifndef LIBRW_SDL2
#include <rw.h>
#include "skeleton.h"
using namespace sk;
using namespace rw;
#ifdef RW_OPENGL
GLFWwindow *window;
int keymap[GLFW_KEY_LAST+1];
static void
initkeymap(void)
{
int i;
for(i = 0; i < GLFW_KEY_LAST+1; i++)
keymap[i] = KEY_NULL;
keymap[GLFW_KEY_SPACE] = ' ';
keymap[GLFW_KEY_APOSTROPHE] = '\'';
keymap[GLFW_KEY_COMMA] = ',';
keymap[GLFW_KEY_MINUS] = '-';
keymap[GLFW_KEY_PERIOD] = '.';
keymap[GLFW_KEY_SLASH] = '/';
keymap[GLFW_KEY_0] = '0';
keymap[GLFW_KEY_1] = '1';
keymap[GLFW_KEY_2] = '2';
keymap[GLFW_KEY_3] = '3';
keymap[GLFW_KEY_4] = '4';
keymap[GLFW_KEY_5] = '5';
keymap[GLFW_KEY_6] = '6';
keymap[GLFW_KEY_7] = '7';
keymap[GLFW_KEY_8] = '8';
keymap[GLFW_KEY_9] = '9';
keymap[GLFW_KEY_SEMICOLON] = ';';
keymap[GLFW_KEY_EQUAL] = '=';
keymap[GLFW_KEY_A] = 'A';
keymap[GLFW_KEY_B] = 'B';
keymap[GLFW_KEY_C] = 'C';
keymap[GLFW_KEY_D] = 'D';
keymap[GLFW_KEY_E] = 'E';
keymap[GLFW_KEY_F] = 'F';
keymap[GLFW_KEY_G] = 'G';
keymap[GLFW_KEY_H] = 'H';
keymap[GLFW_KEY_I] = 'I';
keymap[GLFW_KEY_J] = 'J';
keymap[GLFW_KEY_K] = 'K';
keymap[GLFW_KEY_L] = 'L';
keymap[GLFW_KEY_M] = 'M';
keymap[GLFW_KEY_N] = 'N';
keymap[GLFW_KEY_O] = 'O';
keymap[GLFW_KEY_P] = 'P';
keymap[GLFW_KEY_Q] = 'Q';
keymap[GLFW_KEY_R] = 'R';
keymap[GLFW_KEY_S] = 'S';
keymap[GLFW_KEY_T] = 'T';
keymap[GLFW_KEY_U] = 'U';
keymap[GLFW_KEY_V] = 'V';
keymap[GLFW_KEY_W] = 'W';
keymap[GLFW_KEY_X] = 'X';
keymap[GLFW_KEY_Y] = 'Y';
keymap[GLFW_KEY_Z] = 'Z';
keymap[GLFW_KEY_LEFT_BRACKET] = '[';
keymap[GLFW_KEY_BACKSLASH] = '\\';
keymap[GLFW_KEY_RIGHT_BRACKET] = ']';
keymap[GLFW_KEY_GRAVE_ACCENT] = '`';
keymap[GLFW_KEY_ESCAPE] = KEY_ESC;
keymap[GLFW_KEY_ENTER] = KEY_ENTER;
keymap[GLFW_KEY_TAB] = KEY_TAB;
keymap[GLFW_KEY_BACKSPACE] = KEY_BACKSP;
keymap[GLFW_KEY_INSERT] = KEY_INS;
keymap[GLFW_KEY_DELETE] = KEY_DEL;
keymap[GLFW_KEY_RIGHT] = KEY_RIGHT;
keymap[GLFW_KEY_LEFT] = KEY_LEFT;
keymap[GLFW_KEY_DOWN] = KEY_DOWN;
keymap[GLFW_KEY_UP] = KEY_UP;
keymap[GLFW_KEY_PAGE_UP] = KEY_PGUP;
keymap[GLFW_KEY_PAGE_DOWN] = KEY_PGDN;
keymap[GLFW_KEY_HOME] = KEY_HOME;
keymap[GLFW_KEY_END] = KEY_END;
keymap[GLFW_KEY_CAPS_LOCK] = KEY_CAPSLK;
keymap[GLFW_KEY_SCROLL_LOCK] = KEY_NULL;
keymap[GLFW_KEY_NUM_LOCK] = KEY_NULL;
keymap[GLFW_KEY_PRINT_SCREEN] = KEY_NULL;
keymap[GLFW_KEY_PAUSE] = KEY_NULL;
keymap[GLFW_KEY_F1] = KEY_F1;
keymap[GLFW_KEY_F2] = KEY_F2;
keymap[GLFW_KEY_F3] = KEY_F3;
keymap[GLFW_KEY_F4] = KEY_F4;
keymap[GLFW_KEY_F5] = KEY_F5;
keymap[GLFW_KEY_F6] = KEY_F6;
keymap[GLFW_KEY_F7] = KEY_F7;
keymap[GLFW_KEY_F8] = KEY_F8;
keymap[GLFW_KEY_F9] = KEY_F9;
keymap[GLFW_KEY_F10] = KEY_F10;
keymap[GLFW_KEY_F11] = KEY_F11;
keymap[GLFW_KEY_F12] = KEY_F12;
keymap[GLFW_KEY_F13] = KEY_NULL;
keymap[GLFW_KEY_F14] = KEY_NULL;
keymap[GLFW_KEY_F15] = KEY_NULL;
keymap[GLFW_KEY_F16] = KEY_NULL;
keymap[GLFW_KEY_F17] = KEY_NULL;
keymap[GLFW_KEY_F18] = KEY_NULL;
keymap[GLFW_KEY_F19] = KEY_NULL;
keymap[GLFW_KEY_F20] = KEY_NULL;
keymap[GLFW_KEY_F21] = KEY_NULL;
keymap[GLFW_KEY_F22] = KEY_NULL;
keymap[GLFW_KEY_F23] = KEY_NULL;
keymap[GLFW_KEY_F24] = KEY_NULL;
keymap[GLFW_KEY_F25] = KEY_NULL;
keymap[GLFW_KEY_KP_0] = KEY_NULL;
keymap[GLFW_KEY_KP_1] = KEY_NULL;
keymap[GLFW_KEY_KP_2] = KEY_NULL;
keymap[GLFW_KEY_KP_3] = KEY_NULL;
keymap[GLFW_KEY_KP_4] = KEY_NULL;
keymap[GLFW_KEY_KP_5] = KEY_NULL;
keymap[GLFW_KEY_KP_6] = KEY_NULL;
keymap[GLFW_KEY_KP_7] = KEY_NULL;
keymap[GLFW_KEY_KP_8] = KEY_NULL;
keymap[GLFW_KEY_KP_9] = KEY_NULL;
keymap[GLFW_KEY_KP_DECIMAL] = KEY_NULL;
keymap[GLFW_KEY_KP_DIVIDE] = KEY_NULL;
keymap[GLFW_KEY_KP_MULTIPLY] = KEY_NULL;
keymap[GLFW_KEY_KP_SUBTRACT] = KEY_NULL;
keymap[GLFW_KEY_KP_ADD] = KEY_NULL;
keymap[GLFW_KEY_KP_ENTER] = KEY_NULL;
keymap[GLFW_KEY_KP_EQUAL] = KEY_NULL;
keymap[GLFW_KEY_LEFT_SHIFT] = KEY_LSHIFT;
keymap[GLFW_KEY_LEFT_CONTROL] = KEY_LCTRL;
keymap[GLFW_KEY_LEFT_ALT] = KEY_LALT;
keymap[GLFW_KEY_LEFT_SUPER] = KEY_NULL;
keymap[GLFW_KEY_RIGHT_SHIFT] = KEY_RSHIFT;
keymap[GLFW_KEY_RIGHT_CONTROL] = KEY_RCTRL;
keymap[GLFW_KEY_RIGHT_ALT] = KEY_RALT;
keymap[GLFW_KEY_RIGHT_SUPER] = KEY_NULL;
keymap[GLFW_KEY_MENU] = KEY_NULL;
}
static void KeyUp(int key) { EventHandler(KEYUP, &key); }
static void KeyDown(int key) { EventHandler(KEYDOWN, &key); }
static void
keypress(GLFWwindow *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
mousemove(GLFWwindow *window, double x, double y)
{
sk::MouseState ms;
ms.posx = x;
ms.posy = y;
EventHandler(MOUSEMOVE, &ms);
}
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;
}
ms.buttons = buttons;
EventHandler(MOUSEBTN, &ms);
}
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;
initkeymap();
glfwSetKeyCallback(window, keypress);
glfwSetCharCallback(window, charinput);
glfwSetWindowSizeCallback(window, resize);
glfwSetCursorPosCallback(window, mousemove);
glfwSetMouseButtonCallback(window, mousebtn);
float lastTime = glfwGetTime()*1000;
while(!sk::globals.quit && !glfwWindowShouldClose(window)){
float currTime = glfwGetTime()*1000;
float timeDelta = (currTime - lastTime)*0.001f;
glfwPollEvents();
EventHandler(IDLE, &timeDelta);
lastTime = currTime;
}
EventHandler(RWTERMINATE, nil);
return 0;
}
namespace sk {
void
SetMousePosition(int x, int y)
{
glfwSetCursorPos(*engineOpenParams.window, (double)x, (double)y);
}
}
#endif
#endif

2724
vendor/librw/skeleton/imgui/ImGuizmo.cpp vendored Normal file

File diff suppressed because it is too large Load diff

213
vendor/librw/skeleton/imgui/ImGuizmo.h vendored Normal file
View file

@ -0,0 +1,213 @@
// https://github.com/CedricGuillemet/ImGuizmo
// v 1.61 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
// 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.
//
// -------------------------------------------------------------------------------------------
// History :
// 2019/11/03 View gizmo
// 2016/09/11 Behind camera culling. Scaling Delta matrix not multiplied by source matrix scales. local/world rotation and translation fixed. Display message is incorrect (X: ... Y:...) in local mode.
// 2016/09/09 Hatched negative axis. Snapping. Documentation update.
// 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved
// 2016/09/01 Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing scale and translation/rotation gives bad results.
// 2016/08/31 First version
//
// -------------------------------------------------------------------------------------------
// Future (no order):
//
// - Multi view
// - display rotation/translation/scale infos in local/world space and not only local
// - finish local/world matrix application
// - OPERATION as bitmask
//
// -------------------------------------------------------------------------------------------
// Example
#if 0
void EditTransform(const Camera& camera, matrix_t& matrix)
{
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE);
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD);
if (ImGui::IsKeyPressed(90))
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
if (ImGui::IsKeyPressed(69))
mCurrentGizmoOperation = ImGuizmo::ROTATE;
if (ImGui::IsKeyPressed(82)) // r Key
mCurrentGizmoOperation = ImGuizmo::SCALE;
if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
ImGui::SameLine();
if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
mCurrentGizmoOperation = ImGuizmo::ROTATE;
ImGui::SameLine();
if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
mCurrentGizmoOperation = ImGuizmo::SCALE;
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
ImGuizmo::DecomposeMatrixToComponents(matrix.m16, matrixTranslation, matrixRotation, matrixScale);
ImGui::InputFloat3("Tr", matrixTranslation, 3);
ImGui::InputFloat3("Rt", matrixRotation, 3);
ImGui::InputFloat3("Sc", matrixScale, 3);
ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix.m16);
if (mCurrentGizmoOperation != ImGuizmo::SCALE)
{
if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
mCurrentGizmoMode = ImGuizmo::LOCAL;
ImGui::SameLine();
if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
mCurrentGizmoMode = ImGuizmo::WORLD;
}
static bool useSnap(false);
if (ImGui::IsKeyPressed(83))
useSnap = !useSnap;
ImGui::Checkbox("", &useSnap);
ImGui::SameLine();
vec_t snap;
switch (mCurrentGizmoOperation)
{
case ImGuizmo::TRANSLATE:
snap = config.mSnapTranslation;
ImGui::InputFloat3("Snap", &snap.x);
break;
case ImGuizmo::ROTATE:
snap = config.mSnapRotation;
ImGui::InputFloat("Angle Snap", &snap.x);
break;
case ImGuizmo::SCALE:
snap = config.mSnapScale;
ImGui::InputFloat("Scale Snap", &snap.x);
break;
}
ImGuiIO& io = ImGui::GetIO();
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
ImGuizmo::Manipulate(camera.mView.m16, camera.mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, matrix.m16, NULL, useSnap ? &snap.x : NULL);
}
#endif
#pragma once
#ifdef USE_IMGUI_API
#include "imconfig.h"
#endif
#ifndef IMGUI_API
#define IMGUI_API
#endif
namespace ImGuizmo
{
// 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()).
IMGUI_API void SetDrawlist(ImDrawList* drawlist = nullptr);
// call BeginFrame right after ImGui_XXXX_NewFrame();
IMGUI_API void BeginFrame();
// this is necessary because when imguizmo is compiled into a dll, and imgui into another
// globals are not shared between them.
// More details at https://stackoverflow.com/questions/19373061/what-happens-to-global-and-static-variables-in-a-shared-library-when-it-is-dynam
// expose method to set imgui context
IMGUI_API void SetImGuiContext(ImGuiContext* ctx);
// return true if mouse cursor is over any gizmo control (axis, plan or screen component)
IMGUI_API bool IsOver();
// return true if mouse IsOver or if the gizmo is in moving state
IMGUI_API bool IsUsing();
// 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);
// helper functions for manualy editing translation/rotation/scale with an input float
// translation, rotation and scale float points to 3 floats each
// Angles are in degrees (more suitable for human editing)
// example:
// float matrixTranslation[3], matrixRotation[3], matrixScale[3];
// ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
// ImGui::InputFloat3("Tr", matrixTranslation, 3);
// ImGui::InputFloat3("Rt", matrixRotation, 3);
// ImGui::InputFloat3("Sc", matrixScale, 3);
// ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
//
// These functions have some numerical stability issues for now. Use with caution.
IMGUI_API void DecomposeMatrixToComponents(const float* matrix, float* translation, float* rotation, float* scale);
IMGUI_API void RecomposeMatrixFromComponents(const float* translation, const float* rotation, const float* scale, float* matrix);
IMGUI_API void SetRect(float x, float y, float width, float height);
// default is false
IMGUI_API void SetOrthographic(bool isOrthographic);
// Render a cube with face color corresponding to face normal. Usefull for debug/tests
IMGUI_API void DrawCubes(const float* view, const float* projection, const float* matrices, int matrixCount);
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.
// 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
{
TRANSLATE_X = (1u << 0),
TRANSLATE_Y = (1u << 1),
TRANSLATE_Z = (1u << 2),
ROTATE_X = (1u << 3),
ROTATE_Y = (1u << 4),
ROTATE_Z = (1u << 5),
ROTATE_SCREEN = (1u << 6),
SCALE_X = (1u << 7),
SCALE_Y = (1u << 8),
SCALE_Z = (1u << 9),
BOUNDS = (1u << 10),
TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z,
ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN,
SCALE = SCALE_X | SCALE_Y | SCALE_Z
};
inline OPERATION operator|(OPERATION lhs, OPERATION rhs)
{
return static_cast<OPERATION>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
enum MODE
{
LOCAL,
WORLD
};
IMGUI_API bool Manipulate(const float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float* deltaMatrix = NULL, const float* snap = NULL, const float* localBounds = NULL, const float* boundsSnap = NULL);
//
// Please note that this cubeview is patented by Autodesk : https://patents.google.com/patent/US7782319B2/en
// It seems to be a defensive patent in the US. I don't think it will bring troubles using it as
// other software are using the same mechanics. But just in case, you are now warned!
//
IMGUI_API void ViewManipulate(float* view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
IMGUI_API void SetID(int id);
// return true if the cursor is over the operation's gizmo
IMGUI_API bool IsOver(OPERATION op);
IMGUI_API void SetGizmoSizeClipSpace(float value);
// Allow axis to flip
// 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);
}

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2021 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
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
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.

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 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
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.

121
vendor/librw/skeleton/imgui/imconfig.h vendored Normal file
View file

@ -0,0 +1,121 @@
//-----------------------------------------------------------------------------
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
// 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.
//-----------------------------------------------------------------------------
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
//---- Define assertion handler. Defaults to calling assert().
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
//---- 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 )
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be 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.
//#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.
//---- 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_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_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().
//---- Include imgui_user.h at the end of imgui.h as a convenience
//#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
//#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...)
//#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_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//---- 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 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'.
//#define IMGUI_ENABLE_FREETYPE
//---- 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
//---- 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; } \
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; } \
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/
//---- 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).
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
//struct ImDrawList;
//struct ImDrawCmd;
//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
// (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 slower asserts
//#define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
}
*/

11589
vendor/librw/skeleton/imgui/imgui.cpp vendored Normal file

File diff suppressed because it is too large Load diff

2852
vendor/librw/skeleton/imgui/imgui.h vendored Normal file

File diff suppressed because it is too large Load diff

7725
vendor/librw/skeleton/imgui/imgui_demo.cpp vendored Normal file

File diff suppressed because it is too large Load diff

4152
vendor/librw/skeleton/imgui/imgui_draw.cpp vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,240 @@
#include <rw.h>
#include <skeleton.h>
#include <assert.h>
#include "imgui/imgui.h"
#include "imgui_impl_rw.h"
using namespace rw::RWDEVICE;
static rw::Texture *g_FontTexture;
static Im2DVertex *g_vertbuf;
static int g_vertbufSize;
void
ImGui_ImplRW_RenderDrawLists(ImDrawData* draw_data)
{
ImGuiIO &io = ImGui::GetIO();
// minimized
if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
return;
if(g_vertbuf == nil || g_vertbufSize < draw_data->TotalVtxCount){
if(g_vertbuf){
rwFree(g_vertbuf);
g_vertbuf = nil;
}
g_vertbufSize = draw_data->TotalVtxCount + 5000;
g_vertbuf = rwNewT(Im2DVertex, g_vertbufSize, 0);
}
float xoff = 0.0f;
float yoff = 0.0f;
#ifdef RWHALFPIXEL
xoff = -0.5;
yoff = 0.5;
#endif
rw::Camera *cam = (rw::Camera*)rw::engine->currentCamera;
Im2DVertex *vtx_dst = g_vertbuf;
float recipZ = 1.0f/cam->nearPlane;
for(int n = 0; n < draw_data->CmdListsCount; n++){
const ImDrawList *cmd_list = draw_data->CmdLists[n];
const ImDrawVert *vtx_src = cmd_list->VtxBuffer.Data;
for(int i = 0; i < cmd_list->VtxBuffer.Size; i++){
vtx_dst[i].setScreenX(vtx_src[i].pos.x + xoff);
vtx_dst[i].setScreenY(vtx_src[i].pos.y + yoff);
vtx_dst[i].setScreenZ(rw::im2d::GetNearZ());
vtx_dst[i].setCameraZ(cam->nearPlane);
vtx_dst[i].setRecipCameraZ(recipZ);
vtx_dst[i].setColor(vtx_src[i].col&0xFF, vtx_src[i].col>>8 & 0xFF, vtx_src[i].col>>16 & 0xFF, vtx_src[i].col>>24 & 0xFF);
vtx_dst[i].setU(vtx_src[i].uv.x, recipZ);
vtx_dst[i].setV(vtx_src[i].uv.y, recipZ);
}
vtx_dst += cmd_list->VtxBuffer.Size;
}
int vertexAlpha = rw::GetRenderState(rw::VERTEXALPHA);
int srcBlend = rw::GetRenderState(rw::SRCBLEND);
int dstBlend = rw::GetRenderState(rw::DESTBLEND);
int ztest = rw::GetRenderState(rw::ZTESTENABLE);
void *tex = rw::GetRenderStatePtr(rw::TEXTURERASTER);
int addrU = rw::GetRenderState(rw::TEXTUREADDRESSU);
int addrV = rw::GetRenderState(rw::TEXTUREADDRESSV);
int filter = rw::GetRenderState(rw::TEXTUREFILTER);
int cullmode = rw::GetRenderState(rw::CULLMODE);
rw::SetRenderState(rw::VERTEXALPHA, 1);
rw::SetRenderState(rw::SRCBLEND, rw::BLENDSRCALPHA);
rw::SetRenderState(rw::DESTBLEND, rw::BLENDINVSRCALPHA);
rw::SetRenderState(rw::ZTESTENABLE, 0);
rw::SetRenderState(rw::CULLMODE, rw::CULLNONE);
int vtx_offset = 0;
for(int n = 0; n < draw_data->CmdListsCount; n++){
const ImDrawList *cmd_list = draw_data->CmdLists[n];
int idx_offset = 0;
for(int i = 0; i < cmd_list->CmdBuffer.Size; i++){
const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[i];
if(pcmd->UserCallback)
pcmd->UserCallback(cmd_list, pcmd);
else{
rw::Texture *tex = (rw::Texture*)pcmd->TextureId;
if(tex && tex->raster){
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
rw::SetRenderState(rw::TEXTUREADDRESSU, tex->getAddressU());
rw::SetRenderState(rw::TEXTUREADDRESSV, tex->getAddressV());
rw::SetRenderState(rw::TEXTUREFILTER, tex->getFilter());
}else
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
g_vertbuf+vtx_offset, cmd_list->VtxBuffer.Size,
cmd_list->IdxBuffer.Data+idx_offset, pcmd->ElemCount);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.Size;
}
rw::SetRenderState(rw::VERTEXALPHA,vertexAlpha);
rw::SetRenderState(rw::SRCBLEND, srcBlend);
rw::SetRenderState(rw::DESTBLEND, dstBlend);
rw::SetRenderState(rw::ZTESTENABLE, ztest);
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex);
rw::SetRenderState(rw::TEXTUREADDRESSU, addrU);
rw::SetRenderState(rw::TEXTUREADDRESSV, addrV);
rw::SetRenderState(rw::TEXTUREFILTER, filter);
rw::SetRenderState(rw::CULLMODE, cullmode);
}
bool
ImGui_ImplRW_Init(void)
{
using namespace sk;
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;
}
void
ImGui_ImplRW_Shutdown(void)
{
}
static bool
ImGui_ImplRW_CreateFontsTexture()
{
// Build texture atlas
ImGuiIO &io = ImGui::GetIO();
unsigned char *pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, nil);
rw::Image *image;
image = rw::Image::create(width, height, 32);
image->allocate();
for(int y = 0; y < height; y++)
memcpy(image->pixels + image->stride*y, pixels + width*4* y, width*4);
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;
return true;
}
bool
ImGui_ImplRW_CreateDeviceObjects()
{
// if(!g_pd3dDevice)
// return false;
if(!ImGui_ImplRW_CreateFontsTexture())
return false;
return true;
}
void
ImGui_ImplRW_NewFrame(float timeDelta)
{
if(!g_FontTexture)
ImGui_ImplRW_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
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.KeySuper = false;
if(io.WantSetMousePos)
sk::SetMousePosition(io.MousePos.x, io.MousePos.y);
ImGui::NewFrame();
}
sk::EventStatus
ImGuiEventHandler(sk::Event e, void *param)
{
using namespace sk;
ImGuiIO &io = ImGui::GetIO();
MouseState *ms;
uint c;
switch(e){
case KEYDOWN:
c = *(int*)param;
if(c < 256)
io.KeysDown[c] = 1;
return EVENTPROCESSED;
case KEYUP:
c = *(int*)param;
if(c < 256)
io.KeysDown[c] = 0;
return EVENTPROCESSED;
case CHARINPUT:
c = (uint)(uintptr)param;
io.AddInputCharacter((unsigned short)c);
return EVENTPROCESSED;
case MOUSEMOVE:
ms = (MouseState*)param;
io.MousePos.x = ms->posx;
io.MousePos.y = ms->posy;
return EVENTPROCESSED;
case MOUSEBTN:
ms = (MouseState*)param;
io.MouseDown[0] = !!(ms->buttons & 1);
io.MouseDown[2] = !!(ms->buttons & 2);
io.MouseDown[1] = !!(ms->buttons & 4);
return EVENTPROCESSED;
}
return EVENTPROCESSED;
}

View file

@ -0,0 +1,5 @@
IMGUI_API bool ImGui_ImplRW_Init(void);
IMGUI_API void ImGui_ImplRW_Shutdown(void);
IMGUI_API void ImGui_ImplRW_NewFrame(float timeDelta);
sk::EventStatus ImGuiEventHandler(sk::Event e, void *param);
void ImGui_ImplRW_RenderDrawLists(ImDrawData* draw_data);

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

View file

@ -0,0 +1,639 @@
// [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
// Grep for [DEAR IMGUI] to find the changes.
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation.
//
// 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).
//
// Has only had a few tests run, may have issues.
//
// More docs to come.
//
// No memory allocations; uses qsort() and assert() from stdlib.
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
//
// This library currently uses the Skyline Bottom-Left algorithm.
//
// Please note: better rectangle packers are welcome! Please
// implement them to the same API, but with a different init
// function.
//
// Credits
//
// Library
// Sean Barrett
// Minor features
// Martins Mozeiko
// github:IntellectualKitty
//
// Bugfixes / warning fixes
// Jeremy Jaussaud
// Fabian Giesen
//
// Version history:
//
// 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
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
// 0.09 (2016-08-27) fix compiler warnings
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
// 0.05: added STBRP_ASSERT to allow replacing assert
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
// 0.01: initial release
//
// LICENSE
//
// See end of file for license information.
//////////////////////////////////////////////////////////////////////////////
//
// INCLUDE SECTION
//
#ifndef STB_INCLUDE_STB_RECT_PACK_H
#define STB_INCLUDE_STB_RECT_PACK_H
#define STB_RECT_PACK_VERSION 1
#ifdef STBRP_STATIC
#define STBRP_DEF static
#else
#define STBRP_DEF extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
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
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
// 'stbrp_rect' defined below, stored in the array 'rects', and there
// are 'num_rects' many of them.
//
// Rectangles which are successfully packed have the 'was_packed' flag
// set to a non-zero value and 'x' and 'y' store the minimum location
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
// if you imagine y increasing downwards). Rectangles which do not fit
// have the 'was_packed' flag set to 0.
//
// You should not try to access the 'rects' array from another thread
// while this function is running, as the function temporarily reorders
// the array while it executes.
//
// To pack into another rectangle, you need to call stbrp_init_target
// again. To continue packing into the same rectangle, you can call
// this function again. Calling this multiple times with multiple rect
// arrays will probably produce worse packing results than calling it
// a single time with the full rectangle array, but the option is
// available.
//
// The function returns 1 if all of the rectangles were successfully
// packed and 0 otherwise.
struct stbrp_rect
{
// reserved for your use:
int id;
// input:
stbrp_coord w, h;
// output:
stbrp_coord x, y;
int was_packed; // non-zero if valid packing
}; // 16 bytes, nominally
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
// Initialize a rectangle packer to:
// pack a rectangle that is 'width' by 'height' in dimensions
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
//
// You must call this function every time you start packing into a new target.
//
// There is no "shutdown" function. The 'nodes' memory must stay valid for
// the following stbrp_pack_rects() call (or calls), but can be freed after
// the call (or calls) finish.
//
// Note: to guarantee best results, either:
// 1. make sure 'num_nodes' >= 'width'
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
//
// If you don't do either of the above things, widths will be quantized to multiples
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
//
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
// may run out of temporary storage and be unable to pack some rectangles.
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
// Optionally call this function after init but before doing any packing to
// change the handling of the out-of-temp-memory scenario, described above.
// If you call init again, this will be reset to the default (false).
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
// Optionally select which packing heuristic the library should use. Different
// heuristics will produce better/worse results for different data sets.
// If you call init again, this will be reset to the default.
enum
{
STBRP_HEURISTIC_Skyline_default=0,
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
STBRP_HEURISTIC_Skyline_BF_sortHeight
};
//////////////////////////////////////////////////////////////////////////////
//
// the details of the following structures don't matter to you, but they must
// be visible so you can handle the memory allocations for them
struct stbrp_node
{
stbrp_coord x,y;
stbrp_node *next;
};
struct stbrp_context
{
int width;
int height;
int align;
int init_mode;
int heuristic;
int num_nodes;
stbrp_node *active_head;
stbrp_node *free_head;
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
};
#ifdef __cplusplus
}
#endif
#endif
//////////////////////////////////////////////////////////////////////////////
//
// IMPLEMENTATION SECTION
//
#ifdef STB_RECT_PACK_IMPLEMENTATION
#ifndef STBRP_SORT
#include <stdlib.h>
#define STBRP_SORT qsort
#endif
#ifndef STBRP_ASSERT
#include <assert.h>
#define STBRP_ASSERT assert
#endif
// [DEAR IMGUI] Added STBRP__CDECL
#ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v)
#define STBRP__CDECL __cdecl
#else
#define STBRP__NOTUSED(v) (void)sizeof(v)
#define STBRP__CDECL
#endif
enum
{
STBRP__INIT_skyline = 1
};
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
{
switch (context->init_mode) {
case STBRP__INIT_skyline:
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
context->heuristic = heuristic;
break;
default:
STBRP_ASSERT(0);
}
}
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
{
if (allow_out_of_mem)
// if it's ok to run out of memory, then don't bother aligning them;
// this gives better packing, but may fail due to OOM (even though
// the rectangles easily fit). @TODO a smarter approach would be to only
// quantize once we've hit OOM, then we could get rid of this parameter.
context->align = 1;
else {
// if it's not ok to run out of memory, then quantize the widths
// so that num_nodes is always enough nodes.
//
// I.e. num_nodes * align >= width
// align >= width / num_nodes
// align = ceil(width/num_nodes)
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
}
}
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];
nodes[i].next = NULL;
context->init_mode = STBRP__INIT_skyline;
context->heuristic = STBRP_HEURISTIC_Skyline_default;
context->free_head = &nodes[0];
context->active_head = &context->extra[0];
context->width = width;
context->height = height;
context->num_nodes = num_nodes;
stbrp_setup_allow_out_of_mem(context, 0);
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
context->extra[0].x = 0;
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;
}
// find minimum y position if it starts at x1
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
{
stbrp_node *node = first;
int x1 = x0 + width;
int min_y, visited_width, waste_area;
STBRP__NOTUSED(c);
STBRP_ASSERT(first->x <= x0);
#if 0
// skip in case we're past the node
while (node->next->x <= x0)
++node;
#else
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
#endif
STBRP_ASSERT(node->x <= x0);
min_y = 0;
waste_area = 0;
visited_width = 0;
while (node->x < x1) {
if (node->y > min_y) {
// raise min_y higher.
// we've accounted for all waste up to min_y,
// but we'll now add more waste for everything we've visted
waste_area += visited_width * (node->y - min_y);
min_y = node->y;
// the first time through, visited_width might be reduced
if (node->x < x0)
visited_width += node->next->x - x0;
else
visited_width += node->next->x - node->x;
} else {
// add waste area
int under_width = node->next->x - node->x;
if (under_width + visited_width > width)
under_width = width - visited_width;
waste_area += under_width * (min_y - node->y);
visited_width += under_width;
}
node = node->next;
}
*pwaste = waste_area;
return min_y;
}
typedef struct
{
int x,y;
stbrp_node **prev_link;
} stbrp__findresult;
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
{
int best_waste = (1<<30), best_x, best_y = (1 << 30);
stbrp__findresult fr;
stbrp_node **prev, *node, *tail, **best = NULL;
// align to multiple of c->align
width = (width + c->align - 1);
width -= width % c->align;
STBRP_ASSERT(width % c->align == 0);
// if it can't possibly fit, bail immediately
if (width > c->width || height > c->height) {
fr.prev_link = NULL;
fr.x = fr.y = 0;
return fr;
}
node = c->active_head;
prev = &c->active_head;
while (node->x + width <= c->width) {
int y,waste;
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
// bottom left
if (y < best_y) {
best_y = y;
best = prev;
}
} else {
// best-fit
if (y + height <= c->height) {
// can only use it if it first vertically
if (y < best_y || (y == best_y && waste < best_waste)) {
best_y = y;
best_waste = waste;
best = prev;
}
}
}
prev = &node->next;
node = node->next;
}
best_x = (best == NULL) ? 0 : (*best)->x;
// if doing best-fit (BF), we also have to try aligning right edge to each node position
//
// e.g, if fitting
//
// ____________________
// |____________________|
//
// into
//
// | |
// | ____________|
// |____________|
//
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
//
// This makes BF take about 2x the time
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
tail = c->active_head;
node = c->active_head;
prev = &c->active_head;
// find first node that's admissible
while (tail->x < width)
tail = tail->next;
while (tail) {
int xpos = tail->x - width;
int y,waste;
STBRP_ASSERT(xpos >= 0);
// find the left position that matches this
while (node->next->x <= xpos) {
prev = &node->next;
node = node->next;
}
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
if (y + height <= c->height) {
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);
best_y = y;
best_waste = waste;
best = prev;
}
}
}
tail = tail->next;
}
}
fr.prev_link = best;
fr.x = best_x;
fr.y = best_y;
return fr;
}
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
{
// find best position according to heuristic
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
stbrp_node *node, *cur;
// bail if:
// 1. it failed
// 2. the best node doesn't fit (we don't always check this)
// 3. we're out of memory
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
res.prev_link = NULL;
return res;
}
// on success, create new node
node = context->free_head;
node->x = (stbrp_coord) res.x;
node->y = (stbrp_coord) (res.y + height);
context->free_head = node->next;
// insert the new node into the right starting point, and
// let 'cur' point to the remaining nodes needing to be
// stiched back in
cur = *res.prev_link;
if (cur->x < res.x) {
// preserve the existing one, so start testing with the next one
stbrp_node *next = cur->next;
cur->next = node;
cur = next;
} else {
*res.prev_link = node;
}
// from here, traverse cur and free the nodes, until we get to one
// that shouldn't be freed
while (cur->next && cur->next->x <= res.x + width) {
stbrp_node *next = cur->next;
// move the current node to the free list
cur->next = context->free_head;
context->free_head = cur;
cur = next;
}
// stitch the list back in
node->next = cur;
if (cur->x < res.x + width)
cur->x = (stbrp_coord) (res.x + width);
#ifdef _DEBUG
cur = context->active_head;
while (cur->x < context->width) {
STBRP_ASSERT(cur->x < cur->next->x);
cur = cur->next;
}
STBRP_ASSERT(cur->next == NULL);
{
int count=0;
cur = context->active_head;
while (cur) {
cur = cur->next;
++count;
}
cur = context->free_head;
while (cur) {
cur = cur->next;
++count;
}
STBRP_ASSERT(count == context->num_nodes+2);
}
#endif
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;
const stbrp_rect *q = (const stbrp_rect *) b;
if (p->h > q->h)
return -1;
if (p->h < q->h)
return 1;
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;
const stbrp_rect *q = (const stbrp_rect *) 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;
// we use the 'was_packed' field internally to allow sorting/unsorting
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = i;
}
// sort according to heuristic
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
for (i=0; i < num_rects; ++i) {
if (rects[i].w == 0 || rects[i].h == 0) {
rects[i].x = rects[i].y = 0; // empty rect needs no space
} else {
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
if (fr.prev_link) {
rects[i].x = (stbrp_coord) fr.x;
rects[i].y = (stbrp_coord) fr.y;
} else {
rects[i].x = rects[i].y = STBRP__MAXVAL;
}
}
}
// unsort
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
// set was_packed flags and all_rects_packed status
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
if (!rects[i].was_packed)
all_rects_packed = 0;
}
// return the all_rects_packed status
return all_rects_packed;
}
#endif
/*
------------------------------------------------------------------------------
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
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
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,
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
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
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

326
vendor/librw/skeleton/sdl2.cpp vendored Normal file
View file

@ -0,0 +1,326 @@
#ifdef LIBRW_SDL2
#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_QUOTE: 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_BACKQUOTE: 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;
float lastTime = SDL_GetTicks();
SDL_Event event;
int mouseButtons = 0;
SDL_StartTextInput();
while(!sk::globals.quit){
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT:
sk::globals.quit = true;
break;
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_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;
}
}
break;
case SDL_KEYUP: {
int c = keyCodeToSkKey(event.key.keysym.sym);
EventHandler(KEYUP, &c);
break;
}
case SDL_KEYDOWN: {
int c = keyCodeToSkKey(event.key.keysym.sym);
EventHandler(KEYDOWN, &c);
break;
}
case SDL_TEXTINPUT: {
char *c = event.text.text;
while (int ci = *c) {
EventHandler(CHARINPUT, (void*)(uintptr)ci);
++c;
}
break;
}
case SDL_MOUSEMOTION: {
sk::MouseState ms;
ms.posx = event.motion.x;
ms.posy = event.motion.y;
EventHandler(MOUSEMOVE, &ms);
break;
}
case SDL_MOUSEBUTTONDOWN: {
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_MOUSEBUTTONUP: {
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;
}
}
}
float currTime = SDL_GetTicks();
float timeDelta = (currTime - lastTime) * 0.001f;
EventHandler(IDLE, &timeDelta);
lastTime = currTime;
}
SDL_StopTextInput();
EventHandler(RWTERMINATE, nil);
return 0;
}
namespace sk {
void
SetMousePosition(int x, int y)
{
SDL_WarpMouseInWindow(*engineOpenParams.window, x, y);
}
}
#endif
#endif

192
vendor/librw/skeleton/skeleton.cpp vendored Normal file
View file

@ -0,0 +1,192 @@
#include <rw.h>
#include "skeleton.h"
namespace sk {
Globals globals;
Args args;
bool
InitRW(void)
{
if(!rw::Engine::init())
return false;
if(AppEventHandler(sk::PLUGINATTACH, nil) == EVENTERROR)
return false;
if(!rw::Engine::open(&engineOpenParams))
return false;
SubSystemInfo info;
int i, n;
n = Engine::getNumSubSystems();
for(i = 0; i < n; i++)
if(Engine::getSubSystemInfo(&info, i))
printf("subsystem: %s\n", info.name);
Engine::setSubSystem(n-1);
int want = -1;
VideoMode mode;
n = Engine::getNumVideoModes();
for(i = 0; i < n; i++)
if(Engine::getVideoModeInfo(&mode, i)){
// 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);
}
// if(want >= 0) Engine::setVideoMode(want);
Engine::getVideoModeInfo(&mode, Engine::getCurrentVideoMode());
if(mode.flags & VIDEOMODEEXCLUSIVE){
globals.width = mode.width;
globals.height = mode.height;
}
if(!rw::Engine::start())
return false;
rw::Charset::open();
rw::Image::setSearchPath("./");
return true;
}
void
TerminateRW(void)
{
rw::Charset::close();
// TODO: delete all tex dicts
rw::Engine::stop();
rw::Engine::close();
rw::Engine::term();
}
Camera*
CameraCreate(int32 width, int32 height, bool32 z)
{
Camera *cam;
cam = Camera::create();
cam->setFrame(Frame::create());
cam->frameBuffer = Raster::create(width, height, 0, Raster::CAMERA);
cam->zBuffer = Raster::create(width, height, 0, Raster::ZBUFFER);
return cam;
}
void
CameraDestroy(rw::Camera *cam)
{
if(cam->frameBuffer){
cam->frameBuffer->destroy();
cam->frameBuffer = nil;
}
if(cam->zBuffer){
cam->zBuffer->destroy();
cam->zBuffer = nil;
}
rw::Frame *frame = cam->getFrame();
if(frame){
cam->setFrame(nil);
frame->destroy();
}
cam->destroy();
}
void
CameraSize(Camera *cam, Rect *r, float viewWindow, float aspectRatio)
{
if(cam->frameBuffer){
cam->frameBuffer->destroy();
cam->frameBuffer = nil;
}
if(cam->zBuffer){
cam->zBuffer->destroy();
cam->zBuffer = nil;
}
cam->frameBuffer = Raster::create(r->w, r->h, 0, Raster::CAMERA);
cam->zBuffer = Raster::create(r->w, r->h, 0, Raster::ZBUFFER);
if(viewWindow != 0.0f){
rw::V2d vw;
// TODO: aspect ratio when fullscreen
if(r->w > r->h){
vw.x = viewWindow;
vw.y = viewWindow / ((float)r->w/r->h);
}else{
vw.x = viewWindow / ((float)r->h/r->w);
vw.y = viewWindow;
}
cam->setViewWindow(&vw);
}
}
void
CameraMove(Camera *cam, V3d *delta)
{
rw::V3d offset;
rw::V3d::transformVectors(&offset, delta, 1, &cam->getFrame()->matrix);
cam->getFrame()->translate(&offset);
}
void
CameraPan(Camera *cam, V3d *pos, float angle)
{
rw::Frame *frame = cam->getFrame();
rw::V3d trans = pos ? *pos : frame->matrix.pos;
rw::V3d negTrans = rw::scale(trans, -1.0f);
frame->translate(&negTrans);
frame->rotate(&frame->matrix.up, angle);
frame->translate(&trans);
}
void
CameraTilt(Camera *cam, V3d *pos, float angle)
{
rw::Frame *frame = cam->getFrame();
rw::V3d trans = pos ? *pos : frame->matrix.pos;
rw::V3d negTrans = rw::scale(trans, -1.0f);
frame->translate(&negTrans);
frame->rotate(&frame->matrix.right, angle);
frame->translate(&trans);
}
void
CameraRotate(Camera *cam, V3d *pos, float angle)
{
rw::Frame *frame = cam->getFrame();
rw::V3d trans = pos ? *pos : frame->matrix.pos;
rw::V3d negTrans = rw::scale(trans, -1.0f);
frame->translate(&negTrans);
frame->rotate(&frame->matrix.at, angle);
frame->translate(&negTrans);
}
EventStatus
EventHandler(Event e, void *param)
{
EventStatus s;
if (e == INITIALIZE) {
ImGui::CreateContext();
}
s = AppEventHandler(e, param);
if(e == QUIT){
globals.quit = 1;
return EVENTPROCESSED;
}
if(s == EVENTNOTPROCESSED)
switch(e){
case RWINITIALIZE:
return InitRW() ? EVENTPROCESSED : EVENTERROR;
case RWTERMINATE:
TerminateRW();
return EVENTPROCESSED;
default:
break;
}
return s;
}
}

120
vendor/librw/skeleton/skeleton.h vendored Normal file
View file

@ -0,0 +1,120 @@
extern rw::EngineOpenParams engineOpenParams;
namespace sk {
using namespace rw;
// same as RW skeleton
enum Key
{
// ascii...
KEY_ESC = 128,
KEY_F1 = 129,
KEY_F2 = 130,
KEY_F3 = 131,
KEY_F4 = 132,
KEY_F5 = 133,
KEY_F6 = 134,
KEY_F7 = 135,
KEY_F8 = 136,
KEY_F9 = 137,
KEY_F10 = 138,
KEY_F11 = 139,
KEY_F12 = 140,
KEY_INS = 141,
KEY_DEL = 142,
KEY_HOME = 143,
KEY_END = 144,
KEY_PGUP = 145,
KEY_PGDN = 146,
KEY_UP = 147,
KEY_DOWN = 148,
KEY_LEFT = 149,
KEY_RIGHT = 150,
// some stuff ommitted
KEY_BACKSP = 168,
KEY_TAB = 169,
KEY_CAPSLK = 170,
KEY_ENTER = 171,
KEY_LSHIFT = 172,
KEY_RSHIFT = 173,
KEY_LCTRL = 174,
KEY_RCTRL = 175,
KEY_LALT = 176,
KEY_RALT = 177,
KEY_NULL, // unused
KEY_NUMKEYS,
};
enum EventStatus
{
EVENTERROR,
EVENTPROCESSED,
EVENTNOTPROCESSED
};
enum Event
{
INITIALIZE,
RWINITIALIZE,
RWTERMINATE,
SELECTDEVICE,
PLUGINATTACH,
KEYDOWN,
KEYUP,
CHARINPUT,
MOUSEMOVE,
MOUSEBTN,
RESIZE,
IDLE,
QUIT
};
struct Globals
{
const char *windowtitle;
int32 width;
int32 height;
bool32 quit;
};
extern Globals globals;
// Argument to mouse events
struct MouseState
{
int posx, posy;
int buttons; // bits 0-2 are left, middle, right button down
};
struct Args
{
int argc;
char **argv;
};
extern Args args;
bool InitRW(void);
void TerminateRW(void);
Camera *CameraCreate(int32 width, int32 height, bool32 z);
void CameraDestroy(rw::Camera *cam);
void CameraSize(Camera *cam, Rect *r, float viewWindow = 0.0f, float aspectRatio = 0.0f);
void CameraMove(Camera *cam, V3d *delta);
void CameraPan(Camera *cam, V3d *pos, float angle);
void CameraTilt(Camera *cam, V3d *pos, float angle);
void CameraRotate(Camera *cam, V3d *pos, float angle);
void SetMousePosition(int x, int y);
EventStatus EventHandler(Event e, void *param);
}
sk::EventStatus AppEventHandler(sk::Event e, void *param);
#include "imgui/imgui.h"
#include "imgui/imgui_impl_rw.h"

315
vendor/librw/skeleton/win.cpp vendored Normal file
View file

@ -0,0 +1,315 @@
#ifdef _WIN32
#include <windows.h>
#include <rw.h>
#include "skeleton.h"
using namespace sk;
using namespace rw;
#ifdef RW_D3D9
#ifndef VK_OEM_NEC_EQUAL
#define VK_OEM_NEC_EQUAL 0x92
#endif
static int keymap[256];
static void
initkeymap(void)
{
int i;
for(i = 0; i < 256; i++)
keymap[i] = KEY_NULL;
keymap[VK_SPACE] = ' ';
keymap[VK_OEM_7] = '\'';
keymap[VK_OEM_COMMA] = ',';
keymap[VK_OEM_MINUS] = '-';
keymap[VK_OEM_PERIOD] = '.';
keymap[VK_OEM_2] = '/';
for(i = '0'; i <= '9'; i++)
keymap[i] = i;
keymap[VK_OEM_1] = ';';
keymap[VK_OEM_NEC_EQUAL] = '=';
for(i = 'A'; i <= 'Z'; i++)
keymap[i] = i;
keymap[VK_OEM_4] = '[';
keymap[VK_OEM_5] = '\\';
keymap[VK_OEM_6] = ']';
keymap[VK_OEM_3] = '`';
keymap[VK_ESCAPE] = KEY_ESC;
keymap[VK_RETURN] = KEY_ENTER;
keymap[VK_TAB] = KEY_TAB;
keymap[VK_BACK] = KEY_BACKSP;
keymap[VK_INSERT] = KEY_INS;
keymap[VK_DELETE] = KEY_DEL;
keymap[VK_RIGHT] = KEY_RIGHT;
keymap[VK_LEFT] = KEY_LEFT;
keymap[VK_DOWN] = KEY_DOWN;
keymap[VK_UP] = KEY_UP;
keymap[VK_PRIOR] = KEY_PGUP;
keymap[VK_NEXT] = KEY_PGDN;
keymap[VK_HOME] = KEY_HOME;
keymap[VK_END] = KEY_END;
keymap[VK_MODECHANGE] = KEY_CAPSLK;
for(i = VK_F1; i <= VK_F24; i++)
keymap[i] = i-VK_F1+KEY_F1;
keymap[VK_LSHIFT] = KEY_LSHIFT;
keymap[VK_LCONTROL] = KEY_LCTRL;
keymap[VK_LMENU] = KEY_LALT;
keymap[VK_RSHIFT] = KEY_RSHIFT;
keymap[VK_RCONTROL] = KEY_RCTRL;
keymap[VK_RMENU] = KEY_RALT;
}
bool running;
static void KeyUp(int key) { EventHandler(KEYUP, &key); }
static void KeyDown(int key) { EventHandler(KEYDOWN, &key); }
LRESULT CALLBACK
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static int resizing = 0;
static int buttons = 0;
POINTS p;
MouseState ms;
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
if(wParam == VK_MENU){
if(GetKeyState(VK_LMENU) & 0x8000) KeyDown(keymap[VK_LMENU]);
if(GetKeyState(VK_RMENU) & 0x8000) KeyDown(keymap[VK_RMENU]);
}else if(wParam == VK_CONTROL){
if(GetKeyState(VK_LCONTROL) & 0x8000) KeyDown(keymap[VK_LCONTROL]);
if(GetKeyState(VK_RCONTROL) & 0x8000) KeyDown(keymap[VK_RCONTROL]);
}else if(wParam == VK_SHIFT){
if(GetKeyState(VK_LSHIFT) & 0x8000) KeyDown(keymap[VK_LSHIFT]);
if(GetKeyState(VK_RSHIFT) & 0x8000) KeyDown(keymap[VK_RSHIFT]);
}else
KeyDown(keymap[wParam]);
break;
case WM_SYSKEYUP:
case WM_KEYUP:
if(wParam == VK_MENU){
if((GetKeyState(VK_LMENU) & 0x8000) == 0) KeyUp(keymap[VK_LMENU]);
if((GetKeyState(VK_RMENU) & 0x8000) == 0) KeyUp(keymap[VK_RMENU]);
}else if(wParam == VK_CONTROL){
if((GetKeyState(VK_LCONTROL) & 0x8000) == 0) KeyUp(keymap[VK_LCONTROL]);
if((GetKeyState(VK_RCONTROL) & 0x8000) == 0) KeyUp(keymap[VK_RCONTROL]);
}else if(wParam == VK_SHIFT){
if((GetKeyState(VK_LSHIFT) & 0x8000) == 0) KeyUp(keymap[VK_LSHIFT]);
if((GetKeyState(VK_RSHIFT) & 0x8000) == 0) KeyUp(keymap[VK_RSHIFT]);
}else
KeyUp(keymap[wParam]);
break;
case WM_CHAR:
if(wParam > 0 && wParam < 0x10000)
EventHandler(CHARINPUT, (void*)wParam);
break;
case WM_MOUSEMOVE:
p = MAKEPOINTS(lParam);
ms.posx = p.x;
ms.posy = p.y;
EventHandler(MOUSEMOVE, &ms);
break;
case WM_LBUTTONDOWN:
buttons |= 1; goto mbtn;
case WM_LBUTTONUP:
buttons &= ~1; goto mbtn;
case WM_MBUTTONDOWN:
buttons |= 2; goto mbtn;
case WM_MBUTTONUP:
buttons &= ~2; goto mbtn;
case WM_RBUTTONDOWN:
buttons |= 4; goto mbtn;
case WM_RBUTTONUP:
buttons &= ~4;
mbtn:
ms.buttons = buttons;
EventHandler(MOUSEBTN, &ms);
break;
case WM_SIZE:
rw::Rect r;
r.x = 0;
r.y = 0;
r.w = LOWORD(lParam);
r.h = HIWORD(lParam);
EventHandler(RESIZE, &r);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_QUIT:
running = false;
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
HWND
MakeWindow(HINSTANCE instance, int width, int height, const char *title)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = "librwD3D9";
if(!RegisterClass(&wc)){
MessageBox(0, "RegisterClass() - FAILED", 0, 0);
return 0;
}
int offx = 100;
int offy = 100;
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = width;
rect.bottom = height;
DWORD style = WS_OVERLAPPEDWINDOW;
AdjustWindowRect(&rect, style, FALSE);
rect.right += -rect.left;
rect.bottom += -rect.top;
HWND win;
win = CreateWindow("librwD3D9", title, style,
offx, offy, rect.right, rect.bottom, 0, 0, instance, 0);
if(!win){
MessageBox(0, "CreateWindow() - FAILED", 0, 0);
return 0;
}
ShowWindow(win, SW_SHOW);
UpdateWindow(win);
return win;
}
void
pollEvents(void)
{
MSG msg;
while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
if(msg.message == WM_QUIT){
running = false;
break;
}else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
int WINAPI
WinMain(HINSTANCE instance, HINSTANCE,
PSTR cmdLine, int showCmd)
{
/*
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
*/
INT64 ticks;
INT64 ticksPerSecond;
if(!QueryPerformanceFrequency((LARGE_INTEGER*)&ticksPerSecond))
return 0;
if(!QueryPerformanceCounter((LARGE_INTEGER*)&ticks))
return 0;
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
args.argc = _argc;
args.argv = _argv;
#else
args.argc = __argc;
args.argv = __argv;
#endif
if(EventHandler(INITIALIZE, nil) == EVENTERROR)
return 0;
HWND win = MakeWindow(instance,
sk::globals.width, sk::globals.height,
sk::globals.windowtitle);
if(win == 0){
MessageBox(0, "MakeWindow() - FAILED", 0, 0);
return 0;
}
engineOpenParams.window = win;
initkeymap();
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
return 0;
INT64 lastTicks;
QueryPerformanceCounter((LARGE_INTEGER *)&lastTicks);
running = true;
while((pollEvents(), running) && !globals.quit){
QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
float timeDelta = (float)(ticks - lastTicks)/ticksPerSecond;
EventHandler(IDLE, &timeDelta);
lastTicks = ticks;
}
EventHandler(RWTERMINATE, nil);
return 0;
}
namespace sk {
void
SetMousePosition(int x, int y)
{
POINT pos = { x, y };
ClientToScreen(engineOpenParams.window, &pos);
SetCursorPos(pos.x, pos.y);
}
}
#endif
#ifdef RW_OPENGL
int main(int argc, char *argv[]);
int WINAPI
WinMain(HINSTANCE instance, HINSTANCE,
PSTR cmdLine, int showCmd)
{
/*
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
*/
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
return main(_argc, _argv);
#else
return main(__argc, __argv);
#endif
}
#endif
#endif

255
vendor/librw/src/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,255 @@
add_library(librw
"${PROJECT_SOURCE_DIR}/args.h"
"${PROJECT_SOURCE_DIR}/rw.h"
anim.cpp
base.cpp
bmp.cpp
camera.cpp
charset.cpp
clump.cpp
engine.cpp
error.cpp
frame.cpp
geometry.cpp
geoplg.cpp
hanim.cpp
image.cpp
light.cpp
matfx.cpp
pipeline.cpp
plg.cpp
png.cpp
prim.cpp
raster.cpp
render.cpp
rwanim.h
rwengine.h
rwerror.h
rwobjects.h
rwpipeline.h
rwplg.h
rwplugins.h
rwrender.h
rwuserdata.h
skin.cpp
texture.cpp
tga.cpp
tristrip.cpp
userdata.cpp
uvanim.cpp
world.cpp
d3d/d3d8.cpp
d3d/d3d8matfx.cpp
d3d/d3d8render.cpp
d3d/d3d8skin.cpp
d3d/d3d9.cpp
d3d/d3d9matfx.cpp
d3d/d3d9render.cpp
d3d/d3d9skin.cpp
d3d/d3d.cpp
d3d/d3ddevice.cpp
d3d/d3dimmed.cpp
d3d/d3drender.cpp
d3d/rwd3d8.h
d3d/rwd3d9.h
d3d/rwd3d.h
d3d/rwd3dimpl.h
d3d/rwxbox.h
d3d/rwxboximpl.h
d3d/xbox.cpp
d3d/xboxmatfx.cpp
d3d/xboxskin.cpp
d3d/xboxvfmt.cpp
gl/gl3.cpp
gl/gl3device.cpp
gl/gl3immed.cpp
gl/gl3matfx.cpp
gl/gl3pipe.cpp
gl/gl3raster.cpp
gl/gl3render.cpp
gl/gl3shader.cpp
gl/gl3skin.cpp
gl/rwgl3.h
gl/rwgl3impl.h
gl/rwgl3plg.h
gl/rwgl3shader.h
gl/rwwdgl.h
gl/wdgl.cpp
gl/glad/glad.h
gl/glad/glad.c
gl/glad/khrplatform.h
lodepng/lodepng.h
lodepng/lodepng.cpp
ps2/pds.cpp
ps2/ps2.cpp
ps2/ps2device.cpp
ps2/ps2matfx.cpp
ps2/ps2raster.cpp
ps2/ps2skin.cpp
ps2/rwps2.h
ps2/rwps2impl.h
ps2/rwps2plg.h
)
add_library(librw::librw ALIAS librw)
target_include_directories(librw
INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${LIBRW_INSTALL_INCLUDEDIR}>
)
target_compile_definitions(librw
PRIVATE
LODEPNG_NO_COMPILE_CPP
"$<IF:$<CONFIG:DEBUG>,DEBUG,NDEBUG>"
PUBLIC
"RW_${LIBRW_PLATFORM}"
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_link_libraries(librw
PRIVATE
m
)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
target_compile_options(librw
PRIVATE
"-Wall"
)
if (NOT LIBRW_PLATFORM_PS2)
target_compile_options(librw
PRIVATE
"-Wextra"
"-Wdouble-promotion"
"-Wpedantic"
)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(librw
PUBLIC
/wd4996 /wd4244
)
endif()
set_target_properties(librw
PROPERTIES
C_STANDARD 11
C_EXTENSIONS OFF
C_STANDARD_REQUIRED ON
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED ON
PREFIX ""
)
if(LIBRW_PLATFORM_GL3)
if (LIBRW_GL3_GFXLIB STREQUAL "GLFW")
find_package(glfw3 REQUIRED)
target_link_libraries(librw
PUBLIC
glfw
)
elseif (LIBRW_GL3_GFXLIB STREQUAL "SDL2")
find_package(SDL2 REQUIRED)
target_compile_definitions(librw PUBLIC LIBRW_SDL2)
target_link_libraries(librw
PUBLIC
SDL2::SDL2
)
endif()
set(OpenGL_GL_PREFERENCE GLVND)
find_package(OpenGL)
if(TARGET OpenGL::OpenGL)
target_link_libraries(librw
PRIVATE
OpenGL::OpenGL
)
elseif(TARGET OpenGL::EGL)
target_link_libraries(librw
PRIVATE
OpenGL::EGL
)
elseif(TARGET OpenGL::GL)
target_link_libraries(librw
PRIVATE
OpenGL::GL
)
else()
message(FATAL_ERROR "find_package(OpenGL) failed.")
endif()
elseif(LIBRW_PLATFORM_D3D9)
target_link_libraries(librw
PRIVATE
d3d9
xinput
)
endif()
if(LIBRW_INSTALL)
install(
FILES
"${PROJECT_SOURCE_DIR}/args.h"
"${PROJECT_SOURCE_DIR}/rw.h"
DESTINATION "${LIBRW_INSTALL_INCLUDEDIR}"
)
install(
FILES
base.err
rwbase.h
rwcharset.h
rwerror.h
rwplg.h
rwrender.h
rwengine.h
rwpipeline.h
rwobjects.h
rwanim.h
rwplugins.h
rwuserdata.h
DESTINATION "${LIBRW_INSTALL_INCLUDEDIR}/src"
)
install(
FILES
d3d/rwxbox.h
d3d/rwd3d.h
d3d/rwd3d8.h
d3d/rwd3d9.h
DESTINATION "${LIBRW_INSTALL_INCLUDEDIR}/src/d3d"
)
install(
FILES
ps2/rwps2.h
ps2/rwps2plg.h
DESTINATION "${LIBRW_INSTALL_INCLUDEDIR}/src/ps2"
)
install(
FILES
gl/rwwdgl.h
gl/rwgl3.h
gl/rwgl3plg.h
gl/rwgl3shader.h
DESTINATION "${LIBRW_INSTALL_INCLUDEDIR}/src/gl"
)
install(
FILES
gl/glad/glad.h
gl/glad/khrplatform.h
DESTINATION "${LIBRW_INSTALL_INCLUDEDIR}/src/gl/glad"
)
install(
TARGETS librw
EXPORT librw-targets
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
endif()

293
vendor/librw/src/anim.cpp vendored Normal file
View file

@ -0,0 +1,293 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#include "rwanim.h"
#include "rwplugins.h"
#define PLUGIN_ID ID_ANIMANIMATION
namespace rw {
//
// AnimInterpolatorInfo
//
#define MAXINTERPINFO 10
static AnimInterpolatorInfo *interpInfoList[MAXINTERPINFO];
void
AnimInterpolatorInfo::registerInterp(AnimInterpolatorInfo *interpInfo)
{
for(int32 i = 0; i < MAXINTERPINFO; i++)
if(interpInfoList[i] == nil){
interpInfoList[i] = interpInfo;
return;
}
assert(0 && "no room for interpolatorInfo");
}
void
AnimInterpolatorInfo::unregisterInterp(AnimInterpolatorInfo *interpInfo)
{
for(int32 i = 0; i < MAXINTERPINFO; i++)
if(interpInfoList[i] == interpInfo){
rwFree(interpInfoList[i]);
interpInfoList[i] = nil;
return;
}
}
AnimInterpolatorInfo*
AnimInterpolatorInfo::find(int32 id)
{
for(int32 i = 0; i < MAXINTERPINFO; i++){
if(interpInfoList[i] && interpInfoList[i]->id == id)
return interpInfoList[i];
}
return nil;
}
//
// Animation
//
Animation*
Animation::create(AnimInterpolatorInfo *interpInfo, int32 numFrames,
int32 flags, float duration)
{
int32 sz = sizeof(Animation) +
numFrames*interpInfo->animKeyFrameSize +
interpInfo->customDataSize;
uint8 *data = (uint8*)rwMalloc(sz, MEMDUR_EVENT | ID_ANIMANIMATION);
if(data == nil){
RWERROR((ERR_ALLOC, sz));
return nil;
}
Animation *anim = (Animation*)data;
data += sizeof(Animation);
anim->interpInfo = interpInfo;
anim->numFrames = numFrames;
anim->flags = flags;
anim->duration = duration;
anim->keyframes = data;
data += anim->numFrames*interpInfo->animKeyFrameSize;
anim->customData = data;
return anim;
}
void
Animation::destroy(void)
{
rwFree(this);
}
int32
Animation::getNumNodes(void)
{
int32 sz = this->interpInfo->animKeyFrameSize;
KeyFrameHeader *first = (KeyFrameHeader*)this->keyframes;
int32 n = 0;
for(KeyFrameHeader *f = first; f->prev != first; f = f->next(sz))
n++;
return n;
}
Animation*
Animation::streamRead(Stream *stream)
{
Animation *anim;
if(stream->readI32() != 0x100)
return nil;
int32 typeID = stream->readI32();
AnimInterpolatorInfo *interpInfo = AnimInterpolatorInfo::find(typeID);
int32 numFrames = stream->readI32();
int32 flags = stream->readI32();
float duration = stream->readF32();
anim = Animation::create(interpInfo, numFrames, flags, duration);
interpInfo->streamRead(stream, anim);
return anim;
}
Animation*
Animation::streamReadLegacy(Stream *stream)
{
Animation *anim;
AnimInterpolatorInfo *interpInfo = AnimInterpolatorInfo::find(1);
int32 numFrames = stream->readI32();
int32 flags = stream->readI32();
float duration = stream->readF32();
anim = Animation::create(interpInfo, numFrames, flags, duration);
HAnimKeyFrame *frames = (HAnimKeyFrame*)anim->keyframes;
for(int32 i = 0; i < anim->numFrames; i++){
stream->read32(&frames[i].q, 4*4);
frames[i].q = conj(frames[i].q);
stream->read32(&frames[i].t, 3*4);
frames[i].time = stream->readF32();
int32 prev = stream->readI32()/0x24;
frames[i].prev = &frames[prev];
}
return anim;
}
bool
Animation::streamWrite(Stream *stream)
{
writeChunkHeader(stream, ID_ANIMANIMATION, this->streamGetSize());
stream->writeI32(0x100);
stream->writeI32(this->interpInfo->id);
stream->writeI32(this->numFrames);
stream->writeI32(this->flags);
stream->writeF32(this->duration);
this->interpInfo->streamWrite(stream, this);
return true;
}
bool
Animation::streamWriteLegacy(Stream *stream)
{
stream->writeI32(this->numFrames);
stream->writeI32(this->flags);
stream->writeF32(this->duration);
assert(interpInfo->id == 1);
HAnimKeyFrame *frames = (HAnimKeyFrame*)this->keyframes;
for(int32 i = 0; i < this->numFrames; i++){
frames[i].q = conj(frames[i].q);
stream->write32(&frames[i].q, 4*4);
frames[i].q = conj(frames[i].q);
stream->write32(&frames[i].t, 3*4);
stream->writeF32(frames[i].time);
stream->writeI32((frames[i].prev - frames)*0x24);
}
return true;
}
uint32
Animation::streamGetSize(void)
{
uint32 size = 4 + 4 + 4 + 4 + 4;
size += this->interpInfo->streamGetSize(this);
return size;
}
//
// AnimInterpolator
//
AnimInterpolator*
AnimInterpolator::create(int32 numNodes, int32 maxFrameSize)
{
AnimInterpolator *interp;
int32 sz;
int32 realsz = maxFrameSize;
// Add some space for pointers and padding, hopefully this will be
// enough. Don't change maxFrameSize not to mess up streaming.
if(sizeof(void*) > 4)
realsz += 16;
sz = sizeof(AnimInterpolator) + numNodes*realsz;
interp = (AnimInterpolator*)rwMalloc(sz, MEMDUR_EVENT | ID_ANIMANIMATION);
if(interp == nil){
RWERROR((ERR_ALLOC, sz));
return nil;
}
interp->currentAnim = nil;
interp->currentTime = 0.0f;
interp->nextFrame = nil;
interp->maxInterpKeyFrameSize = maxFrameSize;
interp->currentInterpKeyFrameSize = maxFrameSize;
interp->currentAnimKeyFrameSize = -1;
interp->numNodes = numNodes;;
return interp;
}
void
AnimInterpolator::destroy(void)
{
rwFree(this);
}
bool32
AnimInterpolator::setCurrentAnim(Animation *anim)
{
int32 i;
AnimInterpolatorInfo *interpInfo = anim->interpInfo;
this->currentAnim = anim;
this->currentTime = 0.0f;
int32 maxkf = this->maxInterpKeyFrameSize;
if(sizeof(void*) > 4) // see above in create()
maxkf += 16;
if(interpInfo->interpKeyFrameSize > maxkf){
RWERROR((ERR_GENERAL, "interpolation frame too big"));
return 0;
}
this->currentInterpKeyFrameSize = interpInfo->interpKeyFrameSize;
this->currentAnimKeyFrameSize = interpInfo->animKeyFrameSize;
this->applyCB = interpInfo->applyCB;
this->blendCB = interpInfo->blendCB;
this->interpCB = interpInfo->interpCB;
this->addCB = interpInfo->addCB;
for(i = 0; i < numNodes; i++){
InterpFrameHeader *intf;
KeyFrameHeader *kf1, *kf2;
intf = this->getInterpFrame(i);
kf1 = this->getAnimFrame(i);
kf2 = this->getAnimFrame(i+numNodes);
intf->keyFrame1 = kf1;
intf->keyFrame2 = kf2;
// TODO: perhaps just implement all interpolator infos?
if(this->interpCB)
this->interpCB(intf, kf1, kf2, 0.0f, anim->customData);
}
this->nextFrame = this->getAnimFrame(numNodes*2);
return 1;
}
void
AnimInterpolator::addTime(float32 t)
{
int32 i;
if(t <= 0.0f)
return;
this->currentTime += t;
// reset animation
if(this->currentTime > this->currentAnim->duration){
this->setCurrentAnim(this->currentAnim);
return;
}
KeyFrameHeader *last = this->getAnimFrame(this->currentAnim->numFrames);
KeyFrameHeader *next = (KeyFrameHeader*)this->nextFrame;
InterpFrameHeader *ifrm = nil;
while(next < last && next->prev->time <= this->currentTime){
// find next interpolation frame to expire
for(i = 0; i < this->numNodes; i++){
ifrm = this->getInterpFrame(i);
if(ifrm->keyFrame2 == next->prev)
break;
}
// advance interpolation frame
ifrm->keyFrame1 = ifrm->keyFrame2;
ifrm->keyFrame2 = next;
// ... and next frame
next = (KeyFrameHeader*)((uint8*)this->nextFrame +
currentAnimKeyFrameSize);
this->nextFrame = next;
}
for(i = 0; i < this->numNodes; i++){
ifrm = this->getInterpFrame(i);
this->interpCB(ifrm, ifrm->keyFrame1, ifrm->keyFrame2,
this->currentTime,
this->currentAnim->customData);
}
}
}

1121
vendor/librw/src/base.cpp vendored Normal file

File diff suppressed because it is too large Load diff

24
vendor/librw/src/base.err vendored Normal file
View file

@ -0,0 +1,24 @@
ECODE(ERR_GENERAL,
"Error: %s"),
ECODE(ERR_ALLOC,
"Couldn't allocate 0x%X bytes"),
ECODE(ERR_FILE,
"Couldn't open file %s"),
ECODE(ERR_CHUNK,
"Couldn't find chunk %s"),
ECODE(ERR_VERSION,
"Unsupported version %X"),
ECODE(ERR_PLATFORM,
"Unsupported platform %d"),
ECODE(ERR_ENGINEINIT,
"Engine could not be initialized"),
ECODE(ERR_ENGINEOPEN,
"Engine could not be opened"),
ECODE(ERR_ENGINESTART,
"Engine could not be started"),
ECODE(ERR_INVRASTER,
"Invalid raster format"),
ECODE(ERR_NOTEXTURE,
"Could not create texture"),
ECODE(ERR_FORMAT_UNSUPPORTED,
"Unsupported raster format")

284
vendor/librw/src/bmp.cpp vendored Normal file
View file

@ -0,0 +1,284 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#define PLUGIN_ID 0
namespace rw {
// NB: this has padding and cannot be streamed directly!
struct BMPheader
{
uint16 magic;
uint32 size;
uint16 reserved[2];
uint32 offset;
bool32 read(Stream *stream);
void write(Stream *stream);
};
// This one is aligned and can be streamed directly
struct DIBheader
{
uint32 headerSize;
int32 width;
int32 height;
int16 numPlanes;
int16 depth;
uint32 compression;
uint32 imgSize;
int32 hres;
int32 vres;
int32 paletteLen;
int32 numImportant;
// end of 40 btyes
uint32 rmask, gmask, bmask, amask;
};
bool32
BMPheader::read(Stream *stream)
{
magic = stream->readU16();
size = stream->readU32();
reserved[0] = stream->readU16();
reserved[1] = stream->readU16();
offset = stream->readU32();
return magic == 0x4D42;
}
void
BMPheader::write(Stream *stream)
{
stream->writeU16(magic);
stream->writeU32(size);
stream->writeU16(reserved[0]);
stream->writeU16(reserved[1]);
stream->writeU32(offset);
}
Image*
readBMP(const char *filename)
{
ASSERTLITTLE;
Image *image;
uint32 length;
uint8 *data;
StreamMemory file;
int i, x, y;
bool32 noalpha;
int pad;
data = getFileContents(filename, &length);
if(data == nil)
return nil;
file.open(data, length);
/* read headers */
BMPheader bmp;
DIBheader dib;
if(!bmp.read(&file))
goto lose;
file.read8(&dib, sizeof(dib));
file.seek(dib.headerSize-sizeof(dib)); // skip the part of the header we're ignoring
if(dib.headerSize <= 16){
dib.compression = 0;
dib.paletteLen = 0;
}
noalpha = true;
// Recognize 32 bit formats
if(dib.compression == 3){
if(dib.rmask != 0xFF0000 ||
dib.gmask != 0x00FF00 ||
dib.bmask != 0x0000FF)
goto lose;
dib.compression = 0;
if(dib.headerSize > 52 && dib.amask == 0xFF000000)
noalpha = false;
}
if(dib.compression != 0)
goto lose;
image = Image::create(dib.width, dib.height, dib.depth);
image->allocate();
if(image->palette){
int len = 1<<dib.depth;
uint8 (*color)[4] = (uint8 (*)[4])image->palette;
for(i = 0; i < len; i++){
color[i][2] = file.readU8(); // blue
color[i][1] = file.readU8(); // green
color[i][0] = file.readU8(); // red
color[i][3] = file.readU8(); // alpha
if(noalpha)
color[i][3] = 0xFF;
}
}
file.seek(bmp.offset, 0);
pad = image->width*image->bpp % 4;
uint8 *px, *line;
line = image->pixels + (image->height-1)*image->stride;
for(y = 0; y < image->height; y++){
px = line;
for(x = 0; x < image->width; x++){
switch(image->depth){
case 4:
i = file.readU8();;
px[x+0] = (i>>4)&0xF;
px[x+1] = i&0xF;
x++;
break;
case 8:
px[x] = file.readU8();
break;
case 16:
// TODO: what format is this even? and what does Image expect?
px[x*2 + 0] = file.readU8();
px[x*2 + 1] = file.readU8();
break;
case 24:
px[x*3 + 2] = file.readU8();
px[x*3 + 1] = file.readU8();
px[x*3 + 0] = file.readU8();
break;
case 32:
px[x*4 + 2] = file.readU8();
px[x*4 + 1] = file.readU8();
px[x*4 + 0] = file.readU8();
px[x*4 + 3] = file.readU8();
if(noalpha)
px[x*4 + 3] = 0xFF;
break;
default:
goto lose;
}
}
line -= image->stride;
file.seek(pad);
}
file.close();
rwFree(data);
return image;
lose:
file.close();
rwFree(data);
return nil;
}
/* can't write alpha */
void
writeBMP(Image *image, const char *filename)
{
ASSERTLITTLE;
uint8 *p;
StreamFile file;
if(!file.open(filename, "wb")){
RWERROR((ERR_FILE, filename));
return;
}
int32 pallen = image->depth > 8 ? 0 :
image->depth == 4 ? 16 : 256;
int32 stride = image->width*image->depth/8;
int32 depth = image->depth == 32 ? 24 : image->depth;
stride = stride+3 & ~3;
// File headers
BMPheader bmp;
bmp.magic = 0x4D42; // BM
bmp.size = 0x36 + 4*pallen + image->height*stride;
bmp.reserved[0] = 0;
bmp.reserved[1] = 0;
bmp.offset = 0x36 + 4*pallen;
bmp.write(&file);
DIBheader dib;
dib.headerSize = 0x28;
dib.width = image->width;
dib.height = image->height;
dib.numPlanes = 1;
dib.depth = depth;
dib.compression = 0;
dib.imgSize = 0;
dib.hres = 2835; // 72dpi
dib.vres = 2835; // 72dpi
dib.paletteLen = 0;
dib.numImportant = 0;
file.write8(&dib, dib.headerSize);
for(int i = 0; i < pallen; i++){
file.writeU8(image->palette[i*4+2]);
file.writeU8(image->palette[i*4+1]);
file.writeU8(image->palette[i*4+0]);
file.writeU8(0xFF);
}
uint8 *line = image->pixels + (image->height-1)*image->stride;
int32 n;
for(int y = 0; y < image->height; y++){
p = line;
for(int x = 0; x < image->width; x++){
switch(image->depth){
case 4:
file.writeU8((p[0]&0xF)<<4 | (p[1]&0xF));
p += 2;
x++;
break;
case 8:
file.writeU8(*p++);
break;
case 16:
file.writeU8(p[0]);
file.writeU8(p[1]);
p += 2;
break;
case 24:
file.writeU8(p[2]);
file.writeU8(p[1]);
file.writeU8(p[0]);
p += 3;
break;
case 32:
file.writeU8(p[2]);
file.writeU8(p[1]);
file.writeU8(p[0]);
p += 4;
}
}
n = (p-line) % 4;
while(n--)
file.writeU8(0);
line -= image->stride;
}
file.close();
}
}

524
vendor/librw/src/camera.cpp vendored Normal file
View file

@ -0,0 +1,524 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#define PLUGIN_ID ID_CAMERA
namespace rw {
int32 Camera::numAllocated;
PluginList Camera::s_plglist(sizeof(Camera));
void
defaultBeginUpdateCB(Camera *cam)
{
engine->currentCamera = cam;
Frame::syncDirty();
engine->device.beginUpdate(cam);
}
void
defaultEndUpdateCB(Camera *cam)
{
engine->device.endUpdate(cam);
}
static void
buildPlanes(Camera *cam)
{
V3d *c = cam->frustumCorners;
FrustumPlane *p = cam->frustumPlanes;
V3d v51 = sub(c[1], c[5]);
V3d v73 = sub(c[3], c[7]);
/* Far plane */
p[0].plane.normal = cam->getFrame()->getLTM()->at;
p[0].plane.distance = dot(p[0].plane.normal, c[4]);
p[0].closestX = p[0].plane.normal.x < 0.0f ? 0 : 1;
p[0].closestY = p[0].plane.normal.y < 0.0f ? 0 : 1;
p[0].closestZ = p[0].plane.normal.z < 0.0f ? 0 : 1;
/* Near plane */
p[1].plane.normal = neg(p[0].plane.normal);
p[1].plane.distance = dot(p[1].plane.normal, c[0]);
p[1].closestX = p[1].plane.normal.x < 0.0f ? 0 : 1;
p[1].closestY = p[1].plane.normal.y < 0.0f ? 0 : 1;
p[1].closestZ = p[1].plane.normal.z < 0.0f ? 0 : 1;
/* Right plane */
p[2].plane.normal = normalize(cross(v51,
sub(c[6], c[5])));
p[2].plane.distance = dot(p[2].plane.normal, c[1]);
p[2].closestX = p[2].plane.normal.x < 0.0f ? 0 : 1;
p[2].closestY = p[2].plane.normal.y < 0.0f ? 0 : 1;
p[2].closestZ = p[2].plane.normal.z < 0.0f ? 0 : 1;
/* Top plane */
p[3].plane.normal = normalize(cross(sub(c[4], c[5]),
v51));
p[3].plane.distance = dot(p[3].plane.normal, c[1]);
p[3].closestX = p[3].plane.normal.x < 0.0f ? 0 : 1;
p[3].closestY = p[3].plane.normal.y < 0.0f ? 0 : 1;
p[3].closestZ = p[3].plane.normal.z < 0.0f ? 0 : 1;
/* Left plane */
p[4].plane.normal = normalize(cross(v73,
sub(c[4], c[7])));
p[4].plane.distance = dot(p[4].plane.normal, c[3]);
p[4].closestX = p[4].plane.normal.x < 0.0f ? 0 : 1;
p[4].closestY = p[4].plane.normal.y < 0.0f ? 0 : 1;
p[4].closestZ = p[4].plane.normal.z < 0.0f ? 0 : 1;
/* Bottom plane */
p[5].plane.normal = normalize(cross(sub(c[6], c[7]),
v73));
p[5].plane.distance = dot(p[5].plane.normal, c[3]);
p[5].closestX = p[5].plane.normal.x < 0.0f ? 0 : 1;
p[5].closestY = p[5].plane.normal.y < 0.0f ? 0 : 1;
p[5].closestZ = p[5].plane.normal.z < 0.0f ? 0 : 1;
}
static void
buildClipPersp(Camera *cam)
{
Matrix *ltm = cam->getFrame()->getLTM();
/* First we calculate the 4 points on the view window. */
V3d up = scale(ltm->up, cam->viewWindow.y);
V3d left = scale(ltm->right, cam->viewWindow.x);
V3d *c = cam->frustumCorners;
c[0] = add(add(ltm->at, up), left); // top left
c[1] = sub(add(ltm->at, up), left); // top right
c[2] = sub(sub(ltm->at, up), left); // bottom right
c[3] = add(sub(ltm->at, up), left); // bottom left
/* Now Calculate near and far corners. */
V3d off = sub(scale(ltm->up, cam->viewOffset.y),
scale(ltm->right, cam->viewOffset.x));
for(int32 i = 0; i < 4; i++){
V3d corner = sub(cam->frustumCorners[i], off);
V3d pos = add(ltm->pos, off);
c[i] = add(scale(corner, cam->nearPlane), pos);
c[i+4] = add(scale(corner, cam->farPlane), pos);
}
buildPlanes(cam);
}
static void
buildClipParallel(Camera *cam)
{
Matrix *ltm = cam->getFrame()->getLTM();
float32 nearoffx = -(1.0f - cam->nearPlane)*cam->viewOffset.x;
float32 nearoffy = (1.0f - cam->nearPlane)*cam->viewOffset.y;
float32 faroffx = -(1.0f - cam->farPlane)*cam->viewOffset.x;
float32 faroffy = (1.0f - cam->farPlane)*cam->viewOffset.y;
V3d *c = cam->frustumCorners;
c[0].x = nearoffx + cam->viewWindow.x;
c[0].y = nearoffy + cam->viewWindow.y;
c[0].z = cam->nearPlane;
c[1].x = nearoffx - cam->viewWindow.x;
c[1].y = nearoffy + cam->viewWindow.y;
c[1].z = cam->nearPlane;
c[2].x = nearoffx - cam->viewWindow.x;
c[2].y = nearoffy - cam->viewWindow.y;
c[2].z = cam->nearPlane;
c[3].x = nearoffx + cam->viewWindow.x;
c[3].y = nearoffy - cam->viewWindow.y;
c[3].z = cam->nearPlane;
c[4].x = faroffx + cam->viewWindow.x;
c[4].y = faroffy + cam->viewWindow.y;
c[4].z = cam->farPlane;
c[5].x = faroffx - cam->viewWindow.x;
c[5].y = faroffy + cam->viewWindow.y;
c[5].z = cam->farPlane;
c[6].x = faroffx - cam->viewWindow.x;
c[6].y = faroffy - cam->viewWindow.y;
c[6].z = cam->farPlane;
c[7].x = faroffx + cam->viewWindow.x;
c[7].y = faroffy - cam->viewWindow.y;
c[7].z = cam->farPlane;
V3d::transformPoints(c, c, 8, ltm);
buildPlanes(cam);
}
static void
cameraSync(ObjectWithFrame *obj)
{
/*
* RW projection matrix looks like this:
* (cf. Camera View Matrix white paper)
* w = viewWindow width
* h = viewWindow height
* o = view offset
*
* perspective:
* 1/2w 0 ox/2w + 1/2 -ox/2w
* 0 -1/2h -oy/2h + 1/2 oy/2h
* 0 0 1 0
* 0 0 1 0
*
* parallel:
* 1/2w 0 ox/2w -ox/2w + 1/2
* 0 -1/2h -oy/2h oy/2h + 1/2
* 0 0 1 0
* 0 0 0 1
*
* The view matrix transforms from world to clip space, it is however
* not used for OpenGL or D3D since transformation to camera space
* and to clip space are handled by separate matrices there.
* On these platforms the two matrices are built in the platform's
* beginUpdate function.
* On the PS2 the z- and w-rows are the same and the
* 1/2 translation/shear is removed again on the VU1 by
* subtracting the w-row/2 from the x- and y-rows.
*
* perspective:
* 1/2w 0 ox/2w -ox/2w
* 0 -1/2h -oy/2h oy/2h
* 0 0 1 0
* 0 0 1 0
*
* parallel:
* 1/2w 0 ox/2w -ox/2w
* 0 -1/2h -oy/2h oy/2h
* 0 0 1 0
* 0 0 0 1
*
* RW builds this matrix directly without using explicit
* inversion and matrix multiplication.
*/
Camera *cam = (Camera*)obj;
Matrix inv, proj;
Matrix::invertOrthonormal(&inv, cam->getFrame()->getLTM());
inv.right.x = -inv.right.x;
inv.up.x = -inv.up.x;
inv.at.x = -inv.at.x;
inv.pos.x = -inv.pos.x;
float32 xscl = 1.0f/(2.0f*cam->viewWindow.x);
float32 yscl = 1.0f/(2.0f*cam->viewWindow.y);
proj.flags = 0;
proj.right.x = xscl;
proj.right.y = 0.0f;
proj.right.z = 0.0f;
proj.up.x = 0.0f;
proj.up.y = -yscl;
proj.up.z = 0.0f;
if(cam->projection == Camera::PERSPECTIVE){
proj.pos.x = -cam->viewOffset.x*xscl;
proj.pos.y = cam->viewOffset.y*yscl;
proj.pos.z = 0.0f;
proj.at.x = -proj.pos.x + 0.5f;
proj.at.y = -proj.pos.y + 0.5f;
proj.at.z = 1.0f;
proj.optimize();
Matrix::mult(&cam->viewMatrix, &inv, &proj);
buildClipPersp(cam);
}else{
proj.at.x = cam->viewOffset.x*xscl;
proj.at.y = -cam->viewOffset.y*yscl;
proj.at.z = 1.0f;
proj.pos.x = -proj.at.x + 0.5f;
proj.pos.y = -proj.at.y + 0.5f;
proj.pos.z = 0.0f;
proj.optimize();
Matrix::mult(&cam->viewMatrix, &inv, &proj);
buildClipParallel(cam);
}
cam->frustumBoundBox.calculate(cam->frustumCorners, 8);
}
void
worldBeginUpdateCB(Camera *cam)
{
engine->currentWorld = cam->world;
cam->originalBeginUpdate(cam);
}
void
worldEndUpdateCB(Camera *cam)
{
cam->originalEndUpdate(cam);
}
static void
worldCameraSync(ObjectWithFrame *obj)
{
Camera *camera = (Camera*)obj;
camera->originalSync(obj);
}
Camera*
Camera::create(void)
{
Camera *cam = (Camera*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_CAMERA);
if(cam == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
numAllocated++;
cam->object.object.init(Camera::ID, 0);
cam->object.syncCB = cameraSync;
cam->beginUpdateCB = defaultBeginUpdateCB;
cam->endUpdateCB = defaultEndUpdateCB;
cam->viewWindow.set(1.0f, 1.0f);
cam->viewOffset.set(0.0f, 0.0f);
cam->nearPlane = 0.05f;
cam->farPlane = 10.0f;
cam->fogPlane = 5.0f;
cam->projection = Camera::PERSPECTIVE;
cam->frameBuffer = nil;
cam->zBuffer = nil;
// clump extension
cam->clump = nil;
cam->inClump.init();
// world extension
cam->world = nil;
cam->originalSync = cam->object.syncCB;
cam->originalBeginUpdate = cam->beginUpdateCB;
cam->originalEndUpdate = cam->endUpdateCB;
cam->object.syncCB = worldCameraSync;
cam->beginUpdateCB = worldBeginUpdateCB;
cam->endUpdateCB = worldEndUpdateCB;
s_plglist.construct(cam);
return cam;
}
Camera*
Camera::clone(void)
{
Camera *cam = Camera::create();
if(cam == nil)
return nil;
cam->object.object.copy(&this->object.object);
cam->setFrame(this->getFrame());
cam->viewWindow = this->viewWindow;
cam->viewOffset = this->viewOffset;
cam->nearPlane = this->nearPlane;
cam->farPlane = this->farPlane;
cam->fogPlane = this->fogPlane;
cam->projection = this->projection;
cam->frameBuffer = this->frameBuffer;
cam->zBuffer = this->zBuffer;
if(this->world)
this->world->addCamera(cam);
s_plglist.copy(cam, this);
return cam;
}
void
Camera::destroy(void)
{
s_plglist.destruct(this);
assert(this->clump == nil);
assert(this->world == nil);
this->setFrame(nil);
rwFree(this);
numAllocated--;
}
void
Camera::clear(RGBA *col, uint32 mode)
{
engine->device.clearCamera(this, col, mode);
}
void
Camera::showRaster(uint32 flags)
{
this->frameBuffer->show(flags);
}
void
calczShiftScale(Camera *cam)
{
float32 n = cam->nearPlane;
float32 f = cam->farPlane;
float32 N = engine->device.zNear;
float32 F = engine->device.zFar;
// RW does this
N += (F - N)/10000.0f;
F -= (F - N)/10000.0f;
if(cam->projection == Camera::PERSPECTIVE){
cam->zScale = (N - F)*n*f/(f - n);
cam->zShift = (F*f - N*n)/(f - n);
}else{
cam->zScale = (F - N)/(f -n);
cam->zShift = (N*f - F*n)/(f - n);
}
}
void
Camera::setNearPlane(float32 near)
{
this->nearPlane = near;
calczShiftScale(this);
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setFarPlane(float32 far)
{
this->farPlane = far;
calczShiftScale(this);
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setViewWindow(const V2d *window)
{
this->viewWindow = *window;
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setViewOffset(const V2d *offset)
{
this->viewOffset = *offset;
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setProjection(int32 proj)
{
this->projection = proj;
if(this->getFrame())
this->getFrame()->updateObjects();
}
int32
Camera::frustumTestSphere(const Sphere *s) const
{
int32 res = SPHEREINSIDE;
const FrustumPlane *p = this->frustumPlanes;
for(int32 i = 0; i < 6; i++){
float32 dist = dot(p->plane.normal, s->center) - p->plane.distance;
if(s->radius < dist)
return SPHEREOUTSIDE;
if(s->radius > -dist)
res = SPHEREBOUNDARY;
p++;
}
return res;
}
struct CameraChunkData
{
V2d viewWindow;
V2d viewOffset;
float32 nearPlane, farPlane;
float32 fogPlane;
int32 projection;
};
Camera*
Camera::streamRead(Stream *stream)
{
CameraChunkData buf;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
stream->read32(&buf, sizeof(CameraChunkData));
Camera *cam = Camera::create();
cam->viewWindow = buf.viewWindow;
cam->viewOffset = buf.viewOffset;
cam->nearPlane = buf.nearPlane;
cam->farPlane = buf.farPlane;
cam->fogPlane = buf.fogPlane;
cam->projection = buf.projection;
if(s_plglist.streamRead(stream, cam))
return cam;
cam->destroy();
return nil;
}
bool
Camera::streamWrite(Stream *stream)
{
CameraChunkData buf;
writeChunkHeader(stream, ID_CAMERA, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, sizeof(CameraChunkData));
buf.viewWindow = this->viewWindow;
buf.viewOffset = this->viewOffset;
buf.nearPlane = this->nearPlane;
buf.farPlane = this->farPlane;
buf.fogPlane = this->fogPlane;
buf.projection = this->projection;
stream->write32(&buf, sizeof(CameraChunkData));
s_plglist.streamWrite(stream, this);
return true;
}
uint32
Camera::streamGetSize(void)
{
return 12 + sizeof(CameraChunkData) + 12 +
s_plglist.streamGetSize(this);
}
// Assumes horizontal FOV for 4:3, but we convert to vertical FOV
void
Camera::setFOV(float32 hfov, float32 ratio)
{
V2d v;
float w, h;
w = (float)this->frameBuffer->width;
h = (float)this->frameBuffer->height;
if(w < 1 || h < 1){
w = 1;
h = 1;
}
hfov = hfov*3.14159f/360.0f; // deg to rad and halved
float ar1 = 4.0f/3.0f;
float ar2 = w/h;
float vfov = atanf(tanf(hfov/2) / ar1) *2;
hfov = atanf(tanf(vfov/2) * ar2) *2;
float32 a = tanf(hfov);
v.set(a, a/ratio);
this->setViewWindow(&v);
v.set(0.0f, 0.0f);
this->setViewOffset(&v);
}
}

244
vendor/librw/src/charset.cpp vendored Normal file
View file

@ -0,0 +1,244 @@
#include <stdio.h>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwrender.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#include "rwcharset.h"
#include "ps2/rwps2.h"
#include "d3d/rwd3d.h"
#include "gl/rwgl3.h"
#define PLUGIN_ID 1000 // TODO: find a better ID
#ifndef RW_NULL
#ifdef RWHALFPIXEL
#define HALFPX (0.5f)
#else
#define HALFPX (0.0f)
#endif
namespace rw {
const uint8 fontbits[256*256] = {
#include "vgafont.inc"
};
#define NUMCHARS 100
static uint16 *indices;
static RWDEVICE::Im2DVertex *vertices;
static int32 numChars;
static Raster *lastRaster;
bool32
Charset::open(void)
{
if(indices || vertices)
return 0;
numChars = 0;
lastRaster = nil;
indices = rwNewT(uint16, NUMCHARS*6, MEMDUR_EVENT);
vertices = rwNewT(RWDEVICE::Im2DVertex, NUMCHARS*4, MEMDUR_EVENT);
if(indices == nil || vertices == nil){
close();
return 0;
}
return 1;
}
void
Charset::close(void)
{
rwFree(indices);
indices = nil;
rwFree(vertices);
vertices = nil;
}
Charset*
Charset::create(const RGBA *foreground, const RGBA *background)
{
Charset *charset = (Charset*)rwMalloc(sizeof(Charset), MEMDUR_EVENT);
if(charset == nil){
RWERROR((ERR_ALLOC, sizeof(Charset)));
return nil;
}
charset->raster = nil;
if(charset->setColors(foreground, background) == nil){
charset->destroy();
return nil;
}
charset->desc.count = 256;
charset->desc.tileWidth = 28;
charset->desc.tileHeight = 10;
charset->desc.width = 9;
charset->desc.height = 16;
charset->desc.width_internal = 9;
charset->desc.height_internal = 16;
return charset;
}
void
Charset::destroy(void)
{
if(raster)
raster->destroy();
rwFree(this);
}
Charset*
Charset::setColors(const RGBA *foreground, const RGBA *background)
{
Image *img = Image::create(256, 256, 8);
if(img == nil)
return nil;
img->pixels = (uint8*)fontbits;
img->stride = 256;
img->allocate();
img->palette[0] = background->red;
img->palette[1] = background->green;
img->palette[2] = background->blue;
img->palette[3] = background->alpha;
img->palette[4] = foreground->red;
img->palette[5] = foreground->green;
img->palette[6] = foreground->blue;
img->palette[7] = foreground->alpha;
Raster *newRaster = Raster::createFromImage(img);
img->destroy();
if(newRaster == nil)
return nil;
if(this->raster)
this->raster->destroy();
this->raster = newRaster;
return this;
}
void
Charset::flushBuffer(void)
{
if(numChars){
rw::SetRenderStatePtr(rw::TEXTURERASTER, lastRaster);
rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP);
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST);
uint32 cull = rw::GetRenderState(rw::CULLMODE);
uint32 ztest = rw::GetRenderState(rw::ZTESTENABLE);
rw::SetRenderState(rw::CULLMODE, rw::CULLNONE);
rw::SetRenderState(rw::ZTESTENABLE, 0);
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
vertices, numChars*4, indices, numChars*6);
rw::SetRenderState(rw::CULLMODE, cull);
rw::SetRenderState(rw::ZTESTENABLE, ztest);
}
numChars = 0;
lastRaster = nil;
}
void
Charset::printChar(int32 c, int32 x, int32 y)
{
Camera *cam;
float recipZ;
float u, v, du, dv;
RWDEVICE::Im2DVertex *vert;
uint16 *ix;
if(c >= this->desc.count)
return;
if(this->raster != lastRaster || numChars >= NUMCHARS)
flushBuffer();
lastRaster = this->raster;
cam = (Camera*)engine->currentCamera;
vert = &vertices[numChars*4];
ix = &indices[numChars*6];
recipZ = 1.0f/cam->nearPlane;
u = ((c % this->desc.tileWidth)*this->desc.width_internal + HALFPX) / (float32)this->raster->width;
v = ((c / this->desc.tileWidth)*this->desc.height_internal + HALFPX) / (float32)this->raster->height;
du = this->desc.width_internal/(float32)this->raster->width;
dv = this->desc.height_internal/(float32)this->raster->height;
vert->setScreenX((float)x);
vert->setScreenY((float)y);
vert->setScreenZ(rw::im2d::GetNearZ());
vert->setCameraZ(cam->nearPlane);
vert->setRecipCameraZ(recipZ);
vert->setColor(255, 255, 255, 255);
vert->setU(u, recipZ);
vert->setV(v, recipZ);
vert++;
vert->setScreenX(float(x+this->desc.width_internal));
vert->setScreenY((float)y);
vert->setScreenZ(rw::im2d::GetNearZ());
vert->setCameraZ(cam->nearPlane);
vert->setRecipCameraZ(recipZ);
vert->setColor(255, 255, 255, 255);
vert->setU(u+du, recipZ);
vert->setV(v, recipZ);
vert++;
vert->setScreenX((float)x);
vert->setScreenY(float(y+this->desc.height_internal));
vert->setScreenZ(rw::im2d::GetNearZ());
vert->setCameraZ(cam->nearPlane);
vert->setRecipCameraZ(recipZ);
vert->setColor(255, 255, 255, 255);
vert->setU(u, recipZ);
vert->setV(v+dv, recipZ);
vert++;
vert->setScreenX(float(x+this->desc.width_internal));
vert->setScreenY(float(y+this->desc.height_internal));
vert->setScreenZ(rw::im2d::GetNearZ());
vert->setCameraZ(cam->nearPlane);
vert->setRecipCameraZ(recipZ);
vert->setColor(255, 255, 255, 255);
vert->setU(u+du, recipZ);
vert->setV(v+dv, recipZ);
vert++;
*ix++ = numChars*4;
*ix++ = numChars*4+1;
*ix++ = numChars*4+2;
*ix++ = numChars*4+2;
*ix++ = numChars*4+1;
*ix++ = numChars*4+3;
numChars++;
}
void
Charset::print(const char *str, int32 x, int32 y, bool32 hideSpaces)
{
this->printBuffered(str, x, y, hideSpaces);
flushBuffer();
}
void
Charset::printBuffered(const char *str, int32 x, int32 y, bool32 hideSpaces)
{
while(*str){
if(!hideSpaces || *str != ' ')
printChar((uint8)*str, x, y);
x += this->desc.width;
str++;
}
}
}
#endif

669
vendor/librw/src/clump.cpp vendored Normal file
View file

@ -0,0 +1,669 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#define PLUGIN_ID 2
namespace rw {
int32 Clump::numAllocated;
int32 Atomic::numAllocated;
PluginList Clump::s_plglist(sizeof(Clump));
PluginList Atomic::s_plglist(sizeof(Atomic));
//
// Clump
//
Clump*
Clump::create(void)
{
Clump *clump = (Clump*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_CLUMP);
if(clump == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
numAllocated++;
clump->object.init(Clump::ID, 0);
clump->atomics.init();
clump->lights.init();
clump->cameras.init();
// World extension
clump->world = nil;
clump->inWorld.init();
s_plglist.construct(clump);
return clump;
}
Clump*
Clump::clone(void)
{
Clump *clump = Clump::create();
Frame *root = this->getFrame()->cloneAndLink();
clump->setFrame(root);
FORLIST(lnk, this->atomics){
Atomic *a = Atomic::fromClump(lnk);
Atomic *atomic = a->clone();
atomic->setFrame(a->getFrame()->root);
clump->addAtomic(atomic);
}
this->getFrame()->purgeClone();
// World extension
if(this->world)
this->world->addClump(clump);
s_plglist.copy(clump, this);
return clump;
}
void
Clump::destroy(void)
{
Frame *f;
s_plglist.destruct(this);
FORLIST(lnk, this->atomics){
Atomic *a = Atomic::fromClump(lnk);
this->removeAtomic(a);
a->destroy();
}
FORLIST(lnk, this->lights){
Light *l = Light::fromClump(lnk);
this->removeLight(l);
l->destroy();
}
FORLIST(lnk, this->cameras){
Camera *c = Camera::fromClump(lnk);
this->removeCamera(c);
c->destroy();
}
if(f = this->getFrame(), f)
f->destroyHierarchy();
assert(this->world == nil);
rwFree(this);
numAllocated--;
}
void
Clump::addAtomic(Atomic *a)
{
assert(a->clump == nil);
a->clump = this;
this->atomics.append(&a->inClump);
}
void
Clump::removeAtomic(Atomic *a)
{
assert(a->clump == this);
a->inClump.remove();
a->clump = nil;
}
void
Clump::addLight(Light *l)
{
assert(l->clump == nil);
l->clump = this;
this->lights.append(&l->inClump);
}
void
Clump::removeLight(Light *l)
{
assert(l->clump == this);
l->inClump.remove();
l->clump = nil;
}
void
Clump::addCamera(Camera *c)
{
assert(c->clump == nil);
c->clump = this;
this->cameras.append(&c->inClump);
}
void
Clump::removeCamera(Camera *c)
{
assert(c->clump == this);
c->inClump.remove();
c->clump = nil;
}
Clump*
Clump::streamRead(Stream *stream)
{
uint32 length, version;
int32 buf[3];
Clump *clump;
int32 numGeometries;
Geometry **geometryList;
if(!findChunk(stream, ID_STRUCT, &length, &version)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
stream->read32(buf, length);
int32 numAtomics = buf[0];
int32 numLights = 0;
int32 numCameras = 0;
if(version > 0x33000){
numLights = buf[1];
numCameras = buf[2];
}
clump = Clump::create();
if(clump == nil)
return nil;
// Frame list
FrameList_ frmlst;
frmlst.frames = nil;
if(!findChunk(stream, ID_FRAMELIST, nil, nil)){
RWERROR((ERR_CHUNK, "FRAMELIST"));
goto fail;
}
if(frmlst.streamRead(stream) == nil)
goto fail;
clump->setFrame(frmlst.frames[0]);
// Geometry list
numGeometries = 0;
geometryList = nil;
if(version >= 0x30400){
if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRYLIST"));
goto fail;
}
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
goto fail;
}
numGeometries = stream->readI32();
if(numGeometries){
size_t sz = numGeometries*sizeof(Geometry*);
geometryList = (Geometry**)rwMalloc(sz, MEMDUR_FUNCTION | ID_CLUMP);
if(geometryList == nil){
RWERROR((ERR_ALLOC, sz));
goto fail;
}
memset(geometryList, 0, sz);
}
for(int32 i = 0; i < numGeometries; i++){
if(!findChunk(stream, ID_GEOMETRY, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRY"));
goto failgeo;
}
geometryList[i] = Geometry::streamRead(stream);
if(geometryList[i] == nil)
goto failgeo;
}
}
// Atomics
Atomic *a;
for(int32 i = 0; i < numAtomics; i++){
if(!findChunk(stream, ID_ATOMIC, nil, nil)){
RWERROR((ERR_CHUNK, "ATOMIC"));
goto failgeo;
}
a = Atomic::streamReadClump(stream, &frmlst, geometryList);
if(a == nil)
goto failgeo;
clump->addAtomic(a);
}
// Lights
int32 frm;
Light *l;
for(int32 i = 0; i < numLights; i++){
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
goto failgeo;
}
frm = stream->readI32();
if(!findChunk(stream, ID_LIGHT, nil, nil)){
RWERROR((ERR_CHUNK, "LIGHT"));
goto failgeo;
}
l = Light::streamRead(stream);
if(l == nil)
goto failgeo;
l->setFrame(frmlst.frames[frm]);
clump->addLight(l);
}
// Cameras
Camera *cam;
for(int32 i = 0; i < numCameras; i++){
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
goto failgeo;
}
frm = stream->readI32();
if(!findChunk(stream, ID_CAMERA, nil, nil)){
RWERROR((ERR_CHUNK, "CAMERA"));
goto failgeo;
}
cam = Camera::streamRead(stream);
if(cam == nil)
goto failgeo;
cam->setFrame(frmlst.frames[frm]);
clump->addCamera(cam);
}
for(int32 i = 0; i < numGeometries; i++)
if(geometryList[i])
geometryList[i]->destroy();
rwFree(geometryList);
rwFree(frmlst.frames);
if(s_plglist.streamRead(stream, clump))
return clump;
failgeo:
for(int32 i = 0; i < numGeometries; i++)
if(geometryList[i])
geometryList[i]->destroy();
rwFree(geometryList);
fail:
rwFree(frmlst.frames);
clump->destroy();
return nil;
}
bool
Clump::streamWrite(Stream *stream)
{
int size = this->streamGetSize();
writeChunkHeader(stream, ID_CLUMP, size);
int32 numAtomics = this->countAtomics();
int32 numLights = this->countLights();
int32 numCameras = this->countCameras();
int32 buf[3] = { numAtomics, numLights, numCameras };
size = version > 0x33000 ? 12 : 4;
writeChunkHeader(stream, ID_STRUCT, size);
stream->write32(buf, size);
FrameList_ frmlst;
frmlst.numFrames = this->getFrame()->count();
frmlst.frames = (Frame**)rwMalloc(frmlst.numFrames*sizeof(Frame*), MEMDUR_FUNCTION | ID_CLUMP);
makeFrameList(this->getFrame(), frmlst.frames);
frmlst.streamWrite(stream);
if(rw::version >= 0x30400){
size = 12+4;
FORLIST(lnk, this->atomics)
size += 12 + Atomic::fromClump(lnk)->geometry->streamGetSize();
writeChunkHeader(stream, ID_GEOMETRYLIST, size);
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeI32(numAtomics); // same as numGeometries
FORLIST(lnk, this->atomics)
Atomic::fromClump(lnk)->geometry->streamWrite(stream);
}
FORLIST(lnk, this->atomics)
Atomic::fromClump(lnk)->streamWriteClump(stream, &frmlst);
FORLIST(lnk, this->lights){
Light *l = Light::fromClump(lnk);
int frm = findPointer(l->getFrame(), (void**)frmlst.frames, frmlst.numFrames);
if(frm < 0)
return false;
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeI32(frm);
l->streamWrite(stream);
}
FORLIST(lnk, this->cameras){
Camera *c = Camera::fromClump(lnk);
int frm = findPointer(c->getFrame(), (void**)frmlst.frames, frmlst.numFrames);
if(frm < 0)
return false;
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeI32(frm);
c->streamWrite(stream);
}
rwFree(frmlst.frames);
s_plglist.streamWrite(stream, this);
return true;
}
uint32
Clump::streamGetSize(void)
{
uint32 size = 0;
size += 12; // Struct
size += 4; // numAtomics
if(version > 0x33000)
size += 8; // numLights, numCameras
// Frame list
size += FrameList_::streamGetSize(this->getFrame());
if(rw::version >= 0x30400){
// Geometry list
size += 12 + 12 + 4;
FORLIST(lnk, this->atomics)
size += 12 + Atomic::fromClump(lnk)->geometry->streamGetSize();
}
// Atomics
FORLIST(lnk, this->atomics)
size += 12 + Atomic::fromClump(lnk)->streamGetSize();
// Lights
FORLIST(lnk, this->lights)
size += 16 + 12 + Light::fromClump(lnk)->streamGetSize();
// Cameras
FORLIST(lnk, this->cameras)
size += 16 + 12 + Camera::fromClump(lnk)->streamGetSize();
size += 12 + s_plglist.streamGetSize(this);
return size;
}
void
Clump::render(void)
{
Atomic *a;
FORLIST(lnk, this->atomics){
a = Atomic::fromClump(lnk);
if(a->object.object.flags & Atomic::RENDER)
a->render();
}
}
//
// Atomic
//
static void
atomicSync(ObjectWithFrame *obj)
{
// TODO: interpolate
obj->object.privateFlags |= Atomic::WORLDBOUNDDIRTY;
}
static void
worldAtomicSync(ObjectWithFrame *obj)
{
Atomic *atomic = (Atomic*)obj;
atomic->originalSync(obj);
}
Atomic*
Atomic::create(void)
{
Atomic *atomic = (Atomic*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_ATOMIC);
if(atomic == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
numAllocated++;
atomic->object.object.init(Atomic::ID, 0);
atomic->object.syncCB = atomicSync;
atomic->geometry = nil;
atomic->boundingSphere.center.set(0.0f, 0.0f, 0.0f);
atomic->boundingSphere.radius = 0.0f;
atomic->worldBoundingSphere.center.set(0.0f, 0.0f, 0.0f);
atomic->worldBoundingSphere.radius = 0.0f;
atomic->setFrame(nil);
atomic->object.object.privateFlags |= WORLDBOUNDDIRTY;
atomic->clump = nil;
atomic->inClump.init();
atomic->pipeline = nil;
atomic->renderCB = Atomic::defaultRenderCB;
atomic->object.object.flags = Atomic::COLLISIONTEST | Atomic::RENDER;
// TODO: interpolator
// World extension
atomic->world = nil;
atomic->originalSync = atomic->object.syncCB;
atomic->object.syncCB = worldAtomicSync;
s_plglist.construct(atomic);
return atomic;
}
Atomic*
Atomic::clone()
{
Atomic *atomic = Atomic::create();
if(atomic == nil)
return nil;
atomic->object.object.copy(&this->object.object);
atomic->object.object.privateFlags |= WORLDBOUNDDIRTY;
if(this->geometry)
atomic->setGeometry(this->geometry, 0);
atomic->renderCB = this->renderCB;
atomic->pipeline = this->pipeline;
// World extension doesn't add to world
s_plglist.copy(atomic, this);
return atomic;
}
void
Atomic::destroy(void)
{
s_plglist.destruct(this);
if(this->geometry)
this->geometry->destroy();
assert(this->clump == nil);
assert(this->world == nil);
this->setFrame(nil);
rwFree(this);
numAllocated--;
}
void
Atomic::setGeometry(Geometry *geo, uint32 flags)
{
if(this->geometry)
this->geometry->destroy();
if(geo)
geo->addRef();
this->geometry = geo;
if(flags & SAMEBOUNDINGSPHERE)
return;
if(geo){
this->boundingSphere = geo->morphTargets[0].boundingSphere;
if(this->getFrame()) // TODO: && getWorld???
this->getFrame()->updateObjects();
}
}
Sphere*
Atomic::getWorldBoundingSphere(void)
{
Sphere *s = &this->worldBoundingSphere;
// TODO: if we ever support morphing, check interpolation
if(!this->getFrame()->dirty() &&
(this->object.object.privateFlags & WORLDBOUNDDIRTY) == 0)
return s;
Matrix *ltm = this->getFrame()->getLTM();
// TODO: support scaling
V3d::transformPoints(&s->center, &this->boundingSphere.center, 1, ltm);
s->radius = this->boundingSphere.radius;
this->object.object.privateFlags &= ~WORLDBOUNDDIRTY;
return s;
}
static uint32 atomicRights[2];
Atomic*
Atomic::streamReadClump(Stream *stream,
FrameList_ *frameList, Geometry **geometryList)
{
int32 buf[4];
uint32 version;
if(!findChunk(stream, ID_STRUCT, nil, &version)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
stream->read32(buf, version < 0x30400 ? 12 : 16);
Atomic *atomic = Atomic::create();
if(atomic == nil)
return nil;
atomic->setFrame(frameList->frames[buf[0]]);
Geometry *g;
if(version < 0x30400){
if(!findChunk(stream, ID_GEOMETRY, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
goto fail;
}
g = Geometry::streamRead(stream);
if(g == nil)
goto fail;
atomic->setGeometry(g, 0);
g->destroy();
}else
atomic->setGeometry(geometryList[buf[1]], 0);
atomic->object.object.flags = buf[2];
atomicRights[0] = 0;
if(!s_plglist.streamRead(stream, atomic))
goto fail;
if(atomicRights[0])
s_plglist.assertRights(atomic, atomicRights[0], atomicRights[1]);
return atomic;
fail:
atomic->destroy();
return nil;
}
bool
Atomic::streamWriteClump(Stream *stream, FrameList_ *frmlst)
{
int32 buf[4] = { 0, 0, 0, 0 };
Clump *c = this->clump;
if(c == nil)
return false;
writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, rw::version < 0x30400 ? 12 : 16);
buf[0] = findPointer(this->getFrame(), (void**)frmlst->frames, frmlst->numFrames);
if(version < 0x30400){
buf[1] = this->object.object.flags;
stream->write32(buf, sizeof(int32[3]));
this->geometry->streamWrite(stream);
}else{
buf[1] = 0;
FORLIST(lnk, c->atomics){
if(Atomic::fromClump(lnk)->geometry == this->geometry)
goto foundgeo;
buf[1]++;
}
return false;
foundgeo:
buf[2] = this->object.object.flags;
stream->write32(buf, sizeof(buf));
}
s_plglist.streamWrite(stream, this);
return true;
}
uint32
Atomic::streamGetSize(void)
{
uint32 size = 12 + 12 + 12 + s_plglist.streamGetSize(this);
if(rw::version < 0x30400)
size += 12 + this->geometry->streamGetSize();
else
size += 4;
return size;
}
ObjPipeline*
Atomic::getPipeline(void)
{
return this->pipeline ?
this->pipeline :
engine->driver[platform]->defaultPipeline;
}
void
Atomic::instance(void)
{
if(this->geometry->flags & Geometry::NATIVE)
return;
this->getPipeline()->instance(this);
this->geometry->flags |= Geometry::NATIVE;
}
void
Atomic::uninstance(void)
{
if(!(this->geometry->flags & Geometry::NATIVE))
return;
this->getPipeline()->uninstance(this);
// this should be done by the CB already, just make sure
this->geometry->flags &= ~Geometry::NATIVE;
}
void
Atomic::defaultRenderCB(Atomic *atomic)
{
atomic->getPipeline()->render(atomic);
}
// Atomic Rights plugin
static Stream*
readAtomicRights(Stream *stream, int32, void *, int32, int32)
{
stream->read32(atomicRights, 8);
return stream;
}
static Stream*
writeAtomicRights(Stream *stream, int32, void *object, int32, int32)
{
Atomic *atomic = (Atomic*)object;
uint32 buffer[2];
buffer[0] = atomic->pipeline->pluginID;
buffer[1] = atomic->pipeline->pluginData;
stream->write32(buffer, 8);
return stream;
}
static int32
getSizeAtomicRights(void *object, int32, int32)
{
Atomic *atomic = (Atomic*)object;
if(atomic->pipeline == nil || atomic->pipeline->pluginID == 0)
return 0;
return 8;
}
void
registerAtomicRightsPlugin(void)
{
Atomic::registerPlugin(0, ID_RIGHTTORENDER, nil, nil, nil);
Atomic::registerPluginStream(ID_RIGHTTORENDER,
readAtomicRights,
writeAtomicRights,
getSizeAtomicRights);
}
}

1087
vendor/librw/src/d3d/d3d.cpp vendored Normal file

File diff suppressed because it is too large Load diff

678
vendor/librw/src/d3d/d3d8.cpp vendored Normal file
View file

@ -0,0 +1,678 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "rwd3d.h"
#include "rwd3d8.h"
#include "rwd3dimpl.h"
#define PLUGIN_ID 2
namespace rw {
namespace d3d8 {
using namespace d3d;
static void*
driverOpen(void *o, int32, int32)
{
engine->driver[PLATFORM_D3D8]->defaultPipeline = makeDefaultPipeline();
engine->driver[PLATFORM_D3D8]->rasterNativeOffset = nativeRasterOffset;
engine->driver[PLATFORM_D3D8]->rasterCreate = rasterCreate;
engine->driver[PLATFORM_D3D8]->rasterLock = rasterLock;
engine->driver[PLATFORM_D3D8]->rasterUnlock = rasterUnlock;
engine->driver[PLATFORM_D3D8]->rasterNumLevels = rasterNumLevels;
engine->driver[PLATFORM_D3D8]->imageFindRasterFormat = imageFindRasterFormat;
engine->driver[PLATFORM_D3D8]->rasterFromImage = rasterFromImage;
engine->driver[PLATFORM_D3D8]->rasterToImage = rasterToImage;
return o;
}
static void*
driverClose(void *o, int32, int32)
{
return o;
}
void
registerPlatformPlugins(void)
{
Driver::registerPlugin(PLATFORM_D3D8, 0, PLATFORM_D3D8,
driverOpen, driverClose);
// shared between D3D8 and 9
if(nativeRasterOffset == 0)
registerNativeRaster();
}
uint32
makeFVFDeclaration(uint32 flags, int32 numTex)
{
uint32 fvf = 0x2;
if(flags & Geometry::NORMALS)
fvf |= 0x10;
if(flags & Geometry::PRELIT)
fvf |= 0x40;
fvf |= numTex << 8;
return fvf;
}
int32
getStride(uint32 flags, int32 numTex)
{
int32 stride = 12;
if(flags & Geometry::NORMALS)
stride += 12;;
if(flags & Geometry::PRELIT)
stride += 4;
stride += numTex*8;
return stride;
}
void*
destroyNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D8)
return object;
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = nil;
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
destroyIndexBuffer(inst->indexBuffer);
destroyVertexBuffer(inst->vertexBuffer);
inst++;
}
rwFree(header->inst);
rwFree(header);
return object;
}
Stream*
readNativeData(Stream *stream, int32, void *object, int32, int32)
{
ASSERTLITTLE;
Geometry *geometry = (Geometry*)object;
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_D3D8){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geometry->instData = header;
header->platform = PLATFORM_D3D8;
int32 size = stream->readI32();
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
stream->read8(data, size);
uint8 *p = data;
header->serialNumber = *(uint16*)p; p += 2;
header->numMeshes = *(uint16*)p; p += 2;
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
inst->minVert = *(uint32*)p; p += 4;
inst->stride = *(uint32*)p; p += 4;
inst->numVertices = *(uint32*)p; p += 4;
inst->numIndices = *(uint32*)p; p += 4;
uint32 matid = *(uint32*)p; p += 4;
inst->material = geometry->matList.materials[matid];
inst->vertexShader = *(uint32*)p; p += 4;
inst->primType = *(uint32*)p; p += 4;
inst->indexBuffer = nil; p += 4;
inst->vertexBuffer = nil; p += 4;
inst->baseIndex = 0; p += 4;
inst->vertexAlpha = *p++;
inst->managed = 0; p++;
inst->remapped = 0; p++; // TODO: really unused? and what's that anyway?
inst++;
}
rwFree(data);
inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
assert(inst->indexBuffer == nil);
inst->indexBuffer = createIndexBuffer(inst->numIndices*2, false);
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
stream->read8(indices, 2*inst->numIndices);
unlockIndices(inst->indexBuffer);
inst->managed = 1;
assert(inst->vertexBuffer == nil);
inst->vertexBuffer = createVertexBuffer(inst->stride*inst->numVertices, 0, false);
uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
stream->read8(verts, inst->stride*inst->numVertices);
unlockVertices(inst->vertexBuffer);
inst++;
}
return stream;
}
Stream*
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
{
ASSERTLITTLE;
Geometry *geometry = (Geometry*)object;
writeChunkHeader(stream, ID_STRUCT, len-12);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D8)
return stream;
stream->writeU32(PLATFORM_D3D8);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
int32 size = 4 + geometry->meshHeader->numMeshes*0x2C;
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
stream->writeI32(size);
uint8 *p = data;
*(uint16*)p = header->serialNumber; p += 2;
*(uint16*)p = header->numMeshes; p += 2;
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
*(uint32*)p = inst->minVert; p += 4;
*(uint32*)p = inst->stride; p += 4;
*(uint32*)p = inst->numVertices; p += 4;
*(uint32*)p = inst->numIndices; p += 4;
int32 matid = geometry->matList.findIndex(inst->material);
*(int32*)p = matid; p += 4;
*(uint32*)p = inst->vertexShader; p += 4;
*(uint32*)p = inst->primType; p += 4;
*(uint32*)p = 0; p += 4; // index buffer
*(uint32*)p = 0; p += 4; // vertex buffer
*(uint32*)p = inst->baseIndex; p += 4;
*p++ = inst->vertexAlpha;
*p++ = inst->managed;
*p++ = inst->remapped;
inst++;
}
stream->write8(data, size);
rwFree(data);
inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
stream->write8(indices, 2*inst->numIndices);
unlockIndices(inst->indexBuffer);
uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
stream->write8(verts, inst->stride*inst->numVertices);
unlockVertices(inst->vertexBuffer);
inst++;
}
return stream;
}
int32
getSizeNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D8)
return 0;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
InstanceData *inst = header->inst;
int32 size = 12 + 4 + 4 + 4 + header->numMeshes*0x2C;
for(int32 i = 0; i < header->numMeshes; i++){
size += inst->numIndices*2 + inst->numVertices*inst->stride;
inst++;
}
return size;
}
void
registerNativeDataPlugin(void)
{
Geometry::registerPlugin(0, ID_NATIVEDATA,
nil, destroyNativeData, nil);
Geometry::registerPluginStream(ID_NATIVEDATA,
readNativeData,
writeNativeData,
getSizeNativeData);
}
static void
instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry;
// TODO: allow for REINSTANCE
if(geo->instData)
return;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
MeshHeader *meshh = geo->meshHeader;
geo->instData = header;
header->platform = PLATFORM_D3D8;
header->serialNumber = meshh->serialNum;
header->numMeshes = meshh->numMeshes;
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
InstanceData *inst = header->inst;
Mesh *mesh = meshh->getMeshes();
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
&inst->minVert, &inst->numVertices);
inst->numIndices = mesh->numIndices;
inst->material = mesh->material;
inst->vertexShader = 0;
inst->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
inst->vertexBuffer = nil;
inst->baseIndex = 0; // (maybe) not used by us
inst->vertexAlpha = 0;
inst->managed = 0;
inst->remapped = 0;
inst->indexBuffer = createIndexBuffer(inst->numIndices*2, false);
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
if(inst->minVert == 0)
memcpy(indices, mesh->indices, inst->numIndices*2);
else
for(int32 j = 0; j < inst->numIndices; j++)
indices[j] = mesh->indices[j] - inst->minVert;
unlockIndices(inst->indexBuffer);
pipe->instanceCB(geo, inst);
mesh++;
inst++;
}
}
static void
uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry;
if((geo->flags & Geometry::NATIVE) == 0)
return;
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D8);
geo->numTriangles = geo->meshHeader->guessNumTriangles();
geo->allocateData();
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
InstanceData *inst = header->inst;
Mesh *mesh = geo->meshHeader->getMeshes();
for(uint32 i = 0; i < header->numMeshes; i++){
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
if(inst->minVert == 0)
memcpy(mesh->indices, indices, inst->numIndices*2);
else
for(int32 j = 0; j < inst->numIndices; j++)
mesh->indices[j] = indices[j] + inst->minVert;
unlockIndices(inst->indexBuffer);
pipe->uninstanceCB(geo, inst);
mesh++;
inst++;
}
geo->generateTriangles();
geo->flags &= ~Geometry::NATIVE;
destroyNativeData(geo, 0, 0);
}
static void
render(rw::ObjPipeline *rwpipe, Atomic *atomic)
{
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry;
// TODO: allow for REINSTANCE
if(geo->instData == nil)
pipe->instance(atomic);
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D8);
if(pipe->renderCB)
pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
}
void
ObjPipeline::init(void)
{
this->rw::ObjPipeline::init(PLATFORM_D3D8);
this->impl.instance = d3d8::instance;
this->impl.uninstance = d3d8::uninstance;
this->impl.render = d3d8::render;
this->instanceCB = nil;
this->uninstanceCB = nil;
this->renderCB = nil;
}
ObjPipeline*
ObjPipeline::create(void)
{
ObjPipeline *pipe = rwNewT(ObjPipeline, 1, MEMDUR_GLOBAL);
pipe->init();
return pipe;
}
void
defaultInstanceCB(Geometry *geo, InstanceData *inst)
{
inst->vertexShader = makeFVFDeclaration(geo->flags, geo->numTexCoordSets);
inst->stride = getStride(geo->flags, geo->numTexCoordSets);
assert(inst->vertexBuffer == nil);
inst->vertexBuffer = createVertexBuffer(inst->numVertices*inst->stride,
inst->vertexShader, false);
inst->managed = 1;
uint8 *dst = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
instV3d(VERT_FLOAT3, dst,
&geo->morphTargets[0].vertices[inst->minVert],
inst->numVertices, inst->stride);
dst += 12;
if(geo->flags & Geometry::NORMALS){
instV3d(VERT_FLOAT3, dst,
&geo->morphTargets[0].normals[inst->minVert],
inst->numVertices, inst->stride);
dst += 12;
}
inst->vertexAlpha = 0;
if(geo->flags & Geometry::PRELIT){
inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[inst->minVert],
inst->numVertices, inst->stride);
dst += 4;
}
for(int32 i = 0; i < geo->numTexCoordSets; i++){
instTexCoords(VERT_FLOAT2, dst, &geo->texCoords[i][inst->minVert],
inst->numVertices, inst->stride);
dst += 8;
}
unlockVertices(inst->vertexBuffer);
}
void
defaultUninstanceCB(Geometry *geo, InstanceData *inst)
{
uint8 *src = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
uninstV3d(VERT_FLOAT3,
&geo->morphTargets[0].vertices[inst->minVert],
src, inst->numVertices, inst->stride);
src += 12;
if(geo->flags & Geometry::NORMALS){
uninstV3d(VERT_FLOAT3,
&geo->morphTargets[0].normals[inst->minVert],
src, inst->numVertices, inst->stride);
src += 12;
}
inst->vertexAlpha = 0;
if(geo->flags & Geometry::PRELIT){
uninstColor(VERT_ARGB, &geo->colors[inst->minVert], src,
inst->numVertices, inst->stride);
src += 4;
}
for(int32 i = 0; i < geo->numTexCoordSets; i++){
uninstTexCoords(VERT_FLOAT2, &geo->texCoords[i][inst->minVert], src,
inst->numVertices, inst->stride);
src += 8;
}
unlockVertices(inst->vertexBuffer);
}
ObjPipeline*
makeDefaultPipeline(void)
{
ObjPipeline *pipe = ObjPipeline::create();
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
return pipe;
}
// Native Texture and Raster
// only handles 4 and 8 bit textures right now
Raster*
readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format, int32 numLevels)
{
uint8 palette[256*4];
int32 pallen = 0;
uint8 *data = nil;
Image *img = Image::create(width, height, 32);
img->allocate();
if(format & Raster::PAL4){
pallen = 16;
stream->read8(palette, 4*32);
}else if(format & Raster::PAL8){
pallen = 256;
stream->read8(palette, 4*256);
}
if(!Raster::formatHasAlpha(format))
for(int32 i = 0; i < pallen; i++)
palette[i*4+3] = 0xFF;
Raster *ras = nil;
for(int i = 0; i < numLevels; i++){
uint32 size = stream->readU32();
// don't read levels that don't exist
if(ras && i >= ras->getNumLevels()){
stream->seek(size);
continue;
}
// one allocation is enough, first level is largest
if(data == nil)
data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_IMAGE);
stream->read8(data, size);
if(ras){
ras->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
img->width = ras->width;
img->height = ras->height;
img->stride = img->width*img->bpp;
}
if(format & (Raster::PAL4 | Raster::PAL8)){
uint8 *idx = data;
uint8 *pixels = img->pixels;
for(int y = 0; y < img->height; y++){
uint8 *line = pixels;
for(int x = 0; x < img->width; x++){
line[0] = palette[*idx*4+0];
line[1] = palette[*idx*4+1];
line[2] = palette[*idx*4+2];
if(img->bpp > 3)
line[3] = palette[*idx*4+3];
line += img->bpp;
idx++;
}
pixels += img->stride;
}
}
if(ras == nil){
// Important to have filled the image with data
int32 newformat;
Raster::imageFindRasterFormat(img, format&7, &width, &height, &depth, &newformat);
newformat |= format & (Raster::MIPMAP | Raster::AUTOMIPMAP);
ras = Raster::create(width, height, depth, newformat);
ras->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
}
ras->setFromImage(img);
ras->unlock(i);
}
rwFree(data);
img->destroy();
return ras;
}
Texture*
readNativeTexture(Stream *stream)
{
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_D3D8){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
Texture *tex = Texture::create(nil);
if(tex == nil)
return nil;
// Texture
tex->filterAddressing = stream->readU32();
stream->read8(tex->name, 32);
stream->read8(tex->mask, 32);
// Raster
uint32 format = stream->readU32();
bool32 hasAlpha = stream->readI32();
int32 width = stream->readU16();
int32 height = stream->readU16();
int32 depth = stream->readU8();
int32 numLevels = stream->readU8();
int32 type = stream->readU8();
int32 compression = stream->readU8();
int32 pallength = 0;
if(format & Raster::PAL4 || format & Raster::PAL8){
pallength = format & Raster::PAL4 ? 32 : 256;
if(!d3d::isP8supported){
tex->raster = readAsImage(stream, width, height, depth, format|type, numLevels);
return tex;
}
}
Raster *raster;
D3dRaster *ras;
if(compression){
raster = Raster::create(width, height, depth, format | type | Raster::DONTALLOCATE, PLATFORM_D3D8);
ras = GETD3DRASTEREXT(raster);
allocateDXT(raster, compression, numLevels, hasAlpha);
ras->customFormat = 1;
}else{
raster = Raster::create(width, height, depth, format | type, PLATFORM_D3D8);
ras = GETD3DRASTEREXT(raster);
}
tex->raster = raster;
// TODO: check if format supported and convert if necessary
if(pallength != 0)
stream->read8(ras->palette, 4*pallength);
uint32 size;
uint8 *data;
for(int32 i = 0; i < numLevels; i++){
size = stream->readU32();
if(i < raster->getNumLevels()){
data = raster->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
stream->read8(data, size);
raster->unlock(i);
}else
stream->seek(size);
}
return tex;
}
void
writeNativeTexture(Texture *tex, Stream *stream)
{
int32 chunksize = getSizeNativeTexture(tex);
writeChunkHeader(stream, ID_STRUCT, chunksize-12);
stream->writeU32(PLATFORM_D3D8);
// Texture
stream->writeU32(tex->filterAddressing);
stream->write8(tex->name, 32);
stream->write8(tex->mask, 32);
// Raster
Raster *raster = tex->raster;
D3dRaster *ras = GETD3DRASTEREXT(raster);
int32 numLevels = raster->getNumLevels();
stream->writeI32(raster->format);
stream->writeI32(ras->hasAlpha);
stream->writeU16(raster->width);
stream->writeU16(raster->height);
stream->writeU8(raster->depth);
stream->writeU8(numLevels);
stream->writeU8(raster->type);
int32 compression = 0;
if(ras->format)
switch(ras->format){
case 0x31545844: // DXT1
compression = 1;
break;
case 0x32545844: // DXT2
compression = 2;
break;
case 0x33545844: // DXT3
compression = 3;
break;
case 0x34545844: // DXT4
compression = 4;
break;
case 0x35545844: // DXT5
compression = 5;
break;
}
stream->writeU8(compression);
if(raster->format & Raster::PAL4)
stream->write8(ras->palette, 4*32);
else if(raster->format & Raster::PAL8)
stream->write8(ras->palette, 4*256);
uint32 size;
uint8 *data;
for(int32 i = 0; i < numLevels; i++){
size = getLevelSize(raster, i);
stream->writeU32(size);
data = raster->lock(i, Raster::LOCKREAD);
stream->write8(data, size);
raster->unlock(i);
}
}
uint32
getSizeNativeTexture(Texture *tex)
{
uint32 size = 12 + 72 + 16;
int32 levels = tex->raster->getNumLevels();
if(tex->raster->format & Raster::PAL4)
size += 4*32;
else if(tex->raster->format & Raster::PAL8)
size += 4*256;
for(int32 i = 0; i < levels; i++)
size += 4 + getLevelSize(tex->raster, i);
return size;
}
}
}

56
vendor/librw/src/d3d/d3d8matfx.cpp vendored Normal file
View file

@ -0,0 +1,56 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwanim.h"
#include "../rwengine.h"
#include "../rwplugins.h"
#include "rwd3d.h"
#include "rwd3d8.h"
namespace rw {
namespace d3d8 {
using namespace d3d;
static void*
matfxOpen(void *o, int32, int32)
{
matFXGlobals.pipelines[PLATFORM_D3D8] = makeMatFXPipeline();
return o;
}
static void*
matfxClose(void *o, int32, int32)
{
((ObjPipeline*)matFXGlobals.pipelines[PLATFORM_D3D8])->destroy();
matFXGlobals.pipelines[PLATFORM_D3D8] = nil;
return o;
}
void
initMatFX(void)
{
Driver::registerPlugin(PLATFORM_D3D8, 0, ID_MATFX,
matfxOpen, matfxClose);
}
ObjPipeline*
makeMatFXPipeline(void)
{
ObjPipeline *pipe = ObjPipeline::create();
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;
}
}
}

65
vendor/librw/src/d3d/d3d8render.cpp vendored Normal file
View file

@ -0,0 +1,65 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "rwd3d.h"
#include "rwd3d8.h"
namespace rw {
namespace d3d8 {
using namespace d3d;
#ifndef RW_D3D9
void defaultRenderCB(Atomic*, InstanceDataHeader*) {}
#else
// This is a bit abandoned, use d3d9 instead
void
defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
{
RawMatrix world;
d3d::lightingCB_Fix(atomic);
uint32 flags = atomic->geometry->flags;
d3d::setRenderState(D3DRS_LIGHTING, !!(flags & rw::Geometry::LIGHT));
Frame *f = atomic->getFrame();
convMatrix(&world, f->getLTM());
d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
d3d::setTexture(0, inst->material->texture);
d3d::setMaterial(flags, inst->material->color, inst->material->surfaceProps);
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
if(flags & Geometry::PRELIT)
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
else
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
d3ddevice->SetFVF(inst->vertexShader);
setStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
setIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3;
d3d::flushCache();
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
0, inst->numVertices, 0, numPrim);
inst++;
}
}
#endif
}
}

56
vendor/librw/src/d3d/d3d8skin.cpp vendored Normal file
View file

@ -0,0 +1,56 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwanim.h"
#include "../rwengine.h"
#include "../rwplugins.h"
#include "rwd3d.h"
#include "rwd3d8.h"
namespace rw {
namespace d3d8 {
using namespace d3d;
static void*
skinOpen(void *o, int32, int32)
{
skinGlobals.pipelines[PLATFORM_D3D8] = makeSkinPipeline();
return o;
}
static void*
skinClose(void *o, int32, int32)
{
((ObjPipeline*)skinGlobals.pipelines[PLATFORM_D3D8])->destroy();
skinGlobals.pipelines[PLATFORM_D3D8] = nil;
return o;
}
void
initSkin(void)
{
Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN,
skinOpen, skinClose);
}
ObjPipeline*
makeSkinPipeline(void)
{
ObjPipeline *pipe = ObjPipeline::create();
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
}
}
}

853
vendor/librw/src/d3d/d3d9.cpp vendored Normal file
View file

@ -0,0 +1,853 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "rwd3d.h"
#include "rwd3d9.h"
#include "rwd3dimpl.h"
#define PLUGIN_ID 2
namespace rw {
namespace d3d9 {
using namespace d3d;
// TODO: move to header, but not as #define
#ifndef RW_D3D9
static VertexElement _d3ddec_end = {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0};
#define D3DDECL_END() _d3ddec_end
#endif
#define NUMDECLELT 12
static void*
driverOpen(void *o, int32, int32)
{
#ifdef RW_D3D9
createDefaultShaders();
#endif
engine->driver[PLATFORM_D3D9]->defaultPipeline = makeDefaultPipeline();
engine->driver[PLATFORM_D3D9]->rasterNativeOffset = nativeRasterOffset;
engine->driver[PLATFORM_D3D9]->rasterCreate = rasterCreate;
engine->driver[PLATFORM_D3D9]->rasterLock = rasterLock;
engine->driver[PLATFORM_D3D9]->rasterUnlock = rasterUnlock;
engine->driver[PLATFORM_D3D9]->rasterNumLevels = rasterNumLevels;
engine->driver[PLATFORM_D3D9]->imageFindRasterFormat = imageFindRasterFormat;
engine->driver[PLATFORM_D3D9]->rasterFromImage = rasterFromImage;
engine->driver[PLATFORM_D3D9]->rasterToImage = rasterToImage;
return o;
}
static void*
driverClose(void *o, int32, int32)
{
#ifdef RW_D3D9
destroyDefaultShaders();
#endif
return o;
}
void
registerPlatformPlugins(void)
{
Driver::registerPlugin(PLATFORM_D3D9, 0, PLATFORM_D3D9,
driverOpen, driverClose);
// shared between D3D8 and 9
if(nativeRasterOffset == 0)
registerNativeRaster();
}
void*
createVertexDeclaration(VertexElement *elements)
{
#ifdef RW_D3D9
IDirect3DVertexDeclaration9 *decl = 0;
d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &decl);
if(decl)
d3d9Globals.numVertexDeclarations++;
return decl;
#else
int n = 0;
VertexElement *e = (VertexElement*)elements;
while(e[n++].stream != 0xFF)
;
e = rwNewT(VertexElement, n, MEMDUR_EVENT | ID_DRIVER);
memcpy(e, elements, n*sizeof(VertexElement));
return e;
#endif
}
void
destroyVertexDeclaration(void *declaration)
{
#ifdef RW_D3D9
if(declaration){
if(((IUnknown*)declaration)->Release() != 0)
printf("declaration wasn't destroyed\n");
d3d9Globals.numVertexDeclarations--;
}
#else
rwFree(declaration);
#endif
}
uint32
getDeclaration(void *declaration, VertexElement *elements)
{
#ifdef RW_D3D9
IDirect3DVertexDeclaration9 *decl = (IDirect3DVertexDeclaration9*)declaration;
UINT numElt;
decl->GetDeclaration((D3DVERTEXELEMENT9*)elements, &numElt);
return numElt;
#else
int n = 0;
VertexElement *e = (VertexElement*)declaration;
while(e[n++].stream != 0xFF)
;
if(elements)
memcpy(elements, declaration, n*sizeof(VertexElement));
return n;
#endif
}
void
freeInstanceData(Geometry *geometry)
{
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D9)
return;
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = nil;
destroyVertexDeclaration(header->vertexDeclaration);
destroyIndexBuffer(header->indexBuffer);
destroyVertexBuffer(header->vertexStream[0].vertexBuffer);
destroyVertexBuffer(header->vertexStream[1].vertexBuffer);
rwFree(header->inst);
rwFree(header);
return;
}
void*
destroyNativeData(void *object, int32, int32)
{
freeInstanceData((Geometry*)object);
return object;
}
Stream*
readNativeData(Stream *stream, int32, void *object, int32, int32)
{
ASSERTLITTLE;
Geometry *geometry = (Geometry*)object;
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_D3D9){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geometry->instData = header;
header->platform = PLATFORM_D3D9;
int32 size = stream->readI32();
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
stream->read8(data, size);
uint8 *p = data;
header->serialNumber = *(uint32*)p; p += 4;
header->numMeshes = *(uint32*)p; p += 4;
header->indexBuffer = nil; p += 4;
header->primType = *(uint32*)p; p += 4;
p += 16*2; // skip vertex streams, they're repeated with the vertex buffers
header->useOffsets = *(bool32*)p; p += 4;
header->vertexDeclaration = nil; p += 4;
header->totalNumIndex = *(uint32*)p; p += 4;
header->totalNumVertex = *(uint32*)p; p += 4;
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
inst->numIndex = *(uint32*)p; p += 4;
inst->minVert = *(uint32*)p; p += 4;
uint32 matid = *(uint32*)p; p += 4;
inst->material = geometry->matList.materials[matid];
inst->vertexAlpha = *(bool32*)p; p += 4;
inst->vertexShader = nil; p += 4;
inst->baseIndex = 0; p += 4;
inst->numVertices = *(uint32*)p; p += 4;
inst->startIndex = *(uint32*)p; p += 4;
inst->numPrimitives = *(uint32*)p; p += 4;
inst++;
}
VertexElement elements[NUMDECLELT];
uint32 numDeclarations = stream->readU32();
stream->read8(elements, numDeclarations*8);
header->vertexDeclaration = createVertexDeclaration(elements);
assert(header->indexBuffer == nil);
header->indexBuffer = createIndexBuffer(header->totalNumIndex*2, false);
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
stream->read8(indices, 2*header->totalNumIndex);
unlockIndices(header->indexBuffer);
VertexStream *s;
p = data;
for(int i = 0; i < 2; i++){
stream->read8(p, 16);
s = &header->vertexStream[i];
s->vertexBuffer = (void*)(uintptr)*(uint32*)p; p += 4;
s->offset = 0; p += 4;
s->stride = *(uint32*)p; p += 4;
s->geometryFlags = *(uint16*)p; p += 2;
s->managed = *p++;
s->dynamicLock = *p++;
if(s->vertexBuffer == nil)
continue;
// TODO: use dynamic VB when doing morphing
assert(s->vertexBuffer == nil);
s->vertexBuffer = createVertexBuffer(s->stride*header->totalNumVertex, 0, false);
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
stream->read8(verts, s->stride*header->totalNumVertex);
unlockVertices(s->vertexBuffer);
}
// TODO: somehow depends on number of streams used (baseIndex = minVert when more than one)
inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
inst->baseIndex = inst->minVert + header->vertexStream[0].offset / header->vertexStream[0].stride;
inst++;
}
rwFree(data);
return stream;
}
Stream*
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
{
ASSERTLITTLE;
Geometry *geometry = (Geometry*)object;
writeChunkHeader(stream, ID_STRUCT, len-12);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D9)
return stream;
stream->writeU32(PLATFORM_D3D9);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
int32 size = 64 + geometry->meshHeader->numMeshes*36;
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
stream->writeI32(size);
uint8 *p = data;
*(uint32*)p = header->serialNumber; p += 4;
*(uint32*)p = header->numMeshes; p += 4;
p += 4; // skip index buffer
*(uint32*)p = header->primType; p += 4;
p += 16*2; // skip vertex streams, they're repeated with the vertex buffers
*(bool32*)p = header->useOffsets; p += 4;
p += 4; // skip vertex declaration
*(uint32*)p = header->totalNumIndex; p += 4;
*(uint32*)p = header->totalNumVertex; p += 4;
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
*(uint32*)p = inst->numIndex; p += 4;
*(uint32*)p = inst->minVert; p += 4;
int32 matid = geometry->matList.findIndex(inst->material);
*(int32*)p = matid; p += 4;
*(bool32*)p = inst->vertexAlpha; p += 4;
*(uint32*)p = 0; p += 4; // vertex shader
*(uint32*)p = inst->baseIndex; p += 4; // not used but meh...
*(uint32*)p = inst->numVertices; p += 4;
*(uint32*)p = inst->startIndex; p += 4;
*(uint32*)p = inst->numPrimitives; p += 4;
inst++;
}
stream->write8(data, size);
VertexElement elements[NUMDECLELT];
uint32 numElt = getDeclaration(header->vertexDeclaration, elements);
stream->writeU32(numElt);
stream->write8(elements, 8*numElt);
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
stream->write8(indices, 2*header->totalNumIndex);
unlockIndices(header->indexBuffer);
VertexStream *s;
for(int i = 0; i < 2; i++){
s = &header->vertexStream[i];
p = data;
*(uint32*)p = s->vertexBuffer ? 0xbadeaffe : 0; p += 4;
*(uint32*)p = s->offset; p += 4;
*(uint32*)p = s->stride; p += 4;
*(uint16*)p = s->geometryFlags; p += 2;
*p++ = s->managed;
*p++ = s->dynamicLock;
stream->write8(data, 16);
if(s->vertexBuffer == nil)
continue;
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
stream->write8(verts, s->stride*header->totalNumVertex);
unlockVertices(s->vertexBuffer);
}
rwFree(data);
return stream;
}
int32
getSizeNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D9)
return 0;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
int32 size = 12 + 4 + 4 + 64 + header->numMeshes*36;
uint32 numElt = getDeclaration(header->vertexDeclaration, nil);
size += 4 + numElt*8;
size += 2*header->totalNumIndex;
size += 0x10 + header->vertexStream[0].stride*header->totalNumVertex;
size += 0x10 + header->vertexStream[1].stride*header->totalNumVertex;
return size;
}
void
registerNativeDataPlugin(void)
{
Geometry::registerPlugin(0, ID_NATIVEDATA,
nil, destroyNativeData, nil);
Geometry::registerPluginStream(ID_NATIVEDATA,
readNativeData,
writeNativeData,
getSizeNativeData);
}
static InstanceDataHeader*
instanceMesh(rw::ObjPipeline *rwpipe, Geometry *geo)
{
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
MeshHeader *meshh = geo->meshHeader;
header->platform = PLATFORM_D3D9;
header->serialNumber = meshh->serialNum;
header->numMeshes = meshh->numMeshes;
header->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
header->useOffsets = 0;
header->vertexDeclaration = nil;
header->totalNumVertex = geo->numVertices;
header->totalNumIndex = meshh->totalIndices;
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
header->indexBuffer = createIndexBuffer(header->totalNumIndex*2, false);
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
InstanceData *inst = header->inst;
Mesh *mesh = meshh->getMeshes();
uint32 startindex = 0;
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
&inst->minVert, (int32*)&inst->numVertices);
inst->numIndex = mesh->numIndices;
inst->material = mesh->material;
inst->vertexAlpha = 0;
inst->vertexShader = nil;
inst->baseIndex = inst->minVert;
inst->startIndex = startindex;
inst->numPrimitives = header->primType == D3DPT_TRIANGLESTRIP ? inst->numIndex-2 : inst->numIndex/3;
if(inst->minVert == 0)
memcpy(&indices[inst->startIndex], mesh->indices, inst->numIndex*2);
else
for(uint32 j = 0; j < inst->numIndex; j++)
indices[inst->startIndex+j] = mesh->indices[j] - inst->minVert;
startindex += inst->numIndex;
mesh++;
inst++;
}
unlockIndices(header->indexBuffer);
memset(&header->vertexStream, 0, 2*sizeof(VertexStream));
return header;
}
static void
instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry;
// don't try to (re)instance native data
if(geo->flags & Geometry::NATIVE)
return;
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
if(geo->instData){
// Already have instanced data, so check if we have to reinstance
assert(header->platform == PLATFORM_D3D9);
if(header->serialNumber != geo->meshHeader->serialNum){
// Mesh changed, so reinstance everything
freeInstanceData(geo);
}
}
// no instance or complete reinstance
if(geo->instData == nil){
geo->instData = instanceMesh(rwpipe, geo);
pipe->instanceCB(geo, (InstanceDataHeader*)geo->instData, 0);
}else if(geo->lockedSinceInst)
pipe->instanceCB(geo, (InstanceDataHeader*)geo->instData, 1);
geo->lockedSinceInst = 0;
}
static void
uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry;
if((geo->flags & Geometry::NATIVE) == 0)
return;
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D9);
geo->numTriangles = geo->meshHeader->guessNumTriangles();
geo->allocateData();
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
InstanceData *inst = header->inst;
Mesh *mesh = geo->meshHeader->getMeshes();
for(uint32 i = 0; i < header->numMeshes; i++){
if(inst->minVert == 0)
memcpy(mesh->indices, &indices[inst->startIndex], inst->numIndex*2);
else
for(uint32 j = 0; j < inst->numIndex; j++)
mesh->indices[j] = indices[inst->startIndex+j] + inst->minVert;
mesh++;
inst++;
}
unlockIndices(header->indexBuffer);
pipe->uninstanceCB(geo, header);
geo->generateTriangles();
geo->flags &= ~Geometry::NATIVE;
destroyNativeData(geo, 0, 0);
}
static void
render(rw::ObjPipeline *rwpipe, Atomic *atomic)
{
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry;
pipe->instance(atomic);
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D9);
if(pipe->renderCB)
pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
}
void
ObjPipeline::init(void)
{
this->rw::ObjPipeline::init(PLATFORM_D3D9);
this->impl.instance = d3d9::instance;
this->impl.uninstance = d3d9::uninstance;
this->impl.render = d3d9::render;
this->instanceCB = nil;
this->uninstanceCB = nil;
this->renderCB = nil;
}
ObjPipeline*
ObjPipeline::create(void)
{
ObjPipeline *pipe = rwNewT(ObjPipeline, 1, MEMDUR_GLOBAL);
pipe->init();
return pipe;
}
void
defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
{
int i = 0;
VertexElement dcl[NUMDECLELT];
VertexStream *s = &header->vertexStream[0];
bool isPrelit = (geo->flags & Geometry::PRELIT) != 0;
bool hasNormals = (geo->flags & Geometry::NORMALS) != 0;
// TODO: support both vertex buffers
if(!reinstance){
// Create declarations and buffers only the first time
assert(s->vertexBuffer == nil);
s->offset = 0;
s->managed = 1;
s->geometryFlags = 0;
s->dynamicLock = 0;
dcl[i].stream = 0;
dcl[i].offset = 0;
dcl[i].type = D3DDECLTYPE_FLOAT3;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_POSITION;
dcl[i].usageIndex = 0;
i++;
uint16 stride = 12;
s->geometryFlags |= 0x2;
if(isPrelit){
dcl[i].stream = 0;
dcl[i].offset = stride;
dcl[i].type = D3DDECLTYPE_D3DCOLOR;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_COLOR;
dcl[i].usageIndex = 0;
i++;
s->geometryFlags |= 0x8;
stride += 4;
}
for(int32 n = 0; n < geo->numTexCoordSets; n++){
dcl[i].stream = 0;
dcl[i].offset = stride;
dcl[i].type = D3DDECLTYPE_FLOAT2;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_TEXCOORD;
dcl[i].usageIndex = (uint8)n;
i++;
s->geometryFlags |= 0x10 << n;
stride += 8;
}
if(hasNormals){
dcl[i].stream = 0;
dcl[i].offset = stride;
dcl[i].type = D3DDECLTYPE_FLOAT3;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_NORMAL;
dcl[i].usageIndex = 0;
i++;
s->geometryFlags |= 0x4;
stride += 12;
}
// We expect some attributes to always be there, use the constant buffer as fallback
if(!isPrelit){
dcl[i].stream = 2;
dcl[i].offset = offsetof(VertexConstantData, color);
dcl[i].type = D3DDECLTYPE_D3DCOLOR;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_COLOR;
dcl[i].usageIndex = 0;
i++;
}
if(geo->numTexCoordSets == 0){
dcl[i].stream = 2;
dcl[i].offset = offsetof(VertexConstantData, texCoors[0]);
dcl[i].type = D3DDECLTYPE_FLOAT2;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_TEXCOORD;
dcl[i].usageIndex = 0;
i++;
}
dcl[i] = D3DDECL_END();
s->stride = stride;
assert(header->vertexDeclaration == nil);
header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl);
assert(s->vertexBuffer == nil);
s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, false);
}else
getDeclaration(header->vertexDeclaration, dcl);
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
// Instance vertices
if(!reinstance || geo->lockedSinceInst&Geometry::LOCKVERTICES){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++)
;
instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
geo->morphTargets[0].vertices,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
// Instance prelight colors
if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++)
;
InstanceData *inst = header->inst;
uint32 n = header->numMeshes;
while(n--){
uint32 stride = header->vertexStream[dcl[i].stream].stride;
inst->vertexAlpha = instColor(vertFormatMap[dcl[i].type],
verts + dcl[i].offset + stride*inst->minVert,
geo->colors + inst->minVert,
inst->numVertices,
stride);
inst++;
}
}
// Instance tex coords
for(int32 n = 0; n < geo->numTexCoordSets; n++){
if(!reinstance || geo->lockedSinceInst&(Geometry::LOCKTEXCOORDS<<n)){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++)
;
instTexCoords(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
geo->texCoords[n],
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
}
// Instance normals
if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++)
;
instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
geo->morphTargets[0].normals,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
unlockVertices(s->vertexBuffer);
}
void
defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header)
{
VertexElement dcl[NUMDECLELT];
uint8 *verts[2];
verts[0] = lockVertices(header->vertexStream[0].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
verts[1] = lockVertices(header->vertexStream[1].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
getDeclaration(header->vertexDeclaration, dcl);
int i;
for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++)
;
uninstV3d(vertFormatMap[dcl[i].type],
geo->morphTargets[0].vertices,
verts[dcl[i].stream] + dcl[i].offset,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
if(geo->flags & Geometry::PRELIT){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++)
;
uninstColor(vertFormatMap[dcl[i].type],
geo->colors,
verts[dcl[i].stream] + dcl[i].offset,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
for(int32 n = 0; n < geo->numTexCoordSets; n++){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++)
;
uninstTexCoords(vertFormatMap[dcl[i].type],
geo->texCoords[n],
verts[dcl[i].stream] + dcl[i].offset,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
if(geo->flags & Geometry::NORMALS){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++)
;
uninstV3d(vertFormatMap[dcl[i].type],
geo->morphTargets[0].normals,
verts[dcl[i].stream] + dcl[i].offset,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
unlockVertices(verts[0]);
unlockVertices(verts[1]);
}
ObjPipeline*
makeDefaultPipeline(void)
{
ObjPipeline *pipe = ObjPipeline::create();
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB_Shader;
return pipe;
}
// Native Texture and Raster
Texture*
readNativeTexture(Stream *stream)
{
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_D3D9){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
Texture *tex = Texture::create(nil);
if(tex == nil)
return nil;
// Texture
tex->filterAddressing = stream->readU32();
stream->read8(tex->name, 32);
stream->read8(tex->mask, 32);
// Raster
int32 format = stream->readI32();
int32 d3dformat = stream->readI32();
int32 width = stream->readU16();
int32 height = stream->readU16();
int32 depth = stream->readU8();
int32 numLevels = stream->readU8();
int32 type = stream->readU8();
/*
#define HAS_ALPHA (1<<0)
#define IS_CUBE (1<<1)
#define USE_AUTOMIPMAPGEN (1<<2)
#define IS_COMPRESSED (1<<3)
*/
int32 flags = stream->readU8();
Raster *raster;
D3dRaster *ext;
if(flags & 8){
// is compressed
assert((flags & 2) == 0 && "Can't have cube maps yet");
raster = Raster::create(width, height, depth, format | type | Raster::DONTALLOCATE, PLATFORM_D3D9);
assert(raster);
ext = GETD3DRASTEREXT(raster);
ext->format = d3dformat;
ext->hasAlpha = flags & 1;
ext->texture = createTexture(raster->width, raster->height,
raster->format & Raster::MIPMAP ? numLevels : 1,
0,
ext->format);
assert(ext->texture);
raster->flags &= ~Raster::DONTALLOCATE;
ext->customFormat = 1;
}else if(flags & 2){
assert(0 && "Can't have cube maps yet");
}else{
raster = Raster::create(width, height, depth, format | type, PLATFORM_D3D9);
assert(raster);
ext = GETD3DRASTEREXT(raster);
}
tex->raster = raster;
// TODO: check if format supported and convert if necessary
if(raster->format & Raster::PAL4)
stream->read8(ext->palette, 4*32);
else if(raster->format & Raster::PAL8)
stream->read8(ext->palette, 4*256);
uint32 size;
uint8 *data;
for(int32 i = 0; i < numLevels; i++){
size = stream->readU32();
if(i < raster->getNumLevels()){
data = raster->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
stream->read8(data, size);
raster->unlock(i);
}else
stream->seek(size);
}
return tex;
}
void
writeNativeTexture(Texture *tex, Stream *stream)
{
int32 chunksize = getSizeNativeTexture(tex);
writeChunkHeader(stream, ID_STRUCT, chunksize-12);
stream->writeU32(PLATFORM_D3D9);
// Texture
stream->writeU32(tex->filterAddressing);
stream->write8(tex->name, 32);
stream->write8(tex->mask, 32);
// Raster
Raster *raster = tex->raster;
D3dRaster *ext = GETD3DRASTEREXT(raster);
int32 numLevels = raster->getNumLevels();
stream->writeI32(raster->format);
stream->writeU32(ext->format);
stream->writeU16(raster->width);
stream->writeU16(raster->height);
stream->writeU8(raster->depth);
stream->writeU8(numLevels);
stream->writeU8(raster->type);
uint8 flags = 0;
if(ext->hasAlpha)
flags |= 1;
// no cube supported yet
if(ext->autogenMipmap)
flags |= 4;
if(ext->customFormat)
flags |= 8;
stream->writeU8(flags);
if(raster->format & Raster::PAL4)
stream->write8(ext->palette, 4*32);
else if(raster->format & Raster::PAL8)
stream->write8(ext->palette, 4*256);
uint32 size;
uint8 *data;
for(int32 i = 0; i < numLevels; i++){
size = getLevelSize(raster, i);
stream->writeU32(size);
data = raster->lock(i, Raster::LOCKREAD);
stream->write8(data, size);
raster->unlock(i);
}
}
uint32
getSizeNativeTexture(Texture *tex)
{
uint32 size = 12 + 72 + 16;
int32 levels = tex->raster->getNumLevels();
if(tex->raster->format & Raster::PAL4)
size += 4*32;
else if(tex->raster->format & Raster::PAL8)
size += 4*256;
for(int32 i = 0; i < levels; i++)
size += 4 + getLevelSize(tex->raster, i);
return size;
}
}
}

313
vendor/librw/src/d3d/d3d9matfx.cpp vendored Normal file
View file

@ -0,0 +1,313 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwanim.h"
#include "../rwengine.h"
#include "../rwrender.h"
#include "../rwplugins.h"
#include "rwd3d.h"
#include "rwd3d9.h"
namespace rw {
namespace d3d9 {
using namespace d3d;
#ifndef RW_D3D9
void matfxRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) {}
#else
static void *matfx_env_amb_VS;
static void *matfx_env_amb_dir_VS;
static void *matfx_env_all_VS;
static void *matfx_env_PS;
static void *matfx_env_tex_PS;
enum
{
VSLOC_texMat = VSLOC_afterLights,
VSLOC_colorClamp = VSLOC_texMat + 4,
VSLOC_envColor,
PSLOC_shininess = 1,
};
void
matfxRender_Default(InstanceDataHeader *header, InstanceData *inst, int32 lightBits)
{
Material *m = inst->material;
// Pick a shader
if((lightBits & VSLIGHT_MASK) == 0)
setVertexShader(default_amb_VS);
else if((lightBits & VSLIGHT_MASK) == VSLIGHT_DIRECT)
setVertexShader(default_amb_dir_VS);
else
setVertexShader(default_all_VS);
SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
if(inst->material->texture){
d3d::setTexture(0, m->texture);
setPixelShader(default_tex_PS);
}else
setPixelShader(default_PS);
drawInst(header, inst);
}
static Frame *lastEnvFrame;
static RawMatrix normal2texcoord = {
{ 0.5f, 0.0f, 0.0f }, 0.0f,
{ 0.0f, -0.5f, 0.0f }, 0.0f,
{ 0.0f, 0.0f, 1.0f }, 0.0f,
{ 0.5f, 0.5f, 0.0f }, 1.0f
};
void
uploadEnvMatrix(Frame *frame)
{
Matrix invMat;
if(frame == nil)
frame = engine->currentCamera->getFrame();
// cache the matrix across multiple meshes
// can't do it, frame matrix may change
// if(frame == lastEnvFrame)
// return;
// lastEnvFrame = frame;
RawMatrix envMtx, invMtx;
Matrix::invert(&invMat, frame->getLTM());
convMatrix(&invMtx, &invMat);
invMtx.pos.set(0.0f, 0.0f, 0.0f);
float uscale = fabs(normal2texcoord.right.x);
normal2texcoord.right.x = MatFX::envMapFlipU ? -uscale : uscale;
RawMatrix::mult(&envMtx, &invMtx, &normal2texcoord);
d3ddevice->SetVertexShaderConstantF(VSLOC_texMat, (float*)&envMtx, 4);
}
void
matfxRender_EnvMap(InstanceDataHeader *header, InstanceData *inst, int32 lightBits, MatFX::Env *env)
{
Material *m = inst->material;
if(env->tex == nil || env->coefficient == 0.0f){
matfxRender_Default(header, inst, lightBits);
return;
}
d3d::setTexture(1, env->tex);
uploadEnvMatrix(env->frame);
SetRenderState(SRCBLEND, BLENDONE);
static float zero[4];
static float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
struct {
float shininess;
float disableFBA;
float unused[2];
} fxparams;
fxparams.shininess = env->coefficient;
fxparams.disableFBA = env->fbAlpha ? 0.0f : 1.0f;
d3ddevice->SetPixelShaderConstantF(PSLOC_shininess, (float*)&fxparams, 1);
// This clamps the vertex color below. With it we can achieve both PC and PS2 style matfx
if(MatFX::envMapApplyLight)
d3ddevice->SetVertexShaderConstantF(VSLOC_colorClamp, zero, 1);
else
d3ddevice->SetVertexShaderConstantF(VSLOC_colorClamp, one, 1);
RGBAf envcol[4];
if(MatFX::envMapUseMatColor)
convColor(envcol, &m->color);
else
convColor(envcol, &MatFX::envMapColor);
d3ddevice->SetVertexShaderConstantF(VSLOC_envColor, (float*)&envcol, 1);
// Pick a shader
if((lightBits & VSLIGHT_MASK) == 0)
setVertexShader(matfx_env_amb_VS);
else if((lightBits & VSLIGHT_MASK) == VSLIGHT_DIRECT)
setVertexShader(matfx_env_amb_dir_VS);
else
setVertexShader(matfx_env_all_VS);
bool32 texAlpha = GETD3DRASTEREXT(env->tex->raster)->hasAlpha;
if(inst->material->texture){
d3d::setTexture(0, m->texture);
setPixelShader(matfx_env_tex_PS);
}else
setPixelShader(matfx_env_PS);
SetRenderState(VERTEXALPHA, texAlpha || inst->vertexAlpha || m->color.alpha != 255);
drawInst(header, inst);
SetRenderState(SRCBLEND, BLENDSRCALPHA);
}
void
matfxRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header)
{
int vsBits;
uint32 flags = atomic->geometry->flags;
setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer,
0, header->vertexStream[0].stride);
setIndices((IDirect3DIndexBuffer9*)header->indexBuffer);
setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration);
lastEnvFrame = nil;
vsBits = lightingCB_Shader(atomic);
uploadMatrices(atomic->getFrame()->getLTM());
bool normals = !!(atomic->geometry->flags & Geometry::NORMALS);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
Material *m = inst->material;
setMaterial(flags, m->color, m->surfaceProps);
MatFX *matfx = MatFX::get(m);
if(matfx == nil)
matfxRender_Default(header, inst, vsBits);
else switch(matfx->type){
case MatFX::ENVMAP:
if(normals)
matfxRender_EnvMap(header, inst, vsBits, &matfx->fx[0].env);
else
matfxRender_Default(header, inst, vsBits);
break;
case MatFX::NOTHING:
case MatFX::BUMPMAP:
case MatFX::BUMPENVMAP:
case MatFX::DUAL:
case MatFX::UVTRANSFORM:
case MatFX::DUALUVTRANSFORM:
// not supported yet
matfxRender_Default(header, inst, vsBits);
break;
}
inst++;
}
d3d::setTexture(1, nil);
}
#define VS_NAME g_vs20_main
#define PS_NAME g_ps20_main
void
createMatFXShaders(void)
{
{
static
#include "shaders/matfx_env_amb_VS.h"
matfx_env_amb_VS = createVertexShader((void*)VS_NAME);
assert(matfx_env_amb_VS);
}
{
static
#include "shaders/matfx_env_amb_dir_VS.h"
matfx_env_amb_dir_VS = createVertexShader((void*)VS_NAME);
assert(matfx_env_amb_dir_VS);
}
{
static
#include "shaders/matfx_env_all_VS.h"
matfx_env_all_VS = createVertexShader((void*)VS_NAME);
assert(matfx_env_all_VS);
}
{
static
#include "shaders/matfx_env_PS.h"
matfx_env_PS = createPixelShader((void*)PS_NAME);
assert(matfx_env_PS);
}
{
static
#include "shaders/matfx_env_tex_PS.h"
matfx_env_tex_PS = createPixelShader((void*)PS_NAME);
assert(matfx_env_tex_PS);
}
}
void
destroyMatFXShaders(void)
{
destroyVertexShader(matfx_env_amb_VS);
matfx_env_amb_VS = nil;
destroyVertexShader(matfx_env_amb_dir_VS);
matfx_env_amb_dir_VS = nil;
destroyVertexShader(matfx_env_all_VS);
matfx_env_all_VS = nil;
destroyPixelShader(matfx_env_PS);
matfx_env_PS = nil;
destroyPixelShader(matfx_env_tex_PS);
matfx_env_tex_PS = nil;
}
#endif
static void*
matfxOpen(void *o, int32, int32)
{
#ifdef RW_D3D9
createMatFXShaders();
#endif
matFXGlobals.pipelines[PLATFORM_D3D9] = makeMatFXPipeline();
return o;
}
static void*
matfxClose(void *o, int32, int32)
{
#ifdef RW_D3D9
destroyMatFXShaders();
#endif
((ObjPipeline*)matFXGlobals.pipelines[PLATFORM_D3D9])->destroy();
matFXGlobals.pipelines[PLATFORM_D3D9] = nil;
return o;
}
void
initMatFX(void)
{
Driver::registerPlugin(PLATFORM_D3D9, 0, ID_MATFX,
matfxOpen, matfxClose);
}
ObjPipeline*
makeMatFXPipeline(void)
{
ObjPipeline *pipe = ObjPipeline::create();
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = matfxRenderCB_Shader;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;
}
}
}

185
vendor/librw/src/d3d/d3d9render.cpp vendored Normal file
View file

@ -0,0 +1,185 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "../rwrender.h"
#include "rwd3d.h"
#include "rwd3d9.h"
namespace rw {
namespace d3d9 {
using namespace d3d;
#ifndef RW_D3D9
void defaultRenderCB(Atomic*, InstanceDataHeader*) {}
void defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) {}
#else
void
drawInst_simple(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst)
{
d3d::flushCache();
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
0, inst->numVertices,
inst->startIndex, inst->numPrimitives);
}
// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer
void
drawInst_GSemu(d3d9::InstanceDataHeader *header, InstanceData *inst)
{
uint32 hasAlpha;
int alphafunc, alpharef, gsalpharef;
int zwrite;
d3d::getRenderState(D3DRS_ALPHABLENDENABLE, &hasAlpha);
if(hasAlpha){
zwrite = rw::GetRenderState(rw::ZWRITEENABLE);
alphafunc = rw::GetRenderState(rw::ALPHATESTFUNC);
if(zwrite){
alpharef = rw::GetRenderState(rw::ALPHATESTREF);
gsalpharef = rw::GetRenderState(rw::GSALPHATESTREF);
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL);
SetRenderState(rw::ALPHATESTREF, gsalpharef);
drawInst_simple(header, inst);
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHALESS);
SetRenderState(rw::ZWRITEENABLE, 0);
drawInst_simple(header, inst);
SetRenderState(rw::ZWRITEENABLE, 1);
SetRenderState(rw::ALPHATESTFUNC, alphafunc);
SetRenderState(rw::ALPHATESTREF, alpharef);
}else{
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAALWAYS);
drawInst_simple(header, inst);
SetRenderState(rw::ALPHATESTFUNC, alphafunc);
}
}else
drawInst_simple(header, inst);
}
void
drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst)
{
if(rw::GetRenderState(rw::GSALPHATEST))
drawInst_GSemu(header, inst);
else
drawInst_simple(header, inst);
}
/*
void
defaultRenderCB_Fix(Atomic *atomic, InstanceDataHeader *header)
{
RawMatrix world;
Geometry *geo = atomic->geometry;
int lighting = !!(geo->flags & rw::Geometry::LIGHT);
if(lighting)
d3d::lightingCB_Fix(atomic);
d3d::setRenderState(D3DRS_LIGHTING, lighting);
Frame *f = atomic->getFrame();
convMatrix(&world, f->getLTM());
d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride);
setIndices(header->indexBuffer);
setVertexDeclaration(header->vertexDeclaration);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
SetRenderState(VERTEXALPHA, inst->vertexAlpha || inst->material->color.alpha != 255);
const static rw::RGBA white = { 255, 255, 255, 255 };
d3d::setMaterial(white, inst->material->surfaceProps);
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
if(geo->flags & Geometry::PRELIT)
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
else
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, inst->vertexAlpha ? D3DMCS_COLOR1 : D3DMCS_MATERIAL);
if(inst->material->texture){
// Texture
d3d::setTexture(0, inst->material->texture);
d3d::setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
d3d::setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT);
d3d::setTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
d3d::setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
d3d::setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
d3d::setTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
}else{
d3d::setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3d::setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT);
d3d::setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
d3d::setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
}
// Material colour
const rw::RGBA *col = &inst->material->color;
d3d::setTextureStageState(1, D3DTSS_CONSTANT, D3DCOLOR_ARGB(col->alpha,col->red,col->green,col->blue));
d3d::setTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
d3d::setTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
d3d::setTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CONSTANT);
d3d::setTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
d3d::setTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
d3d::setTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CONSTANT);
drawInst(header, inst);
inst++;
}
d3d::setTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
d3d::setTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
}
*/
void
defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header)
{
int vsBits;
uint32 flags = atomic->geometry->flags;
setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride);
setIndices(header->indexBuffer);
setVertexDeclaration(header->vertexDeclaration);
vsBits = lightingCB_Shader(atomic);
uploadMatrices(atomic->getFrame()->getLTM());
// Pick a shader
if((vsBits & VSLIGHT_MASK) == 0)
setVertexShader(default_amb_VS);
else if((vsBits & VSLIGHT_MASK) == VSLIGHT_DIRECT)
setVertexShader(default_amb_dir_VS);
else
setVertexShader(default_all_VS);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
Material *m = inst->material;
SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
setMaterial(flags, m->color, m->surfaceProps);
if(m->texture){
d3d::setTexture(0, m->texture);
setPixelShader(default_tex_PS);
}else
setPixelShader(default_PS);
drawInst(header, inst);
inst++;
}
}
#endif
}
}

418
vendor/librw/src/d3d/d3d9skin.cpp vendored Normal file
View file

@ -0,0 +1,418 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwrender.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwanim.h"
#include "../rwengine.h"
#include "../rwplugins.h"
#include "rwd3d.h"
#include "rwd3d9.h"
namespace rw {
namespace d3d9 {
using namespace d3d;
#ifndef RW_D3D9
void skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance) {}
void skinRenderCB(Atomic *atomic, InstanceDataHeader *header) {}
#else
static void *skin_amb_VS;
static void *skin_amb_dir_VS;
static void *skin_all_VS;
#define NUMDECLELT 14
void
skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
{
int i = 0;
VertexElement dcl[NUMDECLELT];
VertexStream *s = &header->vertexStream[0];
bool isPrelit = (geo->flags & Geometry::PRELIT) != 0;
bool hasNormals = (geo->flags & Geometry::NORMALS) != 0;
// TODO: support both vertex buffers
if(!reinstance){
// Create declarations and buffers only the first time
assert(s->vertexBuffer == nil);
s->offset = 0;
s->managed = 1;
s->geometryFlags = 0;
s->dynamicLock = 0;
dcl[i].stream = 0;
dcl[i].offset = 0;
dcl[i].type = D3DDECLTYPE_FLOAT3;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_POSITION;
dcl[i].usageIndex = 0;
i++;
uint16 stride = 12;
s->geometryFlags |= 0x2;
if(isPrelit){
dcl[i].stream = 0;
dcl[i].offset = stride;
dcl[i].type = D3DDECLTYPE_D3DCOLOR;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_COLOR;
dcl[i].usageIndex = 0;
i++;
s->geometryFlags |= 0x8;
stride += 4;
}
for(int32 n = 0; n < geo->numTexCoordSets; n++){
dcl[i].stream = 0;
dcl[i].offset = stride;
dcl[i].type = D3DDECLTYPE_FLOAT2;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_TEXCOORD;
dcl[i].usageIndex = (uint8)n;
i++;
s->geometryFlags |= 0x10 << n;
stride += 8;
}
if(hasNormals){
dcl[i].stream = 0;
dcl[i].offset = stride;
dcl[i].type = D3DDECLTYPE_FLOAT3;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_NORMAL;
dcl[i].usageIndex = 0;
i++;
s->geometryFlags |= 0x4;
stride += 12;
}
dcl[i].stream = 0;
dcl[i].offset = stride;
dcl[i].type = D3DDECLTYPE_FLOAT4;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_BLENDWEIGHT;
dcl[i].usageIndex = 0;
i++;
stride += 16;
dcl[i].stream = 0;
dcl[i].offset = stride;
dcl[i].type = D3DDECLTYPE_UBYTE4;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_BLENDINDICES;
dcl[i].usageIndex = 0;
i++;
stride += 4;
// We expect some attributes to always be there, use the constant buffer as fallback
if(!isPrelit){
dcl[i].stream = 2;
dcl[i].offset = offsetof(VertexConstantData, color);
dcl[i].type = D3DDECLTYPE_D3DCOLOR;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_COLOR;
dcl[i].usageIndex = 0;
i++;
}
if(geo->numTexCoordSets == 0){
dcl[i].stream = 2;
dcl[i].offset = offsetof(VertexConstantData, texCoors[0]);
dcl[i].type = D3DDECLTYPE_FLOAT2;
dcl[i].method = D3DDECLMETHOD_DEFAULT;
dcl[i].usage = D3DDECLUSAGE_TEXCOORD;
dcl[i].usageIndex = 0;
i++;
}
dcl[i] = D3DDECL_END();
s->stride = stride;
assert(header->vertexDeclaration == nil);
header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl);
assert(s->vertexBuffer == nil);
s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, false);
}else
getDeclaration(header->vertexDeclaration, dcl);
Skin *skin = Skin::get(geo);
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
// Instance vertices
if(!reinstance || geo->lockedSinceInst&Geometry::LOCKVERTICES){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++)
;
instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
geo->morphTargets[0].vertices,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
// Instance prelight colors
if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++)
;
InstanceData *inst = header->inst;
uint32 n = header->numMeshes;
while(n--){
uint32 stride = header->vertexStream[dcl[i].stream].stride;
inst->vertexAlpha = instColor(vertFormatMap[dcl[i].type],
verts + dcl[i].offset + stride*inst->minVert,
geo->colors + inst->minVert,
inst->numVertices,
stride);
inst++;
}
}
// Instance tex coords
for(int32 n = 0; n < geo->numTexCoordSets; n++){
if(!reinstance || geo->lockedSinceInst&(Geometry::LOCKTEXCOORDS<<n)){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++)
;
instTexCoords(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
geo->texCoords[n],
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
}
// Instance normals
if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++)
;
instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
geo->morphTargets[0].normals,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
// Instance skin weights
if(!reinstance){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_BLENDWEIGHT || dcl[i].usageIndex != 0; i++)
;
instV4d(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
(V4d*)skin->weights,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
// Instance skin indices
if(!reinstance){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_BLENDINDICES || dcl[i].usageIndex != 0; i++)
;
// not really colors of course but what the heck
instColor(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
(RGBA*)skin->indices,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
unlockVertices(s->vertexBuffer);
}
enum
{
VSLOC_boneMatrices = VSLOC_afterLights
};
static float skinMatrices[64*16];
void
uploadSkinMatrices(Atomic *a)
{
int i;
Skin *skin = Skin::get(a->geometry);
float *m = skinMatrices;
HAnimHierarchy *hier = Skin::getHierarchy(a);
if(hier){
Matrix *invMats = (Matrix*)skin->inverseMatrices;
Matrix tmp, tmp2;
assert(skin->numBones == hier->numNodes);
if(hier->flags & HAnimHierarchy::LOCALSPACEMATRICES){
for(i = 0; i < hier->numNodes; i++){
invMats[i].flags = 0;
Matrix::mult(&tmp, &invMats[i], &hier->matrices[i]);
RawMatrix::transpose((RawMatrix*)m, (RawMatrix*)&tmp);
m += 12;
}
}else{
Matrix invAtmMat;
Matrix::invert(&invAtmMat, a->getFrame()->getLTM());
for(i = 0; i < hier->numNodes; i++){
invMats[i].flags = 0;
Matrix::mult(&tmp, &hier->matrices[i], &invAtmMat);
Matrix::mult(&tmp2, &invMats[i], &tmp);
RawMatrix::transpose((RawMatrix*)m, (RawMatrix*)&tmp2);
m += 12;
}
}
}else{
for(i = 0; i < skin->numBones; i++){
m[0] = 1.0f;
m[1] = 0.0f;
m[2] = 0.0f;
m[3] = 0.0f;
m[4] = 0.0f;
m[5] = 1.0f;
m[6] = 0.0f;
m[7] = 0.0f;
m[8] = 0.0f;
m[9] = 0.0f;
m[10] = 1.0f;
m[11] = 0.0f;
m += 12;
}
}
d3ddevice->SetVertexShaderConstantF(VSLOC_boneMatrices, skinMatrices, skin->numBones*3);
}
void
skinRenderCB(Atomic *atomic, InstanceDataHeader *header)
{
int vsBits;
uint32 flags = atomic->geometry->flags;
setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer,
0, header->vertexStream[0].stride);
setIndices((IDirect3DIndexBuffer9*)header->indexBuffer);
setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration);
vsBits = lightingCB_Shader(atomic);
uploadMatrices(atomic->getFrame()->getLTM());
uploadSkinMatrices(atomic);
// Pick a shader
if((vsBits & VSLIGHT_MASK) == 0)
setVertexShader(skin_amb_VS);
else if((vsBits & VSLIGHT_MASK) == VSLIGHT_DIRECT)
setVertexShader(skin_amb_dir_VS);
else
setVertexShader(skin_all_VS);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
Material *m = inst->material;
SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
setMaterial(flags, m->color, m->surfaceProps);
if(inst->material->texture){
d3d::setTexture(0, m->texture);
setPixelShader(default_tex_PS);
}else
setPixelShader(default_PS);
drawInst(header, inst);
inst++;
}
}
#define VS_NAME g_vs20_main
#define PS_NAME g_ps20_main
void
createSkinShaders(void)
{
{
static
#include "shaders/skin_amb_VS.h"
skin_amb_VS = createVertexShader((void*)VS_NAME);
assert(skin_amb_VS);
}
{
static
#include "shaders/skin_amb_dir_VS.h"
skin_amb_dir_VS = createVertexShader((void*)VS_NAME);
assert(skin_amb_dir_VS);
}
// Skinning takes a lot of instructions....lighting may be not possible
// TODO: should do something about this
{
static
#include "shaders/skin_all_VS.h"
skin_all_VS = createVertexShader((void*)VS_NAME);
// assert(skin_all_VS);
}
}
void
destroySkinShaders(void)
{
destroyVertexShader(skin_amb_VS);
skin_amb_VS = nil;
destroyVertexShader(skin_amb_dir_VS);
skin_amb_dir_VS = nil;
if(skin_all_VS){
destroyVertexShader(skin_all_VS);
skin_all_VS = nil;
}
}
#endif
static void*
skinOpen(void *o, int32, int32)
{
#ifdef RW_D3D9
createSkinShaders();
#endif
skinGlobals.pipelines[PLATFORM_D3D9] = makeSkinPipeline();
return o;
}
static void*
skinClose(void *o, int32, int32)
{
#ifdef RW_D3D9
destroySkinShaders();
#endif
((ObjPipeline*)skinGlobals.pipelines[PLATFORM_D3D9])->destroy();
skinGlobals.pipelines[PLATFORM_D3D9] = nil;
return o;
}
void
initSkin(void)
{
Driver::registerPlugin(PLATFORM_D3D9, 0, ID_SKIN,
skinOpen, skinClose);
}
ObjPipeline*
makeSkinPipeline(void)
{
ObjPipeline *pipe = ObjPipeline::create();
pipe->instanceCB = skinInstanceCB;
pipe->uninstanceCB = nil;
pipe->renderCB = skinRenderCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
}
}
}

2023
vendor/librw/src/d3d/d3ddevice.cpp vendored Normal file

File diff suppressed because it is too large Load diff

386
vendor/librw/src/d3d/d3dimmed.cpp vendored Normal file
View file

@ -0,0 +1,386 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwrender.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "rwd3d.h"
#include "rwd3d9.h"
#include "rwd3dimpl.h"
namespace rw {
namespace d3d {
#ifdef RW_D3D9
// might want to tweak this
#define NUMINDICES 10000
#define NUMVERTICES 10000
static int primTypeMap[] = {
D3DPT_POINTLIST, // invalid
D3DPT_LINELIST,
D3DPT_LINESTRIP,
D3DPT_TRIANGLELIST,
D3DPT_TRIANGLESTRIP,
D3DPT_TRIANGLEFAN,
D3DPT_POINTLIST, // actually not supported!
};
static IDirect3DVertexDeclaration9 *im2ddecl;
static IDirect3DVertexBuffer9 *im2dvertbuf;
static IDirect3DIndexBuffer9 *im2dindbuf;
void *im2dOverridePS;
void
openIm2D(void)
{
D3DVERTEXELEMENT9 elements[4] = {
// can't get proper fog with this :(
// { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, offsetof(Im2DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, offsetof(Im2DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};
assert(im2ddecl == nil);
im2ddecl = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements);
assert(im2ddecl);
assert(im2dvertbuf == nil);
im2dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertex), 0, true);
assert(im2dvertbuf);
addDynamicVB(NUMVERTICES*sizeof(Im2DVertex), 0, &im2dvertbuf);
assert(im2dindbuf == nil);
im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16), true);
assert(im2dindbuf);
addDynamicIB(NUMINDICES*sizeof(uint16), &im2dindbuf);
}
void
closeIm2D(void)
{
d3d9::destroyVertexDeclaration(im2ddecl);
im2ddecl = nil;
removeDynamicVB(&im2dvertbuf);
destroyVertexBuffer(im2dvertbuf);
im2dvertbuf = nil;
removeDynamicIB(&im2dindbuf);
destroyIndexBuffer(im2dindbuf);
im2dindbuf = nil;
}
static Im2DVertex tmpprimbuf[3];
void
im2DRenderLine(void *vertices, int32 numVertices, int32 vert1, int32 vert2)
{
Im2DVertex *verts = (Im2DVertex*)vertices;
tmpprimbuf[0] = verts[vert1];
tmpprimbuf[1] = verts[vert2];
im2DRenderPrimitive(PRIMTYPELINELIST, tmpprimbuf, 2);
}
void
im2DRenderTriangle(void *vertices, int32 numVertices, int32 vert1, int32 vert2, int32 vert3)
{
Im2DVertex *verts = (Im2DVertex*)vertices;
tmpprimbuf[0] = verts[vert1];
tmpprimbuf[1] = verts[vert2];
tmpprimbuf[2] = verts[vert3];
im2DRenderPrimitive(PRIMTYPETRILIST, tmpprimbuf, 3);
}
void
im2DSetXform(void)
{
float xform[4];
Camera *cam;
cam = (Camera*)engine->currentCamera;
xform[0] = 2.0f/cam->frameBuffer->width;
xform[1] = -2.0f/cam->frameBuffer->height;
xform[2] = -1.0f;
xform[3] = 1.0f;
// TODO: should cache this...
d3ddevice->SetVertexShaderConstantF(VSLOC_afterLights, xform, 1);
}
void
im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices)
{
if(numVertices > NUMVERTICES){
// TODO: error
return;
}
uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_DISCARD);
memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex));
unlockVertices(im2dvertbuf);
setStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex));
setVertexDeclaration(im2ddecl);
im2DSetXform();
setVertexShader(im2d_VS);
if(im2dOverridePS)
setPixelShader(im2dOverridePS);
else if(engine->device.getRenderState(TEXTURERASTER))
setPixelShader(im2d_tex_PS);
else
setPixelShader(im2d_PS);
d3d::flushCache();
uint32 primCount = 0;
switch(primType){
case PRIMTYPELINELIST:
primCount = numVertices/2;
break;
case PRIMTYPEPOLYLINE:
primCount = numVertices-1;
break;
case PRIMTYPETRILIST:
primCount = numVertices/3;
break;
case PRIMTYPETRISTRIP:
primCount = numVertices-2;
break;
case PRIMTYPETRIFAN:
primCount = numVertices-2;
break;
case PRIMTYPEPOINTLIST:
primCount = numVertices;
break;
}
d3ddevice->DrawPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, primCount);
}
void
im2DRenderIndexedPrimitive(PrimitiveType primType,
void *vertices, int32 numVertices, void *indices, int32 numIndices)
{
if(numVertices > NUMVERTICES ||
numIndices > NUMINDICES){
// TODO: error
return;
}
uint16 *lockedindices = lockIndices(im2dindbuf, 0, numIndices*sizeof(uint16), D3DLOCK_DISCARD);
memcpy(lockedindices, indices, numIndices*sizeof(uint16));
unlockIndices(im2dindbuf);
uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_DISCARD);
memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex));
unlockVertices(im2dvertbuf);
setStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex));
setIndices(im2dindbuf);
setVertexDeclaration(im2ddecl);
im2DSetXform();
setVertexShader(im2d_VS);
if(im2dOverridePS)
setPixelShader(im2dOverridePS);
else if(engine->device.getRenderState(TEXTURERASTER))
setPixelShader(im2d_tex_PS);
else
setPixelShader(im2d_PS);
d3d::flushCache();
uint32 primCount = 0;
switch(primType){
case PRIMTYPELINELIST:
primCount = numIndices/2;
break;
case PRIMTYPEPOLYLINE:
primCount = numIndices-1;
break;
case PRIMTYPETRILIST:
primCount = numIndices/3;
break;
case PRIMTYPETRISTRIP:
primCount = numIndices-2;
break;
case PRIMTYPETRIFAN:
primCount = numIndices-2;
break;
case PRIMTYPEPOINTLIST:
primCount = numIndices;
break;
}
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
0, numVertices,
0, primCount);
}
// Im3D
static IDirect3DVertexDeclaration9 *im3ddecl;
static IDirect3DVertexBuffer9 *im3dvertbuf;
static IDirect3DIndexBuffer9 *im3dindbuf;
static int32 num3DVertices;
void
openIm3D(void)
{
D3DVERTEXELEMENT9 elements[4] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 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()
};
assert(im3ddecl == nil);
im3ddecl = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements);
assert(im3ddecl);
assert(im3dvertbuf == nil);
im3dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im3DVertex), 0, true);
assert(im3dvertbuf);
addDynamicVB(NUMVERTICES*sizeof(Im3DVertex), 0, &im3dvertbuf);
assert(im3dindbuf == nil);
im3dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16), true);
assert(im3dindbuf);
addDynamicIB(NUMINDICES*sizeof(uint16), &im3dindbuf);
}
void
closeIm3D(void)
{
d3d9::destroyVertexDeclaration(im3ddecl);
im3ddecl = nil;
removeDynamicVB(&im3dvertbuf);
destroyVertexBuffer(im3dvertbuf);
im3dvertbuf = nil;
removeDynamicIB(&im3dindbuf);
destroyIndexBuffer(im3dindbuf);
im3dindbuf = nil;
}
void
im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
{
if(world == nil)
uploadMatrices();
else
uploadMatrices(world);
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);
uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_DISCARD);
memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex));
unlockVertices(im3dvertbuf);
setStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex));
setVertexDeclaration(im3ddecl);
setVertexShader(default_amb_VS);
num3DVertices = numVertices;
}
void
im3DRenderPrimitive(PrimitiveType primType)
{
if(engine->device.getRenderState(TEXTURERASTER))
setPixelShader(default_tex_PS);
else
setPixelShader(default_PS);
d3d::flushCache();
uint32 primCount = 0;
switch(primType){
case PRIMTYPELINELIST:
primCount = num3DVertices/2;
break;
case PRIMTYPEPOLYLINE:
primCount = num3DVertices-1;
break;
case PRIMTYPETRILIST:
primCount = num3DVertices/3;
break;
case PRIMTYPETRISTRIP:
primCount = num3DVertices-2;
break;
case PRIMTYPETRIFAN:
primCount = num3DVertices-2;
break;
case PRIMTYPEPOINTLIST:
primCount = num3DVertices;
break;
}
d3ddevice->DrawPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, primCount);
}
void
im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices)
{
uint16 *lockedindices = lockIndices(im3dindbuf, 0, numIndices*sizeof(uint16), D3DLOCK_DISCARD);
memcpy(lockedindices, indices, numIndices*sizeof(uint16));
unlockIndices(im3dindbuf);
setIndices(im3dindbuf);
if(engine->device.getRenderState(TEXTURERASTER))
setPixelShader(default_tex_PS);
else
setPixelShader(default_PS);
d3d::flushCache();
uint32 primCount = 0;
switch(primType){
case PRIMTYPELINELIST:
primCount = numIndices/2;
break;
case PRIMTYPEPOLYLINE:
primCount = numIndices-1;
break;
case PRIMTYPETRILIST:
primCount = numIndices/3;
break;
case PRIMTYPETRISTRIP:
primCount = numIndices-2;
break;
case PRIMTYPETRIFAN:
primCount = numIndices-2;
break;
case PRIMTYPEPOINTLIST:
primCount = numIndices;
break;
}
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
0, num3DVertices,
0, primCount);
}
void
im3DEnd(void)
{
}
#endif
}
}

413
vendor/librw/src/d3d/d3drender.cpp vendored Normal file
View file

@ -0,0 +1,413 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "rwd3d.h"
namespace rw {
namespace d3d {
#ifdef RW_D3D9
IDirect3DDevice9 *d3ddevice = nil;
#define MAX_LIGHTS 8
#define VS_NAME g_vs20_main
#define PS_NAME g_ps20_main
void *default_amb_VS;
void *default_amb_dir_VS;
void *default_all_VS;
void *default_PS;
void *default_tex_PS;
void *im2d_VS;
void *im2d_PS;
void *im2d_tex_PS;
void
createDefaultShaders(void)
{
{
static
#include "shaders/default_amb_VS.h"
default_amb_VS = createVertexShader((void*)VS_NAME);
assert(default_amb_VS);
}
{
static
#include "shaders/default_amb_dir_VS.h"
default_amb_dir_VS = createVertexShader((void*)VS_NAME);
assert(default_amb_dir_VS);
}
{
static
#include "shaders/default_all_VS.h"
default_all_VS = createVertexShader((void*)VS_NAME);
assert(default_all_VS);
}
{
static
#include "shaders/default_PS.h"
default_PS = createPixelShader((void*)PS_NAME);
assert(default_PS);
}
{
static
#include "shaders/default_tex_PS.h"
default_tex_PS = createPixelShader((void*)PS_NAME);
assert(default_tex_PS);
}
{
static
#include "shaders/im2d_VS.h"
im2d_VS = createVertexShader((void*)VS_NAME);
assert(im2d_VS);
}
{
static
#include "shaders/im2d_PS.h"
im2d_PS = createPixelShader((void*)PS_NAME);
assert(im2d_PS);
}
{
static
#include "shaders/im2d_tex_PS.h"
im2d_tex_PS = createPixelShader((void*)PS_NAME);
assert(im2d_tex_PS);
}
}
void
destroyDefaultShaders(void)
{
destroyVertexShader(default_amb_VS);
default_amb_VS = nil;
destroyVertexShader(default_amb_dir_VS);
default_amb_dir_VS = nil;
destroyVertexShader(default_all_VS);
default_all_VS = nil;
destroyPixelShader(default_PS);
default_PS = nil;
destroyPixelShader(default_tex_PS);
default_tex_PS = nil;
destroyVertexShader(im2d_VS);
im2d_VS = nil;
destroyPixelShader(im2d_PS);
im2d_PS = nil;
destroyPixelShader(im2d_tex_PS);
im2d_tex_PS = nil;
}
void
lightingCB_Fix(Atomic *atomic)
{
WorldLights lightData;
Light *directionals[8];
Light *locals[8];
lightData.directionals = directionals;
lightData.numDirectionals = 8;
lightData.locals = locals;
lightData.numLocals = 8;
((World*)engine->currentWorld)->enumerateLights(atomic, &lightData);
int i, n;
RGBA amb;
D3DLIGHT9 light;
light.Type = D3DLIGHT_DIRECTIONAL;
//light.Diffuse = { 0.8f, 0.8f, 0.8f, 1.0f };
light.Specular = { 0.0f, 0.0f, 0.0f, 0.0f };
light.Ambient = { 0.0f, 0.0f, 0.0f, 0.0f };
light.Position = { 0.0f, 0.0f, 0.0f };
//light.Direction = { 0.0f, 0.0f, -1.0f };
light.Range = 0.0f;
light.Falloff = 0.0f;
light.Attenuation0 = 0.0f;
light.Attenuation1 = 0.0f;
light.Attenuation2 = 0.0f;
light.Theta = 0.0f;
light.Phi = 0.0f;
convColor(&amb, &lightData.ambient);
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(amb.red, amb.green, amb.blue, amb.alpha));
n = 0;
for(i = 0; i < lightData.numDirectionals; i++){
if(n >= MAX_LIGHTS)
return;
Light *l = lightData.directionals[i];
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse = *(D3DCOLORVALUE*)&l->color;
light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at;
d3ddevice->SetLight(n, &light);
d3ddevice->LightEnable(n, TRUE);
n++;
}
for(i = 0; i < lightData.numLocals; i++){
if(n >= MAX_LIGHTS)
return;
Light *l = lightData.locals[i];
switch(l->getType()){
case Light::POINT:
light.Type = D3DLIGHT_POINT;
light.Diffuse = *(D3DCOLORVALUE*)&l->color;
light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos;
light.Direction.x = 0.0f;
light.Direction.y = 0.0f;
light.Direction.z = 0.0f;
light.Range = l->radius;
light.Falloff = 1.0f;
light.Attenuation0 = 1.0f;
light.Attenuation1 = 0.0f/l->radius;
light.Attenuation2 = 5.0f/(l->radius*l->radius);
d3ddevice->SetLight(n, &light);
d3ddevice->LightEnable(n, TRUE);
n++;
break;
case Light::SPOT:
light.Type = D3DLIGHT_SPOT;
light.Diffuse = *(D3DCOLORVALUE*)&l->color;
light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos;
light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at;
light.Range = l->radius;
light.Falloff = 1.0f;
light.Attenuation0 = 1.0f;
light.Attenuation1 = 0.0f/l->radius;
light.Attenuation2 = 5.0f/(l->radius*l->radius);
light.Theta = l->getAngle()*2.0f;
light.Phi = light.Theta;
d3ddevice->SetLight(n, &light);
d3ddevice->LightEnable(n, TRUE);
n++;
break;
case Light::SOFTSPOT:
light.Type = D3DLIGHT_SPOT;
light.Diffuse = *(D3DCOLORVALUE*)&l->color;
light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos;
light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at;
light.Range = l->radius;
light.Falloff = 1.0f;
light.Attenuation0 = 1.0f;
light.Attenuation1 = 0.0f/l->radius;
light.Attenuation2 = 5.0f/(l->radius*l->radius);
light.Theta = 0.0f;
light.Phi = l->getAngle()*2.0f;
d3ddevice->SetLight(n, &light);
d3ddevice->LightEnable(n, TRUE);
n++;
break;
}
}
for(; n < MAX_LIGHTS; n++)
d3ddevice->LightEnable(n, FALSE);
}
struct LightVS
{
V3d color; float param0;
V3d position; float param1;
V3d direction; float param2;
};
void
setAmbient(const RGBAf &color)
{
if(!equal(d3dShaderState.ambient, color)){
d3dShaderState.ambient = color;
d3ddevice->SetVertexShaderConstantF(VSLOC_ambLight, (float*)&color, 1);
}
}
void
setNumLights(int numDir, int numPoint, int numSpot)
{
static int32 numLights[4*3];
if(d3dShaderState.numDir != numDir ||
d3dShaderState.numPoint != numPoint ||
d3dShaderState.numSpot != numSpot){
numLights[0] = d3dShaderState.numDir = numDir;
numLights[4] = d3dShaderState.numPoint = numPoint;
numLights[8] = d3dShaderState.numSpot = numSpot;
d3ddevice->SetVertexShaderConstantI(VSLOC_numLights, numLights, 3);
}
}
int32
uploadLights(WorldLights *lightData)
{
int i;
int bits = 0;
float32 firstLight[4];
firstLight[0] = 0; // directional
firstLight[1] = 0; // point
firstLight[2] = 0; // spot
firstLight[3] = 0;
if(lightData->numAmbients)
bits |= VSLIGHT_AMBIENT;
LightVS directionals[8];
LightVS points[8];
LightVS spots[8];
for(i = 0; i < lightData->numDirectionals; i++){
Light *l = lightData->directionals[i];
directionals[i].color.x = l->color.red;
directionals[i].color.y = l->color.green;
directionals[i].color.z = l->color.blue;
directionals[i].direction = l->getFrame()->getLTM()->at;
bits |= VSLIGHT_DIRECT;
}
int np = 0;
int ns = 0;
for(i = 0; i < lightData->numLocals; i++){
Light *l = lightData->locals[i];
switch(l->getType()){
case Light::POINT:
points[np].color.x = l->color.red;
points[np].color.y = l->color.green;
points[np].color.z = l->color.blue;
points[np].param0 = l->radius;
points[np].position = l->getFrame()->getLTM()->pos;
np++;
bits |= VSLIGHT_POINT;
break;
case Light::SPOT:
case Light::SOFTSPOT:
spots[ns].color.x = l->color.red;
spots[ns].color.y = l->color.green;
spots[ns].color.z = l->color.blue;
spots[ns].param0 = l->radius;
spots[ns].position = l->getFrame()->getLTM()->pos;
spots[ns].direction = l->getFrame()->getLTM()->at;
spots[ns].param1 = l->minusCosAngle;
// lower bound of falloff
if(l->getType() == Light::SOFTSPOT)
spots[ns].param2 = 0.0f;
else
spots[ns].param2 = 1.0f;
bits |= VSLIGHT_SPOT;
ns++;
break;
}
}
firstLight[0] = 0;
int numDir = lightData->numDirectionals;
firstLight[1] = numDir + firstLight[0];
int numPoint = np;
firstLight[2] = numPoint + firstLight[1];
int numSpot = ns;
setNumLights(numDir, numPoint, numSpot);
if(d3dShaderState.lightOffset[0] != firstLight[0] ||
d3dShaderState.lightOffset[1] != firstLight[1] ||
d3dShaderState.lightOffset[2] != firstLight[2]){
d3dShaderState.lightOffset[0] = firstLight[0];
d3dShaderState.lightOffset[1] = firstLight[1];
d3dShaderState.lightOffset[2] = firstLight[2];
d3ddevice->SetVertexShaderConstantF(VSLOC_lightOffset, firstLight, 1);
}
int32 off = VSLOC_lights;
if(numDir)
d3ddevice->SetVertexShaderConstantF(off, (float*)&directionals, numDir*3);
off += numDir*3;
if(numPoint)
d3ddevice->SetVertexShaderConstantF(off, (float*)&points, numPoint*3);
off += numPoint*3;
if(numSpot)
d3ddevice->SetVertexShaderConstantF(off, (float*)&spots, numSpot*3);
return bits;
}
int32
lightingCB_Shader(Atomic *atomic)
{
WorldLights lightData;
Light *directionals[8];
Light *locals[8];
lightData.directionals = directionals;
lightData.numDirectionals = 8;
lightData.locals = locals;
lightData.numLocals = 8;
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 };
setAmbient(black);
setNumLights(0, 0, 0);
return 0;
}
}
static RawMatrix identityXform = {
{ 1.0f, 0.0f, 0.0f }, 0.0f,
{ 0.0f, 1.0f, 0.0f }, 0.0f,
{ 0.0f, 0.0f, 1.0f }, 0.0f,
{ 0.0f, 0.0f, 0.0f }, 1.0f
};
void
uploadMatrices(void)
{
RawMatrix combined;
Camera *cam = engine->currentCamera;
d3ddevice->SetVertexShaderConstantF(VSLOC_world, (float*)&identityXform, 4);
d3ddevice->SetVertexShaderConstantF(VSLOC_normal, (float*)&identityXform, 4);
RawMatrix::mult(&combined, &cam->devView, &cam->devProj);
d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&combined, 4);
}
void
uploadMatrices(Matrix *worldMat)
{
RawMatrix combined, world, worldview;
Camera *cam = engine->currentCamera;
convMatrix(&world, worldMat);
d3ddevice->SetVertexShaderConstantF(VSLOC_world, (float*)&world, 4);
// TODO: inverse transpose
d3ddevice->SetVertexShaderConstantF(VSLOC_normal, (float*)&world, 4);
RawMatrix::mult(&worldview, &world, &cam->devView);
RawMatrix::mult(&combined, &worldview, &cam->devProj);
d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&combined, 4);
}
#endif
}
}

411
vendor/librw/src/d3d/rwd3d.h vendored Normal file
View file

@ -0,0 +1,411 @@
#ifdef RW_D3D9
#ifdef WITH_D3D
#include <d3d9.h>
#endif
#endif
namespace rw {
#ifdef RW_D3D9
#ifdef _WINDOWS_
struct EngineOpenParams
{
HWND window;
};
#else
struct EngineOpenParams
{
uint32 please_include_windows_h;
};
#endif
#else
#ifdef _D3D9_H_
#error "please don't include d3d9.h for non-d3d9 platforms"
#endif
#endif
namespace d3d {
extern bool32 isP8supported;
extern Device renderdevice;
#ifdef RW_D3D9
#ifdef _D3D9_H_
extern IDirect3DDevice9 *d3ddevice;
void setD3dMaterial(D3DMATERIAL9 *mat9);
#endif
#define COLOR_ARGB(a, r, g, b) ((rw::uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
struct Im3DVertex
{
V3d position;
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 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; }
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->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; }
};
struct Im2DVertex
{
float32 x, y, z;
//float32 q; // recipz no longer used because we have a vertex stage now
float32 w;
uint32 color;
float32 u, v;
void setScreenX(float32 x) { this->x = x; }
void setScreenY(float32 y) { this->y = y; }
void setScreenZ(float32 z) { this->z = z; }
void setCameraZ(float32 z) { this->w = z; }
// void setRecipCameraZ(float32 recipz) { this->q = recipz; }
void setRecipCameraZ(float32 recipz) { this->w = 1.0f/recipz; }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = COLOR_ARGB(a, r, g, b); }
void setU(float32 u, float recipZ) { this->u = u; }
void setV(float32 v, float recipZ) { this->v = v; }
float getScreenX(void) { return this->x; }
float getScreenY(void) { return this->y; }
float getScreenZ(void) { return this->z; }
// float getCameraZ(void) { return 1.0f/this->q; }
// float getRecipCameraZ(void) { return this->q; }
float getCameraZ(void) { return this->w; }
float getRecipCameraZ(void) { return 1.0f/this->w; }
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; }
};
#else
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \
((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
#endif
enum {
D3DFMT_UNKNOWN = 0,
D3DFMT_R8G8B8 = 20,
D3DFMT_A8R8G8B8 = 21,
D3DFMT_X8R8G8B8 = 22,
D3DFMT_R5G6B5 = 23,
D3DFMT_X1R5G5B5 = 24,
D3DFMT_A1R5G5B5 = 25,
D3DFMT_A4R4G4B4 = 26,
D3DFMT_R3G3B2 = 27,
D3DFMT_A8 = 28,
D3DFMT_A8R3G3B2 = 29,
D3DFMT_X4R4G4B4 = 30,
D3DFMT_A2B10G10R10 = 31,
D3DFMT_A8B8G8R8 = 32,
D3DFMT_X8B8G8R8 = 33,
D3DFMT_G16R16 = 34,
D3DFMT_A2R10G10B10 = 35,
D3DFMT_A16B16G16R16 = 36,
D3DFMT_A8P8 = 40,
D3DFMT_P8 = 41,
D3DFMT_L8 = 50,
D3DFMT_A8L8 = 51,
D3DFMT_A4L4 = 52,
D3DFMT_V8U8 = 60,
D3DFMT_L6V5U5 = 61,
D3DFMT_X8L8V8U8 = 62,
D3DFMT_Q8W8V8U8 = 63,
D3DFMT_V16U16 = 64,
D3DFMT_A2W10V10U10 = 67,
D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'),
D3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'),
D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'),
D3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'),
D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'),
D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'),
D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'),
D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'),
D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'),
D3DFMT_D16_LOCKABLE = 70,
D3DFMT_D32 = 71,
D3DFMT_D15S1 = 73,
D3DFMT_D24S8 = 75,
D3DFMT_D24X8 = 77,
D3DFMT_D24X4S4 = 79,
D3DFMT_D16 = 80,
D3DFMT_D32F_LOCKABLE = 82,
D3DFMT_D24FS8 = 83,
// d3d9ex only
/* Z-Stencil formats valid for CPU access */
D3DFMT_D32_LOCKABLE = 84,
D3DFMT_S8_LOCKABLE = 85,
D3DFMT_L16 = 81,
D3DFMT_VERTEXDATA =100,
D3DFMT_INDEX16 =101,
D3DFMT_INDEX32 =102,
D3DFMT_Q16W16V16U16 =110,
D3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M','E','T','1'),
// Floating point surface formats
// s10e5 formats (16-bits per channel)
D3DFMT_R16F = 111,
D3DFMT_G16R16F = 112,
D3DFMT_A16B16G16R16F = 113,
// IEEE s23e8 formats (32-bits per channel)
D3DFMT_R32F = 114,
D3DFMT_G32R32F = 115,
D3DFMT_A32B32G32R32F = 116,
D3DFMT_CxV8U8 = 117,
// d3d9ex only
// Monochrome 1 bit per pixel format
D3DFMT_A1 = 118,
// 2.8 biased fixed point
D3DFMT_A2B10G10R10_XR_BIAS = 119,
// Binary format indicating that the data has no inherent type
D3DFMT_BINARYBUFFER = 199
};
enum {
D3DLOCK_NOSYSLOCK = 0, // ignored
D3DPOOL_MANAGED = 0, // ignored
D3DPT_TRIANGLELIST = 4,
D3DPT_TRIANGLESTRIP = 5,
D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
D3DDECLTYPE_FLOAT4 = 3, // 4D float
D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range
// Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte
D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.)
D3DDECLTYPE_SHORT4 = 7, // 4D signed short
D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0
D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1)
D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values
D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused.
D3DDECLMETHOD_DEFAULT = 0,
D3DDECLUSAGE_POSITION = 0,
D3DDECLUSAGE_BLENDWEIGHT, // 1
D3DDECLUSAGE_BLENDINDICES, // 2
D3DDECLUSAGE_NORMAL, // 3
D3DDECLUSAGE_PSIZE, // 4
D3DDECLUSAGE_TEXCOORD, // 5
D3DDECLUSAGE_TANGENT, // 6
D3DDECLUSAGE_BINORMAL, // 7
D3DDECLUSAGE_TESSFACTOR, // 8
D3DDECLUSAGE_POSITIONT, // 9
D3DDECLUSAGE_COLOR, // 10
D3DDECLUSAGE_FOG, // 11
D3DDECLUSAGE_DEPTH, // 12
D3DDECLUSAGE_SAMPLE // 13
,
D3DUSAGE_AUTOGENMIPMAP = 0x400
};
#endif
extern int vertFormatMap[];
void *createIndexBuffer(uint32 length, bool dynamic);
void destroyIndexBuffer(void *indexBuffer);
uint16 *lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags);
void unlockIndices(void *indexBuffer);
void *createVertexBuffer(uint32 length, uint32 fvf, bool dynamic);
void destroyVertexBuffer(void *vertexBuffer);
uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags);
void unlockVertices(void *vertexBuffer);
void *createTexture(int32 width, int32 height, int32 levels, uint32 usage, uint32 format);
void destroyTexture(void *texture);
uint8 *lockTexture(void *texture, int32 level);
void unlockTexture(void *texture, int32 level);
// Native Texture and Raster
struct D3dRaster
{
void *texture;
void *palette;
void *lockedSurf;
uint32 format;
uint32 bpp; // bytes per pixel
bool hasAlpha;
bool customFormat;
bool autogenMipmap;
};
int32 getLevelSize(Raster *raster, int32 level);
void allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha);
void setPalette(Raster *raster, void *palette, int32 size);
void setTexels(Raster *raster, void *texels, int32 level);
extern int32 nativeRasterOffset;
void registerNativeRaster(void);
#define GETD3DRASTEREXT(raster) PLUGINOFFSET(rw::d3d::D3dRaster, raster, rw::d3d::nativeRasterOffset)
// Rendering
void setRenderState(uint32 state, uint32 value);
void getRenderState(uint32 state, uint32 *value);
void setTextureStageState(uint32 stage, uint32 type, uint32 value);
void getTextureStageState(uint32 stage, uint32 type, uint32 *value);
void setSamplerState(uint32 stage, uint32 type, uint32 value);
void getSamplerState(uint32 stage, uint32 type, uint32 *value);
void flushCache(void);
void setTexture(uint32 stage, Texture *tex);
void setMaterial(const RGBA &color, const SurfaceProperties &surfaceprops, float extraSurfProp = 0.0f);
inline void setMaterial(uint32 flags, const RGBA &color, const SurfaceProperties &surfaceprops, float extraSurfProp = 0.0f)
{
static RGBA white = { 255, 255, 255, 255 };
if(flags & Geometry::MODULATE)
setMaterial(color, surfaceprops, extraSurfProp);
else
setMaterial(white, surfaceprops, extraSurfProp);
}
void setVertexShader(void *vs);
void setPixelShader(void *ps);
void setIndices(void *indexBuffer);
void setStreamSource(int n, void *buffer, uint32 offset, uint32 stride);
void setVertexDeclaration(void *declaration);
void *createVertexShader(void *csosrc);
void *createPixelShader(void *csosrc);
void destroyVertexShader(void *shader);
void destroyPixelShader(void *shader);
/*
* Vertex shaders and common pipeline stuff
*/
// This data will be available in vertex stream 2
struct VertexConstantData
{
V3d normal;
RGBA color;
TexCoords texCoors[8];
};
extern void *constantVertexStream;
// TODO: figure out why this even still exists...
struct D3dShaderState
{
// for VS
struct {
float32 start;
float32 end;
float32 range; // 1/(start-end)
float32 disable; // lower clamp
} fogData, fogDisable;
RGBA matColor;
SurfaceProperties surfProps;
float extraSurfProp;
float lightOffset[3];
int32 numDir, numPoint, numSpot;
RGBAf ambient;
// for PS
RGBAf fogColor;
bool fogDirty;
};
extern D3dShaderState d3dShaderState;
// Standard Vertex shader locations
enum
{
VSLOC_combined = 0,
VSLOC_world = 4,
VSLOC_normal = 8,
VSLOC_matColor = 12,
VSLOC_surfProps = 13,
VSLOC_fogData = 14,
VSLOC_ambLight = 15,
VSLOC_lightOffset = 16,
VSLOC_lights = 17,
VSLOC_afterLights = VSLOC_lights + 8*3,
VSLOC_numLights = 0,
PSLOC_fogColor = 0
};
// Vertex shader bits
enum
{
// These should be low so they could be used as indices
VSLIGHT_DIRECT = 1,
VSLIGHT_POINT = 2,
VSLIGHT_SPOT = 4,
VSLIGHT_MASK = 7, // all the above
// less critical
VSLIGHT_AMBIENT = 8,
};
void lightingCB_Fix(Atomic *atomic);
int32 lightingCB_Shader(Atomic *atomic);
// for VS
void uploadMatrices(void); // no world transform
void uploadMatrices(Matrix *worldMat);
void setAmbient(const RGBAf &color);
void setNumLights(int numDir, int numPoint, int numSpot);
int32 uploadLights(WorldLights *lightData); // called by lightingCB_Shader
extern void *im2dOverridePS;
extern void *default_amb_VS;
extern void *default_amb_dir_VS;
extern void *default_all_VS;
extern void *default_PS;
extern void *default_tex_PS;
extern void *im2d_VS;
extern void *im2d_PS;
extern void *im2d_tex_PS;
void createDefaultShaders(void);
void destroyDefaultShaders(void);
}
}

74
vendor/librw/src/d3d/rwd3d8.h vendored Normal file
View file

@ -0,0 +1,74 @@
namespace rw {
namespace d3d8 {
void registerPlatformPlugins(void);
struct InstanceData
{
uint32 minVert;
int32 stride;
int32 numVertices;
int32 numIndices;
Material *material;
uint32 vertexShader;
uint32 primType;
void *indexBuffer;
void *vertexBuffer;
uint32 baseIndex;
uint8 vertexAlpha;
uint8 managed;
uint8 remapped;
};
struct InstanceDataHeader : rw::InstanceDataHeader
{
uint16 serialNumber;
uint16 numMeshes;
InstanceData *inst;
};
uint32 makeFVFDeclaration(uint32 flags, int32 numTex);
int32 getStride(uint32 flags, int32 numTex);
void *destroyNativeData(void *object, int32, int32);
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);
class ObjPipeline : public rw::ObjPipeline
{
public:
void init(void);
static ObjPipeline *create(void);
void (*instanceCB)(Geometry *geo, InstanceData *header);
void (*uninstanceCB)(Geometry *geo, InstanceData *header);
void (*renderCB)(Atomic *atomic, InstanceDataHeader *header);
};
void defaultInstanceCB(Geometry *geo, InstanceData *header);
void defaultUninstanceCB(Geometry *geo, InstanceData *header);
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
ObjPipeline *makeDefaultPipeline(void);
// Skin plugin
void initSkin(void);
ObjPipeline *makeSkinPipeline(void);
// MatFX plugin
void initMatFX(void);
ObjPipeline *makeMatFXPipeline(void);
// Native Texture and Raster
Texture *readNativeTexture(Stream *stream);
void writeNativeTexture(Texture *tex, Stream *stream);
uint32 getSizeNativeTexture(Texture *tex);
}
}

112
vendor/librw/src/d3d/rwd3d9.h vendored Normal file
View file

@ -0,0 +1,112 @@
namespace rw {
namespace d3d9 {
void registerPlatformPlugins(void);
struct VertexElement
{
uint16 stream;
uint16 offset;
uint8 type;
uint8 method;
uint8 usage;
uint8 usageIndex;
};
struct VertexStream
{
void *vertexBuffer;
uint32 offset;
uint32 stride;
uint16 geometryFlags;
uint8 managed;
uint8 dynamicLock;
};
struct InstanceData
{
uint32 numIndex;
uint32 minVert;
Material *material;
bool32 vertexAlpha;
void *vertexShader;
uint32 baseIndex;
uint32 numVertices;
uint32 startIndex;
uint32 numPrimitives;
};
struct InstanceDataHeader : rw::InstanceDataHeader
{
uint32 serialNumber;
uint32 numMeshes;
void *indexBuffer;
uint32 primType;
VertexStream vertexStream[2];
bool32 useOffsets;
void *vertexDeclaration;
uint32 totalNumIndex;
uint32 totalNumVertex;
InstanceData *inst;
};
void *createVertexDeclaration(VertexElement *elements);
void destroyVertexDeclaration(void *delaration);
uint32 getDeclaration(void *declaration, VertexElement *elements);
void drawInst_simple(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst);
// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer
void drawInst_GSemu(d3d9::InstanceDataHeader *header, InstanceData *inst);
// This one switches between the above two depending on render state;
void drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst);
void *destroyNativeData(void *object, int32, int32);
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);
class ObjPipeline : public rw::ObjPipeline
{
public:
void init(void);
static ObjPipeline *create(void);
void (*instanceCB)(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header);
void (*renderCB)(Atomic *atomic, InstanceDataHeader *header);
};
void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
void defaultRenderCB_Fix(Atomic *atomic, InstanceDataHeader *header);
void defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header);
ObjPipeline *makeDefaultPipeline(void);
// Skin plugin
void initSkin(void);
void uploadSkinMatrices(Atomic *atomic);
void skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
void skinRenderCB(Atomic *atomic, InstanceDataHeader *header);
ObjPipeline *makeSkinPipeline(void);
// MatFX plugin
void initMatFX(void);
ObjPipeline *makeMatFXPipeline(void);
// Native Texture and Raster
Texture *readNativeTexture(Stream *stream);
void writeNativeTexture(Texture *tex, Stream *stream);
uint32 getSizeNativeTexture(Texture *tex);
}
}

81
vendor/librw/src/d3d/rwd3dimpl.h vendored Normal file
View file

@ -0,0 +1,81 @@
namespace rw {
namespace d3d {
#ifdef RW_D3D9
void openIm2D(void);
void closeIm2D(void);
void im2DRenderLine(void *vertices, int32 numVertices, int32 vert1, int32 vert2);
void im2DRenderTriangle(void *vertices, int32 numVertices, int32 vert1, int32 vert2, int32 vert3);
void im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices);
void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices);
void openIm3D(void);
void closeIm3D(void);
void im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags);
void im3DRenderPrimitive(PrimitiveType primType);
void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices);
void im3DEnd(void);
struct DisplayMode
{
D3DDISPLAYMODE mode;
uint32 flags;
};
struct D3d9Globals
{
HWND window;
IDirect3D9 *d3d9;
int numAdapters;
int adapter;
D3DCAPS9 caps;
DisplayMode *modes;
int numModes;
int currentMode;
DisplayMode startMode;
uint32 msLevel;
D3DPRESENT_PARAMETERS present;
IDirect3DSurface9 *defaultRenderTarget;
IDirect3DSurface9 *defaultDepthSurf;
int numTextures;
int numVertexShaders;
int numPixelShaders;
int numVertexBuffers;
int numIndexBuffers;
int numVertexDeclarations;
};
extern D3d9Globals d3d9Globals;
void addVidmemRaster(Raster *raster);
void removeVidmemRaster(Raster *raster);
void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); // NB: don't share this pointer
void removeDynamicVB(IDirect3DVertexBuffer9 **buf);
void addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf); // NB: don't share this pointer
void removeDynamicIB(IDirect3DIndexBuffer9 **buf);
int findFormatDepth(uint32 format);
void evictD3D9Raster(Raster *raster);
#endif
Raster *rasterCreate(Raster *raster);
uint8 *rasterLock(Raster *raster, int32 level, int32 lockMode);
void rasterUnlock(Raster *raster, int32 level);
int32 rasterNumLevels(Raster *raster);
bool32 imageFindRasterFormat(Image *img, int32 type,
int32 *width, int32 *height, int32 *depth, int32 *format);
bool32 rasterFromImage(Raster *raster, Image *image);
Image *rasterToImage(Raster *raster);
}
}

195
vendor/librw/src/d3d/rwxbox.h vendored Normal file
View file

@ -0,0 +1,195 @@
namespace rw {
namespace xbox {
void registerPlatformPlugins(void);
extern int v3dFormatMap[6];
extern int v2dFormatMap[6];
struct InstanceData
{
uint32 minVert;
int32 numVertices;
int32 numIndices;
void *indexBuffer;
Material *material;
uint32 vertexShader;
};
struct InstanceDataHeader : rw::InstanceDataHeader
{
int32 size;
uint16 serialNumber;
uint16 numMeshes;
uint32 primType;
int32 numVertices;
int32 stride;
void *vertexBuffer;
bool32 vertexAlpha;
InstanceData *begin;
InstanceData *end;
uint8 *data;
};
void *destroyNativeData(void *object, int32, int32);
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);
class ObjPipeline : public rw::ObjPipeline
{
public:
void init(void);
static ObjPipeline *create(void);
void (*instanceCB)(Geometry *geo, InstanceDataHeader *header);
void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header);
};
ObjPipeline *makeDefaultPipeline(void);
void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header);
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
// Skin plugin
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
int32 getSizeNativeSkin(void *object, int32 offset);
void initSkin(void);
ObjPipeline *makeSkinPipeline(void);
// MatFX plugin
void initMatFX(void);
ObjPipeline *makeMatFXPipeline(void);
// Vertex Format plugin
extern uint32 vertexFormatSizes[6];
uint32 *getVertexFmt(Geometry *g);
uint32 makeVertexFmt(int32 flags, uint32 numTexSets);
uint32 getVertexFmtStride(uint32 fmt);
void registerVertexFormatPlugin(void);
// Native Texture and Raster
struct XboxRaster
{
void *texture;
void *palette;
uint32 format;
uint32 bpp; // bytes per pixel
bool hasAlpha;
bool customFormat;
bool32 unknownFlag;
};
int32 getLevelSize(Raster *raster, int32 level);
extern int32 nativeRasterOffset;
void registerNativeRaster(void);
#define GETXBOXRASTEREXT(raster) PLUGINOFFSET(rw::xbox::XboxRaster, raster, rw::xbox::nativeRasterOffset)
Texture *readNativeTexture(Stream *stream);
void writeNativeTexture(Texture *tex, Stream *stream);
uint32 getSizeNativeTexture(Texture *tex);
enum {
D3DFMT_UNKNOWN = 0xFFFFFFFF,
/* Swizzled formats */
D3DFMT_A8R8G8B8 = 0x00000006,
D3DFMT_X8R8G8B8 = 0x00000007,
D3DFMT_R5G6B5 = 0x00000005,
D3DFMT_R6G5B5 = 0x00000027,
D3DFMT_X1R5G5B5 = 0x00000003,
D3DFMT_A1R5G5B5 = 0x00000002,
D3DFMT_A4R4G4B4 = 0x00000004,
D3DFMT_A8 = 0x00000019,
D3DFMT_A8B8G8R8 = 0x0000003A,
D3DFMT_B8G8R8A8 = 0x0000003B,
D3DFMT_R4G4B4A4 = 0x00000039,
D3DFMT_R5G5B5A1 = 0x00000038,
D3DFMT_R8G8B8A8 = 0x0000003C,
D3DFMT_R8B8 = 0x00000029,
D3DFMT_G8B8 = 0x00000028,
D3DFMT_P8 = 0x0000000B,
D3DFMT_L8 = 0x00000000,
D3DFMT_A8L8 = 0x0000001A,
D3DFMT_AL8 = 0x00000001,
D3DFMT_L16 = 0x00000032,
D3DFMT_V8U8 = 0x00000028,
D3DFMT_L6V5U5 = 0x00000027,
D3DFMT_X8L8V8U8 = 0x00000007,
D3DFMT_Q8W8V8U8 = 0x0000003A,
D3DFMT_V16U16 = 0x00000033,
D3DFMT_D16_LOCKABLE = 0x0000002C,
D3DFMT_D16 = 0x0000002C,
D3DFMT_D24S8 = 0x0000002A,
D3DFMT_F16 = 0x0000002D,
D3DFMT_F24S8 = 0x0000002B,
/* YUV formats */
D3DFMT_YUY2 = 0x00000024,
D3DFMT_UYVY = 0x00000025,
/* Compressed formats */
D3DFMT_DXT1 = 0x0000000C,
D3DFMT_DXT2 = 0x0000000E,
D3DFMT_DXT3 = 0x0000000E,
D3DFMT_DXT4 = 0x0000000F,
D3DFMT_DXT5 = 0x0000000F,
/* Linear formats */
D3DFMT_LIN_A1R5G5B5 = 0x00000010,
D3DFMT_LIN_A4R4G4B4 = 0x0000001D,
D3DFMT_LIN_A8 = 0x0000001F,
D3DFMT_LIN_A8B8G8R8 = 0x0000003F,
D3DFMT_LIN_A8R8G8B8 = 0x00000012,
D3DFMT_LIN_B8G8R8A8 = 0x00000040,
D3DFMT_LIN_G8B8 = 0x00000017,
D3DFMT_LIN_R4G4B4A4 = 0x0000003E,
D3DFMT_LIN_R5G5B5A1 = 0x0000003D,
D3DFMT_LIN_R5G6B5 = 0x00000011,
D3DFMT_LIN_R6G5B5 = 0x00000037,
D3DFMT_LIN_R8B8 = 0x00000016,
D3DFMT_LIN_R8G8B8A8 = 0x00000041,
D3DFMT_LIN_X1R5G5B5 = 0x0000001C,
D3DFMT_LIN_X8R8G8B8 = 0x0000001E,
D3DFMT_LIN_A8L8 = 0x00000020,
D3DFMT_LIN_AL8 = 0x0000001B,
D3DFMT_LIN_L16 = 0x00000035,
D3DFMT_LIN_L8 = 0x00000013,
D3DFMT_LIN_V16U16 = 0x00000036,
D3DFMT_LIN_V8U8 = 0x00000017,
D3DFMT_LIN_L6V5U5 = 0x00000037,
D3DFMT_LIN_X8L8V8U8 = 0x0000001E,
D3DFMT_LIN_Q8W8V8U8 = 0x00000012,
D3DFMT_LIN_D24S8 = 0x0000002E,
D3DFMT_LIN_F24S8 = 0x0000002F,
D3DFMT_LIN_D16 = 0x00000030,
D3DFMT_LIN_F16 = 0x00000031,
D3DFMT_VERTEXDATA = 100,
D3DFMT_INDEX16 = 101
};
}
}

11
vendor/librw/src/d3d/rwxboximpl.h vendored Normal file
View file

@ -0,0 +1,11 @@
namespace rw {
namespace xbox {
Raster *rasterCreate(Raster *raster);
uint8 *rasterLock(Raster *raster, int32 level, int32 lockMode);
void rasterUnlock(Raster*, int32);
int32 rasterNumLevels(Raster *raster);
Image *rasterToImage(Raster *raster);
}
}

View file

@ -0,0 +1,72 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T ps_2_0 /Fh default_PS.h default_PS.hlsl
//
//
// Parameters:
//
// float4 fogColor;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// fogColor c0 1
//
ps_2_0
dcl t0.xyz
dcl v0
add r0.xyz, v0, -c0
mad r0.xyz, t0.z, r0, c0
mov r0.w, v0.w
mov oC0, r0
// approximately 4 instruction slots used
#endif
const BYTE g_ps20_main[] =
{
0, 2, 255, 255, 254, 255,
34, 0, 67, 84, 65, 66,
28, 0, 0, 0, 83, 0,
0, 0, 0, 2, 255, 255,
1, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
76, 0, 0, 0, 48, 0,
0, 0, 2, 0, 0, 0,
1, 0, 2, 0, 60, 0,
0, 0, 0, 0, 0, 0,
102, 111, 103, 67, 111, 108,
111, 114, 0, 171, 171, 171,
1, 0, 3, 0, 1, 0,
4, 0, 1, 0, 0, 0,
0, 0, 0, 0, 112, 115,
95, 50, 95, 48, 0, 77,
105, 99, 114, 111, 115, 111,
102, 116, 32, 40, 82, 41,
32, 72, 76, 83, 76, 32,
83, 104, 97, 100, 101, 114,
32, 67, 111, 109, 112, 105,
108, 101, 114, 32, 57, 46,
50, 57, 46, 57, 53, 50,
46, 51, 49, 49, 49, 0,
31, 0, 0, 2, 0, 0,
0, 128, 0, 0, 7, 176,
31, 0, 0, 2, 0, 0,
0, 128, 0, 0, 15, 144,
2, 0, 0, 3, 0, 0,
7, 128, 0, 0, 228, 144,
0, 0, 228, 161, 4, 0,
0, 4, 0, 0, 7, 128,
0, 0, 170, 176, 0, 0,
228, 128, 0, 0, 228, 160,
1, 0, 0, 2, 0, 0,
8, 128, 0, 0, 255, 144,
1, 0, 0, 2, 0, 8,
15, 128, 0, 0, 228, 128,
255, 255, 0, 0
};

View file

@ -0,0 +1,19 @@
struct VS_out {
float4 Position : POSITION;
float3 TexCoord0 : TEXCOORD0;
float4 Color : COLOR0;
};
sampler2D tex0 : register(s0);
float4 fogColor : register(c0);
float4 main(VS_out input) : COLOR
{
float4 color = input.Color;
#ifdef TEX
color *= tex2D(tex0, input.TexCoord0.xy);
#endif
color.rgb = lerp(fogColor.rgb, color.rgb, input.TexCoord0.z);
return color;
}

View file

@ -0,0 +1,51 @@
#include "standardConstants.h"
struct VS_in
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD0;
float4 Prelight : COLOR0;
};
struct VS_out {
float4 Position : POSITION;
float3 TexCoord0 : TEXCOORD0; // also fog
float4 Color : COLOR0;
};
VS_out main(in VS_in input)
{
VS_out output;
output.Position = mul(combinedMat, input.Position);
float3 Vertex = mul(worldMat, input.Position).xyz;
float3 Normal = mul(normalMat, input.Normal);
output.TexCoord0.xy = input.TexCoord;
output.Color = input.Prelight;
output.Color.rgb += ambientLight.rgb * surfAmbient;
int i;
#ifdef DIRECTIONALS
for(i = 0; i < numDirLights; i++)
output.Color.xyz += DoDirLight(lights[i+firstDirLight], Normal)*surfDiffuse;
#endif
#ifdef POINTLIGHTS
for(i = 0; i < numPointLights; i++)
output.Color.xyz += DoPointLight(lights[i+firstPointLight], Vertex.xyz, Normal)*surfDiffuse;
#endif
#ifdef SPOTLIGHTS
for(i = 0; i < numSpotLights; i++)
output.Color.xyz += DoSpotLight(lights[i+firstSpotLight], Vertex.xyz, Normal)*surfDiffuse;
#endif
// PS2 clamps before material color
output.Color = clamp(output.Color, 0.0, 1.0);
output.Color *= matCol;
output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0);
return output;
}

View file

@ -0,0 +1,491 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh
// default_all_VS.h default_VS.hlsl
//
//
// Parameters:
//
// float4 ambientLight;
// float4x4 combinedMat;
// int4 firstLight;
// float4 fogData;
//
// struct
// {
// float4 color;
// float4 position;
// float4 direction;
//
// } lights[8];
//
// float4 matCol;
// float3x3 normalMat;
// int numDirLights;
// int numPointLights;
// int numSpotLights;
// float4 surfProps;
// float4x4 worldMat;
//
//
// Registers:
//
// Name Reg Size
// -------------- ----- ----
// numDirLights i0 1
// numPointLights i1 1
// numSpotLights i2 1
// combinedMat c0 4
// worldMat c4 4
// normalMat c8 3
// matCol c12 1
// surfProps c13 1
// fogData c14 1
// ambientLight c15 1
// firstLight c16 1
// lights c17 24
//
vs_2_0
def c11, 0, 3, 1, 0
dcl_position v0
dcl_normal v1
dcl_texcoord v2
dcl_color v3
mul r0, v0.y, c1
mad r0, c0, v0.x, r0
mad r0, c2, v0.z, r0
mad r0, c3, v0.w, r0
mov oPos, r0
mul r0.xyz, v0.y, c5
mad r0.xyz, c4, v0.x, r0
mad r0.xyz, c6, v0.z, r0
mad r0.xyz, c7, v0.w, r0
mul r1.xyz, v1.y, c9
mad r1.xyz, c8, v1.x, r1
mad r1.xyz, c10, v1.z, r1
mov r2.x, c13.x
mad r2.xyz, c15, r2.x, v3
mov r3.xyz, r2
mov r1.w, c11.x
rep i0
add r2.w, r1.w, c16.x
mul r2.w, r2.w, c11.y
mova a0.x, r2.w
dp3 r2.w, r1, -c19[a0.x]
max r2.w, r2.w, c11.x
mul r4.xyz, r2.w, c17[a0.x]
mad r3.xyz, r4, c13.z, r3
add r1.w, r1.w, c11.z
endrep
mov r2.xyz, r3
mov r1.w, c11.x
rep i1
add r2.w, r1.w, c16.y
mul r2.w, r2.w, c11.y
mova a0.x, r2.w
add r4.xyz, r0, -c18[a0.x]
dp3 r2.w, r4, r4
rsq r2.w, r2.w
mul r4.xyz, r2.w, r4
dp3 r3.w, r1, -r4
max r3.w, r3.w, c11.x
mul r4.xyz, r3.w, c17[a0.x]
rcp r2.w, r2.w
rcp r3.w, c17[a0.x].w
mad r2.w, r2.w, -r3.w, c11.z
max r2.w, r2.w, c11.x
mul r4.xyz, r2.w, r4
mad r2.xyz, r4, c13.z, r2
add r1.w, r1.w, c11.z
endrep
mov r3.xyz, r2
mov r1.w, c11.x
rep i2
add r2.w, r1.w, c16.z
mul r2.w, r2.w, c11.y
mova a0.x, r2.w
add r4.xyz, r0, -c18[a0.x]
dp3 r2.w, r4, r4
rsq r2.w, r2.w
mul r4.xyz, r2.w, r4
dp3 r4.w, r1, -r4
dp3 r4.x, r4, c19[a0.x]
max r4.y, r4.w, c11.x
mov r4.z, c11.z
add r4.xz, r4, c18[a0.x].w
rcp r4.z, r4.z
mul r4.x, r4.z, r4.x
slt r4.z, r4.x, c11.x
mad r4.y, r4.z, -r4.y, r4.y
max r4.x, r4.x, c19[a0.x].w
mul r4.x, r4.x, r4.y
mul r4.xyz, r4.x, c17[a0.x]
rcp r2.w, r2.w
rcp r4.w, c17[a0.x].w
mad r2.w, r2.w, -r4.w, c11.z
max r2.w, r2.w, c11.x
mul r4.xyz, r2.w, r4
mad r3.xyz, r4, c13.z, r3
add r1.w, r1.w, c11.z
endrep
mov r3.w, v3.w
max r1, r3, c11.x
min r1, r1, c11.z
mul oD0, r1, c12
add r0.x, r0.w, -c14.y
mul r0.x, r0.x, c14.z
max r0.x, r0.x, c14.w
min oT0.z, r0.x, c11.z
mov oT0.xy, v2
// approximately 95 instruction slots used
#endif
const BYTE g_vs20_main[] =
{
0, 2, 254, 255, 254, 255,
158, 0, 67, 84, 65, 66,
28, 0, 0, 0, 67, 2,
0, 0, 0, 2, 254, 255,
12, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
60, 2, 0, 0, 12, 1,
0, 0, 2, 0, 15, 0,
1, 0, 62, 0, 28, 1,
0, 0, 0, 0, 0, 0,
44, 1, 0, 0, 2, 0,
0, 0, 4, 0, 2, 0,
56, 1, 0, 0, 0, 0,
0, 0, 72, 1, 0, 0,
2, 0, 16, 0, 1, 0,
66, 0, 84, 1, 0, 0,
0, 0, 0, 0, 100, 1,
0, 0, 2, 0, 14, 0,
1, 0, 58, 0, 28, 1,
0, 0, 0, 0, 0, 0,
108, 1, 0, 0, 2, 0,
17, 0, 24, 0, 70, 0,
184, 1, 0, 0, 0, 0,
0, 0, 200, 1, 0, 0,
2, 0, 12, 0, 1, 0,
50, 0, 28, 1, 0, 0,
0, 0, 0, 0, 207, 1,
0, 0, 2, 0, 8, 0,
3, 0, 34, 0, 220, 1,
0, 0, 0, 0, 0, 0,
236, 1, 0, 0, 1, 0,
0, 0, 1, 0, 2, 0,
252, 1, 0, 0, 0, 0,
0, 0, 12, 2, 0, 0,
1, 0, 1, 0, 1, 0,
6, 0, 252, 1, 0, 0,
0, 0, 0, 0, 27, 2,
0, 0, 1, 0, 2, 0,
1, 0, 10, 0, 252, 1,
0, 0, 0, 0, 0, 0,
41, 2, 0, 0, 2, 0,
13, 0, 1, 0, 54, 0,
28, 1, 0, 0, 0, 0,
0, 0, 51, 2, 0, 0,
2, 0, 4, 0, 4, 0,
18, 0, 56, 1, 0, 0,
0, 0, 0, 0, 97, 109,
98, 105, 101, 110, 116, 76,
105, 103, 104, 116, 0, 171,
171, 171, 1, 0, 3, 0,
1, 0, 4, 0, 1, 0,
0, 0, 0, 0, 0, 0,
99, 111, 109, 98, 105, 110,
101, 100, 77, 97, 116, 0,
3, 0, 3, 0, 4, 0,
4, 0, 1, 0, 0, 0,
0, 0, 0, 0, 102, 105,
114, 115, 116, 76, 105, 103,
104, 116, 0, 171, 1, 0,
2, 0, 1, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 102, 111, 103, 68,
97, 116, 97, 0, 108, 105,
103, 104, 116, 115, 0, 99,
111, 108, 111, 114, 0, 171,
171, 171, 1, 0, 3, 0,
1, 0, 4, 0, 1, 0,
0, 0, 0, 0, 0, 0,
112, 111, 115, 105, 116, 105,
111, 110, 0, 100, 105, 114,
101, 99, 116, 105, 111, 110,
0, 171, 115, 1, 0, 0,
124, 1, 0, 0, 140, 1,
0, 0, 124, 1, 0, 0,
149, 1, 0, 0, 124, 1,
0, 0, 5, 0, 0, 0,
1, 0, 12, 0, 8, 0,
3, 0, 160, 1, 0, 0,
109, 97, 116, 67, 111, 108,
0, 110, 111, 114, 109, 97,
108, 77, 97, 116, 0, 171,
171, 171, 3, 0, 3, 0,
3, 0, 3, 0, 1, 0,
0, 0, 0, 0, 0, 0,
110, 117, 109, 68, 105, 114,
76, 105, 103, 104, 116, 115,
0, 171, 171, 171, 0, 0,
2, 0, 1, 0, 1, 0,
1, 0, 0, 0, 0, 0,
0, 0, 110, 117, 109, 80,
111, 105, 110, 116, 76, 105,
103, 104, 116, 115, 0, 110,
117, 109, 83, 112, 111, 116,
76, 105, 103, 104, 116, 115,
0, 115, 117, 114, 102, 80,
114, 111, 112, 115, 0, 119,
111, 114, 108, 100, 77, 97,
116, 0, 118, 115, 95, 50,
95, 48, 0, 77, 105, 99,
114, 111, 115, 111, 102, 116,
32, 40, 82, 41, 32, 72,
76, 83, 76, 32, 83, 104,
97, 100, 101, 114, 32, 67,
111, 109, 112, 105, 108, 101,
114, 32, 57, 46, 50, 57,
46, 57, 53, 50, 46, 51,
49, 49, 49, 0, 81, 0,
0, 5, 11, 0, 15, 160,
0, 0, 0, 0, 0, 0,
64, 64, 0, 0, 128, 63,
0, 0, 0, 0, 31, 0,
0, 2, 0, 0, 0, 128,
0, 0, 15, 144, 31, 0,
0, 2, 3, 0, 0, 128,
1, 0, 15, 144, 31, 0,
0, 2, 5, 0, 0, 128,
2, 0, 15, 144, 31, 0,
0, 2, 10, 0, 0, 128,
3, 0, 15, 144, 5, 0,
0, 3, 0, 0, 15, 128,
0, 0, 85, 144, 1, 0,
228, 160, 4, 0, 0, 4,
0, 0, 15, 128, 0, 0,
228, 160, 0, 0, 0, 144,
0, 0, 228, 128, 4, 0,
0, 4, 0, 0, 15, 128,
2, 0, 228, 160, 0, 0,
170, 144, 0, 0, 228, 128,
4, 0, 0, 4, 0, 0,
15, 128, 3, 0, 228, 160,
0, 0, 255, 144, 0, 0,
228, 128, 1, 0, 0, 2,
0, 0, 15, 192, 0, 0,
228, 128, 5, 0, 0, 3,
0, 0, 7, 128, 0, 0,
85, 144, 5, 0, 228, 160,
4, 0, 0, 4, 0, 0,
7, 128, 4, 0, 228, 160,
0, 0, 0, 144, 0, 0,
228, 128, 4, 0, 0, 4,
0, 0, 7, 128, 6, 0,
228, 160, 0, 0, 170, 144,
0, 0, 228, 128, 4, 0,
0, 4, 0, 0, 7, 128,
7, 0, 228, 160, 0, 0,
255, 144, 0, 0, 228, 128,
5, 0, 0, 3, 1, 0,
7, 128, 1, 0, 85, 144,
9, 0, 228, 160, 4, 0,
0, 4, 1, 0, 7, 128,
8, 0, 228, 160, 1, 0,
0, 144, 1, 0, 228, 128,
4, 0, 0, 4, 1, 0,
7, 128, 10, 0, 228, 160,
1, 0, 170, 144, 1, 0,
228, 128, 1, 0, 0, 2,
2, 0, 1, 128, 13, 0,
0, 160, 4, 0, 0, 4,
2, 0, 7, 128, 15, 0,
228, 160, 2, 0, 0, 128,
3, 0, 228, 144, 1, 0,
0, 2, 3, 0, 7, 128,
2, 0, 228, 128, 1, 0,
0, 2, 1, 0, 8, 128,
11, 0, 0, 160, 38, 0,
0, 1, 0, 0, 228, 240,
2, 0, 0, 3, 2, 0,
8, 128, 1, 0, 255, 128,
16, 0, 0, 160, 5, 0,
0, 3, 2, 0, 8, 128,
2, 0, 255, 128, 11, 0,
85, 160, 46, 0, 0, 2,
0, 0, 1, 176, 2, 0,
255, 128, 8, 0, 0, 4,
2, 0, 8, 128, 1, 0,
228, 128, 19, 32, 228, 161,
0, 0, 0, 176, 11, 0,
0, 3, 2, 0, 8, 128,
2, 0, 255, 128, 11, 0,
0, 160, 5, 0, 0, 4,
4, 0, 7, 128, 2, 0,
255, 128, 17, 32, 228, 160,
0, 0, 0, 176, 4, 0,
0, 4, 3, 0, 7, 128,
4, 0, 228, 128, 13, 0,
170, 160, 3, 0, 228, 128,
2, 0, 0, 3, 1, 0,
8, 128, 1, 0, 255, 128,
11, 0, 170, 160, 39, 0,
0, 0, 1, 0, 0, 2,
2, 0, 7, 128, 3, 0,
228, 128, 1, 0, 0, 2,
1, 0, 8, 128, 11, 0,
0, 160, 38, 0, 0, 1,
1, 0, 228, 240, 2, 0,
0, 3, 2, 0, 8, 128,
1, 0, 255, 128, 16, 0,
85, 160, 5, 0, 0, 3,
2, 0, 8, 128, 2, 0,
255, 128, 11, 0, 85, 160,
46, 0, 0, 2, 0, 0,
1, 176, 2, 0, 255, 128,
2, 0, 0, 4, 4, 0,
7, 128, 0, 0, 228, 128,
18, 32, 228, 161, 0, 0,
0, 176, 8, 0, 0, 3,
2, 0, 8, 128, 4, 0,
228, 128, 4, 0, 228, 128,
7, 0, 0, 2, 2, 0,
8, 128, 2, 0, 255, 128,
5, 0, 0, 3, 4, 0,
7, 128, 2, 0, 255, 128,
4, 0, 228, 128, 8, 0,
0, 3, 3, 0, 8, 128,
1, 0, 228, 128, 4, 0,
228, 129, 11, 0, 0, 3,
3, 0, 8, 128, 3, 0,
255, 128, 11, 0, 0, 160,
5, 0, 0, 4, 4, 0,
7, 128, 3, 0, 255, 128,
17, 32, 228, 160, 0, 0,
0, 176, 6, 0, 0, 2,
2, 0, 8, 128, 2, 0,
255, 128, 6, 0, 0, 3,
3, 0, 8, 128, 17, 32,
255, 160, 0, 0, 0, 176,
4, 0, 0, 4, 2, 0,
8, 128, 2, 0, 255, 128,
3, 0, 255, 129, 11, 0,
170, 160, 11, 0, 0, 3,
2, 0, 8, 128, 2, 0,
255, 128, 11, 0, 0, 160,
5, 0, 0, 3, 4, 0,
7, 128, 2, 0, 255, 128,
4, 0, 228, 128, 4, 0,
0, 4, 2, 0, 7, 128,
4, 0, 228, 128, 13, 0,
170, 160, 2, 0, 228, 128,
2, 0, 0, 3, 1, 0,
8, 128, 1, 0, 255, 128,
11, 0, 170, 160, 39, 0,
0, 0, 1, 0, 0, 2,
3, 0, 7, 128, 2, 0,
228, 128, 1, 0, 0, 2,
1, 0, 8, 128, 11, 0,
0, 160, 38, 0, 0, 1,
2, 0, 228, 240, 2, 0,
0, 3, 2, 0, 8, 128,
1, 0, 255, 128, 16, 0,
170, 160, 5, 0, 0, 3,
2, 0, 8, 128, 2, 0,
255, 128, 11, 0, 85, 160,
46, 0, 0, 2, 0, 0,
1, 176, 2, 0, 255, 128,
2, 0, 0, 4, 4, 0,
7, 128, 0, 0, 228, 128,
18, 32, 228, 161, 0, 0,
0, 176, 8, 0, 0, 3,
2, 0, 8, 128, 4, 0,
228, 128, 4, 0, 228, 128,
7, 0, 0, 2, 2, 0,
8, 128, 2, 0, 255, 128,
5, 0, 0, 3, 4, 0,
7, 128, 2, 0, 255, 128,
4, 0, 228, 128, 8, 0,
0, 3, 4, 0, 8, 128,
1, 0, 228, 128, 4, 0,
228, 129, 8, 0, 0, 4,
4, 0, 1, 128, 4, 0,
228, 128, 19, 32, 228, 160,
0, 0, 0, 176, 11, 0,
0, 3, 4, 0, 2, 128,
4, 0, 255, 128, 11, 0,
0, 160, 1, 0, 0, 2,
4, 0, 4, 128, 11, 0,
170, 160, 2, 0, 0, 4,
4, 0, 5, 128, 4, 0,
228, 128, 18, 32, 255, 160,
0, 0, 0, 176, 6, 0,
0, 2, 4, 0, 4, 128,
4, 0, 170, 128, 5, 0,
0, 3, 4, 0, 1, 128,
4, 0, 170, 128, 4, 0,
0, 128, 12, 0, 0, 3,
4, 0, 4, 128, 4, 0,
0, 128, 11, 0, 0, 160,
4, 0, 0, 4, 4, 0,
2, 128, 4, 0, 170, 128,
4, 0, 85, 129, 4, 0,
85, 128, 11, 0, 0, 4,
4, 0, 1, 128, 4, 0,
0, 128, 19, 32, 255, 160,
0, 0, 0, 176, 5, 0,
0, 3, 4, 0, 1, 128,
4, 0, 0, 128, 4, 0,
85, 128, 5, 0, 0, 4,
4, 0, 7, 128, 4, 0,
0, 128, 17, 32, 228, 160,
0, 0, 0, 176, 6, 0,
0, 2, 2, 0, 8, 128,
2, 0, 255, 128, 6, 0,
0, 3, 4, 0, 8, 128,
17, 32, 255, 160, 0, 0,
0, 176, 4, 0, 0, 4,
2, 0, 8, 128, 2, 0,
255, 128, 4, 0, 255, 129,
11, 0, 170, 160, 11, 0,
0, 3, 2, 0, 8, 128,
2, 0, 255, 128, 11, 0,
0, 160, 5, 0, 0, 3,
4, 0, 7, 128, 2, 0,
255, 128, 4, 0, 228, 128,
4, 0, 0, 4, 3, 0,
7, 128, 4, 0, 228, 128,
13, 0, 170, 160, 3, 0,
228, 128, 2, 0, 0, 3,
1, 0, 8, 128, 1, 0,
255, 128, 11, 0, 170, 160,
39, 0, 0, 0, 1, 0,
0, 2, 3, 0, 8, 128,
3, 0, 255, 144, 11, 0,
0, 3, 1, 0, 15, 128,
3, 0, 228, 128, 11, 0,
0, 160, 10, 0, 0, 3,
1, 0, 15, 128, 1, 0,
228, 128, 11, 0, 170, 160,
5, 0, 0, 3, 0, 0,
15, 208, 1, 0, 228, 128,
12, 0, 228, 160, 2, 0,
0, 3, 0, 0, 1, 128,
0, 0, 255, 128, 14, 0,
85, 161, 5, 0, 0, 3,
0, 0, 1, 128, 0, 0,
0, 128, 14, 0, 170, 160,
11, 0, 0, 3, 0, 0,
1, 128, 0, 0, 0, 128,
14, 0, 255, 160, 10, 0,
0, 3, 0, 0, 4, 224,
0, 0, 0, 128, 11, 0,
170, 160, 1, 0, 0, 2,
0, 0, 3, 224, 2, 0,
228, 144, 255, 255, 0, 0
};

View file

@ -0,0 +1,156 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T vs_2_0 /Fh default_amb_VS.h default_VS.hlsl
//
//
// Parameters:
//
// float4 ambientLight;
// float4x4 combinedMat;
// float4 fogData;
// float4 matCol;
// float4 surfProps;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// combinedMat c0 4
// matCol c12 1
// surfProps c13 1
// fogData c14 1
// ambientLight c15 1
//
vs_2_0
def c4, 0, 1, 0, 0
dcl_position v0
dcl_texcoord v1
dcl_color v2
mov r0.xyz, c15
mad r0.xyz, r0, c13.x, v2
mov r0.w, v2.w
max r0, r0, c4.x
min r0, r0, c4.y
mul oD0, r0, c12
mul r0, v0.y, c1
mad r0, c0, v0.x, r0
mad r0, c2, v0.z, r0
mad r0, c3, v0.w, r0
add r1.x, r0.w, -c14.y
mov oPos, r0
mul r0.x, r1.x, c14.z
max r0.x, r0.x, c14.w
min oT0.z, r0.x, c4.y
mov oT0.xy, v1
// approximately 16 instruction slots used
#endif
const BYTE g_vs20_main[] =
{
0, 2, 254, 255, 254, 255,
69, 0, 67, 84, 65, 66,
28, 0, 0, 0, 220, 0,
0, 0, 0, 2, 254, 255,
5, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
213, 0, 0, 0, 128, 0,
0, 0, 2, 0, 15, 0,
1, 0, 62, 0, 144, 0,
0, 0, 0, 0, 0, 0,
160, 0, 0, 0, 2, 0,
0, 0, 4, 0, 2, 0,
172, 0, 0, 0, 0, 0,
0, 0, 188, 0, 0, 0,
2, 0, 14, 0, 1, 0,
58, 0, 144, 0, 0, 0,
0, 0, 0, 0, 196, 0,
0, 0, 2, 0, 12, 0,
1, 0, 50, 0, 144, 0,
0, 0, 0, 0, 0, 0,
203, 0, 0, 0, 2, 0,
13, 0, 1, 0, 54, 0,
144, 0, 0, 0, 0, 0,
0, 0, 97, 109, 98, 105,
101, 110, 116, 76, 105, 103,
104, 116, 0, 171, 171, 171,
1, 0, 3, 0, 1, 0,
4, 0, 1, 0, 0, 0,
0, 0, 0, 0, 99, 111,
109, 98, 105, 110, 101, 100,
77, 97, 116, 0, 3, 0,
3, 0, 4, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 102, 111, 103, 68,
97, 116, 97, 0, 109, 97,
116, 67, 111, 108, 0, 115,
117, 114, 102, 80, 114, 111,
112, 115, 0, 118, 115, 95,
50, 95, 48, 0, 77, 105,
99, 114, 111, 115, 111, 102,
116, 32, 40, 82, 41, 32,
72, 76, 83, 76, 32, 83,
104, 97, 100, 101, 114, 32,
67, 111, 109, 112, 105, 108,
101, 114, 32, 57, 46, 50,
57, 46, 57, 53, 50, 46,
51, 49, 49, 49, 0, 171,
171, 171, 81, 0, 0, 5,
4, 0, 15, 160, 0, 0,
0, 0, 0, 0, 128, 63,
0, 0, 0, 0, 0, 0,
0, 0, 31, 0, 0, 2,
0, 0, 0, 128, 0, 0,
15, 144, 31, 0, 0, 2,
5, 0, 0, 128, 1, 0,
15, 144, 31, 0, 0, 2,
10, 0, 0, 128, 2, 0,
15, 144, 1, 0, 0, 2,
0, 0, 7, 128, 15, 0,
228, 160, 4, 0, 0, 4,
0, 0, 7, 128, 0, 0,
228, 128, 13, 0, 0, 160,
2, 0, 228, 144, 1, 0,
0, 2, 0, 0, 8, 128,
2, 0, 255, 144, 11, 0,
0, 3, 0, 0, 15, 128,
0, 0, 228, 128, 4, 0,
0, 160, 10, 0, 0, 3,
0, 0, 15, 128, 0, 0,
228, 128, 4, 0, 85, 160,
5, 0, 0, 3, 0, 0,
15, 208, 0, 0, 228, 128,
12, 0, 228, 160, 5, 0,
0, 3, 0, 0, 15, 128,
0, 0, 85, 144, 1, 0,
228, 160, 4, 0, 0, 4,
0, 0, 15, 128, 0, 0,
228, 160, 0, 0, 0, 144,
0, 0, 228, 128, 4, 0,
0, 4, 0, 0, 15, 128,
2, 0, 228, 160, 0, 0,
170, 144, 0, 0, 228, 128,
4, 0, 0, 4, 0, 0,
15, 128, 3, 0, 228, 160,
0, 0, 255, 144, 0, 0,
228, 128, 2, 0, 0, 3,
1, 0, 1, 128, 0, 0,
255, 128, 14, 0, 85, 161,
1, 0, 0, 2, 0, 0,
15, 192, 0, 0, 228, 128,
5, 0, 0, 3, 0, 0,
1, 128, 1, 0, 0, 128,
14, 0, 170, 160, 11, 0,
0, 3, 0, 0, 1, 128,
0, 0, 0, 128, 14, 0,
255, 160, 10, 0, 0, 3,
0, 0, 4, 224, 0, 0,
0, 128, 4, 0, 85, 160,
1, 0, 0, 2, 0, 0,
3, 224, 1, 0, 228, 144,
255, 255, 0, 0
};

View file

@ -0,0 +1,272 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T vs_2_0 /DDIRECTIONALS /Fh default_amb_dir_VS.h
// default_VS.hlsl
//
//
// Parameters:
//
// float4 ambientLight;
// float4x4 combinedMat;
// int4 firstLight;
// float4 fogData;
//
// struct
// {
// float4 color;
// float4 position;
// float4 direction;
//
// } lights[8];
//
// float4 matCol;
// float3x3 normalMat;
// int numDirLights;
// float4 surfProps;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// numDirLights i0 1
// combinedMat c0 4
// normalMat c8 3
// matCol c12 1
// surfProps c13 1
// fogData c14 1
// ambientLight c15 1
// firstLight c16 1
// lights c17 24
//
vs_2_0
def c4, 0, 3, 1, 0
dcl_position v0
dcl_normal v1
dcl_texcoord v2
dcl_color v3
mul r0, v0.y, c1
mad r0, c0, v0.x, r0
mad r0, c2, v0.z, r0
mad r0, c3, v0.w, r0
mov oPos, r0
mul r0.xyz, v1.y, c9
mad r0.xyz, c8, v1.x, r0
mad r0.xyz, c10, v1.z, r0
mov r1.x, c13.x
mad r1.xyz, c15, r1.x, v3
mov r2.xyz, r1
mov r1.w, c4.x
rep i0
add r3.x, r1.w, c16.x
mul r3.x, r3.x, c4.y
mova a0.x, r3.x
dp3 r3.x, r0, -c19[a0.x]
max r3.x, r3.x, c4.x
mul r3.xyz, r3.x, c17[a0.x]
mad r2.xyz, r3, c13.z, r2
add r1.w, r1.w, c4.z
endrep
mov r2.w, v3.w
max r1, r2, c4.x
min r1, r1, c4.z
mul oD0, r1, c12
add r0.x, r0.w, -c14.y
mul r0.x, r0.x, c14.z
max r0.x, r0.x, c14.w
min oT0.z, r0.x, c4.z
mov oT0.xy, v2
// approximately 34 instruction slots used
#endif
const BYTE g_vs20_main[] =
{
0, 2, 254, 255, 254, 255,
134, 0, 67, 84, 65, 66,
28, 0, 0, 0, 225, 1,
0, 0, 0, 2, 254, 255,
9, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
218, 1, 0, 0, 208, 0,
0, 0, 2, 0, 15, 0,
1, 0, 62, 0, 224, 0,
0, 0, 0, 0, 0, 0,
240, 0, 0, 0, 2, 0,
0, 0, 4, 0, 2, 0,
252, 0, 0, 0, 0, 0,
0, 0, 12, 1, 0, 0,
2, 0, 16, 0, 1, 0,
66, 0, 24, 1, 0, 0,
0, 0, 0, 0, 40, 1,
0, 0, 2, 0, 14, 0,
1, 0, 58, 0, 224, 0,
0, 0, 0, 0, 0, 0,
48, 1, 0, 0, 2, 0,
17, 0, 24, 0, 70, 0,
124, 1, 0, 0, 0, 0,
0, 0, 140, 1, 0, 0,
2, 0, 12, 0, 1, 0,
50, 0, 224, 0, 0, 0,
0, 0, 0, 0, 147, 1,
0, 0, 2, 0, 8, 0,
3, 0, 34, 0, 160, 1,
0, 0, 0, 0, 0, 0,
176, 1, 0, 0, 1, 0,
0, 0, 1, 0, 2, 0,
192, 1, 0, 0, 0, 0,
0, 0, 208, 1, 0, 0,
2, 0, 13, 0, 1, 0,
54, 0, 224, 0, 0, 0,
0, 0, 0, 0, 97, 109,
98, 105, 101, 110, 116, 76,
105, 103, 104, 116, 0, 171,
171, 171, 1, 0, 3, 0,
1, 0, 4, 0, 1, 0,
0, 0, 0, 0, 0, 0,
99, 111, 109, 98, 105, 110,
101, 100, 77, 97, 116, 0,
3, 0, 3, 0, 4, 0,
4, 0, 1, 0, 0, 0,
0, 0, 0, 0, 102, 105,
114, 115, 116, 76, 105, 103,
104, 116, 0, 171, 1, 0,
2, 0, 1, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 102, 111, 103, 68,
97, 116, 97, 0, 108, 105,
103, 104, 116, 115, 0, 99,
111, 108, 111, 114, 0, 171,
171, 171, 1, 0, 3, 0,
1, 0, 4, 0, 1, 0,
0, 0, 0, 0, 0, 0,
112, 111, 115, 105, 116, 105,
111, 110, 0, 100, 105, 114,
101, 99, 116, 105, 111, 110,
0, 171, 55, 1, 0, 0,
64, 1, 0, 0, 80, 1,
0, 0, 64, 1, 0, 0,
89, 1, 0, 0, 64, 1,
0, 0, 5, 0, 0, 0,
1, 0, 12, 0, 8, 0,
3, 0, 100, 1, 0, 0,
109, 97, 116, 67, 111, 108,
0, 110, 111, 114, 109, 97,
108, 77, 97, 116, 0, 171,
171, 171, 3, 0, 3, 0,
3, 0, 3, 0, 1, 0,
0, 0, 0, 0, 0, 0,
110, 117, 109, 68, 105, 114,
76, 105, 103, 104, 116, 115,
0, 171, 171, 171, 0, 0,
2, 0, 1, 0, 1, 0,
1, 0, 0, 0, 0, 0,
0, 0, 115, 117, 114, 102,
80, 114, 111, 112, 115, 0,
118, 115, 95, 50, 95, 48,
0, 77, 105, 99, 114, 111,
115, 111, 102, 116, 32, 40,
82, 41, 32, 72, 76, 83,
76, 32, 83, 104, 97, 100,
101, 114, 32, 67, 111, 109,
112, 105, 108, 101, 114, 32,
57, 46, 50, 57, 46, 57,
53, 50, 46, 51, 49, 49,
49, 0, 171, 171, 81, 0,
0, 5, 4, 0, 15, 160,
0, 0, 0, 0, 0, 0,
64, 64, 0, 0, 128, 63,
0, 0, 0, 0, 31, 0,
0, 2, 0, 0, 0, 128,
0, 0, 15, 144, 31, 0,
0, 2, 3, 0, 0, 128,
1, 0, 15, 144, 31, 0,
0, 2, 5, 0, 0, 128,
2, 0, 15, 144, 31, 0,
0, 2, 10, 0, 0, 128,
3, 0, 15, 144, 5, 0,
0, 3, 0, 0, 15, 128,
0, 0, 85, 144, 1, 0,
228, 160, 4, 0, 0, 4,
0, 0, 15, 128, 0, 0,
228, 160, 0, 0, 0, 144,
0, 0, 228, 128, 4, 0,
0, 4, 0, 0, 15, 128,
2, 0, 228, 160, 0, 0,
170, 144, 0, 0, 228, 128,
4, 0, 0, 4, 0, 0,
15, 128, 3, 0, 228, 160,
0, 0, 255, 144, 0, 0,
228, 128, 1, 0, 0, 2,
0, 0, 15, 192, 0, 0,
228, 128, 5, 0, 0, 3,
0, 0, 7, 128, 1, 0,
85, 144, 9, 0, 228, 160,
4, 0, 0, 4, 0, 0,
7, 128, 8, 0, 228, 160,
1, 0, 0, 144, 0, 0,
228, 128, 4, 0, 0, 4,
0, 0, 7, 128, 10, 0,
228, 160, 1, 0, 170, 144,
0, 0, 228, 128, 1, 0,
0, 2, 1, 0, 1, 128,
13, 0, 0, 160, 4, 0,
0, 4, 1, 0, 7, 128,
15, 0, 228, 160, 1, 0,
0, 128, 3, 0, 228, 144,
1, 0, 0, 2, 2, 0,
7, 128, 1, 0, 228, 128,
1, 0, 0, 2, 1, 0,
8, 128, 4, 0, 0, 160,
38, 0, 0, 1, 0, 0,
228, 240, 2, 0, 0, 3,
3, 0, 1, 128, 1, 0,
255, 128, 16, 0, 0, 160,
5, 0, 0, 3, 3, 0,
1, 128, 3, 0, 0, 128,
4, 0, 85, 160, 46, 0,
0, 2, 0, 0, 1, 176,
3, 0, 0, 128, 8, 0,
0, 4, 3, 0, 1, 128,
0, 0, 228, 128, 19, 32,
228, 161, 0, 0, 0, 176,
11, 0, 0, 3, 3, 0,
1, 128, 3, 0, 0, 128,
4, 0, 0, 160, 5, 0,
0, 4, 3, 0, 7, 128,
3, 0, 0, 128, 17, 32,
228, 160, 0, 0, 0, 176,
4, 0, 0, 4, 2, 0,
7, 128, 3, 0, 228, 128,
13, 0, 170, 160, 2, 0,
228, 128, 2, 0, 0, 3,
1, 0, 8, 128, 1, 0,
255, 128, 4, 0, 170, 160,
39, 0, 0, 0, 1, 0,
0, 2, 2, 0, 8, 128,
3, 0, 255, 144, 11, 0,
0, 3, 1, 0, 15, 128,
2, 0, 228, 128, 4, 0,
0, 160, 10, 0, 0, 3,
1, 0, 15, 128, 1, 0,
228, 128, 4, 0, 170, 160,
5, 0, 0, 3, 0, 0,
15, 208, 1, 0, 228, 128,
12, 0, 228, 160, 2, 0,
0, 3, 0, 0, 1, 128,
0, 0, 255, 128, 14, 0,
85, 161, 5, 0, 0, 3,
0, 0, 1, 128, 0, 0,
0, 128, 14, 0, 170, 160,
11, 0, 0, 3, 0, 0,
1, 128, 0, 0, 0, 128,
14, 0, 255, 160, 10, 0,
0, 3, 0, 0, 4, 224,
0, 0, 0, 128, 4, 0,
170, 160, 1, 0, 0, 2,
0, 0, 3, 224, 2, 0,
228, 144, 255, 255, 0, 0
};

View file

@ -0,0 +1,89 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T ps_2_0 /DTEX /Fh default_tex_PS.h default_PS.hlsl
//
//
// Parameters:
//
// float4 fogColor;
// sampler2D tex0;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// fogColor c0 1
// tex0 s0 1
//
ps_2_0
dcl t0.xyz
dcl v0
dcl_2d s0
texld r0, t0, s0
mad r0.xyz, v0, r0, -c0
mul r1.w, r0.w, v0.w
mad r1.xyz, t0.z, r0, c0
mov oC0, r1
// approximately 5 instruction slots used (1 texture, 4 arithmetic)
#endif
const BYTE g_ps20_main[] =
{
0, 2, 255, 255, 254, 255,
45, 0, 67, 84, 65, 66,
28, 0, 0, 0, 127, 0,
0, 0, 0, 2, 255, 255,
2, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
120, 0, 0, 0, 68, 0,
0, 0, 2, 0, 0, 0,
1, 0, 2, 0, 80, 0,
0, 0, 0, 0, 0, 0,
96, 0, 0, 0, 3, 0,
0, 0, 1, 0, 2, 0,
104, 0, 0, 0, 0, 0,
0, 0, 102, 111, 103, 67,
111, 108, 111, 114, 0, 171,
171, 171, 1, 0, 3, 0,
1, 0, 4, 0, 1, 0,
0, 0, 0, 0, 0, 0,
116, 101, 120, 48, 0, 171,
171, 171, 4, 0, 12, 0,
1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0,
112, 115, 95, 50, 95, 48,
0, 77, 105, 99, 114, 111,
115, 111, 102, 116, 32, 40,
82, 41, 32, 72, 76, 83,
76, 32, 83, 104, 97, 100,
101, 114, 32, 67, 111, 109,
112, 105, 108, 101, 114, 32,
57, 46, 50, 57, 46, 57,
53, 50, 46, 51, 49, 49,
49, 0, 31, 0, 0, 2,
0, 0, 0, 128, 0, 0,
7, 176, 31, 0, 0, 2,
0, 0, 0, 128, 0, 0,
15, 144, 31, 0, 0, 2,
0, 0, 0, 144, 0, 8,
15, 160, 66, 0, 0, 3,
0, 0, 15, 128, 0, 0,
228, 176, 0, 8, 228, 160,
4, 0, 0, 4, 0, 0,
7, 128, 0, 0, 228, 144,
0, 0, 228, 128, 0, 0,
228, 161, 5, 0, 0, 3,
1, 0, 8, 128, 0, 0,
255, 128, 0, 0, 255, 144,
4, 0, 0, 4, 1, 0,
7, 128, 0, 0, 170, 176,
0, 0, 228, 128, 0, 0,
228, 160, 1, 0, 0, 2,
0, 8, 15, 128, 1, 0,
228, 128, 255, 255, 0, 0
};

72
vendor/librw/src/d3d/shaders/im2d_PS.h vendored Normal file
View file

@ -0,0 +1,72 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T ps_2_0 /Fh im2d_PS.h im2d_PS.hlsl
//
//
// Parameters:
//
// float4 fogColor;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// fogColor c0 1
//
ps_2_0
dcl t0.xyz
dcl v0
add r0.xyz, v0, -c0
mad r0.xyz, t0.z, r0, c0
mov r0.w, v0.w
mov oC0, r0
// approximately 4 instruction slots used
#endif
const BYTE g_ps20_main[] =
{
0, 2, 255, 255, 254, 255,
34, 0, 67, 84, 65, 66,
28, 0, 0, 0, 83, 0,
0, 0, 0, 2, 255, 255,
1, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
76, 0, 0, 0, 48, 0,
0, 0, 2, 0, 0, 0,
1, 0, 2, 0, 60, 0,
0, 0, 0, 0, 0, 0,
102, 111, 103, 67, 111, 108,
111, 114, 0, 171, 171, 171,
1, 0, 3, 0, 1, 0,
4, 0, 1, 0, 0, 0,
0, 0, 0, 0, 112, 115,
95, 50, 95, 48, 0, 77,
105, 99, 114, 111, 115, 111,
102, 116, 32, 40, 82, 41,
32, 72, 76, 83, 76, 32,
83, 104, 97, 100, 101, 114,
32, 67, 111, 109, 112, 105,
108, 101, 114, 32, 57, 46,
50, 57, 46, 57, 53, 50,
46, 51, 49, 49, 49, 0,
31, 0, 0, 2, 0, 0,
0, 128, 0, 0, 7, 176,
31, 0, 0, 2, 0, 0,
0, 128, 0, 0, 15, 144,
2, 0, 0, 3, 0, 0,
7, 128, 0, 0, 228, 144,
0, 0, 228, 161, 4, 0,
0, 4, 0, 0, 7, 128,
0, 0, 170, 176, 0, 0,
228, 128, 0, 0, 228, 160,
1, 0, 0, 2, 0, 0,
8, 128, 0, 0, 255, 144,
1, 0, 0, 2, 0, 8,
15, 128, 0, 0, 228, 128,
255, 255, 0, 0
};

View file

@ -0,0 +1,19 @@
struct VS_out {
float4 Position : POSITION;
float3 TexCoord0 : TEXCOORD0;
float4 Color : COLOR0;
};
sampler2D tex0 : register(s0);
float4 fogColor : register(c0);
float4 main(VS_out input) : COLOR
{
float4 color = input.Color;
#ifdef TEX
color *= tex2D(tex0, input.TexCoord0.xy);
#endif
color.rgb = lerp(fogColor.rgb, color.rgb, input.TexCoord0.z);
return color;
}

107
vendor/librw/src/d3d/shaders/im2d_VS.h vendored Normal file
View file

@ -0,0 +1,107 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T vs_2_0 /Fh im2d_VS.h im2d_VS.hlsl
//
//
// Parameters:
//
// float4 fogData;
// float4 xform;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// fogData c14 1
// xform c41 1
//
vs_2_0
def c0, 1, 0, 0, 0
dcl_position v0
dcl_texcoord v1
dcl_color v2
add r0.x, v0.w, -c14.y
mul r0.x, r0.x, c14.z
max r0.x, r0.x, c14.w
min oT0.z, r0.x, c0.x
mad r0.xy, v0, c41, c41.zwzw
mov r0.z, v0.z
mul oPos.xyz, r0, v0.w
mov oPos.w, v0.w
mov oT0.xy, v1
mov oD0, v2
// approximately 10 instruction slots used
#endif
const BYTE g_vs20_main[] =
{
0, 2, 254, 255, 254, 255,
40, 0, 67, 84, 65, 66,
28, 0, 0, 0, 105, 0,
0, 0, 0, 2, 254, 255,
2, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
98, 0, 0, 0, 68, 0,
0, 0, 2, 0, 14, 0,
1, 0, 58, 0, 76, 0,
0, 0, 0, 0, 0, 0,
92, 0, 0, 0, 2, 0,
41, 0, 1, 0, 166, 0,
76, 0, 0, 0, 0, 0,
0, 0, 102, 111, 103, 68,
97, 116, 97, 0, 1, 0,
3, 0, 1, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 120, 102, 111, 114,
109, 0, 118, 115, 95, 50,
95, 48, 0, 77, 105, 99,
114, 111, 115, 111, 102, 116,
32, 40, 82, 41, 32, 72,
76, 83, 76, 32, 83, 104,
97, 100, 101, 114, 32, 67,
111, 109, 112, 105, 108, 101,
114, 32, 57, 46, 50, 57,
46, 57, 53, 50, 46, 51,
49, 49, 49, 0, 171, 171,
81, 0, 0, 5, 0, 0,
15, 160, 0, 0, 128, 63,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
31, 0, 0, 2, 0, 0,
0, 128, 0, 0, 15, 144,
31, 0, 0, 2, 5, 0,
0, 128, 1, 0, 15, 144,
31, 0, 0, 2, 10, 0,
0, 128, 2, 0, 15, 144,
2, 0, 0, 3, 0, 0,
1, 128, 0, 0, 255, 144,
14, 0, 85, 161, 5, 0,
0, 3, 0, 0, 1, 128,
0, 0, 0, 128, 14, 0,
170, 160, 11, 0, 0, 3,
0, 0, 1, 128, 0, 0,
0, 128, 14, 0, 255, 160,
10, 0, 0, 3, 0, 0,
4, 224, 0, 0, 0, 128,
0, 0, 0, 160, 4, 0,
0, 4, 0, 0, 3, 128,
0, 0, 228, 144, 41, 0,
228, 160, 41, 0, 238, 160,
1, 0, 0, 2, 0, 0,
4, 128, 0, 0, 170, 144,
5, 0, 0, 3, 0, 0,
7, 192, 0, 0, 228, 128,
0, 0, 255, 144, 1, 0,
0, 2, 0, 0, 8, 192,
0, 0, 255, 144, 1, 0,
0, 2, 0, 0, 3, 224,
1, 0, 228, 144, 1, 0,
0, 2, 0, 0, 15, 208,
2, 0, 228, 144, 255, 255,
0, 0
};

View file

@ -0,0 +1,30 @@
#include "standardConstants.h"
struct VS_in
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD0;
float4 Color : COLOR0;
};
struct VS_out {
float4 Position : POSITION;
float3 TexCoord0 : TEXCOORD0;
float4 Color : COLOR0;
};
float4 xform : register(c41);
VS_out main(in VS_in input)
{
VS_out output;
output.Position = input.Position;
output.Position.xy = output.Position.xy * xform.xy + xform.zw;
output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0);
output.Position.xyz *= output.Position.w;
output.Color = input.Color;
output.TexCoord0.xy = input.TexCoord;
return output;
}

View file

@ -0,0 +1,89 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T ps_2_0 /DTEX /Fh im2d_tex_PS.h im2d_PS.hlsl
//
//
// Parameters:
//
// float4 fogColor;
// sampler2D tex0;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// fogColor c0 1
// tex0 s0 1
//
ps_2_0
dcl t0.xyz
dcl v0
dcl_2d s0
texld r0, t0, s0
mad r0.xyz, v0, r0, -c0
mul r1.w, r0.w, v0.w
mad r1.xyz, t0.z, r0, c0
mov oC0, r1
// approximately 5 instruction slots used (1 texture, 4 arithmetic)
#endif
const BYTE g_ps20_main[] =
{
0, 2, 255, 255, 254, 255,
45, 0, 67, 84, 65, 66,
28, 0, 0, 0, 127, 0,
0, 0, 0, 2, 255, 255,
2, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
120, 0, 0, 0, 68, 0,
0, 0, 2, 0, 0, 0,
1, 0, 2, 0, 80, 0,
0, 0, 0, 0, 0, 0,
96, 0, 0, 0, 3, 0,
0, 0, 1, 0, 2, 0,
104, 0, 0, 0, 0, 0,
0, 0, 102, 111, 103, 67,
111, 108, 111, 114, 0, 171,
171, 171, 1, 0, 3, 0,
1, 0, 4, 0, 1, 0,
0, 0, 0, 0, 0, 0,
116, 101, 120, 48, 0, 171,
171, 171, 4, 0, 12, 0,
1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0,
112, 115, 95, 50, 95, 48,
0, 77, 105, 99, 114, 111,
115, 111, 102, 116, 32, 40,
82, 41, 32, 72, 76, 83,
76, 32, 83, 104, 97, 100,
101, 114, 32, 67, 111, 109,
112, 105, 108, 101, 114, 32,
57, 46, 50, 57, 46, 57,
53, 50, 46, 51, 49, 49,
49, 0, 31, 0, 0, 2,
0, 0, 0, 128, 0, 0,
7, 176, 31, 0, 0, 2,
0, 0, 0, 128, 0, 0,
15, 144, 31, 0, 0, 2,
0, 0, 0, 144, 0, 8,
15, 160, 66, 0, 0, 3,
0, 0, 15, 128, 0, 0,
228, 176, 0, 8, 228, 160,
4, 0, 0, 4, 0, 0,
7, 128, 0, 0, 228, 144,
0, 0, 228, 128, 0, 0,
228, 161, 5, 0, 0, 3,
1, 0, 8, 128, 0, 0,
255, 128, 0, 0, 255, 144,
4, 0, 0, 4, 1, 0,
7, 128, 0, 0, 170, 176,
0, 0, 228, 128, 0, 0,
228, 160, 1, 0, 0, 2,
0, 8, 15, 128, 1, 0,
228, 128, 255, 255, 0, 0
};

44
vendor/librw/src/d3d/shaders/lighting.h vendored Normal file
View file

@ -0,0 +1,44 @@
struct Light
{
float4 color; // and radius
float4 position; // and -cos(angle)
float4 direction; // and falloff clamp
};
float3 DoDirLight(Light L, float3 N)
{
float l = max(0.0, dot(N, -L.direction.xyz));
return l*L.color.xyz;
}
float3 DoDirLightSpec(Light L, float3 N, float3 V, float power)
{
return pow(saturate(dot(N, normalize(V + -L.direction.xyz))), power)*L.color.xyz;
}
float3 DoPointLight(Light L, float3 V, float3 N)
{
// As on PS2
float3 dir = V - L.position.xyz;
float dist = length(dir);
float atten = max(0.0, (1.0 - dist/L.color.w));
float l = max(0.0, dot(N, -normalize(dir)));
return l*L.color.xyz*atten;
}
float3 DoSpotLight(Light L, float3 V, float3 N)
{
// As on PS2
float3 dir = V - L.position.xyz;
float dist = length(dir);
float atten = max(0.0, (1.0 - dist/L.color.w));
dir /= dist;
float l = max(0.0, dot(N, -dir));
float pcos = dot(dir, L.direction.xyz); // cos to point
float ccos = -L.position.w; // cos of cone
float falloff = (pcos-ccos)/(1.0-ccos);
if(falloff < 0) // outside of cone
l = 0;
l *= max(falloff, L.direction.w); // falloff clamp
return l*L.color.xyz*atten;
}

View file

@ -0,0 +1,11 @@
@echo off
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /Fh default_amb_VS.h default_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /Fh default_amb_dir_VS.h default_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh default_all_VS.h default_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /Fh default_PS.h default_PS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /DTEX /Fh default_tex_PS.h default_PS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /Fh im2d_VS.h im2d_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /Fh im2d_PS.h im2d_PS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /DTEX /Fh im2d_tex_PS.h im2d_PS.hlsl

View file

@ -0,0 +1,7 @@
@echo off
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /Fh matfx_env_amb_VS.h matfx_env_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /Fh matfx_env_amb_dir_VS.h matfx_env_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh matfx_env_all_VS.h matfx_env_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /Fh matfx_env_PS.h matfx_env_PS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /DTEX /Fh matfx_env_tex_PS.h matfx_env_PS.hlsl

View file

@ -0,0 +1,4 @@
@echo off
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /Fh skin_amb_VS.h skin_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /Fh skin_amb_dir_VS.h skin_VS.hlsl
"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh skin_all_VS.h skin_VS.hlsl

View file

@ -0,0 +1,124 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /nologo /T ps_2_0 /Fh matfx_env_PS.h matfx_env_PS.hlsl
//
//
// Parameters:
//
// sampler2D envTex;
// float4 fogColor;
// float4 fxparams;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// fogColor c0 1
// fxparams c1 1
// envTex s1 1
//
ps_2_0
dcl t0.xyz
dcl t1.xy
dcl v0
dcl v1.xyz
dcl_2d s1
texld r0, t1, s1
mul r1.xyz, v1, c1.x
mul r0.xyz, r0, r1
mul r0.xyz, r0, t0.z
max r0.w, v0.w, c1.y
mul r0.xyz, r0.w, r0
add r1.xyz, v0, -c0
mad r1.xyz, t0.z, r1, c0
mad r0.xyz, r1, v0.w, r0
mov r0.w, v0.w
mov oC0, r0
// approximately 11 instruction slots used (1 texture, 10 arithmetic)
#endif
const BYTE g_ps20_main[] =
{
0, 2, 255, 255, 254, 255,
53, 0, 67, 84, 65, 66,
28, 0, 0, 0, 156, 0,
0, 0, 0, 2, 255, 255,
3, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
149, 0, 0, 0, 88, 0,
0, 0, 3, 0, 1, 0,
1, 0, 6, 0, 96, 0,
0, 0, 0, 0, 0, 0,
112, 0, 0, 0, 2, 0,
0, 0, 1, 0, 2, 0,
124, 0, 0, 0, 0, 0,
0, 0, 140, 0, 0, 0,
2, 0, 1, 0, 1, 0,
6, 0, 124, 0, 0, 0,
0, 0, 0, 0, 101, 110,
118, 84, 101, 120, 0, 171,
4, 0, 12, 0, 1, 0,
1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 102, 111,
103, 67, 111, 108, 111, 114,
0, 171, 171, 171, 1, 0,
3, 0, 1, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 102, 120, 112, 97,
114, 97, 109, 115, 0, 112,
115, 95, 50, 95, 48, 0,
77, 105, 99, 114, 111, 115,
111, 102, 116, 32, 40, 82,
41, 32, 72, 76, 83, 76,
32, 83, 104, 97, 100, 101,
114, 32, 67, 111, 109, 112,
105, 108, 101, 114, 32, 57,
46, 50, 57, 46, 57, 53,
50, 46, 51, 49, 49, 49,
0, 171, 171, 171, 31, 0,
0, 2, 0, 0, 0, 128,
0, 0, 7, 176, 31, 0,
0, 2, 0, 0, 0, 128,
1, 0, 3, 176, 31, 0,
0, 2, 0, 0, 0, 128,
0, 0, 15, 144, 31, 0,
0, 2, 0, 0, 0, 128,
1, 0, 7, 144, 31, 0,
0, 2, 0, 0, 0, 144,
1, 8, 15, 160, 66, 0,
0, 3, 0, 0, 15, 128,
1, 0, 228, 176, 1, 8,
228, 160, 5, 0, 0, 3,
1, 0, 7, 128, 1, 0,
228, 144, 1, 0, 0, 160,
5, 0, 0, 3, 0, 0,
7, 128, 0, 0, 228, 128,
1, 0, 228, 128, 5, 0,
0, 3, 0, 0, 7, 128,
0, 0, 228, 128, 0, 0,
170, 176, 11, 0, 0, 3,
0, 0, 8, 128, 0, 0,
255, 144, 1, 0, 85, 160,
5, 0, 0, 3, 0, 0,
7, 128, 0, 0, 255, 128,
0, 0, 228, 128, 2, 0,
0, 3, 1, 0, 7, 128,
0, 0, 228, 144, 0, 0,
228, 161, 4, 0, 0, 4,
1, 0, 7, 128, 0, 0,
170, 176, 1, 0, 228, 128,
0, 0, 228, 160, 4, 0,
0, 4, 0, 0, 7, 128,
1, 0, 228, 128, 0, 0,
255, 144, 0, 0, 228, 128,
1, 0, 0, 2, 0, 0,
8, 128, 0, 0, 255, 144,
1, 0, 0, 2, 0, 8,
15, 128, 0, 0, 228, 128,
255, 255, 0, 0
};

View file

@ -0,0 +1,42 @@
struct VS_out {
float4 Position : POSITION;
float3 TexCoord0 : TEXCOORD0;
float2 TexCoord1 : TEXCOORD1;
float4 Color : COLOR0;
float4 EnvColor : COLOR1;
};
sampler2D diffTex : register(s0);
sampler2D envTex : register(s1);
float4 fogColor : register(c0);
float4 fxparams : register(c1);
#define shininess (fxparams.x)
#define disableFBA (fxparams.y)
float4 main(VS_out input) : COLOR
{
float4 pass1 = input.Color;
#ifdef TEX
pass1 *= tex2D(diffTex, input.TexCoord0.xy);
#endif
float4 pass2 = input.EnvColor*shininess*tex2D(envTex, input.TexCoord1.xy);
pass1.rgb = lerp(fogColor.rgb, pass1.rgb, input.TexCoord0.z);
pass2.rgb = lerp(float3(0.0, 0.0, 0.0), pass2.rgb, input.TexCoord0.z);
// We simulate drawing this in two passes.
// First pass with standard blending, second with addition
// We premultiply alpha so render state should be one.
// For FB alpha rendering assume that diffuse alpha (pass1.a) was
// written to framebuffer, so just multiply pass2 by it as well then.
float fba = max(pass1.a, disableFBA);
float4 color;
color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba;
color.a = pass1.a;
return color;
}

View file

@ -0,0 +1,59 @@
#include "standardConstants.h"
float4x4 texMat : register(c41);
float4 colorClamp : register(c45);
float4 envColor : register(c46);
struct VS_in
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD0;
float4 Prelight : COLOR0;
};
struct VS_out {
float4 Position : POSITION;
float3 TexCoord0 : TEXCOORD0; // also fog
float2 TexCoord1 : TEXCOORD1;
float4 Color : COLOR0;
float4 EnvColor : COLOR1;
};
VS_out main(in VS_in input)
{
VS_out output;
output.Position = mul(combinedMat, input.Position);
float3 V = mul(worldMat, input.Position).xyz;
float3 N = mul(normalMat, input.Normal);
output.TexCoord0.xy = input.TexCoord;
output.TexCoord1 = mul(texMat, float4(N, 1.0)).xy;
output.Color = input.Prelight;
output.Color.rgb += ambientLight.rgb * surfAmbient;
int i;
#ifdef DIRECTIONALS
for(i = 0; i < numDirLights; i++)
output.Color.xyz += DoDirLight(lights[i+firstDirLight], N)*surfDiffuse;
#endif
#ifdef POINTLIGHTS
for(i = 0; i < numPointLights; i++)
output.Color.xyz += DoPointLight(lights[i+firstPointLight], V, N)*surfDiffuse;
#endif
#ifdef SPOTLIGHTS
for(i = 0; i < numSpotLights; i++)
output.Color.xyz += DoSpotLight(lights[i+firstSpotLight], V, N)*surfDiffuse;
#endif
// PS2 clamps before material color
output.Color = clamp(output.Color, 0.0, 1.0);
output.EnvColor = max(output.Color, colorClamp) * envColor;
output.Color *= matCol;
output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0);
return output;
}

Some files were not shown because too many files have changed in this diff Show more