mirror of
https://github.com/simple64/simple64.git
synced 2026-11-14 23:59:21 +01:00
Squashed 'angrylion-rdp-plus/' content from commit 4039a55
git-subtree-dir: angrylion-rdp-plus git-subtree-split: 4039a559eefa0d060c76ec37b2c77d848262dd43
This commit is contained in:
commit
8eaaff75db
67 files changed
+20503
No files matched your search
@@ -0,0 +1,9 @@
|
||||
# Visual Studio cache/options directory
|
||||
.vs/
|
||||
|
||||
# Visual C++ cache files
|
||||
*.aps
|
||||
|
||||
src/core/version.h
|
||||
private/
|
||||
build/
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
option(GLES "Set to ON to use OpenGL ES 3.0 renderer instead of OpenGL 3.3 core")
|
||||
|
||||
project(angrylion-plus)
|
||||
|
||||
set(OpenGL_GL_PREFERENCE GLVND)
|
||||
|
||||
if(GLES)
|
||||
message("OpenGL ES 3.0 renderer enabled")
|
||||
add_definitions(-DGLES)
|
||||
endif(GLES)
|
||||
|
||||
if(ANDROID)
|
||||
add_definitions(-DANDROID)
|
||||
endif()
|
||||
|
||||
# set policy CMP0042 for MacOS X
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
|
||||
# check for INTERPROCEDURAL_OPTIMIZATION support
|
||||
if((${CMAKE_VERSION} VERSION_EQUAL 3.9) OR (${CMAKE_VERSION} VERSION_GREATER 3.9))
|
||||
cmake_policy(SET CMP0069 NEW)
|
||||
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT ENABLE_IPO)
|
||||
if(ENABLE_IPO)
|
||||
message("Interprocedural optimizations enabled")
|
||||
endif(ENABLE_IPO)
|
||||
endif()
|
||||
|
||||
# C++14 is required for the Parallel utility class
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
# disable warnings to use unportable secure file IO
|
||||
if(MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif(MSVC)
|
||||
|
||||
# default to release build
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
find_package(Git REQUIRED)
|
||||
find_package(PythonInterp 3.2 REQUIRED)
|
||||
|
||||
if (NOT ANDROID)
|
||||
find_package(PythonLibs)
|
||||
find_package(OpenGL REQUIRED)
|
||||
endif()
|
||||
|
||||
# use warning levels as recommended by
|
||||
# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md
|
||||
if ( CMAKE_COMPILER_IS_GNUCC )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic")
|
||||
endif()
|
||||
if ( MSVC )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /w14640 /permissive-")
|
||||
endif()
|
||||
|
||||
set(PATH_SRC "src")
|
||||
|
||||
# RDP core library
|
||||
set(PATH_CORE "${PATH_SRC}/core")
|
||||
|
||||
# run script to generate version.h
|
||||
set(PATH_VERSION "${PATH_CORE}/version.h")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PATH_VERSION}
|
||||
COMMAND
|
||||
${PYTHON_EXECUTABLE}
|
||||
"${CMAKE_SOURCE_DIR}/make_version.py"
|
||||
COMMENT "Generate Git version"
|
||||
)
|
||||
|
||||
# static core library
|
||||
file(GLOB SOURCES_CORE "${PATH_CORE}/*.c" "${PATH_CORE}/*.cpp")
|
||||
|
||||
if (ANDROID)
|
||||
find_library( # Defines the name of the path variable that stores the
|
||||
# location of the NDK library.
|
||||
OPENGL_LIBRARIES
|
||||
|
||||
# Specifies the name of the NDK library that
|
||||
# CMake needs to locate.
|
||||
GLESv3 )
|
||||
endif()
|
||||
|
||||
add_library(alp-core STATIC ${SOURCES_CORE} ${PATH_VERSION})
|
||||
|
||||
# output library
|
||||
set(PATH_OUTPUT "${PATH_SRC}/output")
|
||||
|
||||
file(GLOB SOURCES_OUTPUT "${PATH_OUTPUT}/*.c" "${PATH_OUTPUT}/*.cpp")
|
||||
|
||||
add_library(alp-output STATIC ${SOURCES_OUTPUT})
|
||||
|
||||
if(MINGW)
|
||||
# link libgcc/libstdc++ statically, fixes cryptic "_ZNSt13runtime_errorC1EPKc" error
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
|
||||
else(MINGW)
|
||||
# set PIC option for non-MinGW targets
|
||||
set_target_properties(alp-core PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_target_properties(alp-output PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
endif(MINGW)
|
||||
|
||||
# set IPO option, if supported
|
||||
if(ENABLE_IPO AND (CMAKE_BUILD_TYPE STREQUAL "Release"))
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -O3")
|
||||
endif()
|
||||
|
||||
include_directories(${PATH_SRC})
|
||||
|
||||
# Project64 GFX Plugin (Windows only)
|
||||
if(WIN32)
|
||||
set(NAME_PLUGIN_ZILMAR ${CMAKE_PROJECT_NAME})
|
||||
set(PATH_PLUGIN_ZILMAR "${PATH_SRC}/plugin/zilmar")
|
||||
|
||||
enable_language(RC)
|
||||
file(GLOB SOURCES_PLUGIN_ZILMAR "${PATH_PLUGIN_ZILMAR}/*.c" "${PATH_PLUGIN_ZILMAR}/*.rc")
|
||||
add_library(${NAME_PLUGIN_ZILMAR} SHARED ${SOURCES_PLUGIN_ZILMAR})
|
||||
|
||||
set_target_properties(${NAME_PLUGIN_ZILMAR} PROPERTIES PREFIX "")
|
||||
|
||||
target_link_libraries(${NAME_PLUGIN_ZILMAR} alp-core alp-output shlwapi ${OPENGL_LIBRARIES})
|
||||
endif(WIN32)
|
||||
|
||||
# Mupen64Plus GFX plugin
|
||||
set(NAME_PLUGIN_M64P "mupen64plus-video-${CMAKE_PROJECT_NAME}")
|
||||
|
||||
set(PATH_PLUGIN_M64P "${PATH_SRC}/plugin/mupen64plus")
|
||||
|
||||
file(GLOB SOURCES_PLUGIN_M64P "${PATH_PLUGIN_M64P}/*.c")
|
||||
add_library(${NAME_PLUGIN_M64P} SHARED ${SOURCES_PLUGIN_M64P})
|
||||
|
||||
if(NOT ANDROID)
|
||||
set_target_properties(${NAME_PLUGIN_M64P} PROPERTIES PREFIX "")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${NAME_PLUGIN_M64P} alp-core alp-output ${CMAKE_THREAD_LIBS_INIT} ${OPENGL_LIBRARIES})
|
||||
@@ -0,0 +1,7 @@
|
||||
This little RDP plugin was initially based on MESS 0.128 source code.
|
||||
Many thanks to Ville Linde, MooglyGuy and other people who wrote the RDP implementation in MESS 0.128. The rest of the code is by me, angrylion.
|
||||
Many thanks to people who helped me in various ways: olivieryuyu, marshallh, LaC, oman, pinchy, ziggy, FatCat, LegendOfDragoon and other folks I forgot.
|
||||
The code comes under MAME license.
|
||||
Sorry for my terrible English.
|
||||
|
||||
angrylion
|
||||
@@ -0,0 +1,53 @@
|
||||
MAME Legal Information
|
||||
License
|
||||
|
||||
Redistribution and use of the MAME code or any derivative works are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions may not be sold, nor may they be used in a commercial product or activity.
|
||||
* Redistributions that are modified from the original source must include the complete source code, including the source code for all components used by a binary built from the modified sources. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
|
||||
* Redistributions must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Trademark
|
||||
|
||||
MAME® is a registered trademark of Nicola Salmoria. The "MAME" name and MAME logo may not be used without first obtaining permission of the trademark holder.
|
||||
Copyright
|
||||
|
||||
The code in MAME is the work of hundreds of developers, each of whom owns the copyright to the code they wrote. There is no central copyright authority you can license the code from. The proper way to use the MAME source code is to examine it, using it to understand how the games worked, and then write your own emulation code. Sorry, there is no free lunch here.
|
||||
Common Questions
|
||||
|
||||
Q. Can I include MAME with my product?
|
||||
A. No. MAME is not licensed for commercial use. Using MAME as a "freebie" or including it at "no cost" with your product still constitutes commerical usage and is forbidden by the license.
|
||||
|
||||
Q. Can I sell my product with the MAME logo on it?
|
||||
A. No. Putting the logo on your product makes it appear that the product is something officially endorsed by Nicola Salmoria, and constitutes trademark infringement.
|
||||
|
||||
Q. Can I use the MAME logo to advertise my product?
|
||||
A. No. Using the logo in your advertising makes it appear that the product is something officially endorsed by Nicola Salmoria, and constitutes trademark infringement.
|
||||
|
||||
Q. Can I use the term "MAME" in the name of my software?
|
||||
A. Generally, no, especially if it is something that is sold. However, if you are producing a free MAME-related piece of software, it is common that permission is granted. Send a query to double- check first, please.
|
||||
|
||||
Q. Can I put an arcade cabinet running MAME in a public location?
|
||||
A. No. This this a commercial use of MAME and is prohibited by the license. Even if you don't charge money, putting a machine in a public location is "operating" an arcade machine and falls under commercial rules in most locations.
|
||||
|
||||
Q. Can my non-profit use MAME or an arcade cabinet running MAME to help raise money?
|
||||
A. No, sorry. Even for the most worthwhile cause, this still is a commercial use of MAME and is prohibited by the license.
|
||||
|
||||
Q. How do I obtain a license to the MAME source code?
|
||||
A. You can't. See the Copyright section above.
|
||||
|
||||
Q. Is it legal to download ROMs for a game when I own the PCB?
|
||||
A. This is unclear and depends on where you live. In most cases you would need to obtain permission from the original manufacturer to do so.
|
||||
|
||||
Q. What about the free ROMs on the MAME site? Can I use those with my product?
|
||||
A. Almost all of the free ROMs on the MAME site are licensed only for non- commercial use, and only for distribution from the MAME site. Just because they are available for "free" here does not grant further redistribution rights, nor does it allow you to treat them as "freebies" for commercial use.
|
||||
|
||||
Q. If I obtain a license from an original manufacturer to distribute the ROMs can I use MAME to run them?
|
||||
A. Generally, no, because it constitutes a commercial use of MAME. However, we have in the past made a couple of exceptions for this particular case. We will not consider making any further exceptions without proof that such a license has already been obtained.
|
||||
|
||||
Q. Can I use a PC running MAME to replace a real arcade PCB?
|
||||
A. In order to do this you would have to use a copy of the original ROMs, which would require obtaining permission from the original manufacturer. Once you had permission from them, if it was used for non-commercial purposes, then you would not technically be violating the MAME license. However we still do not explicitly give permission to use MAME in this way because of the possibility of the game being sold sometime later, which would constitute commercial use of MAME. If you sell your game later you must sell it without MAME included.
|
||||
|
||||
Q. Can I ask for donations for the work I did on my port of MAME to platform X?
|
||||
A. No. You would be earning money from the MAME trademark and copyrights, and that would be a commercial use, which is prohibited by the license. It is our wish that MAME remain free.
|
||||
@@ -0,0 +1,50 @@
|
||||
# Angrylion RDP Plus
|
||||
|
||||
This is a conservative fork of angrylion's RDP plugin that aims to improve performance and add new features while retaining the accuracy of the original plugin.
|
||||
|
||||
### Current features
|
||||
* More maintainable code base by dividing the huge n64video.cpp into smaller pieces.
|
||||
* Improved portability by separating the emulator plugin interface and window management from the RDP emulation core.
|
||||
* Improved performance on multi-core CPUs by using multi-threaded rendering with scan line interleaving.
|
||||
* Replaced deprecated DirectDraw interface with a modern OpenGL 3.3 implementation.
|
||||
* Added fullscreen support and manual window sizing.
|
||||
* Added BMP screenshot support.
|
||||
* Added settings GUI.
|
||||
* Added Mupen64Plus support.
|
||||
|
||||
Tested with Project64 2.3+. May also work with Project64 1.7 with a RSP plugin of newer builds (1.7.1+).
|
||||
|
||||
The Mupen64Plus plugin was tested with Mupen64Plus 2.5 using the [mupen64plus-rsp-cxd4](https://github.com/mupen64plus/mupen64plus-rsp-cxd4) plugin.
|
||||
|
||||
### Building
|
||||
|
||||
#### Visual Studio
|
||||
|
||||
To build the project with Visual Studio (2015+), you currently need to have Python 3 installed, which is used to fetch Git metadata and write it to `version.h`.
|
||||
You can also build without, but then you have to copy `version.h.in` to `version.h` and disable the custom build event in the core project.
|
||||
|
||||
The glLoadGen files (`gl_core_3_3` and `wgl_ext`) were generated using the following parameters:
|
||||
|
||||
lua LoadGen.lua core_3_3 -style=pointer_c -spec=gl -version=3.3 -profile=core
|
||||
lua LoadGen.lua ext -style=pointer_c -spec=wgl -ext WGL_EXT_swap_control -ext ARB_create_context -ext ARB_create_context_profile
|
||||
|
||||
#### CMake
|
||||
|
||||
Install dependencies:
|
||||
|
||||
apt install cmake freeglut3-dev
|
||||
|
||||
Building:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
To create an OpenGL ES 3 build, add ``-DGLES=ON`` to the cmake arguments.
|
||||
|
||||
### Credits
|
||||
* Angrylion, Ville Linde, MooglyGuy and others involved for creating an awesome N64 RDP reference software.
|
||||
* theboy181 - Testing. Lots of testing.
|
||||
* fallaha56 - Donator.
|
||||
* loganmc10 - Mupen64Plus plugin implementation.
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, subprocess
|
||||
|
||||
def system(cmd, default):
|
||||
args = cmd.split()
|
||||
try:
|
||||
return subprocess.check_output(args).decode("ascii").strip()
|
||||
except:
|
||||
return default
|
||||
|
||||
if __name__ == "__main__":
|
||||
branch = system("git rev-parse --abbrev-ref HEAD", "master")
|
||||
hash = system("git show -s --format=%h", "0" * 40)
|
||||
date = system("git show -s --format=%ci", "")[:10]
|
||||
tag = system("git describe --dirty --always --tags", "")
|
||||
|
||||
# remove hash from git describe output
|
||||
tag = tag.split("-")
|
||||
if len(tag) > 2 and tag[2][1:] in hash:
|
||||
del tag[2]
|
||||
tag = "-".join(tag)
|
||||
|
||||
mappings = {
|
||||
"GIT_BRANCH": branch,
|
||||
"GIT_TAG": tag,
|
||||
"GIT_COMMIT_HASH": hash,
|
||||
"GIT_COMMIT_DATE": date,
|
||||
}
|
||||
|
||||
base_path = os.path.dirname(sys.argv[0])
|
||||
core_path = os.path.join(base_path, "src", "core")
|
||||
in_path = os.path.join(core_path, "version.h.in")
|
||||
out_path = os.path.join(core_path, "version.h")
|
||||
|
||||
with open(in_path, "r") as f:
|
||||
version_str = f.read()
|
||||
|
||||
for mapping, value in mappings.items():
|
||||
version_str = version_str.replace("@" + mapping + "@", value)
|
||||
|
||||
with open(out_path, "w") as f:
|
||||
f.write(version_str)
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
[Xx]64/
|
||||
[Xx]86/
|
||||
[Bb]uild/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
|
||||
# TODO: Un-comment the next line if you do not want to checkin
|
||||
# your web deploy settings because they may include unencrypted
|
||||
# passwords
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# LightSwitch generated files
|
||||
GeneratedArtifacts/
|
||||
ModelManifest.xml
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
@@ -0,0 +1,68 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29806.167
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "core.vcxproj", "{D86C6E84-3371-4B20-8620-A703FF3F2CC5}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin-mupen64plus", "plugin-mupen64plus.vcxproj", "{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5} = {D86C6E84-3371-4B20-8620-A703FF3F2CC5}
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE} = {B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin-zilmar", "plugin-zilmar.vcxproj", "{722AD25D-C281-48FB-9A58-7699E50F8E6D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5} = {D86C6E84-3371-4B20-8620-A703FF3F2CC5}
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE} = {B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "output", "output.vcxproj", "{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5}.Debug|x64.Build.0 = Debug|x64
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5}.Release|x64.ActiveCfg = Release|x64
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5}.Release|x64.Build.0 = Release|x64
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D86C6E84-3371-4B20-8620-A703FF3F2CC5}.Release|x86.Build.0 = Release|Win32
|
||||
{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}.Debug|x64.Build.0 = Debug|x64
|
||||
{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}.Release|x64.ActiveCfg = Release|x64
|
||||
{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}.Release|x64.Build.0 = Release|x64
|
||||
{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}.Release|x86.Build.0 = Release|Win32
|
||||
{722AD25D-C281-48FB-9A58-7699E50F8E6D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{722AD25D-C281-48FB-9A58-7699E50F8E6D}.Debug|x64.Build.0 = Debug|x64
|
||||
{722AD25D-C281-48FB-9A58-7699E50F8E6D}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{722AD25D-C281-48FB-9A58-7699E50F8E6D}.Debug|x86.Build.0 = Debug|Win32
|
||||
{722AD25D-C281-48FB-9A58-7699E50F8E6D}.Release|x64.ActiveCfg = Release|x64
|
||||
{722AD25D-C281-48FB-9A58-7699E50F8E6D}.Release|x64.Build.0 = Release|x64
|
||||
{722AD25D-C281-48FB-9A58-7699E50F8E6D}.Release|x86.ActiveCfg = Release|Win32
|
||||
{722AD25D-C281-48FB-9A58-7699E50F8E6D}.Release|x86.Build.0 = Release|Win32
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}.Debug|x64.Build.0 = Debug|x64
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}.Release|x64.ActiveCfg = Release|x64
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}.Release|x64.Build.0 = Release|x64
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2896B5DF-D1A8-4A2B-BB7D-835C07F05863}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,338 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\core\n64video\rdp.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\blender.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\combiner.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\coverage.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\dither.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\fbuffer.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\rasterizer.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\rdram.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\tcoord.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\tex.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\tmem.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\zbuffer.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\divot.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\fetch.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\gamma.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\lerp.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\restore.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\video.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\parallel.cpp" />
|
||||
<ClCompile Include="..\src\core\n64video.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\core\common.h" />
|
||||
<ClInclude Include="..\src\core\msg.h" />
|
||||
<ClInclude Include="..\src\core\parallel.h" />
|
||||
<ClInclude Include="..\src\core\n64video.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\src\core\version.h.in" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{D86C6E84-3371-4B20-8620-A703FF3F2CC5}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'==''">
|
||||
<!-- Latest Target Version property -->
|
||||
<LatestTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</LatestTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
<TargetPlatformVersion>$(WindowsTargetPlatformVersion)</TargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4204</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>python "$(SolutionDir)..\make_version.py"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4204</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>python "$(SolutionDir)..\make_version.py"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4204</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>python "$(SolutionDir)..\make_version.py"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4204</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>python "$(SolutionDir)..\make_version.py"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{5467dd49-ff5e-4be4-93ad-8291721fc00d}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{142a5325-573c-4fde-9d8f-af10cb6e28e5}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\n64video">
|
||||
<UniqueIdentifier>{201fc67f-a10c-47a3-a9f6-47b9ccdf155a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\n64video\vi">
|
||||
<UniqueIdentifier>{9ac263b1-1e35-44a3-8368-2c88ff3bb096}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\n64video\rdp">
|
||||
<UniqueIdentifier>{0def43d5-fe85-4dc1-9b3e-264603cca8fa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\core\parallel.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\blender.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\combiner.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\coverage.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\dither.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\fbuffer.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\rasterizer.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\rdram.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\tcoord.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\tex.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\tmem.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp\zbuffer.c">
|
||||
<Filter>Source Files\n64video\rdp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\divot.c">
|
||||
<Filter>Source Files\n64video\vi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\fetch.c">
|
||||
<Filter>Source Files\n64video\vi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\gamma.c">
|
||||
<Filter>Source Files\n64video\vi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\lerp.c">
|
||||
<Filter>Source Files\n64video\vi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\restore.c">
|
||||
<Filter>Source Files\n64video\vi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi\video.c">
|
||||
<Filter>Source Files\n64video\vi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\rdp.c">
|
||||
<Filter>Source Files\n64video</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\n64video\vi.c">
|
||||
<Filter>Source Files\n64video</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\core\common.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\core\msg.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\core\parallel.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\core\n64video.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\src\core\version.h.in">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,217 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\output\gl_core_3_3.c" />
|
||||
<ClCompile Include="..\src\output\vdac.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\output\gl_core_3_3.h" />
|
||||
<ClInclude Include="..\src\output\gl_proc.h" />
|
||||
<ClInclude Include="..\src\output\screen.h" />
|
||||
<ClInclude Include="..\src\output\vdac.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B74D5BAF-38F4-4233-9FC1-BE7E02E81FDE}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'==''">
|
||||
<!-- Latest Target Version property -->
|
||||
<LatestTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</LatestTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
<TargetPlatformVersion>$(WindowsTargetPlatformVersion)</TargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4204</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<PreBuildEvent />
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4204</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
<PreBuildEvent />
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4204</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<PreBuildEvent />
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4204</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
<PreBuildEvent />
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\output\gl_core_3_3.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\output\vdac.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\output\gl_core_3_3.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\output\gl_proc.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\output\screen.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\output\vdac.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,238 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_common.h" />
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_config.h" />
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_plugin.h" />
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_types.h" />
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_vidext.h" />
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\gfx_m64p.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\plugin\mupen64plus\gfx_m64p.c" />
|
||||
<ClCompile Include="..\src\plugin\mupen64plus\msg.c" />
|
||||
<ClCompile Include="..\src\plugin\mupen64plus\screen.c" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{54BDC4EF-2526-47F7-A73E-C1C0FBC0237C}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'==''">
|
||||
<!-- Latest Target Version property -->
|
||||
<LatestTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</LatestTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
<TargetPlatformVersion>$(WindowsTargetPlatformVersion)</TargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<TargetName>mupen64plus-video-$(SolutionName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>mupen64plus-video-$(SolutionName)</TargetName>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<TargetName>mupen64plus-video-$(SolutionName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>mupen64plus-video-$(SolutionName)</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4201</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalDependencies>opengl32.lib;core.lib;output.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4201</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<AdditionalDependencies>opengl32.lib;core.lib;output.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4201</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalDependencies>opengl32.lib;core.lib;output.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4201</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<AdditionalDependencies>opengl32.lib;core.lib;output.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{5467dd49-ff5e-4be4-93ad-8291721fc00d}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{142a5325-573c-4fde-9d8f-af10cb6e28e5}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\api">
|
||||
<UniqueIdentifier>{363d4ce3-41b8-4b23-8739-7618a5da0345}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_common.h">
|
||||
<Filter>Source Files\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_config.h">
|
||||
<Filter>Source Files\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_plugin.h">
|
||||
<Filter>Source Files\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_types.h">
|
||||
<Filter>Source Files\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\api\m64p_vidext.h">
|
||||
<Filter>Source Files\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\plugin\mupen64plus\gfx_m64p.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\plugin\mupen64plus\gfx_m64p.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\plugin\mupen64plus\msg.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\plugin\mupen64plus\screen.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,241 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\src\plugin\zilmar\config.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\plugin\zilmar\config.c" />
|
||||
<ClCompile Include="..\src\plugin\zilmar\gfx_1.3.c" />
|
||||
<ClCompile Include="..\src\plugin\zilmar\msg.c" />
|
||||
<ClCompile Include="..\src\plugin\zilmar\screen.c" />
|
||||
<ClCompile Include="..\src\plugin\zilmar\wgl_ext.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\plugin\zilmar\config.h" />
|
||||
<ClInclude Include="..\src\plugin\zilmar\gfx_1.3.h" />
|
||||
<ClInclude Include="..\src\plugin\zilmar\resource.h" />
|
||||
<ClInclude Include="..\src\plugin\zilmar\wgl_ext.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{722AD25D-C281-48FB-9A58-7699E50F8E6D}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'==''">
|
||||
<!-- Latest Target Version property -->
|
||||
<LatestTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</LatestTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
<TargetPlatformVersion>$(WindowsTargetPlatformVersion)</TargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<TargetName>$(SolutionName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>$(SolutionName)</TargetName>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<TargetName>$(SolutionName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>$(SolutionName)</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<ImportLibrary>$(OutDir)angrylion.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalDependencies>opengl32.lib;core.lib;output.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)angrylion.lib</ImportLibrary>
|
||||
<AdditionalDependencies>opengl32.lib;core.lib;output.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<ImportLibrary>$(OutDir)angrylion.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalDependencies>opengl32.lib;core.lib;output.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)angrylion.lib</ImportLibrary>
|
||||
<AdditionalDependencies>opengl32.lib;core.lib;output.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{5467dd49-ff5e-4be4-93ad-8291721fc00d}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{142a5325-573c-4fde-9d8f-af10cb6e28e5}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\plugin\zilmar\config.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\plugin\zilmar\gfx_1.3.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\plugin\zilmar\msg.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\plugin\zilmar\screen.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\plugin\zilmar\wgl_ext.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\plugin\zilmar\config.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\plugin\zilmar\gfx_1.3.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\plugin\zilmar\resource.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\plugin\zilmar\wgl_ext.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\src\plugin\zilmar\config.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
// endianness
|
||||
#define LSB_FIRST 1
|
||||
#ifdef LSB_FIRST
|
||||
#define BYTE_ADDR_XOR 3
|
||||
#define WORD_ADDR_XOR 1
|
||||
#define BYTE4_XOR_BE(a) ((a) ^ BYTE_ADDR_XOR)
|
||||
#else
|
||||
#define BYTE_ADDR_XOR 0
|
||||
#define WORD_ADDR_XOR 0
|
||||
#define BYTE4_XOR_BE(a) (a)
|
||||
#endif
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
#define BYTE_XOR_DWORD_SWAP 7
|
||||
#define WORD_XOR_DWORD_SWAP 3
|
||||
#else
|
||||
#define BYTE_XOR_DWORD_SWAP 4
|
||||
#define WORD_XOR_DWORD_SWAP 2
|
||||
#endif
|
||||
|
||||
#define DWORD_XOR_DWORD_SWAP 1
|
||||
|
||||
// inlining
|
||||
#define INLINE inline
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STRICTINLINE __forceinline
|
||||
#elif defined(__GNUC__)
|
||||
#define STRICTINLINE __attribute__((always_inline)) inline
|
||||
#else
|
||||
#define STRICTINLINE inline
|
||||
#endif
|
||||
|
||||
// misc
|
||||
#define UNUSED(x) (void)(x)
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void msg_error(const char * err, ...);
|
||||
void msg_warning(const char* err, ...);
|
||||
void msg_debug(const char* err, ...);
|
||||
@@ -0,0 +1,319 @@
|
||||
#include "n64video.h"
|
||||
#include "common.h"
|
||||
#include "msg.h"
|
||||
#include "parallel.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define CLAMP(x, lo, hi) (((x) > (hi)) ? (hi) : (((x) < (lo)) ? (lo) : (x)))
|
||||
|
||||
#define SIGN16(x) ((int16_t)(x))
|
||||
#define SIGN8(x) ((int8_t)(x))
|
||||
|
||||
#define SIGN(x, numb) (((x) & ((1 << (numb)) - 1)) | -((x) & (1 << ((numb) - 1))))
|
||||
#define SIGNF(x, numb) ((x) | -((x) & (1 << ((numb) - 1))))
|
||||
|
||||
#define TRELATIVE(x, y) ((x) - ((y) << 3))
|
||||
|
||||
#define PIXELS_TO_BYTES(pix, siz) (((pix) << (siz)) >> 1)
|
||||
|
||||
// RGBA5551 to RGBA8888 helper
|
||||
#define RGBA16_R(x) (((x) >> 8) & 0xf8)
|
||||
#define RGBA16_G(x) (((x) & 0x7c0) >> 3)
|
||||
#define RGBA16_B(x) (((x) & 0x3e) << 2)
|
||||
|
||||
// RGBA8888 helper
|
||||
#define RGBA32_R(x) (((x) >> 24) & 0xff)
|
||||
#define RGBA32_G(x) (((x) >> 16) & 0xff)
|
||||
#define RGBA32_B(x) (((x) >> 8) & 0xff)
|
||||
#define RGBA32_A(x) ((x) & 0xff)
|
||||
|
||||
// maximum number of commands to buffer for parallel processing
|
||||
#define CMD_BUFFER_SIZE 1024
|
||||
|
||||
// maximum data size of a single command in bytes
|
||||
#define CMD_MAX_SIZE 176
|
||||
|
||||
// maximum data size of a single command in 32 bit integers
|
||||
#define CMD_MAX_INTS (CMD_MAX_SIZE / sizeof(int32_t))
|
||||
|
||||
// extracts the command ID from a command buffer
|
||||
#define CMD_ID(cmd) ((*(cmd) >> 24) & 0x3f)
|
||||
|
||||
// list of command IDs
|
||||
#define CMD_ID_NO_OP 0x00
|
||||
#define CMD_ID_FILL_TRIANGLE 0x08
|
||||
#define CMD_ID_FILL_ZBUFFER_TRIANGLE 0x09
|
||||
#define CMD_ID_TEXTURE_TRIANGLE 0x0a
|
||||
#define CMD_ID_TEXTURE_ZBUFFER_TRIANGLE 0x0b
|
||||
#define CMD_ID_SHADE_TRIANGLE 0x0c
|
||||
#define CMD_ID_SHADE_ZBUFFER_TRIANGLE 0x0d
|
||||
#define CMD_ID_SHADE_TEXTURE_TRIANGLE 0x0e
|
||||
#define CMD_ID_SHADE_TEXTURE_Z_BUFFER_TRIANGLE 0x0f
|
||||
#define CMD_ID_TEXTURE_RECTANGLE 0x24
|
||||
#define CMD_ID_TEXTURE_RECTANGLE_FLIP 0x25
|
||||
#define CMD_ID_SYNC_LOAD 0x26
|
||||
#define CMD_ID_SYNC_PIPE 0x27
|
||||
#define CMD_ID_SYNC_TILE 0x28
|
||||
#define CMD_ID_SYNC_FULL 0x29
|
||||
#define CMD_ID_SET_KEY_GB 0x2a
|
||||
#define CMD_ID_SET_KEY_R 0x2b
|
||||
#define CMD_ID_SET_CONVERT 0x2c
|
||||
#define CMD_ID_SET_SCISSOR 0x2d
|
||||
#define CMD_ID_SET_PRIM_DEPTH 0x2e
|
||||
#define CMD_ID_SET_OTHER_MODES 0x2f
|
||||
#define CMD_ID_LOAD_TLUT 0x30
|
||||
#define CMD_ID_SET_TILE_SIZE 0x32
|
||||
#define CMD_ID_LOAD_BLOCK 0x33
|
||||
#define CMD_ID_LOAD_TILE 0x34
|
||||
#define CMD_ID_SET_TILE 0x35
|
||||
#define CMD_ID_FILL_RECTANGLE 0x36
|
||||
#define CMD_ID_SET_FILL_COLOR 0x37
|
||||
#define CMD_ID_SET_FOG_COLOR 0x38
|
||||
#define CMD_ID_SET_BLEND_COLOR 0x39
|
||||
#define CMD_ID_SET_PRIM_COLOR 0x3a
|
||||
#define CMD_ID_SET_ENV_COLOR 0x3b
|
||||
#define CMD_ID_SET_COMBINE 0x3c
|
||||
#define CMD_ID_SET_TEXTURE_IMAGE 0x3d
|
||||
#define CMD_ID_SET_MASK_IMAGE 0x3e
|
||||
#define CMD_ID_SET_COLOR_IMAGE 0x3f
|
||||
|
||||
static struct n64video_config config;
|
||||
|
||||
static struct
|
||||
{
|
||||
bool fillmbitcrashes, vbusclock, nolerp;
|
||||
} onetimewarnings;
|
||||
|
||||
static int rdp_pipeline_crashed = 0;
|
||||
|
||||
static STRICTINLINE int32_t clamp(int32_t value, int32_t min, int32_t max)
|
||||
{
|
||||
if (value < min)
|
||||
return min;
|
||||
else if (value > max)
|
||||
return max;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
static STRICTINLINE uint32_t irand(uint32_t* state)
|
||||
{
|
||||
*state = *state * 0x343fd + 0x269ec3;
|
||||
return ((*state >> 16) & 0x7fff);
|
||||
}
|
||||
|
||||
// include guard to prevent compilation of code modules
|
||||
// as translation units
|
||||
#define N64VIDEO_C
|
||||
|
||||
#include "n64video/rdp.c"
|
||||
#include "n64video/vi.c"
|
||||
|
||||
static uint32_t rdp_cmd_buf[CMD_BUFFER_SIZE][CMD_MAX_INTS];
|
||||
static uint32_t rdp_cmd_buf_pos;
|
||||
|
||||
static uint32_t rdp_cmd_pos;
|
||||
static uint32_t rdp_cmd_id;
|
||||
static uint32_t rdp_cmd_len;
|
||||
|
||||
// table of commands that require thread synchronization in
|
||||
// multithreaded mode
|
||||
static bool rdp_cmd_sync[64];
|
||||
|
||||
static void cmd_run_buffered(uint32_t worker_id)
|
||||
{
|
||||
uint32_t pos;
|
||||
for (pos = 0; pos < rdp_cmd_buf_pos; pos++) {
|
||||
rdp_cmd(&state[worker_id], rdp_cmd_buf[pos]);
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_flush(void)
|
||||
{
|
||||
// only run if there's something buffered
|
||||
if (rdp_cmd_buf_pos) {
|
||||
// let workers run all buffered commands in parallel
|
||||
parallel_run(cmd_run_buffered);
|
||||
// reset buffer by starting from the beginning
|
||||
rdp_cmd_buf_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_init(void)
|
||||
{
|
||||
rdp_cmd_pos = 0;
|
||||
rdp_cmd_id = 0;
|
||||
rdp_cmd_len = CMD_MAX_INTS;
|
||||
}
|
||||
|
||||
void n64video_config_init(struct n64video_config* conf)
|
||||
{
|
||||
memset(conf, 0, sizeof(*conf));
|
||||
|
||||
// config defaults that aren't false or 0
|
||||
conf->parallel = true;
|
||||
conf->vi.vsync = true;
|
||||
}
|
||||
|
||||
static void n64video_init_parallel(uint32_t worker_id)
|
||||
{
|
||||
struct rdp_state* wstate = &state[worker_id];
|
||||
|
||||
wstate->stride = parallel_num_workers();
|
||||
wstate->offset = worker_id;
|
||||
wstate->rseed = 3 + worker_id * 13;
|
||||
|
||||
rdp_init(wstate);
|
||||
}
|
||||
|
||||
void n64video_init(struct n64video_config* _config)
|
||||
{
|
||||
if (_config) {
|
||||
config = *_config;
|
||||
}
|
||||
|
||||
// initialize static lookup tables and RDP state, once is enough
|
||||
static bool static_init;
|
||||
if (!static_init) {
|
||||
blender_init_lut();
|
||||
coverage_init_lut();
|
||||
combiner_init_lut();
|
||||
tex_init_lut();
|
||||
z_init_lut();
|
||||
|
||||
static_init = true;
|
||||
}
|
||||
|
||||
// enable sync switches depending on compatibility mode
|
||||
memset(rdp_cmd_sync, 0, sizeof(rdp_cmd_sync));
|
||||
switch (config.dp.compat) {
|
||||
case DP_COMPAT_HIGH:
|
||||
rdp_cmd_sync[CMD_ID_SET_TEXTURE_IMAGE] = true;
|
||||
case DP_COMPAT_MEDIUM:
|
||||
rdp_cmd_sync[CMD_ID_SET_MASK_IMAGE] = true;
|
||||
rdp_cmd_sync[CMD_ID_SET_COLOR_IMAGE] = true;
|
||||
case DP_COMPAT_LOW:
|
||||
rdp_cmd_sync[CMD_ID_SYNC_FULL] = true;
|
||||
}
|
||||
|
||||
// init internals
|
||||
rdram_init();
|
||||
vi_init();
|
||||
cmd_init();
|
||||
|
||||
rdp_pipeline_crashed = 0;
|
||||
memset(&onetimewarnings, 0, sizeof(onetimewarnings));
|
||||
|
||||
if (config.parallel) {
|
||||
// init worker system
|
||||
parallel_init(config.num_workers);
|
||||
|
||||
// sync states from main worker
|
||||
for (uint32_t i = 1; i < parallel_num_workers(); i++) {
|
||||
memcpy(&state[i], &state[0], sizeof(struct rdp_state));
|
||||
}
|
||||
|
||||
// init workers
|
||||
parallel_run(n64video_init_parallel);
|
||||
} else {
|
||||
struct rdp_state* wstate = &state[0];
|
||||
wstate->stride = 1;
|
||||
wstate->offset = 0;
|
||||
wstate->rseed = 3;
|
||||
rdp_init(wstate);
|
||||
}
|
||||
}
|
||||
|
||||
void n64video_process_list(void)
|
||||
{
|
||||
uint32_t** dp_reg = config.gfx.dp_reg;
|
||||
uint32_t dp_current_al = (*dp_reg[DP_CURRENT] & ~7) >> 2;
|
||||
uint32_t dp_end_al = (*dp_reg[DP_END] & ~7) >> 2;
|
||||
|
||||
// don't do anything if the RDP has crashed or the registers are not set up correctly
|
||||
if (rdp_pipeline_crashed || dp_end_al <= dp_current_al) {
|
||||
return;
|
||||
}
|
||||
|
||||
// while there's data in the command buffer...
|
||||
while (dp_end_al - dp_current_al > 0) {
|
||||
uint32_t i, toload;
|
||||
bool xbus_dma = (*dp_reg[DP_STATUS] & DP_STATUS_XBUS_DMA) != 0;
|
||||
uint32_t* dmem = (uint32_t*)config.gfx.dmem;
|
||||
uint32_t* cmd_buf = rdp_cmd_buf[rdp_cmd_buf_pos];
|
||||
|
||||
// when reading the first int, extract the command ID and update the buffer length
|
||||
if (rdp_cmd_pos == 0) {
|
||||
if (xbus_dma) {
|
||||
cmd_buf[rdp_cmd_pos++] = dmem[dp_current_al++ & 0x3ff];
|
||||
} else {
|
||||
cmd_buf[rdp_cmd_pos++] = rdram_read_idx32(dp_current_al++);
|
||||
}
|
||||
|
||||
rdp_cmd_id = CMD_ID(cmd_buf);
|
||||
rdp_cmd_len = rdp_commands[rdp_cmd_id].length >> 2;
|
||||
}
|
||||
|
||||
// copy more data from the N64 to the local command buffer
|
||||
toload = MIN(dp_end_al - dp_current_al, rdp_cmd_len - 1);
|
||||
|
||||
if (xbus_dma) {
|
||||
for (i = 0; i < toload; i++) {
|
||||
cmd_buf[rdp_cmd_pos++] = dmem[dp_current_al++ & 0x3ff];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < toload; i++) {
|
||||
cmd_buf[rdp_cmd_pos++] = rdram_read_idx32(dp_current_al++);
|
||||
}
|
||||
}
|
||||
|
||||
// if there's enough data for the current command...
|
||||
if (rdp_cmd_pos == rdp_cmd_len) {
|
||||
// check if parallel processing is enabled
|
||||
if (config.parallel) {
|
||||
// special case: sync_full always needs to be run in main thread
|
||||
if (rdp_cmd_id == CMD_ID_SYNC_FULL) {
|
||||
// first, run all pending commands
|
||||
cmd_flush();
|
||||
|
||||
// parameters are unused, so NULL is fine
|
||||
rdp_sync_full(NULL, NULL);
|
||||
} else {
|
||||
// increment buffer position
|
||||
rdp_cmd_buf_pos++;
|
||||
|
||||
// flush buffer when it is full or when the current command requires a sync
|
||||
if (rdp_cmd_buf_pos >= CMD_BUFFER_SIZE || rdp_cmd_sync[rdp_cmd_id]) {
|
||||
cmd_flush();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// run command directly
|
||||
rdp_cmd(&state[0], cmd_buf);
|
||||
}
|
||||
|
||||
// send Z-buffer address to VI for "depth" output mode
|
||||
if (rdp_cmd_id == CMD_ID_SET_MASK_IMAGE) {
|
||||
vi_set_zbuffer_address(cmd_buf[1] & 0x0ffffff);
|
||||
}
|
||||
|
||||
// reset current command buffer to prepare for the next one
|
||||
cmd_init();
|
||||
}
|
||||
}
|
||||
|
||||
// update DP registers to indicate that all bytes have been read
|
||||
*dp_reg[DP_START] = *dp_reg[DP_CURRENT] = *dp_reg[DP_END];
|
||||
}
|
||||
|
||||
void n64video_close(void)
|
||||
{
|
||||
vi_close();
|
||||
parallel_close();
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define RDRAM_MAX_SIZE 0x800000
|
||||
|
||||
// register enums
|
||||
enum dp_register
|
||||
{
|
||||
DP_START,
|
||||
DP_END,
|
||||
DP_CURRENT,
|
||||
DP_STATUS,
|
||||
DP_CLOCK,
|
||||
DP_BUFBUSY,
|
||||
DP_PIPEBUSY,
|
||||
DP_TMEM,
|
||||
DP_NUM_REG
|
||||
};
|
||||
|
||||
enum vi_register
|
||||
{
|
||||
VI_STATUS, // aka VI_CONTROL
|
||||
VI_ORIGIN, // aka VI_DRAM_ADDR
|
||||
VI_WIDTH,
|
||||
VI_INTR,
|
||||
VI_V_CURRENT_LINE,
|
||||
VI_TIMING,
|
||||
VI_V_SYNC,
|
||||
VI_H_SYNC,
|
||||
VI_LEAP, // aka VI_H_SYNC_LEAP
|
||||
VI_H_START, // aka VI_H_VIDEO
|
||||
VI_V_START, // aka VI_V_VIDEO
|
||||
VI_V_BURST,
|
||||
VI_X_SCALE,
|
||||
VI_Y_SCALE,
|
||||
VI_NUM_REG
|
||||
};
|
||||
|
||||
// config enums
|
||||
enum vi_mode
|
||||
{
|
||||
VI_MODE_NORMAL, // color buffer with VI filter
|
||||
VI_MODE_COLOR, // direct color buffer, unfiltered
|
||||
VI_MODE_DEPTH, // depth buffer as grayscale
|
||||
VI_MODE_COVERAGE, // coverage as grayscale
|
||||
VI_MODE_NUM
|
||||
};
|
||||
|
||||
enum vi_interp
|
||||
{
|
||||
VI_INTERP_NEAREST,
|
||||
VI_INTERP_LINEAR,
|
||||
VI_INTERP_NUM
|
||||
};
|
||||
|
||||
enum dp_compat_profile
|
||||
{
|
||||
DP_COMPAT_LOW,
|
||||
DP_COMPAT_MEDIUM,
|
||||
DP_COMPAT_HIGH,
|
||||
DP_COMPAT_NUM
|
||||
};
|
||||
|
||||
struct n64video_pixel
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
};
|
||||
|
||||
struct n64video_frame_buffer
|
||||
{
|
||||
struct n64video_pixel* pixels;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t height_out;
|
||||
uint32_t pitch;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
struct n64video_config
|
||||
{
|
||||
struct {
|
||||
uint8_t* rdram; // RDRAM pointer
|
||||
uint32_t rdram_size; // size of RDRAM, typically 4 or 8 MiB
|
||||
uint8_t* dmem; // RSP data memory pointer
|
||||
uint32_t** vi_reg; // video interface registers
|
||||
uint32_t** dp_reg; // display processor registers
|
||||
uint32_t* mi_intr_reg; // MIPS interface interrupt register
|
||||
void (*mi_intr_cb)(void); // interrupt callback function
|
||||
} gfx;
|
||||
struct {
|
||||
enum vi_mode mode; // output mode
|
||||
enum vi_interp interp; // output interpolation method
|
||||
bool widescreen; // force 16:9 aspect ratio if true
|
||||
bool hide_overscan; // crop to visible area if true
|
||||
bool vsync; // enable vsync if true
|
||||
bool exclusive; // run in exclusive mode when in fullscreen if true
|
||||
} vi;
|
||||
struct {
|
||||
enum dp_compat_profile compat; // multithreading compatibility mode
|
||||
} dp;
|
||||
bool parallel; // use multithreaded renderer if true
|
||||
uint32_t num_workers; // number of rendering workers
|
||||
};
|
||||
|
||||
void n64video_config_init(struct n64video_config* config);
|
||||
void n64video_init(struct n64video_config* config);
|
||||
void n64video_update_screen(struct n64video_frame_buffer* fb);
|
||||
void n64video_process_list(void);
|
||||
void n64video_close(void);
|
||||
@@ -0,0 +1,672 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
// bit constants for DP_STATUS
|
||||
#define DP_STATUS_XBUS_DMA 0x001 // DMEM DMA mode is set
|
||||
#define DP_STATUS_FREEZE 0x002 // Freeze has been set
|
||||
#define DP_STATUS_FLUSH 0x004 // Flush has been set
|
||||
#define DP_STATUS_START_GCLK 0x008 // Unknown
|
||||
#define DP_STATUS_TMEM_BUSY 0x010 // TMEM is in use on the RDP
|
||||
#define DP_STATUS_PIPE_BUSY 0x020 // Graphics pipe is in use on the RDP
|
||||
#define DP_STATUS_CMD_BUSY 0x040 // RDP is currently executing a command
|
||||
#define DP_STATUS_CBUF_BUSY 0x080 // RDRAM RDP command buffer is in use
|
||||
#define DP_STATUS_DMA_BUSY 0x100 // DMEM RDP command buffer is in use
|
||||
#define DP_STATUS_END_VALID 0x200 // Unknown
|
||||
#define DP_STATUS_START_VALID 0x400 // Unknown
|
||||
|
||||
#define PIXEL_SIZE_4BIT 0
|
||||
#define PIXEL_SIZE_8BIT 1
|
||||
#define PIXEL_SIZE_16BIT 2
|
||||
#define PIXEL_SIZE_32BIT 3
|
||||
|
||||
#define CYCLE_TYPE_1 0
|
||||
#define CYCLE_TYPE_2 1
|
||||
#define CYCLE_TYPE_COPY 2
|
||||
#define CYCLE_TYPE_FILL 3
|
||||
|
||||
|
||||
#define FORMAT_RGBA 0
|
||||
#define FORMAT_YUV 1
|
||||
#define FORMAT_CI 2
|
||||
#define FORMAT_IA 3
|
||||
#define FORMAT_I 4
|
||||
|
||||
|
||||
#define TEXEL_RGBA4 0
|
||||
#define TEXEL_RGBA8 1
|
||||
#define TEXEL_RGBA16 2
|
||||
#define TEXEL_RGBA32 3
|
||||
#define TEXEL_YUV4 4
|
||||
#define TEXEL_YUV8 5
|
||||
#define TEXEL_YUV16 6
|
||||
#define TEXEL_YUV32 7
|
||||
#define TEXEL_CI4 8
|
||||
#define TEXEL_CI8 9
|
||||
#define TEXEL_CI16 0xa
|
||||
#define TEXEL_CI32 0xb
|
||||
#define TEXEL_IA4 0xc
|
||||
#define TEXEL_IA8 0xd
|
||||
#define TEXEL_IA16 0xe
|
||||
#define TEXEL_IA32 0xf
|
||||
#define TEXEL_I4 0x10
|
||||
#define TEXEL_I8 0x11
|
||||
#define TEXEL_I16 0x12
|
||||
#define TEXEL_I32 0x13
|
||||
|
||||
|
||||
#define SP_INTERRUPT 0x1
|
||||
#define SI_INTERRUPT 0x2
|
||||
#define AI_INTERRUPT 0x4
|
||||
#define VI_INTERRUPT 0x8
|
||||
#define PI_INTERRUPT 0x10
|
||||
#define DP_INTERRUPT 0x20
|
||||
|
||||
struct color
|
||||
{
|
||||
int32_t r, g, b, a;
|
||||
};
|
||||
|
||||
struct rectangle
|
||||
{
|
||||
uint16_t xl, yl, xh, yh;
|
||||
};
|
||||
|
||||
struct other_modes
|
||||
{
|
||||
int cycle_type;
|
||||
int persp_tex_en;
|
||||
int detail_tex_en;
|
||||
int sharpen_tex_en;
|
||||
int tex_lod_en;
|
||||
int en_tlut;
|
||||
int tlut_type;
|
||||
int sample_type;
|
||||
int mid_texel;
|
||||
int bi_lerp0;
|
||||
int bi_lerp1;
|
||||
int convert_one;
|
||||
int key_en;
|
||||
int rgb_dither_sel;
|
||||
int alpha_dither_sel;
|
||||
int blend_m1a_0;
|
||||
int blend_m1a_1;
|
||||
int blend_m1b_0;
|
||||
int blend_m1b_1;
|
||||
int blend_m2a_0;
|
||||
int blend_m2a_1;
|
||||
int blend_m2b_0;
|
||||
int blend_m2b_1;
|
||||
int force_blend;
|
||||
int alpha_cvg_select;
|
||||
int cvg_times_alpha;
|
||||
int z_mode;
|
||||
int cvg_dest;
|
||||
int color_on_cvg;
|
||||
int image_read_en;
|
||||
int z_update_en;
|
||||
int z_compare_en;
|
||||
int antialias_en;
|
||||
int z_source_sel;
|
||||
int dither_alpha_en;
|
||||
int alpha_compare_en;
|
||||
|
||||
struct
|
||||
{
|
||||
int stalederivs;
|
||||
int dolod;
|
||||
int partialreject_1cycle;
|
||||
int partialreject_2cycle;
|
||||
int rgb_alpha_dither;
|
||||
int realblendershiftersneeded;
|
||||
int interpixelblendershiftersneeded;
|
||||
int getditherlevel;
|
||||
int textureuselevel0;
|
||||
int textureuselevel1;
|
||||
} f;
|
||||
};
|
||||
|
||||
struct spansigs
|
||||
{
|
||||
int endspan;
|
||||
int preendspan;
|
||||
int nextspan;
|
||||
int midspan;
|
||||
int longspan;
|
||||
int onelessthanmid;
|
||||
};
|
||||
|
||||
struct tile
|
||||
{
|
||||
int format;
|
||||
int size;
|
||||
int line;
|
||||
int tmem;
|
||||
int palette;
|
||||
int ct, mt, cs, ms;
|
||||
int mask_t, shift_t, mask_s, shift_s;
|
||||
|
||||
uint16_t sl, tl, sh, th;
|
||||
|
||||
struct
|
||||
{
|
||||
int clampdiffs, clampdifft;
|
||||
int clampens, clampent;
|
||||
int masksclamped, masktclamped;
|
||||
int notlutswitch, tlutswitch;
|
||||
} f;
|
||||
};
|
||||
|
||||
struct span
|
||||
{
|
||||
int lx, rx;
|
||||
int unscrx;
|
||||
int validline;
|
||||
int32_t r, g, b, a, s, t, w, z;
|
||||
int32_t majorx[4];
|
||||
int32_t minorx[4];
|
||||
int32_t invalyscan[4];
|
||||
};
|
||||
|
||||
struct combiner_inputs
|
||||
{
|
||||
int sub_a_rgb0;
|
||||
int sub_b_rgb0;
|
||||
int mul_rgb0;
|
||||
int add_rgb0;
|
||||
int sub_a_a0;
|
||||
int sub_b_a0;
|
||||
int mul_a0;
|
||||
int add_a0;
|
||||
|
||||
int sub_a_rgb1;
|
||||
int sub_b_rgb1;
|
||||
int mul_rgb1;
|
||||
int add_rgb1;
|
||||
int sub_a_a1;
|
||||
int sub_b_a1;
|
||||
int mul_a1;
|
||||
int add_a1;
|
||||
};
|
||||
|
||||
struct rdp_state
|
||||
{
|
||||
uint32_t stride;
|
||||
uint32_t offset;
|
||||
|
||||
int blshifta;
|
||||
int blshiftb;
|
||||
int pastblshifta;
|
||||
int pastblshiftb;
|
||||
|
||||
struct span span[1024];
|
||||
|
||||
// span states
|
||||
int spans_ds;
|
||||
int spans_dt;
|
||||
int spans_dw;
|
||||
int spans_dr;
|
||||
int spans_dg;
|
||||
int spans_db;
|
||||
int spans_da;
|
||||
int spans_dz;
|
||||
int spans_dzpix;
|
||||
|
||||
int spans_drdy;
|
||||
int spans_dgdy;
|
||||
int spans_dbdy;
|
||||
int spans_dady;
|
||||
int spans_dzdy;
|
||||
int spans_cdr;
|
||||
int spans_cdg;
|
||||
int spans_cdb;
|
||||
int spans_cda;
|
||||
int spans_cdz;
|
||||
|
||||
int spans_dsdy;
|
||||
int spans_dtdy;
|
||||
int spans_dwdy;
|
||||
|
||||
struct other_modes other_modes;
|
||||
|
||||
struct color combined_color;
|
||||
struct color texel0_color;
|
||||
struct color texel1_color;
|
||||
struct color nexttexel_color;
|
||||
struct color shade_color;
|
||||
int32_t noise;
|
||||
int32_t primitive_lod_frac;
|
||||
|
||||
struct color pixel_color;
|
||||
struct color memory_color;
|
||||
struct color pre_memory_color;
|
||||
|
||||
struct tile tile[8];
|
||||
|
||||
int32_t k0_tf;
|
||||
int32_t k1_tf;
|
||||
int32_t k2_tf;
|
||||
int32_t k3_tf;
|
||||
int32_t k4;
|
||||
int32_t k5;
|
||||
int32_t lod_frac;
|
||||
|
||||
uint32_t max_level;
|
||||
int32_t min_level;
|
||||
|
||||
// irand
|
||||
uint32_t rseed;
|
||||
|
||||
// blender
|
||||
int32_t *blender1a_r[2];
|
||||
int32_t *blender1a_g[2];
|
||||
int32_t *blender1a_b[2];
|
||||
int32_t *blender1b_a[2];
|
||||
int32_t *blender2a_r[2];
|
||||
int32_t *blender2a_g[2];
|
||||
int32_t *blender2a_b[2];
|
||||
int32_t *blender2b_a[2];
|
||||
|
||||
int32_t blender_shade_alpha;
|
||||
|
||||
struct color blend_color;
|
||||
struct color fog_color;
|
||||
struct color inv_pixel_color;
|
||||
struct color blended_pixel_color;
|
||||
|
||||
// combiner
|
||||
struct combiner_inputs combine;
|
||||
|
||||
int32_t *combiner_rgbsub_a_r[2];
|
||||
int32_t *combiner_rgbsub_a_g[2];
|
||||
int32_t *combiner_rgbsub_a_b[2];
|
||||
int32_t *combiner_rgbsub_b_r[2];
|
||||
int32_t *combiner_rgbsub_b_g[2];
|
||||
int32_t *combiner_rgbsub_b_b[2];
|
||||
int32_t *combiner_rgbmul_r[2];
|
||||
int32_t *combiner_rgbmul_g[2];
|
||||
int32_t *combiner_rgbmul_b[2];
|
||||
int32_t *combiner_rgbadd_r[2];
|
||||
int32_t *combiner_rgbadd_g[2];
|
||||
int32_t *combiner_rgbadd_b[2];
|
||||
|
||||
int32_t *combiner_alphasub_a[2];
|
||||
int32_t *combiner_alphasub_b[2];
|
||||
int32_t *combiner_alphamul[2];
|
||||
int32_t *combiner_alphaadd[2];
|
||||
|
||||
struct color prim_color;
|
||||
struct color env_color;
|
||||
struct color key_scale;
|
||||
struct color key_center;
|
||||
struct color key_width;
|
||||
|
||||
int32_t keyalpha;
|
||||
|
||||
// tcoord
|
||||
void (*tcdiv_ptr)(int32_t, int32_t, int32_t, int32_t*, int32_t*);
|
||||
|
||||
// fbuffer
|
||||
void (*fbread1_ptr)(struct rdp_state*, uint32_t, uint32_t*);
|
||||
void (*fbread2_ptr)(struct rdp_state*, uint32_t, uint32_t*);
|
||||
void (*fbwrite_ptr)(struct rdp_state*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
int fb_format;
|
||||
int fb_size;
|
||||
int fb_width;
|
||||
uint32_t fb_address;
|
||||
uint32_t fill_color;
|
||||
|
||||
// rasterizer
|
||||
struct rectangle clip;
|
||||
int scfield;
|
||||
int sckeepodd;
|
||||
|
||||
uint32_t primitive_z;
|
||||
uint16_t primitive_delta_z;
|
||||
|
||||
// tex
|
||||
int ti_format;
|
||||
int ti_size;
|
||||
int ti_width;
|
||||
uint32_t ti_address;
|
||||
|
||||
// coverage
|
||||
uint8_t cvgbuf[1024];
|
||||
|
||||
// tmem
|
||||
uint8_t tmem[0x1000];
|
||||
|
||||
// zbuffer
|
||||
uint32_t zb_address;
|
||||
int32_t pastrawdzmem;
|
||||
};
|
||||
|
||||
struct rdp_state state[PARALLEL_MAX_WORKERS];
|
||||
|
||||
static int32_t one_color = 0x100;
|
||||
static int32_t zero_color = 0x00;
|
||||
|
||||
void rdp_init(struct rdp_state* wstate);
|
||||
void rdp_invalid(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_noop(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tri_noshade(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tri_noshade_z(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tri_tex(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tri_tex_z(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tri_shade(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tri_shade_z(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tri_texshade(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tri_texshade_z(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tex_rect(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_tex_rect_flip(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_sync_load(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_sync_pipe(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_sync_tile(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_sync_full(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_key_gb(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_key_r(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_convert(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_scissor(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_prim_depth(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_other_modes(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_tile_size(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_load_block(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_load_tlut(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_load_tile(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_tile(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_fill_rect(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_fill_color(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_fog_color(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_blend_color(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_prim_color(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_env_color(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_combine(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_texture_image(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_mask_image(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_set_color_image(struct rdp_state* wstate, const uint32_t* args);
|
||||
void rdp_cmd(struct rdp_state* wstate, const uint32_t* args);
|
||||
|
||||
static const struct
|
||||
{
|
||||
// command handler function pointer
|
||||
void (*handler)(struct rdp_state* wstate, const uint32_t*);
|
||||
// command data length in bytes
|
||||
uint32_t length;
|
||||
} rdp_commands[] = {
|
||||
{rdp_noop, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_tri_noshade, 32},
|
||||
{rdp_tri_noshade_z, 48},
|
||||
{rdp_tri_tex, 96},
|
||||
{rdp_tri_tex_z, 112},
|
||||
{rdp_tri_shade, 96},
|
||||
{rdp_tri_shade_z, 112},
|
||||
{rdp_tri_texshade, 160},
|
||||
{rdp_tri_texshade_z, 176},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_tex_rect, 16},
|
||||
{rdp_tex_rect_flip, 16},
|
||||
{rdp_sync_load, 8},
|
||||
{rdp_sync_pipe, 8},
|
||||
{rdp_sync_tile, 8},
|
||||
{rdp_sync_full, 8},
|
||||
{rdp_set_key_gb, 8},
|
||||
{rdp_set_key_r, 8},
|
||||
{rdp_set_convert, 8},
|
||||
{rdp_set_scissor, 8},
|
||||
{rdp_set_prim_depth, 8},
|
||||
{rdp_set_other_modes, 8},
|
||||
{rdp_load_tlut, 8},
|
||||
{rdp_invalid, 8},
|
||||
{rdp_set_tile_size, 8},
|
||||
{rdp_load_block, 8},
|
||||
{rdp_load_tile, 8},
|
||||
{rdp_set_tile, 8},
|
||||
{rdp_fill_rect, 8},
|
||||
{rdp_set_fill_color, 8},
|
||||
{rdp_set_fog_color, 8},
|
||||
{rdp_set_blend_color, 8},
|
||||
{rdp_set_prim_color, 8},
|
||||
{rdp_set_env_color, 8},
|
||||
{rdp_set_combine, 8},
|
||||
{rdp_set_texture_image, 8},
|
||||
{rdp_set_mask_image, 8},
|
||||
{rdp_set_color_image, 8}
|
||||
};
|
||||
|
||||
static void deduce_derivatives(struct rdp_state* wstate);
|
||||
|
||||
#include "rdp/rdram.c"
|
||||
#include "rdp/dither.c"
|
||||
#include "rdp/blender.c"
|
||||
#include "rdp/combiner.c"
|
||||
#include "rdp/coverage.c"
|
||||
#include "rdp/zbuffer.c"
|
||||
#include "rdp/fbuffer.c"
|
||||
#include "rdp/tmem.c"
|
||||
#include "rdp/tcoord.c"
|
||||
#include "rdp/tex.c"
|
||||
#include "rdp/rasterizer.c"
|
||||
|
||||
static void deduce_derivatives(struct rdp_state* wstate)
|
||||
{
|
||||
int special_bsel0, special_bsel1;
|
||||
|
||||
|
||||
wstate->other_modes.f.partialreject_1cycle = (wstate->blender2b_a[0] == &wstate->inv_pixel_color.a && wstate->blender1b_a[0] == &wstate->pixel_color.a);
|
||||
wstate->other_modes.f.partialreject_2cycle = (wstate->blender2b_a[1] == &wstate->inv_pixel_color.a && wstate->blender1b_a[1] == &wstate->pixel_color.a);
|
||||
|
||||
|
||||
special_bsel0 = (wstate->blender2b_a[0] == &wstate->memory_color.a);
|
||||
special_bsel1 = (wstate->blender2b_a[1] == &wstate->memory_color.a);
|
||||
|
||||
|
||||
wstate->other_modes.f.realblendershiftersneeded = (special_bsel0 && wstate->other_modes.cycle_type == CYCLE_TYPE_1) || (special_bsel1 && wstate->other_modes.cycle_type == CYCLE_TYPE_2);
|
||||
wstate->other_modes.f.interpixelblendershiftersneeded = (special_bsel0 && wstate->other_modes.cycle_type == CYCLE_TYPE_2);
|
||||
|
||||
wstate->other_modes.f.rgb_alpha_dither = (wstate->other_modes.rgb_dither_sel << 2) | wstate->other_modes.alpha_dither_sel;
|
||||
|
||||
wstate->tcdiv_ptr = tcdiv_func[wstate->other_modes.persp_tex_en];
|
||||
|
||||
|
||||
int texel1_used_in_cc1 = 0, texel0_used_in_cc1 = 0, texel0_used_in_cc0 = 0, texel1_used_in_cc0 = 0;
|
||||
//int texels_in_cc0 = 0, texels_in_cc1 = 0;
|
||||
int lod_frac_used_in_cc1 = 0, lod_frac_used_in_cc0 = 0;
|
||||
int texels_or_lf_used_in_ac0 = 0, texel0_used_in_ac0 = 0, texel1_used_in_ac0 = 0;
|
||||
|
||||
if ((wstate->combiner_rgbmul_r[1] == &wstate->lod_frac) || (wstate->combiner_alphamul[1] == &wstate->lod_frac))
|
||||
lod_frac_used_in_cc1 = 1;
|
||||
if ((wstate->combiner_rgbmul_r[0] == &wstate->lod_frac) || (wstate->combiner_alphamul[0] == &wstate->lod_frac))
|
||||
lod_frac_used_in_cc0 = 1;
|
||||
|
||||
if (wstate->combiner_rgbmul_r[1] == &wstate->texel1_color.r || wstate->combiner_rgbsub_a_r[1] == &wstate->texel1_color.r || wstate->combiner_rgbsub_b_r[1] == &wstate->texel1_color.r || wstate->combiner_rgbadd_r[1] == &wstate->texel1_color.r || \
|
||||
wstate->combiner_alphamul[1] == &wstate->texel1_color.a || wstate->combiner_alphasub_a[1] == &wstate->texel1_color.a || wstate->combiner_alphasub_b[1] == &wstate->texel1_color.a || wstate->combiner_alphaadd[1] == &wstate->texel1_color.a || \
|
||||
wstate->combiner_rgbmul_r[1] == &wstate->texel1_color.a)
|
||||
texel1_used_in_cc1 = 1;
|
||||
if (wstate->combiner_rgbmul_r[1] == &wstate->texel0_color.r || wstate->combiner_rgbsub_a_r[1] == &wstate->texel0_color.r || wstate->combiner_rgbsub_b_r[1] == &wstate->texel0_color.r || wstate->combiner_rgbadd_r[1] == &wstate->texel0_color.r || \
|
||||
wstate->combiner_alphamul[1] == &wstate->texel0_color.a || wstate->combiner_alphasub_a[1] == &wstate->texel0_color.a || wstate->combiner_alphasub_b[1] == &wstate->texel0_color.a || wstate->combiner_alphaadd[1] == &wstate->texel0_color.a || \
|
||||
wstate->combiner_rgbmul_r[1] == &wstate->texel0_color.a)
|
||||
texel0_used_in_cc1 = 1;
|
||||
if (wstate->combiner_alphamul[0] == &wstate->texel1_color.a || wstate->combiner_alphasub_a[0] == &wstate->texel1_color.a || wstate->combiner_alphasub_b[0] == &wstate->texel1_color.a || wstate->combiner_alphaadd[0] == &wstate->texel1_color.a)
|
||||
texel1_used_in_ac0 = 1;
|
||||
if (wstate->combiner_alphamul[0] == &wstate->texel0_color.a || wstate->combiner_alphasub_a[0] == &wstate->texel0_color.a || wstate->combiner_alphasub_b[0] == &wstate->texel0_color.a || wstate->combiner_alphaadd[0] == &wstate->texel0_color.a)
|
||||
texel0_used_in_ac0 = 1;
|
||||
if (wstate->combiner_rgbmul_r[0] == &wstate->texel1_color.r || wstate->combiner_rgbsub_a_r[0] == &wstate->texel1_color.r || wstate->combiner_rgbsub_b_r[0] == &wstate->texel1_color.r || wstate->combiner_rgbadd_r[0] == &wstate->texel1_color.r || \
|
||||
texel1_used_in_ac0 || wstate->combiner_rgbmul_r[0] == &wstate->texel1_color.a)
|
||||
texel1_used_in_cc0 = 1;
|
||||
if (wstate->combiner_rgbmul_r[0] == &wstate->texel0_color.r || wstate->combiner_rgbsub_a_r[0] == &wstate->texel0_color.r || wstate->combiner_rgbsub_b_r[0] == &wstate->texel0_color.r || wstate->combiner_rgbadd_r[0] == &wstate->texel0_color.r || \
|
||||
texel0_used_in_ac0 || wstate->combiner_rgbmul_r[0] == &wstate->texel0_color.a)
|
||||
texel0_used_in_cc0 = 1;
|
||||
texels_or_lf_used_in_ac0 = texel0_used_in_ac0 || texel1_used_in_ac0 || (wstate->combiner_alphamul[0] == &wstate->lod_frac);
|
||||
//texels_in_cc0 = texel0_used_in_cc0 || texel1_used_in_cc0;
|
||||
//texels_in_cc1 = texel0_used_in_cc1 || texel1_used_in_cc1;
|
||||
|
||||
|
||||
if (texel1_used_in_cc1)
|
||||
wstate->other_modes.f.textureuselevel0 = 0;
|
||||
else if (texel0_used_in_cc1 || lod_frac_used_in_cc1)
|
||||
wstate->other_modes.f.textureuselevel0 = 1;
|
||||
else
|
||||
wstate->other_modes.f.textureuselevel0 = 2;
|
||||
|
||||
if (texel1_used_in_cc1 || (wstate->other_modes.alpha_compare_en && texels_or_lf_used_in_ac0))
|
||||
wstate->other_modes.f.textureuselevel1 = 0;
|
||||
else if (texel1_used_in_cc0 || texel0_used_in_cc1)
|
||||
wstate->other_modes.f.textureuselevel1 = 1;
|
||||
else if (texel0_used_in_cc0 || lod_frac_used_in_cc0 || lod_frac_used_in_cc1)
|
||||
wstate->other_modes.f.textureuselevel1 = 2;
|
||||
else
|
||||
wstate->other_modes.f.textureuselevel1 = 3;
|
||||
|
||||
|
||||
int lodfracused = 0;
|
||||
|
||||
if ((wstate->other_modes.cycle_type == CYCLE_TYPE_2 && (lod_frac_used_in_cc0 || lod_frac_used_in_cc1)) || \
|
||||
(wstate->other_modes.cycle_type == CYCLE_TYPE_1 && lod_frac_used_in_cc1))
|
||||
lodfracused = 1;
|
||||
|
||||
if ((wstate->other_modes.cycle_type == CYCLE_TYPE_1 && wstate->combiner_rgbsub_a_r[1] == &wstate->noise) || \
|
||||
(wstate->other_modes.cycle_type == CYCLE_TYPE_2 && (wstate->combiner_rgbsub_a_r[0] == &wstate->noise || wstate->combiner_rgbsub_a_r[1] == &wstate->noise)) || \
|
||||
wstate->other_modes.alpha_dither_sel == 2)
|
||||
wstate->other_modes.f.getditherlevel = 0;
|
||||
else if (wstate->other_modes.f.rgb_alpha_dither != 0xf)
|
||||
wstate->other_modes.f.getditherlevel = 1;
|
||||
else
|
||||
wstate->other_modes.f.getditherlevel = 2;
|
||||
|
||||
wstate->other_modes.f.dolod = wstate->other_modes.tex_lod_en || lodfracused;
|
||||
}
|
||||
|
||||
void rdp_init(struct rdp_state* wstate)
|
||||
{
|
||||
fb_init(wstate);
|
||||
combiner_init(wstate);
|
||||
tex_init(wstate);
|
||||
rasterizer_init(wstate);
|
||||
|
||||
uint32_t tmp[2] = { 0 };
|
||||
rdp_set_other_modes(wstate, tmp);
|
||||
}
|
||||
|
||||
void rdp_invalid(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
UNUSED(wstate);
|
||||
UNUSED(args);
|
||||
}
|
||||
|
||||
void rdp_noop(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
UNUSED(wstate);
|
||||
UNUSED(args);
|
||||
}
|
||||
|
||||
void rdp_sync_load(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
UNUSED(wstate);
|
||||
UNUSED(args);
|
||||
}
|
||||
|
||||
void rdp_sync_pipe(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
UNUSED(wstate);
|
||||
UNUSED(args);
|
||||
}
|
||||
|
||||
void rdp_sync_tile(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
UNUSED(wstate);
|
||||
UNUSED(args);
|
||||
}
|
||||
|
||||
void rdp_sync_full(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
UNUSED(wstate);
|
||||
UNUSED(args);
|
||||
|
||||
// signal DP interrupt
|
||||
*config.gfx.mi_intr_reg |= DP_INTERRUPT;
|
||||
config.gfx.mi_intr_cb();
|
||||
}
|
||||
|
||||
void rdp_set_other_modes(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->other_modes.cycle_type = (args[0] >> 20) & 3;
|
||||
wstate->other_modes.persp_tex_en = (args[0] >> 19) & 1;
|
||||
wstate->other_modes.detail_tex_en = (args[0] >> 18) & 1;
|
||||
wstate->other_modes.sharpen_tex_en = (args[0] >> 17) & 1;
|
||||
wstate->other_modes.tex_lod_en = (args[0] >> 16) & 1;
|
||||
wstate->other_modes.en_tlut = (args[0] >> 15) & 1;
|
||||
wstate->other_modes.tlut_type = (args[0] >> 14) & 1;
|
||||
wstate->other_modes.sample_type = (args[0] >> 13) & 1;
|
||||
wstate->other_modes.mid_texel = (args[0] >> 12) & 1;
|
||||
wstate->other_modes.bi_lerp0 = (args[0] >> 11) & 1;
|
||||
wstate->other_modes.bi_lerp1 = (args[0] >> 10) & 1;
|
||||
wstate->other_modes.convert_one = (args[0] >> 9) & 1;
|
||||
wstate->other_modes.key_en = (args[0] >> 8) & 1;
|
||||
wstate->other_modes.rgb_dither_sel = (args[0] >> 6) & 3;
|
||||
wstate->other_modes.alpha_dither_sel = (args[0] >> 4) & 3;
|
||||
wstate->other_modes.blend_m1a_0 = (args[1] >> 30) & 3;
|
||||
wstate->other_modes.blend_m1a_1 = (args[1] >> 28) & 3;
|
||||
wstate->other_modes.blend_m1b_0 = (args[1] >> 26) & 3;
|
||||
wstate->other_modes.blend_m1b_1 = (args[1] >> 24) & 3;
|
||||
wstate->other_modes.blend_m2a_0 = (args[1] >> 22) & 3;
|
||||
wstate->other_modes.blend_m2a_1 = (args[1] >> 20) & 3;
|
||||
wstate->other_modes.blend_m2b_0 = (args[1] >> 18) & 3;
|
||||
wstate->other_modes.blend_m2b_1 = (args[1] >> 16) & 3;
|
||||
wstate->other_modes.force_blend = (args[1] >> 14) & 1;
|
||||
wstate->other_modes.alpha_cvg_select = (args[1] >> 13) & 1;
|
||||
wstate->other_modes.cvg_times_alpha = (args[1] >> 12) & 1;
|
||||
wstate->other_modes.z_mode = (args[1] >> 10) & 3;
|
||||
wstate->other_modes.cvg_dest = (args[1] >> 8) & 3;
|
||||
wstate->other_modes.color_on_cvg = (args[1] >> 7) & 1;
|
||||
wstate->other_modes.image_read_en = (args[1] >> 6) & 1;
|
||||
wstate->other_modes.z_update_en = (args[1] >> 5) & 1;
|
||||
wstate->other_modes.z_compare_en = (args[1] >> 4) & 1;
|
||||
wstate->other_modes.antialias_en = (args[1] >> 3) & 1;
|
||||
wstate->other_modes.z_source_sel = (args[1] >> 2) & 1;
|
||||
wstate->other_modes.dither_alpha_en = (args[1] >> 1) & 1;
|
||||
wstate->other_modes.alpha_compare_en = (args[1] >> 0) & 1;
|
||||
|
||||
set_blender_input(wstate, 0, 0, &wstate->blender1a_r[0], &wstate->blender1a_g[0], &wstate->blender1a_b[0], &wstate->blender1b_a[0],
|
||||
wstate->other_modes.blend_m1a_0, wstate->other_modes.blend_m1b_0);
|
||||
set_blender_input(wstate, 0, 1, &wstate->blender2a_r[0], &wstate->blender2a_g[0], &wstate->blender2a_b[0], &wstate->blender2b_a[0],
|
||||
wstate->other_modes.blend_m2a_0, wstate->other_modes.blend_m2b_0);
|
||||
set_blender_input(wstate, 1, 0, &wstate->blender1a_r[1], &wstate->blender1a_g[1], &wstate->blender1a_b[1], &wstate->blender1b_a[1],
|
||||
wstate->other_modes.blend_m1a_1, wstate->other_modes.blend_m1b_1);
|
||||
set_blender_input(wstate, 1, 1, &wstate->blender2a_r[1], &wstate->blender2a_g[1], &wstate->blender2a_b[1], &wstate->blender2b_a[1],
|
||||
wstate->other_modes.blend_m2a_1, wstate->other_modes.blend_m2b_1);
|
||||
|
||||
wstate->other_modes.f.stalederivs = 1;
|
||||
}
|
||||
|
||||
void rdp_cmd(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
uint32_t cmd_id = CMD_ID(args);
|
||||
rdp_commands[cmd_id].handler(wstate, args);
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,350 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static int32_t blenderone = 0xff;
|
||||
|
||||
static uint8_t bldiv_hwaccurate_table[0x8000];
|
||||
|
||||
static INLINE void set_blender_input(struct rdp_state* wstate, int cycle, int which, int32_t **input_r, int32_t **input_g, int32_t **input_b, int32_t **input_a, int a, int b)
|
||||
{
|
||||
|
||||
switch (a & 0x3)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (cycle == 0)
|
||||
{
|
||||
*input_r = &wstate->pixel_color.r;
|
||||
*input_g = &wstate->pixel_color.g;
|
||||
*input_b = &wstate->pixel_color.b;
|
||||
}
|
||||
else
|
||||
{
|
||||
*input_r = &wstate->blended_pixel_color.r;
|
||||
*input_g = &wstate->blended_pixel_color.g;
|
||||
*input_b = &wstate->blended_pixel_color.b;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
*input_r = &wstate->memory_color.r;
|
||||
*input_g = &wstate->memory_color.g;
|
||||
*input_b = &wstate->memory_color.b;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
*input_r = &wstate->blend_color.r; *input_g = &wstate->blend_color.g; *input_b = &wstate->blend_color.b;
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
*input_r = &wstate->fog_color.r; *input_g = &wstate->fog_color.g; *input_b = &wstate->fog_color.b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (which == 0)
|
||||
{
|
||||
switch (b & 0x3)
|
||||
{
|
||||
case 0: *input_a = &wstate->pixel_color.a; break;
|
||||
case 1: *input_a = &wstate->fog_color.a; break;
|
||||
case 2: *input_a = &wstate->blender_shade_alpha; break;
|
||||
case 3: *input_a = &zero_color; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (b & 0x3)
|
||||
{
|
||||
case 0: *input_a = &wstate->inv_pixel_color.a; break;
|
||||
case 1: *input_a = &wstate->memory_color.a; break;
|
||||
case 2: *input_a = &blenderone; break;
|
||||
case 3: *input_a = &zero_color; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE int alpha_compare(struct rdp_state* wstate, int32_t comb_alpha)
|
||||
{
|
||||
int32_t threshold;
|
||||
if (!wstate->other_modes.alpha_compare_en)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if (!wstate->other_modes.dither_alpha_en)
|
||||
threshold = wstate->blend_color.a;
|
||||
else
|
||||
threshold = irand(&wstate->rseed) & 0xff;
|
||||
|
||||
|
||||
if (comb_alpha >= threshold)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void blender_equation_cycle0(struct rdp_state* wstate, int* r, int* g, int* b)
|
||||
{
|
||||
int blend1a, blend2a;
|
||||
int blr, blg, blb, sum;
|
||||
blend1a = *wstate->blender1b_a[0] >> 3;
|
||||
blend2a = *wstate->blender2b_a[0] >> 3;
|
||||
|
||||
int mulb;
|
||||
|
||||
|
||||
|
||||
if (wstate->blender2b_a[0] == &wstate->memory_color.a)
|
||||
{
|
||||
blend1a = (blend1a >> wstate->blshifta) & 0x3C;
|
||||
blend2a = (blend2a >> wstate->blshiftb) | 3;
|
||||
}
|
||||
|
||||
mulb = blend2a + 1;
|
||||
|
||||
|
||||
blr = (*wstate->blender1a_r[0]) * blend1a + (*wstate->blender2a_r[0]) * mulb;
|
||||
blg = (*wstate->blender1a_g[0]) * blend1a + (*wstate->blender2a_g[0]) * mulb;
|
||||
blb = (*wstate->blender1a_b[0]) * blend1a + (*wstate->blender2a_b[0]) * mulb;
|
||||
|
||||
|
||||
|
||||
if (!wstate->other_modes.force_blend)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sum = ((blend1a & ~3) + (blend2a & ~3) + 4) << 9;
|
||||
*r = bldiv_hwaccurate_table[sum | ((blr >> 2) & 0x7ff)];
|
||||
*g = bldiv_hwaccurate_table[sum | ((blg >> 2) & 0x7ff)];
|
||||
*b = bldiv_hwaccurate_table[sum | ((blb >> 2) & 0x7ff)];
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = (blr >> 5) & 0xff;
|
||||
*g = (blg >> 5) & 0xff;
|
||||
*b = (blb >> 5) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void blender_equation_cycle0_2(struct rdp_state* wstate, int* r, int* g, int* b)
|
||||
{
|
||||
int blend1a, blend2a;
|
||||
blend1a = *wstate->blender1b_a[0] >> 3;
|
||||
blend2a = *wstate->blender2b_a[0] >> 3;
|
||||
|
||||
if (wstate->blender2b_a[0] == &wstate->memory_color.a)
|
||||
{
|
||||
blend1a = (blend1a >> wstate->pastblshifta) & 0x3C;
|
||||
blend2a = (blend2a >> wstate->pastblshiftb) | 3;
|
||||
}
|
||||
|
||||
blend2a += 1;
|
||||
*r = (((*wstate->blender1a_r[0]) * blend1a + (*wstate->blender2a_r[0]) * blend2a) >> 5) & 0xff;
|
||||
*g = (((*wstate->blender1a_g[0]) * blend1a + (*wstate->blender2a_g[0]) * blend2a) >> 5) & 0xff;
|
||||
*b = (((*wstate->blender1a_b[0]) * blend1a + (*wstate->blender2a_b[0]) * blend2a) >> 5) & 0xff;
|
||||
}
|
||||
|
||||
static STRICTINLINE void blender_equation_cycle1(struct rdp_state* wstate, int* r, int* g, int* b)
|
||||
{
|
||||
int blend1a, blend2a;
|
||||
int blr, blg, blb, sum;
|
||||
blend1a = *wstate->blender1b_a[1] >> 3;
|
||||
blend2a = *wstate->blender2b_a[1] >> 3;
|
||||
|
||||
int mulb;
|
||||
if (wstate->blender2b_a[1] == &wstate->memory_color.a)
|
||||
{
|
||||
blend1a = (blend1a >> wstate->blshifta) & 0x3C;
|
||||
blend2a = (blend2a >> wstate->blshiftb) | 3;
|
||||
}
|
||||
|
||||
mulb = blend2a + 1;
|
||||
blr = (*wstate->blender1a_r[1]) * blend1a + (*wstate->blender2a_r[1]) * mulb;
|
||||
blg = (*wstate->blender1a_g[1]) * blend1a + (*wstate->blender2a_g[1]) * mulb;
|
||||
blb = (*wstate->blender1a_b[1]) * blend1a + (*wstate->blender2a_b[1]) * mulb;
|
||||
|
||||
if (!wstate->other_modes.force_blend)
|
||||
{
|
||||
sum = ((blend1a & ~3) + (blend2a & ~3) + 4) << 9;
|
||||
*r = bldiv_hwaccurate_table[sum | ((blr >> 2) & 0x7ff)];
|
||||
*g = bldiv_hwaccurate_table[sum | ((blg >> 2) & 0x7ff)];
|
||||
*b = bldiv_hwaccurate_table[sum | ((blb >> 2) & 0x7ff)];
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = (blr >> 5) & 0xff;
|
||||
*g = (blg >> 5) & 0xff;
|
||||
*b = (blb >> 5) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE int blender_1cycle(struct rdp_state* wstate, uint32_t* fr, uint32_t* fg, uint32_t* fb, int dith, uint32_t blend_en, uint32_t prewrap, uint32_t curpixel_cvg, uint32_t curpixel_cvbit)
|
||||
{
|
||||
int r, g, b, dontblend;
|
||||
|
||||
|
||||
if (alpha_compare(wstate, wstate->pixel_color.a))
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (wstate->other_modes.antialias_en ? curpixel_cvg : curpixel_cvbit)
|
||||
{
|
||||
|
||||
if (!wstate->other_modes.color_on_cvg || prewrap)
|
||||
{
|
||||
dontblend = (wstate->other_modes.f.partialreject_1cycle && wstate->pixel_color.a >= 0xff);
|
||||
if (!blend_en || dontblend)
|
||||
{
|
||||
r = *wstate->blender1a_r[0];
|
||||
g = *wstate->blender1a_g[0];
|
||||
b = *wstate->blender1a_b[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
wstate->inv_pixel_color.a = (~(*wstate->blender1b_a[0])) & 0xff;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
blender_equation_cycle0(wstate, &r, &g, &b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = *wstate->blender2a_r[0];
|
||||
g = *wstate->blender2a_g[0];
|
||||
b = *wstate->blender2a_b[0];
|
||||
}
|
||||
|
||||
if (wstate->other_modes.rgb_dither_sel != 3)
|
||||
rgb_dither(wstate->other_modes.rgb_dither_sel, &r, &g, &b, dith);
|
||||
|
||||
*fr = r;
|
||||
*fg = g;
|
||||
*fb = b;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static STRICTINLINE int blender_2cycle_cycle0(struct rdp_state* wstate, uint32_t curpixel_cvg, uint32_t curpixel_cvbit)
|
||||
{
|
||||
int r, g, b;
|
||||
int wen = (wstate->other_modes.antialias_en ? curpixel_cvg : curpixel_cvbit) > 0 ? 1 : 0;
|
||||
|
||||
if (wen)
|
||||
{
|
||||
wstate->inv_pixel_color.a = (~(*wstate->blender1b_a[0])) & 0xff;
|
||||
|
||||
blender_equation_cycle0_2(wstate, &r, &g, &b);
|
||||
|
||||
wstate->blended_pixel_color.r = r;
|
||||
wstate->blended_pixel_color.g = g;
|
||||
wstate->blended_pixel_color.b = b;
|
||||
}
|
||||
|
||||
wstate->memory_color = wstate->pre_memory_color;
|
||||
|
||||
return wen;
|
||||
}
|
||||
|
||||
|
||||
static STRICTINLINE void blender_2cycle_cycle1(struct rdp_state* wstate, uint32_t* fr, uint32_t* fg, uint32_t* fb, int dith, uint32_t blend_en, uint32_t prewrap)
|
||||
{
|
||||
int r, g, b, dontblend;
|
||||
|
||||
if (!wstate->other_modes.color_on_cvg || prewrap)
|
||||
{
|
||||
dontblend = (wstate->other_modes.f.partialreject_2cycle && wstate->pixel_color.a >= 0xff);
|
||||
if (!blend_en || dontblend)
|
||||
{
|
||||
r = *wstate->blender1a_r[1];
|
||||
g = *wstate->blender1a_g[1];
|
||||
b = *wstate->blender1a_b[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
wstate->inv_pixel_color.a = (~(*wstate->blender1b_a[1])) & 0xff;
|
||||
blender_equation_cycle1(wstate, &r, &g, &b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = *wstate->blender2a_r[1];
|
||||
g = *wstate->blender2a_g[1];
|
||||
b = *wstate->blender2a_b[1];
|
||||
}
|
||||
|
||||
if (wstate->other_modes.rgb_dither_sel != 3)
|
||||
rgb_dither(wstate->other_modes.rgb_dither_sel, &r, &g, &b, dith);
|
||||
|
||||
*fr = r;
|
||||
*fg = g;
|
||||
*fb = b;
|
||||
}
|
||||
|
||||
static void blender_init_lut(void)
|
||||
{
|
||||
int i, k;
|
||||
int d = 0, n = 0, temp = 0, res = 0, invd = 0, nbit = 0;
|
||||
int ps[9];
|
||||
for (i = 0; i < 0x8000; i++)
|
||||
{
|
||||
res = 0;
|
||||
d = (i >> 11) & 0xf;
|
||||
n = i & 0x7ff;
|
||||
invd = (~d) & 0xf;
|
||||
|
||||
|
||||
temp = invd + (n >> 8) + 1;
|
||||
ps[0] = temp & 7;
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
nbit = (n >> (7 - k)) & 1;
|
||||
if (res & (0x100 >> k))
|
||||
temp = invd + (ps[k] << 1) + nbit + 1;
|
||||
else
|
||||
temp = d + (ps[k] << 1) + nbit;
|
||||
ps[k + 1] = temp & 7;
|
||||
if (temp & 0x10)
|
||||
res |= (1 << (7 - k));
|
||||
}
|
||||
bldiv_hwaccurate_table[i] = (uint8_t)res;
|
||||
}
|
||||
}
|
||||
|
||||
void rdp_set_fog_color(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->fog_color.r = RGBA32_R(args[1]);
|
||||
wstate->fog_color.g = RGBA32_G(args[1]);
|
||||
wstate->fog_color.b = RGBA32_B(args[1]);
|
||||
wstate->fog_color.a = RGBA32_A(args[1]);
|
||||
}
|
||||
|
||||
void rdp_set_blend_color(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->blend_color.r = RGBA32_R(args[1]);
|
||||
wstate->blend_color.g = RGBA32_G(args[1]);
|
||||
wstate->blend_color.b = RGBA32_B(args[1]);
|
||||
wstate->blend_color.a = RGBA32_A(args[1]);
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,581 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static uint32_t special_9bit_clamptable[512];
|
||||
static int32_t special_9bit_exttable[512];
|
||||
|
||||
static INLINE void set_suba_rgb_input(struct rdp_state* wstate, int32_t **input_r, int32_t **input_g, int32_t **input_b, int code)
|
||||
{
|
||||
switch (code & 0xf)
|
||||
{
|
||||
case 0: *input_r = &wstate->combined_color.r; *input_g = &wstate->combined_color.g; *input_b = &wstate->combined_color.b; break;
|
||||
case 1: *input_r = &wstate->texel0_color.r; *input_g = &wstate->texel0_color.g; *input_b = &wstate->texel0_color.b; break;
|
||||
case 2: *input_r = &wstate->texel1_color.r; *input_g = &wstate->texel1_color.g; *input_b = &wstate->texel1_color.b; break;
|
||||
case 3: *input_r = &wstate->prim_color.r; *input_g = &wstate->prim_color.g; *input_b = &wstate->prim_color.b; break;
|
||||
case 4: *input_r = &wstate->shade_color.r; *input_g = &wstate->shade_color.g; *input_b = &wstate->shade_color.b; break;
|
||||
case 5: *input_r = &wstate->env_color.r; *input_g = &wstate->env_color.g; *input_b = &wstate->env_color.b; break;
|
||||
case 6: *input_r = &one_color; *input_g = &one_color; *input_b = &one_color; break;
|
||||
case 7: *input_r = &wstate->noise; *input_g = &wstate->noise; *input_b = &wstate->noise; break;
|
||||
case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
|
||||
{
|
||||
*input_r = &zero_color; *input_g = &zero_color; *input_b = &zero_color; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void set_subb_rgb_input(struct rdp_state* wstate, int32_t **input_r, int32_t **input_g, int32_t **input_b, int code)
|
||||
{
|
||||
switch (code & 0xf)
|
||||
{
|
||||
case 0: *input_r = &wstate->combined_color.r; *input_g = &wstate->combined_color.g; *input_b = &wstate->combined_color.b; break;
|
||||
case 1: *input_r = &wstate->texel0_color.r; *input_g = &wstate->texel0_color.g; *input_b = &wstate->texel0_color.b; break;
|
||||
case 2: *input_r = &wstate->texel1_color.r; *input_g = &wstate->texel1_color.g; *input_b = &wstate->texel1_color.b; break;
|
||||
case 3: *input_r = &wstate->prim_color.r; *input_g = &wstate->prim_color.g; *input_b = &wstate->prim_color.b; break;
|
||||
case 4: *input_r = &wstate->shade_color.r; *input_g = &wstate->shade_color.g; *input_b = &wstate->shade_color.b; break;
|
||||
case 5: *input_r = &wstate->env_color.r; *input_g = &wstate->env_color.g; *input_b = &wstate->env_color.b; break;
|
||||
case 6: *input_r = &wstate->key_center.r; *input_g = &wstate->key_center.g; *input_b = &wstate->key_center.b; break;
|
||||
case 7: *input_r = &wstate->k4; *input_g = &wstate->k4; *input_b = &wstate->k4; break;
|
||||
case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
|
||||
{
|
||||
*input_r = &zero_color; *input_g = &zero_color; *input_b = &zero_color; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void set_mul_rgb_input(struct rdp_state* wstate, int32_t **input_r, int32_t **input_g, int32_t **input_b, int code)
|
||||
{
|
||||
switch (code & 0x1f)
|
||||
{
|
||||
case 0: *input_r = &wstate->combined_color.r; *input_g = &wstate->combined_color.g; *input_b = &wstate->combined_color.b; break;
|
||||
case 1: *input_r = &wstate->texel0_color.r; *input_g = &wstate->texel0_color.g; *input_b = &wstate->texel0_color.b; break;
|
||||
case 2: *input_r = &wstate->texel1_color.r; *input_g = &wstate->texel1_color.g; *input_b = &wstate->texel1_color.b; break;
|
||||
case 3: *input_r = &wstate->prim_color.r; *input_g = &wstate->prim_color.g; *input_b = &wstate->prim_color.b; break;
|
||||
case 4: *input_r = &wstate->shade_color.r; *input_g = &wstate->shade_color.g; *input_b = &wstate->shade_color.b; break;
|
||||
case 5: *input_r = &wstate->env_color.r; *input_g = &wstate->env_color.g; *input_b = &wstate->env_color.b; break;
|
||||
case 6: *input_r = &wstate->key_scale.r; *input_g = &wstate->key_scale.g; *input_b = &wstate->key_scale.b; break;
|
||||
case 7: *input_r = &wstate->combined_color.a; *input_g = &wstate->combined_color.a; *input_b = &wstate->combined_color.a; break;
|
||||
case 8: *input_r = &wstate->texel0_color.a; *input_g = &wstate->texel0_color.a; *input_b = &wstate->texel0_color.a; break;
|
||||
case 9: *input_r = &wstate->texel1_color.a; *input_g = &wstate->texel1_color.a; *input_b = &wstate->texel1_color.a; break;
|
||||
case 10: *input_r = &wstate->prim_color.a; *input_g = &wstate->prim_color.a; *input_b = &wstate->prim_color.a; break;
|
||||
case 11: *input_r = &wstate->shade_color.a; *input_g = &wstate->shade_color.a; *input_b = &wstate->shade_color.a; break;
|
||||
case 12: *input_r = &wstate->env_color.a; *input_g = &wstate->env_color.a; *input_b = &wstate->env_color.a; break;
|
||||
case 13: *input_r = &wstate->lod_frac; *input_g = &wstate->lod_frac; *input_b = &wstate->lod_frac; break;
|
||||
case 14: *input_r = &wstate->primitive_lod_frac; *input_g = &wstate->primitive_lod_frac; *input_b = &wstate->primitive_lod_frac; break;
|
||||
case 15: *input_r = &wstate->k5; *input_g = &wstate->k5; *input_b = &wstate->k5; break;
|
||||
case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
|
||||
case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
|
||||
{
|
||||
*input_r = &zero_color; *input_g = &zero_color; *input_b = &zero_color; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void set_add_rgb_input(struct rdp_state* wstate, int32_t **input_r, int32_t **input_g, int32_t **input_b, int code)
|
||||
{
|
||||
switch (code & 0x7)
|
||||
{
|
||||
case 0: *input_r = &wstate->combined_color.r; *input_g = &wstate->combined_color.g; *input_b = &wstate->combined_color.b; break;
|
||||
case 1: *input_r = &wstate->texel0_color.r; *input_g = &wstate->texel0_color.g; *input_b = &wstate->texel0_color.b; break;
|
||||
case 2: *input_r = &wstate->texel1_color.r; *input_g = &wstate->texel1_color.g; *input_b = &wstate->texel1_color.b; break;
|
||||
case 3: *input_r = &wstate->prim_color.r; *input_g = &wstate->prim_color.g; *input_b = &wstate->prim_color.b; break;
|
||||
case 4: *input_r = &wstate->shade_color.r; *input_g = &wstate->shade_color.g; *input_b = &wstate->shade_color.b; break;
|
||||
case 5: *input_r = &wstate->env_color.r; *input_g = &wstate->env_color.g; *input_b = &wstate->env_color.b; break;
|
||||
case 6: *input_r = &one_color; *input_g = &one_color; *input_b = &one_color; break;
|
||||
case 7: *input_r = &zero_color; *input_g = &zero_color; *input_b = &zero_color; break;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void set_sub_alpha_input(struct rdp_state* wstate, int32_t **input, int code)
|
||||
{
|
||||
switch (code & 0x7)
|
||||
{
|
||||
case 0: *input = &wstate->combined_color.a; break;
|
||||
case 1: *input = &wstate->texel0_color.a; break;
|
||||
case 2: *input = &wstate->texel1_color.a; break;
|
||||
case 3: *input = &wstate->prim_color.a; break;
|
||||
case 4: *input = &wstate->shade_color.a; break;
|
||||
case 5: *input = &wstate->env_color.a; break;
|
||||
case 6: *input = &one_color; break;
|
||||
case 7: *input = &zero_color; break;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void set_mul_alpha_input(struct rdp_state* wstate, int32_t **input, int code)
|
||||
{
|
||||
switch (code & 0x7)
|
||||
{
|
||||
case 0: *input = &wstate->lod_frac; break;
|
||||
case 1: *input = &wstate->texel0_color.a; break;
|
||||
case 2: *input = &wstate->texel1_color.a; break;
|
||||
case 3: *input = &wstate->prim_color.a; break;
|
||||
case 4: *input = &wstate->shade_color.a; break;
|
||||
case 5: *input = &wstate->env_color.a; break;
|
||||
case 6: *input = &wstate->primitive_lod_frac; break;
|
||||
case 7: *input = &zero_color; break;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE int32_t color_combiner_equation(int32_t a, int32_t b, int32_t c, int32_t d)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
a = special_9bit_exttable[a];
|
||||
b = special_9bit_exttable[b];
|
||||
c = SIGNF(c, 9);
|
||||
d = special_9bit_exttable[d];
|
||||
a = ((a - b) * c) + (d << 8) + 0x80;
|
||||
return (a & 0x1ffff);
|
||||
}
|
||||
|
||||
static STRICTINLINE int32_t alpha_combiner_equation(int32_t a, int32_t b, int32_t c, int32_t d)
|
||||
{
|
||||
a = special_9bit_exttable[a];
|
||||
b = special_9bit_exttable[b];
|
||||
c = SIGNF(c, 9);
|
||||
d = special_9bit_exttable[d];
|
||||
a = (((a - b) * c) + (d << 8) + 0x80) >> 8;
|
||||
return (a & 0x1ff);
|
||||
}
|
||||
|
||||
static STRICTINLINE int32_t chroma_key_min(struct rdp_state* wstate, struct color* col)
|
||||
{
|
||||
int32_t redkey, greenkey, bluekey, keyalpha;
|
||||
|
||||
|
||||
|
||||
|
||||
redkey = SIGN(col->r, 17);
|
||||
if (redkey > 0)
|
||||
redkey = ((redkey & 0xf) == 8) ? (-redkey + 0x10) : (-redkey);
|
||||
|
||||
redkey = (wstate->key_width.r << 4) + redkey;
|
||||
|
||||
greenkey = SIGN(col->g, 17);
|
||||
if (greenkey > 0)
|
||||
greenkey = ((greenkey & 0xf) == 8) ? (-greenkey + 0x10) : (-greenkey);
|
||||
|
||||
greenkey = (wstate->key_width.g << 4) + greenkey;
|
||||
|
||||
bluekey = SIGN(col->b, 17);
|
||||
if (bluekey > 0)
|
||||
bluekey = ((bluekey & 0xf) == 8) ? (-bluekey + 0x10) : (-bluekey);
|
||||
|
||||
bluekey = (wstate->key_width.b << 4) + bluekey;
|
||||
|
||||
keyalpha = (redkey < greenkey) ? redkey : greenkey;
|
||||
keyalpha = (bluekey < keyalpha) ? bluekey : keyalpha;
|
||||
keyalpha = clamp(keyalpha, 0, 0xff);
|
||||
return keyalpha;
|
||||
}
|
||||
|
||||
static STRICTINLINE void combiner_1cycle(struct rdp_state* wstate, int adseed, uint32_t* curpixel_cvg)
|
||||
{
|
||||
|
||||
int32_t keyalpha = 0, temp = 0;
|
||||
struct color chromabypass = { 0 };
|
||||
|
||||
if (wstate->other_modes.key_en)
|
||||
{
|
||||
chromabypass.r = *wstate->combiner_rgbsub_a_r[1];
|
||||
chromabypass.g = *wstate->combiner_rgbsub_a_g[1];
|
||||
chromabypass.b = *wstate->combiner_rgbsub_a_b[1];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (wstate->combiner_rgbmul_r[1] != &zero_color)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
wstate->combined_color.r = color_combiner_equation(*wstate->combiner_rgbsub_a_r[1],*wstate->combiner_rgbsub_b_r[1],*wstate->combiner_rgbmul_r[1],*wstate->combiner_rgbadd_r[1]);
|
||||
wstate->combined_color.g = color_combiner_equation(*wstate->combiner_rgbsub_a_g[1],*wstate->combiner_rgbsub_b_g[1],*wstate->combiner_rgbmul_g[1],*wstate->combiner_rgbadd_g[1]);
|
||||
wstate->combined_color.b = color_combiner_equation(*wstate->combiner_rgbsub_a_b[1],*wstate->combiner_rgbsub_b_b[1],*wstate->combiner_rgbmul_b[1],*wstate->combiner_rgbadd_b[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
wstate->combined_color.r = ((special_9bit_exttable[*wstate->combiner_rgbadd_r[1]] << 8) + 0x80) & 0x1ffff;
|
||||
wstate->combined_color.g = ((special_9bit_exttable[*wstate->combiner_rgbadd_g[1]] << 8) + 0x80) & 0x1ffff;
|
||||
wstate->combined_color.b = ((special_9bit_exttable[*wstate->combiner_rgbadd_b[1]] << 8) + 0x80) & 0x1ffff;
|
||||
}
|
||||
|
||||
if (wstate->combiner_alphamul[1] != &zero_color)
|
||||
wstate->combined_color.a = alpha_combiner_equation(*wstate->combiner_alphasub_a[1],*wstate->combiner_alphasub_b[1],*wstate->combiner_alphamul[1],*wstate->combiner_alphaadd[1]);
|
||||
else
|
||||
wstate->combined_color.a = special_9bit_exttable[*wstate->combiner_alphaadd[1]] & 0x1ff;
|
||||
|
||||
wstate->pixel_color.a = special_9bit_clamptable[wstate->combined_color.a];
|
||||
if (wstate->pixel_color.a == 0xff)
|
||||
wstate->pixel_color.a = 0x100;
|
||||
|
||||
if (!wstate->other_modes.key_en)
|
||||
{
|
||||
|
||||
wstate->combined_color.r >>= 8;
|
||||
wstate->combined_color.g >>= 8;
|
||||
wstate->combined_color.b >>= 8;
|
||||
wstate->pixel_color.r = special_9bit_clamptable[wstate->combined_color.r];
|
||||
wstate->pixel_color.g = special_9bit_clamptable[wstate->combined_color.g];
|
||||
wstate->pixel_color.b = special_9bit_clamptable[wstate->combined_color.b];
|
||||
}
|
||||
else
|
||||
{
|
||||
keyalpha = chroma_key_min(wstate, &wstate->combined_color);
|
||||
|
||||
|
||||
|
||||
wstate->pixel_color.r = special_9bit_clamptable[chromabypass.r];
|
||||
wstate->pixel_color.g = special_9bit_clamptable[chromabypass.g];
|
||||
wstate->pixel_color.b = special_9bit_clamptable[chromabypass.b];
|
||||
|
||||
|
||||
wstate->combined_color.r >>= 8;
|
||||
wstate->combined_color.g >>= 8;
|
||||
wstate->combined_color.b >>= 8;
|
||||
}
|
||||
|
||||
|
||||
if (wstate->other_modes.cvg_times_alpha)
|
||||
{
|
||||
temp = (wstate->pixel_color.a * (*curpixel_cvg) + 4) >> 3;
|
||||
*curpixel_cvg = (temp >> 5) & 0xf;
|
||||
}
|
||||
|
||||
if (!wstate->other_modes.alpha_cvg_select)
|
||||
{
|
||||
if (!wstate->other_modes.key_en)
|
||||
{
|
||||
wstate->pixel_color.a += adseed;
|
||||
if (wstate->pixel_color.a & 0x100)
|
||||
wstate->pixel_color.a = 0xff;
|
||||
}
|
||||
else
|
||||
wstate->pixel_color.a = keyalpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wstate->other_modes.cvg_times_alpha)
|
||||
wstate->pixel_color.a = temp;
|
||||
else
|
||||
wstate->pixel_color.a = (*curpixel_cvg) << 5;
|
||||
if (wstate->pixel_color.a > 0xff)
|
||||
wstate->pixel_color.a = 0xff;
|
||||
}
|
||||
|
||||
wstate->blender_shade_alpha = wstate->shade_color.a + adseed;
|
||||
if (wstate->blender_shade_alpha & 0x100)
|
||||
wstate->blender_shade_alpha = 0xff;
|
||||
}
|
||||
|
||||
static STRICTINLINE void combiner_2cycle_cycle0(struct rdp_state* wstate, int adseed, uint32_t cvg, uint32_t* acalpha)
|
||||
{
|
||||
if (wstate->combiner_rgbmul_r[0] != &zero_color)
|
||||
{
|
||||
wstate->combined_color.r = color_combiner_equation(*wstate->combiner_rgbsub_a_r[0],*wstate->combiner_rgbsub_b_r[0],*wstate->combiner_rgbmul_r[0],*wstate->combiner_rgbadd_r[0]);
|
||||
wstate->combined_color.g = color_combiner_equation(*wstate->combiner_rgbsub_a_g[0],*wstate->combiner_rgbsub_b_g[0],*wstate->combiner_rgbmul_g[0],*wstate->combiner_rgbadd_g[0]);
|
||||
wstate->combined_color.b = color_combiner_equation(*wstate->combiner_rgbsub_a_b[0],*wstate->combiner_rgbsub_b_b[0],*wstate->combiner_rgbmul_b[0],*wstate->combiner_rgbadd_b[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
wstate->combined_color.r = ((special_9bit_exttable[*wstate->combiner_rgbadd_r[0]] << 8) + 0x80) & 0x1ffff;
|
||||
wstate->combined_color.g = ((special_9bit_exttable[*wstate->combiner_rgbadd_g[0]] << 8) + 0x80) & 0x1ffff;
|
||||
wstate->combined_color.b = ((special_9bit_exttable[*wstate->combiner_rgbadd_b[0]] << 8) + 0x80) & 0x1ffff;
|
||||
}
|
||||
|
||||
if (wstate->combiner_alphamul[0] != &zero_color)
|
||||
wstate->combined_color.a = alpha_combiner_equation(*wstate->combiner_alphasub_a[0],*wstate->combiner_alphasub_b[0],*wstate->combiner_alphamul[0],*wstate->combiner_alphaadd[0]);
|
||||
else
|
||||
wstate->combined_color.a = special_9bit_exttable[*wstate->combiner_alphaadd[0]] & 0x1ff;
|
||||
|
||||
|
||||
|
||||
if (wstate->other_modes.alpha_compare_en)
|
||||
{
|
||||
int32_t preacalpha = special_9bit_clamptable[wstate->combined_color.a];
|
||||
if (preacalpha == 0xff)
|
||||
preacalpha = 0x100;
|
||||
|
||||
if (!wstate->other_modes.alpha_cvg_select)
|
||||
{
|
||||
preacalpha += adseed;
|
||||
if (preacalpha & 0x100)
|
||||
preacalpha = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wstate->other_modes.cvg_times_alpha)
|
||||
preacalpha = (preacalpha * cvg + 4) >> 3;
|
||||
else
|
||||
preacalpha = cvg << 5;
|
||||
|
||||
if (preacalpha > 0xff)
|
||||
preacalpha = 0xff;
|
||||
}
|
||||
|
||||
*acalpha = preacalpha;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
wstate->combined_color.r >>= 8;
|
||||
wstate->combined_color.g >>= 8;
|
||||
wstate->combined_color.b >>= 8;
|
||||
|
||||
wstate->blender_shade_alpha = wstate->shade_color.a + adseed;
|
||||
if (wstate->blender_shade_alpha & 0x100)
|
||||
wstate->blender_shade_alpha = 0xff;
|
||||
}
|
||||
|
||||
static STRICTINLINE void combiner_2cycle_cycle1(struct rdp_state* wstate, int adseed, uint32_t* curpixel_cvg)
|
||||
{
|
||||
int32_t keyalpha = 0, temp = 0;
|
||||
struct color chromabypass = { 0 };
|
||||
|
||||
wstate->texel0_color = wstate->texel1_color;
|
||||
wstate->texel1_color = wstate->nexttexel_color;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (wstate->other_modes.key_en)
|
||||
{
|
||||
chromabypass.r = *wstate->combiner_rgbsub_a_r[1];
|
||||
chromabypass.g = *wstate->combiner_rgbsub_a_g[1];
|
||||
chromabypass.b = *wstate->combiner_rgbsub_a_b[1];
|
||||
}
|
||||
|
||||
if (wstate->combiner_rgbmul_r[1] != &zero_color)
|
||||
{
|
||||
wstate->combined_color.r = color_combiner_equation(*wstate->combiner_rgbsub_a_r[1],*wstate->combiner_rgbsub_b_r[1],*wstate->combiner_rgbmul_r[1],*wstate->combiner_rgbadd_r[1]);
|
||||
wstate->combined_color.g = color_combiner_equation(*wstate->combiner_rgbsub_a_g[1],*wstate->combiner_rgbsub_b_g[1],*wstate->combiner_rgbmul_g[1],*wstate->combiner_rgbadd_g[1]);
|
||||
wstate->combined_color.b = color_combiner_equation(*wstate->combiner_rgbsub_a_b[1],*wstate->combiner_rgbsub_b_b[1],*wstate->combiner_rgbmul_b[1],*wstate->combiner_rgbadd_b[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
wstate->combined_color.r = ((special_9bit_exttable[*wstate->combiner_rgbadd_r[1]] << 8) + 0x80) & 0x1ffff;
|
||||
wstate->combined_color.g = ((special_9bit_exttable[*wstate->combiner_rgbadd_g[1]] << 8) + 0x80) & 0x1ffff;
|
||||
wstate->combined_color.b = ((special_9bit_exttable[*wstate->combiner_rgbadd_b[1]] << 8) + 0x80) & 0x1ffff;
|
||||
}
|
||||
|
||||
if (wstate->combiner_alphamul[1] != &zero_color)
|
||||
wstate->combined_color.a = alpha_combiner_equation(*wstate->combiner_alphasub_a[1],*wstate->combiner_alphasub_b[1],*wstate->combiner_alphamul[1],*wstate->combiner_alphaadd[1]);
|
||||
else
|
||||
wstate->combined_color.a = special_9bit_exttable[*wstate->combiner_alphaadd[1]] & 0x1ff;
|
||||
|
||||
if (!wstate->other_modes.key_en)
|
||||
{
|
||||
|
||||
wstate->combined_color.r >>= 8;
|
||||
wstate->combined_color.g >>= 8;
|
||||
wstate->combined_color.b >>= 8;
|
||||
|
||||
wstate->pixel_color.r = special_9bit_clamptable[wstate->combined_color.r];
|
||||
wstate->pixel_color.g = special_9bit_clamptable[wstate->combined_color.g];
|
||||
wstate->pixel_color.b = special_9bit_clamptable[wstate->combined_color.b];
|
||||
}
|
||||
else
|
||||
{
|
||||
keyalpha = chroma_key_min(wstate, &wstate->combined_color);
|
||||
|
||||
|
||||
|
||||
wstate->pixel_color.r = special_9bit_clamptable[chromabypass.r];
|
||||
wstate->pixel_color.g = special_9bit_clamptable[chromabypass.g];
|
||||
wstate->pixel_color.b = special_9bit_clamptable[chromabypass.b];
|
||||
|
||||
|
||||
wstate->combined_color.r >>= 8;
|
||||
wstate->combined_color.g >>= 8;
|
||||
wstate->combined_color.b >>= 8;
|
||||
}
|
||||
|
||||
wstate->pixel_color.a = special_9bit_clamptable[wstate->combined_color.a];
|
||||
if (wstate->pixel_color.a == 0xff)
|
||||
wstate->pixel_color.a = 0x100;
|
||||
|
||||
|
||||
if (wstate->other_modes.cvg_times_alpha)
|
||||
{
|
||||
temp = (wstate->pixel_color.a * (*curpixel_cvg) + 4) >> 3;
|
||||
|
||||
*curpixel_cvg = (temp >> 5) & 0xf;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (!wstate->other_modes.alpha_cvg_select)
|
||||
{
|
||||
if (!wstate->other_modes.key_en)
|
||||
{
|
||||
wstate->pixel_color.a += adseed;
|
||||
if (wstate->pixel_color.a & 0x100)
|
||||
wstate->pixel_color.a = 0xff;
|
||||
}
|
||||
else
|
||||
wstate->pixel_color.a = keyalpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wstate->other_modes.cvg_times_alpha)
|
||||
wstate->pixel_color.a = temp;
|
||||
else
|
||||
wstate->pixel_color.a = (*curpixel_cvg) << 5;
|
||||
if (wstate->pixel_color.a > 0xff)
|
||||
wstate->pixel_color.a = 0xff;
|
||||
}
|
||||
|
||||
wstate->blender_shade_alpha = wstate->shade_color.a + adseed;
|
||||
if (wstate->blender_shade_alpha & 0x100)
|
||||
wstate->blender_shade_alpha = 0xff;
|
||||
}
|
||||
|
||||
static void combiner_init_lut(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 0x200; i++)
|
||||
{
|
||||
switch((i >> 7) & 3)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
special_9bit_clamptable[i] = i & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
special_9bit_clamptable[i] = 0xff;
|
||||
break;
|
||||
case 3:
|
||||
special_9bit_clamptable[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x200; i++)
|
||||
{
|
||||
special_9bit_exttable[i] = ((i & 0x180) == 0x180) ? (i | ~0x1ff) : (i & 0x1ff);
|
||||
}
|
||||
}
|
||||
|
||||
static void combiner_init(struct rdp_state* wstate)
|
||||
{
|
||||
wstate->combiner_rgbsub_a_r[0] = wstate->combiner_rgbsub_a_r[1] = &one_color;
|
||||
wstate->combiner_rgbsub_a_g[0] = wstate->combiner_rgbsub_a_g[1] = &one_color;
|
||||
wstate->combiner_rgbsub_a_b[0] = wstate->combiner_rgbsub_a_b[1] = &one_color;
|
||||
wstate->combiner_rgbsub_b_r[0] = wstate->combiner_rgbsub_b_r[1] = &one_color;
|
||||
wstate->combiner_rgbsub_b_g[0] = wstate->combiner_rgbsub_b_g[1] = &one_color;
|
||||
wstate->combiner_rgbsub_b_b[0] = wstate->combiner_rgbsub_b_b[1] = &one_color;
|
||||
wstate->combiner_rgbmul_r[0] = wstate->combiner_rgbmul_r[1] = &one_color;
|
||||
wstate->combiner_rgbmul_g[0] = wstate->combiner_rgbmul_g[1] = &one_color;
|
||||
wstate->combiner_rgbmul_b[0] = wstate->combiner_rgbmul_b[1] = &one_color;
|
||||
wstate->combiner_rgbadd_r[0] = wstate->combiner_rgbadd_r[1] = &one_color;
|
||||
wstate->combiner_rgbadd_g[0] = wstate->combiner_rgbadd_g[1] = &one_color;
|
||||
wstate->combiner_rgbadd_b[0] = wstate->combiner_rgbadd_b[1] = &one_color;
|
||||
|
||||
wstate->combiner_alphasub_a[0] = wstate->combiner_alphasub_a[1] = &one_color;
|
||||
wstate->combiner_alphasub_b[0] = wstate->combiner_alphasub_b[1] = &one_color;
|
||||
wstate->combiner_alphamul[0] = wstate->combiner_alphamul[1] = &one_color;
|
||||
wstate->combiner_alphaadd[0] = wstate->combiner_alphaadd[1] = &one_color;
|
||||
}
|
||||
|
||||
void rdp_set_prim_color(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->min_level = (args[0] >> 8) & 0x1f;
|
||||
wstate->primitive_lod_frac = args[0] & 0xff;
|
||||
wstate->prim_color.r = RGBA32_R(args[1]);
|
||||
wstate->prim_color.g = RGBA32_G(args[1]);
|
||||
wstate->prim_color.b = RGBA32_B(args[1]);
|
||||
wstate->prim_color.a = RGBA32_A(args[1]);
|
||||
}
|
||||
|
||||
void rdp_set_env_color(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->env_color.r = RGBA32_R(args[1]);
|
||||
wstate->env_color.g = RGBA32_G(args[1]);
|
||||
wstate->env_color.b = RGBA32_B(args[1]);
|
||||
wstate->env_color.a = RGBA32_A(args[1]);
|
||||
}
|
||||
|
||||
void rdp_set_combine(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->combine.sub_a_rgb0 = (args[0] >> 20) & 0xf;
|
||||
wstate->combine.mul_rgb0 = (args[0] >> 15) & 0x1f;
|
||||
wstate->combine.sub_a_a0 = (args[0] >> 12) & 0x7;
|
||||
wstate->combine.mul_a0 = (args[0] >> 9) & 0x7;
|
||||
wstate->combine.sub_a_rgb1 = (args[0] >> 5) & 0xf;
|
||||
wstate->combine.mul_rgb1 = (args[0] >> 0) & 0x1f;
|
||||
|
||||
wstate->combine.sub_b_rgb0 = (args[1] >> 28) & 0xf;
|
||||
wstate->combine.sub_b_rgb1 = (args[1] >> 24) & 0xf;
|
||||
wstate->combine.sub_a_a1 = (args[1] >> 21) & 0x7;
|
||||
wstate->combine.mul_a1 = (args[1] >> 18) & 0x7;
|
||||
wstate->combine.add_rgb0 = (args[1] >> 15) & 0x7;
|
||||
wstate->combine.sub_b_a0 = (args[1] >> 12) & 0x7;
|
||||
wstate->combine.add_a0 = (args[1] >> 9) & 0x7;
|
||||
wstate->combine.add_rgb1 = (args[1] >> 6) & 0x7;
|
||||
wstate->combine.sub_b_a1 = (args[1] >> 3) & 0x7;
|
||||
wstate->combine.add_a1 = (args[1] >> 0) & 0x7;
|
||||
|
||||
|
||||
set_suba_rgb_input(wstate, &wstate->combiner_rgbsub_a_r[0], &wstate->combiner_rgbsub_a_g[0], &wstate->combiner_rgbsub_a_b[0], wstate->combine.sub_a_rgb0);
|
||||
set_subb_rgb_input(wstate, &wstate->combiner_rgbsub_b_r[0], &wstate->combiner_rgbsub_b_g[0], &wstate->combiner_rgbsub_b_b[0], wstate->combine.sub_b_rgb0);
|
||||
set_mul_rgb_input(wstate, &wstate->combiner_rgbmul_r[0], &wstate->combiner_rgbmul_g[0], &wstate->combiner_rgbmul_b[0], wstate->combine.mul_rgb0);
|
||||
set_add_rgb_input(wstate, &wstate->combiner_rgbadd_r[0], &wstate->combiner_rgbadd_g[0], &wstate->combiner_rgbadd_b[0], wstate->combine.add_rgb0);
|
||||
set_sub_alpha_input(wstate, &wstate->combiner_alphasub_a[0], wstate->combine.sub_a_a0);
|
||||
set_sub_alpha_input(wstate, &wstate->combiner_alphasub_b[0], wstate->combine.sub_b_a0);
|
||||
set_mul_alpha_input(wstate, &wstate->combiner_alphamul[0], wstate->combine.mul_a0);
|
||||
set_sub_alpha_input(wstate, &wstate->combiner_alphaadd[0], wstate->combine.add_a0);
|
||||
|
||||
set_suba_rgb_input(wstate, &wstate->combiner_rgbsub_a_r[1], &wstate->combiner_rgbsub_a_g[1], &wstate->combiner_rgbsub_a_b[1], wstate->combine.sub_a_rgb1);
|
||||
set_subb_rgb_input(wstate, &wstate->combiner_rgbsub_b_r[1], &wstate->combiner_rgbsub_b_g[1], &wstate->combiner_rgbsub_b_b[1], wstate->combine.sub_b_rgb1);
|
||||
set_mul_rgb_input(wstate, &wstate->combiner_rgbmul_r[1], &wstate->combiner_rgbmul_g[1], &wstate->combiner_rgbmul_b[1], wstate->combine.mul_rgb1);
|
||||
set_add_rgb_input(wstate, &wstate->combiner_rgbadd_r[1], &wstate->combiner_rgbadd_g[1], &wstate->combiner_rgbadd_b[1], wstate->combine.add_rgb1);
|
||||
set_sub_alpha_input(wstate, &wstate->combiner_alphasub_a[1], wstate->combine.sub_a_a1);
|
||||
set_sub_alpha_input(wstate, &wstate->combiner_alphasub_b[1], wstate->combine.sub_b_a1);
|
||||
set_mul_alpha_input(wstate, &wstate->combiner_alphamul[1], wstate->combine.mul_a1);
|
||||
set_sub_alpha_input(wstate, &wstate->combiner_alphaadd[1], wstate->combine.add_a1);
|
||||
|
||||
wstate->other_modes.f.stalederivs = 1;
|
||||
}
|
||||
|
||||
void rdp_set_key_gb(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->key_width.g = (args[0] >> 12) & 0xfff;
|
||||
wstate->key_width.b = args[0] & 0xfff;
|
||||
wstate->key_center.g = (args[1] >> 24) & 0xff;
|
||||
wstate->key_scale.g = (args[1] >> 16) & 0xff;
|
||||
wstate->key_center.b = (args[1] >> 8) & 0xff;
|
||||
wstate->key_scale.b = args[1] & 0xff;
|
||||
}
|
||||
|
||||
void rdp_set_key_r(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->key_width.r = (args[1] >> 16) & 0xfff;
|
||||
wstate->key_center.r = (args[1] >> 8) & 0xff;
|
||||
wstate->key_scale.r = args[1] & 0xff;
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,249 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
#define CVG_CLAMP 0
|
||||
#define CVG_WRAP 1
|
||||
#define CVG_ZAP 2
|
||||
#define CVG_SAVE 3
|
||||
|
||||
static struct {
|
||||
uint8_t cvg;
|
||||
uint8_t cvbit;
|
||||
uint8_t xoff;
|
||||
uint8_t yoff;
|
||||
} cvarray[0x100];
|
||||
|
||||
static STRICTINLINE uint32_t rightcvghex(uint32_t x, uint32_t fmask)
|
||||
{
|
||||
uint32_t covered = ((x & 7) + 1) >> 1;
|
||||
|
||||
covered = 0xf0 >> covered;
|
||||
return (covered & fmask);
|
||||
}
|
||||
|
||||
static STRICTINLINE uint32_t leftcvghex(uint32_t x, uint32_t fmask)
|
||||
{
|
||||
uint32_t covered = ((x & 7) + 1) >> 1;
|
||||
covered = 0xf >> covered;
|
||||
return (covered & fmask);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static STRICTINLINE void compute_cvg_flip(struct rdp_state* wstate, int32_t scanline)
|
||||
{
|
||||
int32_t purgestart, purgeend;
|
||||
int i, length, fmask, maskshift, fmaskshifted;
|
||||
int32_t minorcur, majorcur, minorcurint, majorcurint, samecvg;
|
||||
|
||||
purgestart = wstate->span[scanline].rx;
|
||||
purgeend = wstate->span[scanline].lx;
|
||||
length = purgeend - purgestart;
|
||||
if (length >= 0)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
memset(&wstate->cvgbuf[purgestart], 0xff, length + 1);
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
|
||||
fmask = 0xa >> (i & 1);
|
||||
|
||||
|
||||
|
||||
|
||||
maskshift = (i - 2) & 4;
|
||||
fmaskshifted = fmask << maskshift;
|
||||
|
||||
if (!wstate->span[scanline].invalyscan[i])
|
||||
{
|
||||
int k;
|
||||
minorcur = wstate->span[scanline].minorx[i];
|
||||
majorcur = wstate->span[scanline].majorx[i];
|
||||
minorcurint = minorcur >> 3;
|
||||
majorcurint = majorcur >> 3;
|
||||
|
||||
|
||||
for (k = purgestart; k <= majorcurint; k++)
|
||||
wstate->cvgbuf[k] &= ~fmaskshifted;
|
||||
for (k = minorcurint; k <= purgeend; k++)
|
||||
wstate->cvgbuf[k] &= ~fmaskshifted;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (minorcurint > majorcurint)
|
||||
{
|
||||
wstate->cvgbuf[minorcurint] |= (rightcvghex(minorcur, fmask) << maskshift);
|
||||
wstate->cvgbuf[majorcurint] |= (leftcvghex(majorcur, fmask) << maskshift);
|
||||
}
|
||||
else if (minorcurint == majorcurint)
|
||||
{
|
||||
samecvg = rightcvghex(minorcur, fmask) & leftcvghex(majorcur, fmask);
|
||||
wstate->cvgbuf[majorcurint] |= (samecvg << maskshift);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int k;
|
||||
for (k = purgestart; k <= purgeend; k++)
|
||||
wstate->cvgbuf[k] &= ~fmaskshifted;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static STRICTINLINE void compute_cvg_noflip(struct rdp_state* wstate, int32_t scanline)
|
||||
{
|
||||
int32_t purgestart, purgeend;
|
||||
int i, length, fmask, maskshift, fmaskshifted;
|
||||
int32_t minorcur, majorcur, minorcurint, majorcurint, samecvg;
|
||||
|
||||
purgestart = wstate->span[scanline].lx;
|
||||
purgeend = wstate->span[scanline].rx;
|
||||
length = purgeend - purgestart;
|
||||
|
||||
if (length >= 0)
|
||||
{
|
||||
memset(&wstate->cvgbuf[purgestart], 0xff, length + 1);
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
fmask = 0xa >> (i & 1);
|
||||
maskshift = (i - 2) & 4;
|
||||
fmaskshifted = fmask << maskshift;
|
||||
|
||||
if (!wstate->span[scanline].invalyscan[i])
|
||||
{
|
||||
int k;
|
||||
minorcur = wstate->span[scanline].minorx[i];
|
||||
majorcur = wstate->span[scanline].majorx[i];
|
||||
minorcurint = minorcur >> 3;
|
||||
majorcurint = majorcur >> 3;
|
||||
|
||||
for (k = purgestart; k <= minorcurint; k++)
|
||||
wstate->cvgbuf[k] &= ~fmaskshifted;
|
||||
for (k = majorcurint; k <= purgeend; k++)
|
||||
wstate->cvgbuf[k] &= ~fmaskshifted;
|
||||
|
||||
if (majorcurint > minorcurint)
|
||||
{
|
||||
wstate->cvgbuf[minorcurint] |= (leftcvghex(minorcur, fmask) << maskshift);
|
||||
wstate->cvgbuf[majorcurint] |= (rightcvghex(majorcur, fmask) << maskshift);
|
||||
}
|
||||
else if (minorcurint == majorcurint)
|
||||
{
|
||||
samecvg = leftcvghex(minorcur, fmask) & rightcvghex(majorcur, fmask);
|
||||
wstate->cvgbuf[majorcurint] |= (samecvg << maskshift);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int k;
|
||||
for (k = purgestart; k <= purgeend; k++)
|
||||
wstate->cvgbuf[k] &= ~fmaskshifted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE int finalize_spanalpha(int cvg_dest, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg)
|
||||
{
|
||||
int finalcvg = 0;
|
||||
|
||||
|
||||
|
||||
switch(cvg_dest)
|
||||
{
|
||||
case CVG_CLAMP:
|
||||
if (!blend_en)
|
||||
{
|
||||
finalcvg = curpixel_cvg - 1;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
finalcvg = curpixel_cvg + curpixel_memcvg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!(finalcvg & 8))
|
||||
finalcvg &= 7;
|
||||
else
|
||||
finalcvg = 7;
|
||||
|
||||
break;
|
||||
case CVG_WRAP:
|
||||
finalcvg = (curpixel_cvg + curpixel_memcvg) & 7;
|
||||
break;
|
||||
case CVG_ZAP:
|
||||
finalcvg = 7;
|
||||
break;
|
||||
case CVG_SAVE:
|
||||
finalcvg = curpixel_memcvg;
|
||||
break;
|
||||
}
|
||||
|
||||
return finalcvg;
|
||||
}
|
||||
|
||||
static STRICTINLINE uint16_t decompress_cvmask_frombyte(uint8_t x)
|
||||
{
|
||||
uint16_t y = (x & 0x5) | ((x & 0x5a) << 4) | ((x & 0xa0) << 8);
|
||||
return y;
|
||||
}
|
||||
|
||||
static STRICTINLINE void lookup_cvmask_derivatives(uint8_t mask, uint8_t* offx, uint8_t* offy, uint32_t* curpixel_cvg, uint32_t* curpixel_cvbit)
|
||||
{
|
||||
*curpixel_cvg = cvarray[mask].cvg;
|
||||
*curpixel_cvbit = cvarray[mask].cvbit;
|
||||
*offx = cvarray[mask].xoff;
|
||||
*offy = cvarray[mask].yoff;
|
||||
}
|
||||
|
||||
static void coverage_init_lut(void)
|
||||
{
|
||||
uint8_t i = 0, k = 0;
|
||||
uint16_t mask = 0, maskx = 0, masky = 0;
|
||||
uint8_t offx = 0, offy = 0;
|
||||
const uint8_t yarray[16] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
|
||||
const uint8_t xarray[16] = {0, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
do {
|
||||
mask = decompress_cvmask_frombyte(i);
|
||||
cvarray[i].cvg = cvarray[i].cvbit = 0;
|
||||
cvarray[i].cvbit = (i >> 7) & 1;
|
||||
for (k = 0; k < 8; k++)
|
||||
cvarray[i].cvg += ((i >> k) & 1);
|
||||
|
||||
|
||||
masky = maskx = offx = offy = 0;
|
||||
for (k = 0; k < 4; k++)
|
||||
masky |= ((mask & (0xf000 >> (k << 2))) > 0) << k;
|
||||
|
||||
offy = yarray[masky];
|
||||
|
||||
maskx = (mask & (0xf000 >> (offy << 2))) >> ((offy ^ 3) << 2);
|
||||
|
||||
|
||||
offx = xarray[maskx];
|
||||
|
||||
cvarray[i].xoff = offx;
|
||||
cvarray[i].yoff = offy;
|
||||
} while (i++ != 0xff);
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,154 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static const uint8_t bayer_matrix[16] =
|
||||
{
|
||||
0, 4, 1, 5,
|
||||
4, 0, 5, 1,
|
||||
3, 7, 2, 6,
|
||||
7, 3, 6, 2
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t magic_matrix[16] =
|
||||
{
|
||||
0, 6, 1, 7,
|
||||
4, 2, 5, 3,
|
||||
3, 5, 2, 4,
|
||||
7, 1, 6, 0
|
||||
};
|
||||
|
||||
static STRICTINLINE void rgb_dither(int rgb_dither_sel, int* r, int* g, int* b, int dith)
|
||||
{
|
||||
|
||||
int32_t newr = *r, newg = *g, newb = *b;
|
||||
int32_t rcomp, gcomp, bcomp;
|
||||
|
||||
|
||||
if (newr > 247)
|
||||
newr = 255;
|
||||
else
|
||||
newr = (newr & 0xf8) + 8;
|
||||
if (newg > 247)
|
||||
newg = 255;
|
||||
else
|
||||
newg = (newg & 0xf8) + 8;
|
||||
if (newb > 247)
|
||||
newb = 255;
|
||||
else
|
||||
newb = (newb & 0xf8) + 8;
|
||||
|
||||
if (rgb_dither_sel != 2)
|
||||
rcomp = gcomp = bcomp = dith;
|
||||
else
|
||||
{
|
||||
rcomp = dith & 7;
|
||||
gcomp = (dith >> 3) & 7;
|
||||
bcomp = (dith >> 6) & 7;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t replacesign = (rcomp - (*r & 7)) >> 31;
|
||||
|
||||
int32_t ditherdiff = newr - *r;
|
||||
*r = *r + (ditherdiff & replacesign);
|
||||
|
||||
replacesign = (gcomp - (*g & 7)) >> 31;
|
||||
ditherdiff = newg - *g;
|
||||
*g = *g + (ditherdiff & replacesign);
|
||||
|
||||
replacesign = (bcomp - (*b & 7)) >> 31;
|
||||
ditherdiff = newb - *b;
|
||||
*b = *b + (ditherdiff & replacesign);
|
||||
}
|
||||
|
||||
static STRICTINLINE void get_dither_noise(struct rdp_state* wstate, int x, int y, int* cdith, int* adith)
|
||||
{
|
||||
if (!wstate->other_modes.f.getditherlevel)
|
||||
wstate->noise = ((irand(&wstate->rseed) & 7) << 6) | 0x20;
|
||||
|
||||
y >>= wstate->scfield;
|
||||
|
||||
int dithindex;
|
||||
switch(wstate->other_modes.f.rgb_alpha_dither)
|
||||
{
|
||||
case 0:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*adith = *cdith = magic_matrix[dithindex];
|
||||
break;
|
||||
case 1:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = magic_matrix[dithindex];
|
||||
*adith = (~(*cdith)) & 7;
|
||||
break;
|
||||
case 2:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = magic_matrix[dithindex];
|
||||
*adith = (wstate->noise >> 6) & 7;
|
||||
break;
|
||||
case 3:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = magic_matrix[dithindex];
|
||||
*adith = 0;
|
||||
break;
|
||||
case 4:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*adith = *cdith = bayer_matrix[dithindex];
|
||||
break;
|
||||
case 5:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = bayer_matrix[dithindex];
|
||||
*adith = (~(*cdith)) & 7;
|
||||
break;
|
||||
case 6:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = bayer_matrix[dithindex];
|
||||
*adith = (wstate->noise >> 6) & 7;
|
||||
break;
|
||||
case 7:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = bayer_matrix[dithindex];
|
||||
*adith = 0;
|
||||
break;
|
||||
case 8:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = irand(&wstate->rseed);
|
||||
*adith = magic_matrix[dithindex];
|
||||
break;
|
||||
case 9:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = irand(&wstate->rseed);
|
||||
*adith = (~magic_matrix[dithindex]) & 7;
|
||||
break;
|
||||
case 10:
|
||||
*cdith = irand(&wstate->rseed);
|
||||
*adith = (wstate->noise >> 6) & 7;
|
||||
break;
|
||||
case 11:
|
||||
*cdith = irand(&wstate->rseed);
|
||||
*adith = 0;
|
||||
break;
|
||||
case 12:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = 7;
|
||||
*adith = bayer_matrix[dithindex];
|
||||
break;
|
||||
case 13:
|
||||
dithindex = ((y & 3) << 2) | (x & 3);
|
||||
*cdith = 7;
|
||||
*adith = (~bayer_matrix[dithindex]) & 7;
|
||||
break;
|
||||
case 14:
|
||||
*cdith = 7;
|
||||
*adith = (wstate->noise >> 6) & 7;
|
||||
break;
|
||||
case 15:
|
||||
*cdith = 7;
|
||||
*adith = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,324 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static void fbwrite_4(struct rdp_state* wstate, uint32_t curpixel, uint32_t r, uint32_t g, uint32_t b, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg);
|
||||
static void fbwrite_8(struct rdp_state* wstate, uint32_t curpixel, uint32_t r, uint32_t g, uint32_t b, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg);
|
||||
static void fbwrite_16(struct rdp_state* wstate, uint32_t curpixel, uint32_t r, uint32_t g, uint32_t b, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg);
|
||||
static void fbwrite_32(struct rdp_state* wstate, uint32_t curpixel, uint32_t r, uint32_t g, uint32_t b, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg);
|
||||
static void fbread_4(struct rdp_state* wstate, uint32_t num, uint32_t* curpixel_memcvg);
|
||||
static void fbread_8(struct rdp_state* wstate, uint32_t num, uint32_t* curpixel_memcvg);
|
||||
static void fbread_16(struct rdp_state* wstate, uint32_t num, uint32_t* curpixel_memcvg);
|
||||
static void fbread_32(struct rdp_state* wstate, uint32_t num, uint32_t* curpixel_memcvg);
|
||||
static void fbread2_4(struct rdp_state* wstate, uint32_t num, uint32_t* curpixel_memcvg);
|
||||
static void fbread2_8(struct rdp_state* wstate, uint32_t num, uint32_t* curpixel_memcvg);
|
||||
static void fbread2_16(struct rdp_state* wstate, uint32_t num, uint32_t* curpixel_memcvg);
|
||||
static void fbread2_32(struct rdp_state* wstate, uint32_t num, uint32_t* curpixel_memcvg);
|
||||
|
||||
static void (*fbread_func[4])(struct rdp_state*, uint32_t, uint32_t*) =
|
||||
{
|
||||
fbread_4, fbread_8, fbread_16, fbread_32
|
||||
};
|
||||
|
||||
static void (*fbread2_func[4])(struct rdp_state*,uint32_t, uint32_t*) =
|
||||
{
|
||||
fbread2_4, fbread2_8, fbread2_16, fbread2_32
|
||||
};
|
||||
|
||||
static void (*fbwrite_func[4])(struct rdp_state*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) =
|
||||
{
|
||||
fbwrite_4, fbwrite_8, fbwrite_16, fbwrite_32
|
||||
};
|
||||
|
||||
static void fbwrite_4(struct rdp_state* wstate, uint32_t curpixel, uint32_t r, uint32_t g, uint32_t b, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg)
|
||||
{
|
||||
UNUSED(r);
|
||||
UNUSED(g);
|
||||
UNUSED(b);
|
||||
UNUSED(blend_en);
|
||||
UNUSED(curpixel_cvg);
|
||||
UNUSED(curpixel_memcvg);
|
||||
|
||||
uint32_t fb = wstate->fb_address + curpixel;
|
||||
RWRITEADDR8(fb, 0);
|
||||
}
|
||||
|
||||
static void fbwrite_8(struct rdp_state* wstate, uint32_t curpixel, uint32_t r, uint32_t g, uint32_t b, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg)
|
||||
{
|
||||
UNUSED(b);
|
||||
UNUSED(blend_en);
|
||||
UNUSED(curpixel_cvg);
|
||||
UNUSED(curpixel_memcvg);
|
||||
|
||||
uint32_t fb = wstate->fb_address + curpixel;
|
||||
PAIRWRITE8(fb, (fb & 1) ? (g & 0xff) : (r & 0xff));
|
||||
}
|
||||
|
||||
static void fbwrite_16(struct rdp_state* wstate, uint32_t curpixel, uint32_t r, uint32_t g, uint32_t b, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg)
|
||||
{
|
||||
#undef CVG_DRAW
|
||||
#ifdef CVG_DRAW
|
||||
int covdraw = (curpixel_cvg - 1) << 5;
|
||||
r=covdraw; g=covdraw; b=covdraw;
|
||||
#endif
|
||||
|
||||
uint32_t fb;
|
||||
uint16_t rval;
|
||||
uint8_t hval;
|
||||
fb = (wstate->fb_address >> 1) + curpixel;
|
||||
|
||||
int32_t finalcvg = finalize_spanalpha(wstate->other_modes.cvg_dest, blend_en, curpixel_cvg, curpixel_memcvg);
|
||||
int16_t finalcolor;
|
||||
|
||||
if (wstate->fb_format == FORMAT_RGBA)
|
||||
{
|
||||
finalcolor = ((r & ~7) << 8) | ((g & ~7) << 3) | ((b & ~7) >> 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
finalcolor = (int16_t)((r << 8) | (finalcvg << 5));
|
||||
finalcvg = 0;
|
||||
}
|
||||
|
||||
|
||||
rval = finalcolor|(uint16_t)(finalcvg >> 2);
|
||||
hval = finalcvg & 3;
|
||||
PAIRWRITE16(fb, rval, hval);
|
||||
}
|
||||
|
||||
static void fbwrite_32(struct rdp_state* wstate, uint32_t curpixel, uint32_t r, uint32_t g, uint32_t b, uint32_t blend_en, uint32_t curpixel_cvg, uint32_t curpixel_memcvg)
|
||||
{
|
||||
uint32_t fb = (wstate->fb_address >> 2) + curpixel;
|
||||
|
||||
int32_t finalcolor;
|
||||
int32_t finalcvg = finalize_spanalpha(wstate->other_modes.cvg_dest, blend_en, curpixel_cvg, curpixel_memcvg);
|
||||
|
||||
finalcolor = (r << 24) | (g << 16) | (b << 8);
|
||||
finalcolor |= (finalcvg << 5);
|
||||
|
||||
PAIRWRITE32(fb, finalcolor, (g & 1) ? 3 : 0, 0);
|
||||
}
|
||||
|
||||
static void fbfill_4(struct rdp_state* wstate, uint32_t curpixel)
|
||||
{
|
||||
UNUSED(wstate);
|
||||
UNUSED(curpixel);
|
||||
|
||||
rdp_pipeline_crashed = 1;
|
||||
}
|
||||
|
||||
static void fbfill_8(struct rdp_state* wstate, uint32_t curpixel)
|
||||
{
|
||||
uint32_t fb = wstate->fb_address + curpixel;
|
||||
uint8_t val = (wstate->fill_color >> ((fb & 3) ^ 3) << 3) & 0xff;
|
||||
PAIRWRITE8(fb, val);
|
||||
}
|
||||
|
||||
static void fbfill_16(struct rdp_state* wstate, uint32_t curpixel)
|
||||
{
|
||||
uint16_t val;
|
||||
uint8_t hval;
|
||||
uint32_t fb = (wstate->fb_address >> 1) + curpixel;
|
||||
if (fb & 1)
|
||||
val = wstate->fill_color & 0xffff;
|
||||
else
|
||||
val = (wstate->fill_color >> 16) & 0xffff;
|
||||
hval = ((val & 1) << 1) | (val & 1);
|
||||
PAIRWRITE16(fb, val, hval);
|
||||
}
|
||||
|
||||
static void fbfill_32(struct rdp_state* wstate, uint32_t curpixel)
|
||||
{
|
||||
uint32_t fb = (wstate->fb_address >> 2) + curpixel;
|
||||
PAIRWRITE32(fb, wstate->fill_color, (wstate->fill_color & 0x10000) ? 3 : 0, (wstate->fill_color & 0x1) ? 3 : 0);
|
||||
}
|
||||
|
||||
static void fbread_4(struct rdp_state* wstate, uint32_t curpixel, uint32_t* curpixel_memcvg)
|
||||
{
|
||||
UNUSED(curpixel);
|
||||
|
||||
wstate->memory_color.r = wstate->memory_color.g = wstate->memory_color.b = 0;
|
||||
|
||||
*curpixel_memcvg = 7;
|
||||
wstate->memory_color.a = 0xe0;
|
||||
}
|
||||
|
||||
static void fbread2_4(struct rdp_state* wstate, uint32_t curpixel, uint32_t* curpixel_memcvg)
|
||||
{
|
||||
UNUSED(curpixel);
|
||||
|
||||
wstate->pre_memory_color.r = wstate->pre_memory_color.g = wstate->pre_memory_color.b = 0;
|
||||
wstate->pre_memory_color.a = 0xe0;
|
||||
*curpixel_memcvg = 7;
|
||||
}
|
||||
|
||||
static void fbread_8(struct rdp_state* wstate, uint32_t curpixel, uint32_t* curpixel_memcvg)
|
||||
{
|
||||
if (wstate->other_modes.image_read_en)
|
||||
{
|
||||
uint8_t mem;
|
||||
uint32_t addr = wstate->fb_address + curpixel;
|
||||
RREADADDR8(mem, addr);
|
||||
wstate->memory_color.r = wstate->memory_color.g = wstate->memory_color.b = mem;
|
||||
}
|
||||
|
||||
*curpixel_memcvg = 7;
|
||||
wstate->memory_color.a = 0xe0;
|
||||
}
|
||||
|
||||
static void fbread2_8(struct rdp_state* wstate, uint32_t curpixel, uint32_t* curpixel_memcvg)
|
||||
{
|
||||
if (wstate->other_modes.image_read_en)
|
||||
{
|
||||
uint8_t mem;
|
||||
uint32_t addr = wstate->fb_address + curpixel;
|
||||
RREADADDR8(mem, addr);
|
||||
wstate->pre_memory_color.r = wstate->pre_memory_color.g = wstate->pre_memory_color.b = mem;
|
||||
}
|
||||
wstate->pre_memory_color.a = 0xe0;
|
||||
*curpixel_memcvg = 7;
|
||||
}
|
||||
|
||||
static void fbread_16(struct rdp_state* wstate, uint32_t curpixel, uint32_t* curpixel_memcvg)
|
||||
{
|
||||
if (wstate->other_modes.image_read_en)
|
||||
{
|
||||
uint16_t fword;
|
||||
uint8_t hbyte;
|
||||
uint32_t addr = (wstate->fb_address >> 1) + curpixel;
|
||||
|
||||
uint8_t lowbits;
|
||||
|
||||
PAIRREAD16(fword, hbyte, addr);
|
||||
|
||||
if (wstate->fb_format == FORMAT_RGBA)
|
||||
{
|
||||
wstate->memory_color.r = RGBA16_R(fword);
|
||||
wstate->memory_color.g = RGBA16_G(fword);
|
||||
wstate->memory_color.b = RGBA16_B(fword);
|
||||
lowbits = ((fword & 1) << 2) | hbyte;
|
||||
}
|
||||
else
|
||||
{
|
||||
wstate->memory_color.r = wstate->memory_color.g = wstate->memory_color.b = fword >> 8;
|
||||
lowbits = (fword >> 5) & 7;
|
||||
}
|
||||
|
||||
*curpixel_memcvg = lowbits;
|
||||
wstate->memory_color.a = lowbits << 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
*curpixel_memcvg = 7;
|
||||
wstate->memory_color.a = 0xe0;
|
||||
}
|
||||
}
|
||||
|
||||
static void fbread2_16(struct rdp_state* wstate, uint32_t curpixel, uint32_t* curpixel_memcvg)
|
||||
{
|
||||
|
||||
if (wstate->other_modes.image_read_en)
|
||||
{
|
||||
uint16_t fword;
|
||||
uint8_t hbyte;
|
||||
uint32_t addr = (wstate->fb_address >> 1) + curpixel;
|
||||
|
||||
uint8_t lowbits;
|
||||
|
||||
PAIRREAD16(fword, hbyte, addr);
|
||||
|
||||
if (wstate->fb_format == FORMAT_RGBA)
|
||||
{
|
||||
wstate->pre_memory_color.r = RGBA16_R(fword);
|
||||
wstate->pre_memory_color.g = RGBA16_G(fword);
|
||||
wstate->pre_memory_color.b = RGBA16_B(fword);
|
||||
lowbits = ((fword & 1) << 2) | hbyte;
|
||||
}
|
||||
else
|
||||
{
|
||||
wstate->pre_memory_color.r = wstate->pre_memory_color.g = wstate->pre_memory_color.b = fword >> 8;
|
||||
lowbits = (fword >> 5) & 7;
|
||||
}
|
||||
|
||||
*curpixel_memcvg = lowbits;
|
||||
wstate->pre_memory_color.a = lowbits << 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
*curpixel_memcvg = 7;
|
||||
wstate->pre_memory_color.a = 0xe0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void fbread_32(struct rdp_state* wstate, uint32_t curpixel, uint32_t* curpixel_memcvg)
|
||||
{
|
||||
if (wstate->other_modes.image_read_en)
|
||||
{
|
||||
uint32_t mem, addr = (wstate->fb_address >> 2) + curpixel;
|
||||
RREADIDX32(mem, addr);
|
||||
wstate->memory_color.r = RGBA32_R(mem);
|
||||
wstate->memory_color.g = RGBA32_G(mem);
|
||||
wstate->memory_color.b = RGBA32_B(mem);
|
||||
|
||||
*curpixel_memcvg = (mem >> 5) & 7;
|
||||
wstate->memory_color.a = mem & 0xe0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*curpixel_memcvg = 7;
|
||||
wstate->memory_color.a = 0xe0;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void fbread2_32(struct rdp_state* wstate, uint32_t curpixel, uint32_t* curpixel_memcvg)
|
||||
{
|
||||
if (wstate->other_modes.image_read_en)
|
||||
{
|
||||
uint32_t mem, addr = (wstate->fb_address >> 2) + curpixel;
|
||||
RREADIDX32(mem, addr);
|
||||
|
||||
wstate->pre_memory_color.r = RGBA32_R(mem);
|
||||
wstate->pre_memory_color.g = RGBA32_G(mem);
|
||||
wstate->pre_memory_color.b = RGBA32_B(mem);
|
||||
|
||||
*curpixel_memcvg = (mem >> 5) & 7;
|
||||
wstate->pre_memory_color.a = mem & 0xe0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*curpixel_memcvg = 7;
|
||||
wstate->pre_memory_color.a = 0xe0;
|
||||
}
|
||||
}
|
||||
|
||||
void rdp_set_color_image(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->fb_format = (args[0] >> 21) & 0x7;
|
||||
wstate->fb_size = (args[0] >> 19) & 0x3;
|
||||
wstate->fb_width = (args[0] & 0x3ff) + 1;
|
||||
wstate->fb_address = args[1] & 0x0ffffff;
|
||||
|
||||
|
||||
wstate->fbread1_ptr = fbread_func[wstate->fb_size];
|
||||
wstate->fbread2_ptr = fbread2_func[wstate->fb_size];
|
||||
wstate->fbwrite_ptr = fbwrite_func[wstate->fb_size];
|
||||
}
|
||||
|
||||
void rdp_set_fill_color(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->fill_color = args[1];
|
||||
}
|
||||
|
||||
static void fb_init(struct rdp_state* wstate)
|
||||
{
|
||||
wstate->fb_format = FORMAT_RGBA;
|
||||
wstate->fb_size = PIXEL_SIZE_4BIT;
|
||||
wstate->fb_width = 0;
|
||||
wstate->fb_address = 0;
|
||||
|
||||
|
||||
wstate->fbread1_ptr = fbread_func[wstate->fb_size];
|
||||
wstate->fbread2_ptr = fbread2_func[wstate->fb_size];
|
||||
wstate->fbwrite_ptr = fbwrite_func[wstate->fb_size];
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,167 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
//
|
||||
// rdram.c: RDRAM memory interface
|
||||
//
|
||||
|
||||
#define RDRAM_MASK 0x00ffffff
|
||||
|
||||
#define HB_CLEAN 4
|
||||
|
||||
// macros used to interface with AL's code
|
||||
#define RREADADDR8(rdst, in) {(rdst) = rdram_read_idx8((in));}
|
||||
#define RREADIDX16(rdst, in) {(rdst) = rdram_read_idx16((in));}
|
||||
#define RREADIDX32(rdst, in) {(rdst) = rdram_read_idx32((in));}
|
||||
|
||||
#define RWRITEADDR8(in, val) rdram_write_idx8((in), (val))
|
||||
#define RWRITEIDX16(in, val) rdram_write_idx16((in), (val))
|
||||
#define RWRITEIDX32(in, val) rdram_write_idx32((in), (val))
|
||||
|
||||
#define PAIRREAD16(rdst, hdst, in) rdram_read_pair16(&rdst, &hdst, (in))
|
||||
|
||||
#define PAIRWRITE16(in, rval, hval) rdram_write_pair16((in), (rval), (hval))
|
||||
|
||||
#define PAIRWRITE32(in, rval, hval0, hval1) rdram_write_pair32((in), (rval), (hval0), (hval1))
|
||||
|
||||
#define PAIRWRITE8(in, rval) rdram_write_pair8((in), (rval))
|
||||
|
||||
// pointer indexing limits for aliasing RDRAM reads and writes
|
||||
static uint32_t idxlim8;
|
||||
static uint32_t idxlim16;
|
||||
static uint32_t idxlim32;
|
||||
|
||||
static uint32_t* rdram32;
|
||||
static uint16_t* rdram16;
|
||||
static uint8_t* rdram8;
|
||||
static uint8_t rdram_hidden[RDRAM_MAX_SIZE / 2];
|
||||
|
||||
static void rdram_init(void)
|
||||
{
|
||||
idxlim8 = config.gfx.rdram_size - 1;
|
||||
idxlim16 = (idxlim8 >> 1) & 0xffffffu;
|
||||
idxlim32 = (idxlim8 >> 2) & 0xffffffu;
|
||||
|
||||
rdram32 = (uint32_t*)config.gfx.rdram;
|
||||
rdram16 = (uint16_t*)config.gfx.rdram;
|
||||
rdram8 = config.gfx.rdram;
|
||||
|
||||
memset(rdram_hidden, HB_CLEAN, sizeof(rdram_hidden));
|
||||
}
|
||||
|
||||
static STRICTINLINE bool rdram_valid_idx8(uint32_t in)
|
||||
{
|
||||
return in <= idxlim8;
|
||||
}
|
||||
|
||||
static STRICTINLINE bool rdram_valid_idx16(uint32_t in)
|
||||
{
|
||||
return in <= idxlim16;
|
||||
}
|
||||
|
||||
static STRICTINLINE bool rdram_valid_idx32(uint32_t in)
|
||||
{
|
||||
return in <= idxlim32;
|
||||
}
|
||||
|
||||
static STRICTINLINE uint8_t rdram_read_idx8(uint32_t in)
|
||||
{
|
||||
in &= RDRAM_MASK;
|
||||
return rdram_valid_idx8(in) ? rdram8[in ^ BYTE_ADDR_XOR] : 0;
|
||||
}
|
||||
|
||||
static STRICTINLINE uint8_t rdram_read_idx8_fast(uint32_t in)
|
||||
{
|
||||
return rdram8[in ^ BYTE_ADDR_XOR];
|
||||
}
|
||||
|
||||
static STRICTINLINE uint16_t rdram_read_idx16(uint32_t in)
|
||||
{
|
||||
in &= RDRAM_MASK >> 1;
|
||||
return rdram_valid_idx16(in) ? rdram16[in ^ WORD_ADDR_XOR] : 0;
|
||||
}
|
||||
|
||||
static STRICTINLINE uint16_t rdram_read_idx16_fast(uint32_t in)
|
||||
{
|
||||
return rdram16[in ^ WORD_ADDR_XOR];
|
||||
}
|
||||
|
||||
static STRICTINLINE uint32_t rdram_read_idx32(uint32_t in)
|
||||
{
|
||||
in &= RDRAM_MASK >> 2;
|
||||
return rdram_valid_idx32(in) ? rdram32[in] : 0;
|
||||
}
|
||||
|
||||
static STRICTINLINE uint32_t rdram_read_idx32_fast(uint32_t in)
|
||||
{
|
||||
return rdram32[in];
|
||||
}
|
||||
|
||||
static STRICTINLINE void rdram_write_idx8(uint32_t in, uint8_t val)
|
||||
{
|
||||
in &= RDRAM_MASK;
|
||||
if (rdram_valid_idx8(in)) {
|
||||
rdram8[in ^ BYTE_ADDR_XOR] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void rdram_write_idx16(uint32_t in, uint16_t val)
|
||||
{
|
||||
in &= RDRAM_MASK >> 1;
|
||||
if (rdram_valid_idx16(in)) {
|
||||
rdram16[in ^ WORD_ADDR_XOR] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void rdram_write_idx32(uint32_t in, uint32_t val)
|
||||
{
|
||||
in &= RDRAM_MASK >> 2;
|
||||
if (rdram_valid_idx32(in)) {
|
||||
rdram32[in] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void rdram_read_pair16(uint16_t* rdst, uint8_t* hdst, uint32_t in)
|
||||
{
|
||||
in &= RDRAM_MASK >> 1;
|
||||
if (rdram_valid_idx16(in)) {
|
||||
*rdst = rdram16[in ^ WORD_ADDR_XOR];
|
||||
*hdst = rdram_hidden[in];
|
||||
if (*hdst & HB_CLEAN) {
|
||||
*hdst = (*rdst & 1) ? 3 : 0;
|
||||
}
|
||||
} else {
|
||||
*rdst = *hdst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void rdram_write_pair8(uint32_t in, uint8_t rval)
|
||||
{
|
||||
in &= RDRAM_MASK;
|
||||
if (rdram_valid_idx8(in)) {
|
||||
if (in & 1) {
|
||||
rdram_hidden[in >> 1] = (rval & 1) ? 3 : 0;
|
||||
}
|
||||
rdram8[in ^ BYTE_ADDR_XOR] = rval;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void rdram_write_pair16(uint32_t in, uint16_t rval, uint8_t hval)
|
||||
{
|
||||
in &= RDRAM_MASK >> 1;
|
||||
if (rdram_valid_idx16(in)) {
|
||||
rdram16[in ^ WORD_ADDR_XOR] = rval;
|
||||
rdram_hidden[in] = hval;
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void rdram_write_pair32(uint32_t in, uint32_t rval, uint8_t hval0, uint8_t hval1)
|
||||
{
|
||||
in &= RDRAM_MASK >> 2;
|
||||
if (rdram_valid_idx32(in)) {
|
||||
rdram32[in] = rval;
|
||||
rdram_hidden[in << 1] = hval0;
|
||||
rdram_hidden[(in << 1) + 1] = hval1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
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
@@ -0,0 +1,410 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
#define ZMODE_OPAQUE 0
|
||||
#define ZMODE_INTERPENETRATING 1
|
||||
#define ZMODE_TRANSPARENT 2
|
||||
#define ZMODE_DECAL 3
|
||||
|
||||
static uint16_t z_com_table[0x40000];
|
||||
static uint32_t z_complete_dec_table[0x4000];
|
||||
static uint16_t deltaz_comparator_lut[0x10000];
|
||||
|
||||
static struct {uint32_t shift; uint32_t add;} z_dec_table[8] = {
|
||||
{ 6, 0x00000 },
|
||||
{ 5, 0x20000 },
|
||||
{ 4, 0x30000 },
|
||||
{ 3, 0x38000 },
|
||||
{ 2, 0x3c000 },
|
||||
{ 1, 0x3e000 },
|
||||
{ 0, 0x3f000 },
|
||||
{ 0, 0x3f800 },
|
||||
};
|
||||
|
||||
static STRICTINLINE uint32_t z_decompress(uint32_t zb)
|
||||
{
|
||||
return z_complete_dec_table[(zb >> 2) & 0x3fff];
|
||||
}
|
||||
|
||||
static INLINE void z_build_com_table(void)
|
||||
{
|
||||
|
||||
int z;
|
||||
uint16_t altmem = 0;
|
||||
for(z = 0; z < 0x40000; z++)
|
||||
{
|
||||
switch((z >> 11) & 0x7f)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
case 0x18:
|
||||
case 0x19:
|
||||
case 0x1a:
|
||||
case 0x1b:
|
||||
case 0x1c:
|
||||
case 0x1d:
|
||||
case 0x1e:
|
||||
case 0x1f:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
case 0x28:
|
||||
case 0x29:
|
||||
case 0x2a:
|
||||
case 0x2b:
|
||||
case 0x2c:
|
||||
case 0x2d:
|
||||
case 0x2e:
|
||||
case 0x2f:
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34:
|
||||
case 0x35:
|
||||
case 0x36:
|
||||
case 0x37:
|
||||
case 0x38:
|
||||
case 0x39:
|
||||
case 0x3a:
|
||||
case 0x3b:
|
||||
case 0x3c:
|
||||
case 0x3d:
|
||||
case 0x3e:
|
||||
case 0x3f:
|
||||
altmem = (z >> 4) & 0x1ffc;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x4b:
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
altmem = ((z >> 3) & 0x1ffc) | 0x2000;
|
||||
break;
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
case 0x69:
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
altmem = ((z >> 2) & 0x1ffc) | 0x4000;
|
||||
break;
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
altmem = ((z >> 1) & 0x1ffc) | 0x6000;
|
||||
break;
|
||||
case 0x78:
|
||||
case 0x79:
|
||||
case 0x7a:
|
||||
case 0x7b:
|
||||
altmem = (z & 0x1ffc) | 0x8000;
|
||||
break;
|
||||
case 0x7c:
|
||||
case 0x7d:
|
||||
altmem = ((z << 1) & 0x1ffc) | 0xa000;
|
||||
break;
|
||||
case 0x7e:
|
||||
altmem = ((z << 2) & 0x1ffc) | 0xc000;
|
||||
break;
|
||||
case 0x7f:
|
||||
altmem = ((z << 2) & 0x1ffc) | 0xe000;
|
||||
break;
|
||||
default:
|
||||
msg_error("z_build_com_table failed");
|
||||
break;
|
||||
}
|
||||
|
||||
z_com_table[z] = altmem;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static STRICTINLINE void z_store(uint32_t zcurpixel, uint32_t z, int dzpixenc)
|
||||
{
|
||||
uint16_t zval = z_com_table[z & 0x3ffff]|(uint16_t)(dzpixenc >> 2);
|
||||
uint8_t hval = dzpixenc & 3;
|
||||
PAIRWRITE16(zcurpixel, zval, hval);
|
||||
}
|
||||
|
||||
static STRICTINLINE uint32_t dz_decompress(uint32_t dz_compressed)
|
||||
{
|
||||
return (1 << dz_compressed);
|
||||
}
|
||||
|
||||
|
||||
static STRICTINLINE uint32_t dz_compress(uint32_t value)
|
||||
{
|
||||
int j = 0;
|
||||
if (value & 0xff00)
|
||||
j |= 8;
|
||||
if (value & 0xf0f0)
|
||||
j |= 4;
|
||||
if (value & 0xcccc)
|
||||
j |= 2;
|
||||
if (value & 0xaaaa)
|
||||
j |= 1;
|
||||
return j;
|
||||
}
|
||||
|
||||
static STRICTINLINE uint32_t z_compare(struct rdp_state* wstate, uint32_t zcurpixel, uint32_t sz, uint16_t dzpix, int dzpixenc, uint32_t* blend_en, uint32_t* prewrap, uint32_t* curpixel_cvg, uint32_t curpixel_memcvg)
|
||||
{
|
||||
|
||||
|
||||
int force_coplanar = 0;
|
||||
sz &= 0x3ffff;
|
||||
|
||||
uint8_t hval;
|
||||
uint16_t zval;
|
||||
uint32_t oz, dzmem;
|
||||
int32_t rawdzmem;
|
||||
|
||||
if (wstate->other_modes.z_compare_en)
|
||||
{
|
||||
PAIRREAD16(zval, hval, zcurpixel);
|
||||
oz = z_decompress(zval);
|
||||
rawdzmem = ((zval & 3) << 2) | hval;
|
||||
dzmem = dz_decompress(rawdzmem);
|
||||
|
||||
|
||||
|
||||
if (wstate->other_modes.f.realblendershiftersneeded)
|
||||
{
|
||||
wstate->blshifta = clamp(dzpixenc - rawdzmem, 0, 4);
|
||||
wstate->blshiftb = clamp(rawdzmem - dzpixenc, 0, 4);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (wstate->other_modes.f.interpixelblendershiftersneeded)
|
||||
{
|
||||
wstate->pastblshifta = clamp(dzpixenc - wstate->pastrawdzmem, 0, 4);
|
||||
wstate->pastblshiftb = clamp(wstate->pastrawdzmem - dzpixenc, 0, 4);
|
||||
}
|
||||
|
||||
wstate->pastrawdzmem = rawdzmem;
|
||||
|
||||
int precision_factor = (zval >> 13) & 0xf;
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t dzmemmodifier;
|
||||
if (precision_factor < 3)
|
||||
{
|
||||
if (dzmem != 0x8000)
|
||||
{
|
||||
dzmemmodifier = 16 >> precision_factor;
|
||||
dzmem <<= 1;
|
||||
if (dzmem < dzmemmodifier)
|
||||
dzmem = dzmemmodifier;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
force_coplanar = 1;
|
||||
dzmem = 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t dznew = (uint32_t)deltaz_comparator_lut[dzpix | dzmem];
|
||||
|
||||
uint32_t dznotshift = dznew;
|
||||
dznew <<= 3;
|
||||
|
||||
|
||||
uint32_t farther = force_coplanar || ((sz + dznew) >= oz);
|
||||
|
||||
int overflow = (curpixel_memcvg + *curpixel_cvg) & 8;
|
||||
*blend_en = wstate->other_modes.force_blend || (!overflow && wstate->other_modes.antialias_en && farther);
|
||||
|
||||
*prewrap = overflow;
|
||||
|
||||
|
||||
|
||||
int cvgcoeff = 0;
|
||||
uint32_t dzenc = 0;
|
||||
|
||||
int32_t diff;
|
||||
uint32_t nearer, max, infront;
|
||||
|
||||
switch(wstate->other_modes.z_mode)
|
||||
{
|
||||
case ZMODE_OPAQUE:
|
||||
infront = sz < oz;
|
||||
diff = (int32_t)sz - (int32_t)dznew;
|
||||
nearer = force_coplanar || (diff <= (int32_t)oz);
|
||||
max = (oz == 0x3ffff);
|
||||
return (max || (overflow ? infront : nearer));
|
||||
break;
|
||||
case ZMODE_INTERPENETRATING:
|
||||
infront = sz < oz;
|
||||
if (!infront || !farther || !overflow)
|
||||
{
|
||||
diff = (int32_t)sz - (int32_t)dznew;
|
||||
nearer = force_coplanar || (diff <= (int32_t)oz);
|
||||
max = (oz == 0x3ffff);
|
||||
return (max || (overflow ? infront : nearer));
|
||||
}
|
||||
else
|
||||
{
|
||||
dzenc = dz_compress(dznotshift & 0xffff);
|
||||
cvgcoeff = ((oz >> dzenc) - (sz >> dzenc)) & 0xf;
|
||||
*curpixel_cvg = ((cvgcoeff * (*curpixel_cvg)) >> 3) & 0xf;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case ZMODE_TRANSPARENT:
|
||||
infront = sz < oz;
|
||||
max = (oz == 0x3ffff);
|
||||
return (infront || max);
|
||||
break;
|
||||
case ZMODE_DECAL:
|
||||
diff = (int32_t)sz - (int32_t)dznew;
|
||||
nearer = force_coplanar || (diff <= (int32_t)oz);
|
||||
max = (oz == 0x3ffff);
|
||||
return (farther && nearer && !max);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
if (wstate->other_modes.f.realblendershiftersneeded)
|
||||
{
|
||||
wstate->blshifta = 0;
|
||||
if (dzpixenc < 0xb)
|
||||
wstate->blshiftb = 4;
|
||||
else
|
||||
wstate->blshiftb = 0xf - dzpixenc;
|
||||
}
|
||||
|
||||
if (wstate->other_modes.f.interpixelblendershiftersneeded)
|
||||
{
|
||||
wstate->pastblshifta = 0;
|
||||
if (dzpixenc < 0xb)
|
||||
wstate->pastblshiftb = 4;
|
||||
else
|
||||
wstate->pastblshiftb = 0xf - dzpixenc;
|
||||
}
|
||||
|
||||
wstate->pastrawdzmem = 0xf;
|
||||
|
||||
int overflow = (curpixel_memcvg + *curpixel_cvg) & 8;
|
||||
*blend_en = wstate->other_modes.force_blend || (!overflow && wstate->other_modes.antialias_en);
|
||||
*prewrap = overflow;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void rdp_set_mask_image(struct rdp_state* wstate, const uint32_t* args)
|
||||
{
|
||||
wstate->zb_address = args[1] & 0x0ffffff;
|
||||
}
|
||||
|
||||
void z_init_lut(void)
|
||||
{
|
||||
int i;
|
||||
z_build_com_table();
|
||||
|
||||
uint32_t exponent;
|
||||
uint32_t mantissa;
|
||||
for (i = 0; i < 0x4000; i++)
|
||||
{
|
||||
exponent = (i >> 11) & 7;
|
||||
mantissa = i & 0x7ff;
|
||||
z_complete_dec_table[i] = ((mantissa << z_dec_table[exponent].shift) + z_dec_table[exponent].add) & 0x3ffff;
|
||||
}
|
||||
|
||||
deltaz_comparator_lut[0] = 0;
|
||||
for (i = 1; i < 0x10000; i++)
|
||||
{
|
||||
int k;
|
||||
for (k = 15; k >= 0; k--)
|
||||
{
|
||||
if (i & (1 << k))
|
||||
{
|
||||
deltaz_comparator_lut[i] = 1 << k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,743 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
// anamorphic NTSC resolution
|
||||
#define H_RES_NTSC 640
|
||||
#define V_RES_NTSC 480
|
||||
|
||||
// anamorphic PAL resolution
|
||||
#define H_RES_PAL 768
|
||||
#define V_RES_PAL 576
|
||||
|
||||
// typical VI_V_SYNC values for NTSC and PAL
|
||||
#define V_SYNC_NTSC 525
|
||||
#define V_SYNC_PAL 625
|
||||
|
||||
// maximum possible size of the prescale area
|
||||
#define PRESCALE_WIDTH H_RES_NTSC
|
||||
#define PRESCALE_HEIGHT V_SYNC_PAL
|
||||
|
||||
enum vi_type
|
||||
{
|
||||
VI_TYPE_BLANK, // no data, no sync
|
||||
VI_TYPE_RESERVED, // unused, should never be set
|
||||
VI_TYPE_RGBA5551, // 16 bit color (internally 18 bit RGBA5553)
|
||||
VI_TYPE_RGBA8888 // 32 bit color
|
||||
};
|
||||
|
||||
enum vi_aa
|
||||
{
|
||||
VI_AA_RESAMP_EXTRA_ALWAYS, // resample and AA (always fetch extra lines)
|
||||
VI_AA_RESAMP_EXTRA, // resample and AA (fetch extra lines if needed)
|
||||
VI_AA_RESAMP_ONLY, // only resample (treat as all fully covered)
|
||||
VI_AA_REPLICATE // replicate pixels, no interpolation
|
||||
};
|
||||
|
||||
struct vi_reg_ctrl
|
||||
{
|
||||
uint8_t type;
|
||||
bool gamma_dither_enable;
|
||||
bool gamma_enable;
|
||||
bool divot_enable;
|
||||
bool vbus_clock_enable;
|
||||
bool serrate;
|
||||
bool test_mode;
|
||||
uint8_t aa_mode;
|
||||
bool reserved;
|
||||
bool kill_we;
|
||||
uint8_t pixel_advance;
|
||||
bool dither_filter_enable;
|
||||
};
|
||||
|
||||
typedef void(*vi_fetch_filter_func)(struct n64video_pixel*, uint32_t, uint32_t, struct vi_reg_ctrl, uint32_t, uint32_t);
|
||||
|
||||
#include "vi/gamma.c"
|
||||
#include "vi/lerp.c"
|
||||
#include "vi/divot.c"
|
||||
#include "vi/video.c"
|
||||
#include "vi/restore.c"
|
||||
#include "vi/fetch.c"
|
||||
|
||||
// states
|
||||
static int32_t prevvicurrent;
|
||||
static int32_t emucontrolsvicurrent;
|
||||
static bool prevserrate;
|
||||
static bool lowerfield;
|
||||
static int32_t oldvstart;
|
||||
static bool prevwasblank;
|
||||
static int32_t vactivelines;
|
||||
static bool ispal;
|
||||
static int32_t minhpass;
|
||||
static int32_t maxhpass;
|
||||
static uint32_t x_add;
|
||||
static uint32_t x_start;
|
||||
static uint32_t y_add;
|
||||
static uint32_t y_start;
|
||||
static int32_t v_sync;
|
||||
static int32_t vi_width_low;
|
||||
static uint32_t frame_buffer;
|
||||
static uint32_t tvfadeoutstate[PRESCALE_HEIGHT];
|
||||
static uint32_t zb_address;
|
||||
|
||||
// prescale buffer
|
||||
static struct n64video_pixel prescale[PRESCALE_WIDTH * PRESCALE_HEIGHT];
|
||||
static uint32_t prescale_ptr;
|
||||
static int32_t linecount;
|
||||
|
||||
// parsed VI registers
|
||||
static uint32_t** vi_reg_ptr;
|
||||
static struct vi_reg_ctrl ctrl;
|
||||
static int32_t hres, vres;
|
||||
static int32_t hres_raw, vres_raw;
|
||||
static int32_t v_start;
|
||||
static int32_t h_start;
|
||||
static int32_t v_current_line;
|
||||
|
||||
static void vi_init(void)
|
||||
{
|
||||
vi_gamma_init();
|
||||
vi_restore_init();
|
||||
|
||||
memset(prescale, 0, sizeof(prescale));
|
||||
|
||||
prevvicurrent = 0;
|
||||
emucontrolsvicurrent = -1;
|
||||
prevserrate = false;
|
||||
oldvstart = 1337;
|
||||
prevwasblank = false;
|
||||
zb_address = 0;
|
||||
}
|
||||
|
||||
static void vi_process_full_parallel(uint32_t worker_id)
|
||||
{
|
||||
int32_t y;
|
||||
struct n64video_pixel viaa_array[0xa10 << 1];
|
||||
struct n64video_pixel divot_array[0xa10 << 1];
|
||||
|
||||
int32_t cache_marker = 0, cache_next_marker = 0, divot_cache_marker = 0, divot_cache_next_marker = 0;
|
||||
int32_t cache_marker_init = (x_start >> 10) - 1;
|
||||
|
||||
struct n64video_pixel *viaa_cache = &viaa_array[0];
|
||||
struct n64video_pixel *viaa_cache_next = &viaa_array[0xa10];
|
||||
struct n64video_pixel *divot_cache = &divot_array[0];
|
||||
struct n64video_pixel *divot_cache_next = &divot_array[0xa10];
|
||||
|
||||
struct n64video_pixel color, nextcolor, scancolor, scannextcolor;
|
||||
|
||||
vi_fetch_filter_func vi_fetch_filter_ptr = ctrl.type & 1 ? vi_fetch_filter32 : vi_fetch_filter16;
|
||||
|
||||
uint32_t pixels = 0, nextpixels = 0, fetchbugstate = 0;
|
||||
|
||||
int32_t xfrac = 0, yfrac = 0;
|
||||
int32_t line_x = 0, next_line_x = 0, prev_line_x = 0, far_line_x = 0;
|
||||
int32_t prev_scan_x = 0, scan_x = 0, next_scan_x = 0, far_scan_x = 0;
|
||||
int32_t prev_x = 0, cur_x = 0, next_x = 0, far_x = 0;
|
||||
|
||||
bool cache_init = false;
|
||||
|
||||
pixels = 0;
|
||||
|
||||
int32_t y_begin = 0;
|
||||
int32_t y_end = vres;
|
||||
int32_t y_inc = 1;
|
||||
|
||||
if (config.parallel) {
|
||||
y_begin = worker_id;
|
||||
y_inc = parallel_num_workers();
|
||||
}
|
||||
|
||||
for (y = y_begin; y < y_end; y += y_inc) {
|
||||
int32_t x;
|
||||
uint32_t x_offs = x_start;
|
||||
uint32_t curry = y_start + y * y_add;
|
||||
uint32_t nexty = y_start + (y + 1) * y_add;
|
||||
uint32_t prevy = curry >> 10;
|
||||
|
||||
cache_marker = cache_next_marker = cache_marker_init;
|
||||
if (ctrl.divot_enable) {
|
||||
divot_cache_marker = divot_cache_next_marker = cache_marker_init;
|
||||
}
|
||||
|
||||
struct n64video_pixel* pixel_row = &prescale[prescale_ptr + linecount * y];
|
||||
|
||||
yfrac = (curry >> 5) & 0x1f;
|
||||
pixels = vi_width_low * prevy;
|
||||
nextpixels = vi_width_low + pixels;
|
||||
|
||||
if (prevy == (nexty >> 10)) {
|
||||
fetchbugstate = 2;
|
||||
} else {
|
||||
fetchbugstate >>= 1;
|
||||
}
|
||||
|
||||
for (x = 0; x < hres; x++, x_offs += x_add) {
|
||||
line_x = x_offs >> 10;
|
||||
prev_line_x = line_x - 1;
|
||||
next_line_x = line_x + 1;
|
||||
far_line_x = line_x + 2;
|
||||
|
||||
cur_x = pixels + line_x;
|
||||
prev_x = pixels + prev_line_x;
|
||||
next_x = pixels + next_line_x;
|
||||
far_x = pixels + far_line_x;
|
||||
|
||||
scan_x = nextpixels + line_x;
|
||||
prev_scan_x = nextpixels + prev_line_x;
|
||||
next_scan_x = nextpixels + next_line_x;
|
||||
far_scan_x = nextpixels + far_line_x;
|
||||
|
||||
line_x++;
|
||||
prev_line_x++;
|
||||
next_line_x++;
|
||||
far_line_x++;
|
||||
|
||||
xfrac = (x_offs >> 5) & 0x1f;
|
||||
|
||||
if (prev_line_x > cache_marker) {
|
||||
vi_fetch_filter_ptr(&viaa_cache[prev_line_x], frame_buffer, prev_x, ctrl, vi_width_low, 0);
|
||||
vi_fetch_filter_ptr(&viaa_cache[line_x], frame_buffer, cur_x, ctrl, vi_width_low, 0);
|
||||
vi_fetch_filter_ptr(&viaa_cache[next_line_x], frame_buffer, next_x, ctrl, vi_width_low, 0);
|
||||
cache_marker = next_line_x;
|
||||
} else if (line_x > cache_marker) {
|
||||
vi_fetch_filter_ptr(&viaa_cache[line_x], frame_buffer, cur_x, ctrl, vi_width_low, 0);
|
||||
vi_fetch_filter_ptr(&viaa_cache[next_line_x], frame_buffer, next_x, ctrl, vi_width_low, 0);
|
||||
cache_marker = next_line_x;
|
||||
} else if (next_line_x > cache_marker) {
|
||||
vi_fetch_filter_ptr(&viaa_cache[next_line_x], frame_buffer, next_x, ctrl, vi_width_low, 0);
|
||||
cache_marker = next_line_x;
|
||||
}
|
||||
|
||||
if (prev_line_x > cache_next_marker) {
|
||||
vi_fetch_filter_ptr(&viaa_cache_next[prev_line_x], frame_buffer, prev_scan_x, ctrl, vi_width_low, fetchbugstate);
|
||||
vi_fetch_filter_ptr(&viaa_cache_next[line_x], frame_buffer, scan_x, ctrl, vi_width_low, fetchbugstate);
|
||||
vi_fetch_filter_ptr(&viaa_cache_next[next_line_x], frame_buffer, next_scan_x, ctrl, vi_width_low, fetchbugstate);
|
||||
cache_next_marker = next_line_x;
|
||||
} else if (line_x > cache_next_marker) {
|
||||
vi_fetch_filter_ptr(&viaa_cache_next[line_x], frame_buffer, scan_x, ctrl, vi_width_low, fetchbugstate);
|
||||
vi_fetch_filter_ptr(&viaa_cache_next[next_line_x], frame_buffer, next_scan_x, ctrl, vi_width_low, fetchbugstate);
|
||||
cache_next_marker = next_line_x;
|
||||
} else if (next_line_x > cache_next_marker) {
|
||||
vi_fetch_filter_ptr(&viaa_cache_next[next_line_x], frame_buffer, next_scan_x, ctrl, vi_width_low, fetchbugstate);
|
||||
cache_next_marker = next_line_x;
|
||||
}
|
||||
|
||||
if (ctrl.divot_enable) {
|
||||
if (far_line_x > cache_marker) {
|
||||
vi_fetch_filter_ptr(&viaa_cache[far_line_x], frame_buffer, far_x, ctrl, vi_width_low, 0);
|
||||
cache_marker = far_line_x;
|
||||
}
|
||||
|
||||
if (far_line_x > cache_next_marker) {
|
||||
vi_fetch_filter_ptr(&viaa_cache_next[far_line_x], frame_buffer, far_scan_x, ctrl, vi_width_low, fetchbugstate);
|
||||
cache_next_marker = far_line_x;
|
||||
}
|
||||
|
||||
if (line_x > divot_cache_marker) {
|
||||
divot_filter(&divot_cache[line_x], viaa_cache[line_x], viaa_cache[prev_line_x], viaa_cache[next_line_x]);
|
||||
divot_filter(&divot_cache[next_line_x], viaa_cache[next_line_x], viaa_cache[line_x], viaa_cache[far_line_x]);
|
||||
divot_cache_marker = next_line_x;
|
||||
} else if (next_line_x > divot_cache_marker) {
|
||||
divot_filter(&divot_cache[next_line_x], viaa_cache[next_line_x], viaa_cache[line_x], viaa_cache[far_line_x]);
|
||||
divot_cache_marker = next_line_x;
|
||||
}
|
||||
|
||||
if (line_x > divot_cache_next_marker) {
|
||||
divot_filter(&divot_cache_next[line_x], viaa_cache_next[line_x], viaa_cache_next[prev_line_x], viaa_cache_next[next_line_x]);
|
||||
divot_filter(&divot_cache_next[next_line_x], viaa_cache_next[next_line_x], viaa_cache_next[line_x], viaa_cache_next[far_line_x]);
|
||||
divot_cache_next_marker = next_line_x;
|
||||
} else if (next_line_x > divot_cache_next_marker) {
|
||||
divot_filter(&divot_cache_next[next_line_x], viaa_cache_next[next_line_x], viaa_cache_next[line_x], viaa_cache_next[far_line_x]);
|
||||
divot_cache_next_marker = next_line_x;
|
||||
}
|
||||
|
||||
color = divot_cache[line_x];
|
||||
} else {
|
||||
color = viaa_cache[line_x];
|
||||
}
|
||||
|
||||
bool lerping = ctrl.aa_mode != VI_AA_REPLICATE && (xfrac || yfrac);
|
||||
|
||||
if (lerping) {
|
||||
if (ctrl.divot_enable) {
|
||||
nextcolor = divot_cache[next_line_x];
|
||||
scancolor = divot_cache_next[line_x];
|
||||
scannextcolor = divot_cache_next[next_line_x];
|
||||
} else {
|
||||
nextcolor = viaa_cache[next_line_x];
|
||||
scancolor = viaa_cache_next[line_x];
|
||||
scannextcolor = viaa_cache_next[next_line_x];
|
||||
}
|
||||
|
||||
vi_vl_lerp(&color, scancolor, yfrac);
|
||||
vi_vl_lerp(&nextcolor, scannextcolor, yfrac);
|
||||
vi_vl_lerp(&color, nextcolor, xfrac);
|
||||
}
|
||||
|
||||
struct n64video_pixel* pixel = &pixel_row[x];
|
||||
|
||||
if (x >= minhpass && x < maxhpass) {
|
||||
*pixel = color;
|
||||
gamma_filters(pixel, ctrl.gamma_enable, ctrl.gamma_dither_enable, &state[worker_id].rseed);
|
||||
} else {
|
||||
pixel->r = pixel->g = pixel->b = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cache_init && y_add == 0x400) {
|
||||
cache_marker = cache_next_marker;
|
||||
cache_next_marker = cache_marker_init;
|
||||
|
||||
struct n64video_pixel* tempccvgptr = viaa_cache;
|
||||
viaa_cache = viaa_cache_next;
|
||||
viaa_cache_next = tempccvgptr;
|
||||
if (ctrl.divot_enable) {
|
||||
divot_cache_marker = divot_cache_next_marker;
|
||||
divot_cache_next_marker = cache_marker_init;
|
||||
tempccvgptr = divot_cache;
|
||||
divot_cache = divot_cache_next;
|
||||
divot_cache_next = tempccvgptr;
|
||||
}
|
||||
|
||||
cache_init = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool vi_process_full(struct n64video_frame_buffer* fb)
|
||||
{
|
||||
bool isblank = (ctrl.type & 2) == 0;
|
||||
bool validinterlace = !isblank && ctrl.serrate;
|
||||
|
||||
if (validinterlace) {
|
||||
if (prevserrate && emucontrolsvicurrent < 0) {
|
||||
emucontrolsvicurrent = v_current_line != prevvicurrent;
|
||||
}
|
||||
|
||||
if (emucontrolsvicurrent == 1) {
|
||||
lowerfield = v_current_line ^ 1;
|
||||
} else if (!emucontrolsvicurrent) {
|
||||
if (v_start == oldvstart) {
|
||||
lowerfield ^= true;
|
||||
} else {
|
||||
lowerfield = v_start < oldvstart;
|
||||
}
|
||||
}
|
||||
|
||||
prevvicurrent = v_current_line;
|
||||
oldvstart = v_start;
|
||||
}
|
||||
|
||||
prevserrate = validinterlace;
|
||||
|
||||
bool validh = hres > 0 && h_start < PRESCALE_WIDTH;
|
||||
int32_t h_end = hres + h_start; // note: the result appears to be different to VI_H_END
|
||||
int32_t hrightblank = PRESCALE_WIDTH - h_end;
|
||||
|
||||
if (isblank && prevwasblank) {
|
||||
return false;
|
||||
}
|
||||
|
||||
prevwasblank = isblank;
|
||||
|
||||
linecount = PRESCALE_WIDTH << ctrl.serrate;
|
||||
prescale_ptr = v_start * linecount + h_start + (lowerfield ? PRESCALE_WIDTH : 0);
|
||||
|
||||
int32_t i;
|
||||
if (isblank) {
|
||||
// blank signal, clear entire screen buffer
|
||||
memset(tvfadeoutstate, 0, PRESCALE_HEIGHT * sizeof(uint32_t));
|
||||
memset(prescale, 0, sizeof(prescale));
|
||||
} else {
|
||||
// clear left border
|
||||
int32_t j;
|
||||
if (h_start > 0 && h_start < PRESCALE_WIDTH) {
|
||||
for (i = 0; i < vactivelines; i++) {
|
||||
memset(&prescale[i * PRESCALE_WIDTH], 0, h_start * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
// clear right border
|
||||
if (h_end >= 0 && h_end < PRESCALE_WIDTH) {
|
||||
for (i = 0; i < vactivelines; i++) {
|
||||
memset(&prescale[i * PRESCALE_WIDTH + h_end], 0, hrightblank * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
// clear top border
|
||||
for (i = 0; i < ((v_start << ctrl.serrate) + lowerfield); i++) {
|
||||
if (tvfadeoutstate[i]) {
|
||||
tvfadeoutstate[i]--;
|
||||
if (!tvfadeoutstate[i]) {
|
||||
if (validh) {
|
||||
memset(&prescale[i * PRESCALE_WIDTH + h_start], 0, hres * sizeof(uint32_t));
|
||||
} else {
|
||||
memset(&prescale[i * PRESCALE_WIDTH], 0, PRESCALE_WIDTH * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctrl.serrate) {
|
||||
for(j = 0; j < vres; j++) {
|
||||
if (validh) {
|
||||
tvfadeoutstate[i] = 2;
|
||||
} else if (tvfadeoutstate[i]) {
|
||||
tvfadeoutstate[i]--;
|
||||
if (!tvfadeoutstate[i]) {
|
||||
memset(&prescale[i * PRESCALE_WIDTH], 0, PRESCALE_WIDTH * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for(j = 0; j < vres; j++) {
|
||||
if (validh) {
|
||||
tvfadeoutstate[i] = 2;
|
||||
} else if (tvfadeoutstate[i]) {
|
||||
tvfadeoutstate[i]--;
|
||||
if (!tvfadeoutstate[i]) {
|
||||
memset(&prescale[i * PRESCALE_WIDTH], 0, PRESCALE_WIDTH * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (tvfadeoutstate[i + 1]) {
|
||||
tvfadeoutstate[i + 1]--;
|
||||
if (!tvfadeoutstate[i + 1]) {
|
||||
if (validh) {
|
||||
memset(&prescale[(i + 1) * PRESCALE_WIDTH + h_start], 0, hres * sizeof(uint32_t));
|
||||
} else {
|
||||
memset(&prescale[(i + 1) * PRESCALE_WIDTH], 0, PRESCALE_WIDTH * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// clear bottom border
|
||||
for (; i < vactivelines; i++) {
|
||||
if (tvfadeoutstate[i]) {
|
||||
tvfadeoutstate[i]--;
|
||||
}
|
||||
if (!tvfadeoutstate[i]) {
|
||||
if (validh) {
|
||||
memset(&prescale[i * PRESCALE_WIDTH + h_start], 0, hres * sizeof(uint32_t));
|
||||
} else {
|
||||
memset(&prescale[i * PRESCALE_WIDTH], 0, PRESCALE_WIDTH * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!validh) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// run filter update in parallel if enabled
|
||||
if (config.parallel) {
|
||||
parallel_run(vi_process_full_parallel);
|
||||
} else {
|
||||
vi_process_full_parallel(0);
|
||||
}
|
||||
|
||||
// finish and send buffer to screen
|
||||
fb->pixels = prescale;
|
||||
fb->pitch = PRESCALE_WIDTH;
|
||||
|
||||
if (config.vi.hide_overscan) {
|
||||
// crop away overscan area from prescale
|
||||
fb->width = maxhpass - minhpass;
|
||||
fb->height = vres << ctrl.serrate;
|
||||
fb->height_out = (vres << 1) * V_SYNC_NTSC / v_sync;
|
||||
int32_t x = h_start + minhpass;
|
||||
int32_t y = (v_start + (emucontrolsvicurrent ? lowerfield : 0)) << ctrl.serrate;
|
||||
fb->pixels += x + y * fb->pitch;
|
||||
} else {
|
||||
// use entire prescale buffer
|
||||
fb->width = PRESCALE_WIDTH;
|
||||
fb->height = (ispal ? V_RES_PAL : V_RES_NTSC) >> !ctrl.serrate;
|
||||
fb->height_out = V_RES_NTSC;
|
||||
}
|
||||
|
||||
// convert to 16:9 if enabled
|
||||
if (config.vi.widescreen) {
|
||||
fb->height_out = fb->height_out * 3 / 4;
|
||||
}
|
||||
|
||||
return fb->width > 0 && fb->height > 0;
|
||||
}
|
||||
|
||||
static void vi_process_fast_parallel(uint32_t worker_id)
|
||||
{
|
||||
int32_t y;
|
||||
int32_t y_begin = 0;
|
||||
int32_t y_end = vres_raw;
|
||||
int32_t y_inc = 1;
|
||||
|
||||
// drop every other interlaced frame to avoid "wobbly" output due to the
|
||||
// vertical offset
|
||||
// TODO: completely skip rendering these frames in unfiltered to improve
|
||||
// performance?
|
||||
if (ctrl.serrate && v_current_line) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.parallel) {
|
||||
y_begin = worker_id;
|
||||
y_inc = parallel_num_workers();
|
||||
}
|
||||
|
||||
for (y = y_begin; y < y_end; y += y_inc) {
|
||||
int32_t x;
|
||||
int32_t line = y * vi_width_low;
|
||||
|
||||
struct n64video_pixel* pixel_row = &prescale[y * hres_raw];
|
||||
|
||||
for (x = 0; x < hres_raw; x++) {
|
||||
struct n64video_pixel* pixel = &pixel_row[x];
|
||||
|
||||
switch (config.vi.mode) {
|
||||
case VI_MODE_COLOR:
|
||||
switch (ctrl.type) {
|
||||
case VI_TYPE_RGBA5551: {
|
||||
uint16_t pix = rdram_read_idx16((frame_buffer >> 1) + line + x);
|
||||
pixel->r = (uint8_t)RGBA16_R(pix);
|
||||
pixel->g = (uint8_t)RGBA16_G(pix);
|
||||
pixel->b = (uint8_t)RGBA16_B(pix);
|
||||
break;
|
||||
}
|
||||
|
||||
case VI_TYPE_RGBA8888: {
|
||||
uint32_t pix = rdram_read_idx32((frame_buffer >> 2) + line + x);
|
||||
pixel->r = (uint8_t)RGBA32_R(pix);
|
||||
pixel->g = (uint8_t)RGBA32_G(pix);
|
||||
pixel->b = (uint8_t)RGBA32_B(pix);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
gamma_filters(pixel, ctrl.gamma_enable, false, &state[worker_id].rseed);
|
||||
break;
|
||||
|
||||
case VI_MODE_DEPTH: {
|
||||
if (zb_address) {
|
||||
pixel->r = pixel->g = pixel->b = rdram_read_idx16((zb_address >> 1) + line + x) >> 8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VI_MODE_COVERAGE: {
|
||||
// TODO: incorrect for RGBA8888?
|
||||
uint8_t hval;
|
||||
uint16_t pix;
|
||||
rdram_read_pair16(&pix, &hval, (frame_buffer >> 1) + line + x);
|
||||
pixel->r = pixel->g = pixel->b = (((pix & 1) << 2) | hval) << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool vi_process_fast(struct n64video_frame_buffer* fb)
|
||||
{
|
||||
// note: this is probably a very, very crude method to get the frame size,
|
||||
// but should hopefully work most of the time
|
||||
hres_raw = (int32_t)x_add * hres / 1024;
|
||||
vres_raw = (int32_t)y_add * vres / 1024;
|
||||
|
||||
// skip invalid frame sizes
|
||||
if (hres_raw <= 0 || vres_raw <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip blank/invalid modes
|
||||
if (!(ctrl.type & 2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// run filter update in parallel if enabled
|
||||
if (config.parallel) {
|
||||
parallel_run(vi_process_fast_parallel);
|
||||
} else {
|
||||
vi_process_fast_parallel(0);
|
||||
}
|
||||
|
||||
// finish and send buffer to screen
|
||||
fb->pixels = prescale;
|
||||
fb->width = hres_raw;
|
||||
fb->height = vres_raw;
|
||||
fb->pitch = hres_raw;
|
||||
|
||||
// get display size of filtered mode
|
||||
int32_t filtered_width = maxhpass - minhpass;
|
||||
int32_t filtered_height = (vres << 1) * V_SYNC_NTSC / v_sync;
|
||||
|
||||
// re-calculate cropped 8 pixel area on the left and right from filtered mode
|
||||
int32_t border_width = (hres - filtered_width) * hres_raw / hres;
|
||||
fb->pixels += (border_width / 2) + 1;
|
||||
fb->width -= border_width;
|
||||
|
||||
// force aspect ratio of filtered mode
|
||||
fb->height_out = fb->width * filtered_height / filtered_width;
|
||||
|
||||
// convert to 16:9 if enabled
|
||||
if (config.vi.widescreen) {
|
||||
fb->height_out = fb->height_out * 3 / 4;
|
||||
}
|
||||
|
||||
return fb->width > 0 && fb->height > 0;
|
||||
}
|
||||
|
||||
void vi_set_zbuffer_address(uint32_t address)
|
||||
{
|
||||
zb_address = address;
|
||||
}
|
||||
|
||||
void n64video_update_screen(struct n64video_frame_buffer* fb)
|
||||
{
|
||||
// check for configuration errors
|
||||
if (config.vi.mode >= VI_MODE_NUM) {
|
||||
msg_error("Invalid VI mode: %d", config.vi.mode);
|
||||
}
|
||||
|
||||
// parse and check some common registers
|
||||
vi_reg_ptr = config.gfx.vi_reg;
|
||||
|
||||
v_start = (*vi_reg_ptr[VI_V_START] >> 16) & 0x3ff;
|
||||
h_start = (*vi_reg_ptr[VI_H_START] >> 16) & 0x3ff;
|
||||
|
||||
int32_t v_end = *vi_reg_ptr[VI_V_START] & 0x3ff;
|
||||
int32_t h_end = *vi_reg_ptr[VI_H_START] & 0x3ff;
|
||||
|
||||
hres = h_end - h_start;
|
||||
vres = (v_end - v_start) >> 1; // vertical is measured in half-lines
|
||||
|
||||
x_add = *vi_reg_ptr[VI_X_SCALE] & 0xfff;
|
||||
x_start = (*vi_reg_ptr[VI_X_SCALE] >> 16) & 0xfff;
|
||||
|
||||
y_add = *vi_reg_ptr[VI_Y_SCALE] & 0xfff;
|
||||
y_start = (*vi_reg_ptr[VI_Y_SCALE] >> 16) & 0xfff;
|
||||
|
||||
v_sync = *vi_reg_ptr[VI_V_SYNC] & 0x3ff;
|
||||
v_current_line = *vi_reg_ptr[VI_V_CURRENT_LINE] & 1;
|
||||
|
||||
vi_width_low = *vi_reg_ptr[VI_WIDTH] & 0xfff;
|
||||
frame_buffer = *vi_reg_ptr[VI_ORIGIN] & 0xffffff;
|
||||
|
||||
// cancel if the frame buffer contains no valid address
|
||||
if (!frame_buffer) {
|
||||
fb->valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// split up VI_CONTROL bits
|
||||
uint32_t vi_control = *vi_reg_ptr[VI_STATUS];
|
||||
ctrl.type = vi_control & 3;
|
||||
ctrl.gamma_dither_enable = (vi_control >> 2) & 1;
|
||||
ctrl.gamma_enable = (vi_control >> 3) & 1;
|
||||
ctrl.divot_enable = (vi_control >> 4) & 1;
|
||||
ctrl.vbus_clock_enable = (vi_control >> 5) & 1;
|
||||
ctrl.serrate = (vi_control >> 6) & 1;
|
||||
ctrl.test_mode = (vi_control >> 7) & 1;
|
||||
ctrl.aa_mode = (vi_control >> 8) & 3;
|
||||
ctrl.reserved = (vi_control >> 9) & 1;
|
||||
ctrl.kill_we = (vi_control >> 10) & 1;
|
||||
ctrl.pixel_advance = (vi_control >> 12) & 0xf;
|
||||
ctrl.dither_filter_enable = (vi_control >> 16) & 1;
|
||||
|
||||
// check for unexpected VI type bits set
|
||||
if (ctrl.type & ~3) {
|
||||
msg_error("Unknown framebuffer format %d", ctrl.type);
|
||||
}
|
||||
|
||||
// warn about AA glitches in certain cases
|
||||
if (ctrl.aa_mode == VI_AA_REPLICATE && ctrl.type == VI_TYPE_RGBA5551 &&
|
||||
h_start < 0x80 && x_add <= 0x200 && !onetimewarnings.nolerp) {
|
||||
msg_warning("vi_update: Disabling VI interpolation in 16-bit color "
|
||||
"modes causes glitches on hardware if h_start is less than "
|
||||
"128 pixels and x_scale is less or equal to 0x200.");
|
||||
onetimewarnings.nolerp = true;
|
||||
}
|
||||
|
||||
// check for the dangerous vbus_clock_enable flag. it was introduced to
|
||||
// configure Ultra 64 prototypes and enabling it on final hardware will
|
||||
// enable two output drivers on the same bus at the same time
|
||||
if (ctrl.vbus_clock_enable && !onetimewarnings.vbusclock) {
|
||||
msg_warning("vi_update: vbus_clock_enable bit set in VI_CONTROL_REG "
|
||||
"register. Never run this code on your N64! It's rumored "
|
||||
"that turning this bit on will result in permanent damage "
|
||||
"to the hardware! Emulation will now continue.");
|
||||
onetimewarnings.vbusclock = true;
|
||||
}
|
||||
|
||||
// adjust sizes and offsets
|
||||
ispal = v_sync > (V_SYNC_NTSC + 25);
|
||||
h_start -= (ispal ? 128 : 108);
|
||||
|
||||
bool h_start_clamped = false;
|
||||
|
||||
if (h_start < 0) {
|
||||
x_start += (x_add * (-h_start));
|
||||
hres += h_start;
|
||||
|
||||
h_start = 0;
|
||||
h_start_clamped = true;
|
||||
}
|
||||
|
||||
int32_t vstartoffset = ispal ? 44 : 34;
|
||||
v_start = (v_start - vstartoffset) / 2;
|
||||
|
||||
if (v_start < 0) {
|
||||
y_start += (y_add * (uint32_t)(-v_start));
|
||||
v_start = 0;
|
||||
}
|
||||
|
||||
bool hres_clamped = false;
|
||||
|
||||
if ((hres + h_start) > PRESCALE_WIDTH) {
|
||||
hres = PRESCALE_WIDTH - h_start;
|
||||
hres_clamped = true;
|
||||
}
|
||||
|
||||
if ((vres + v_start) > PRESCALE_HEIGHT) {
|
||||
vres = PRESCALE_HEIGHT - v_start;
|
||||
msg_warning("vres = %d v_start = %d v_video_start = %d", vres, v_start, (*vi_reg_ptr[VI_V_START] >> 16) & 0x3ff);
|
||||
}
|
||||
|
||||
vactivelines = v_sync - vstartoffset;
|
||||
|
||||
if (vactivelines > PRESCALE_HEIGHT) {
|
||||
msg_error("VI_V_SYNC_REG too big");
|
||||
}
|
||||
|
||||
fb->valid = true;
|
||||
|
||||
if (vactivelines >= 0) {
|
||||
uint32_t lineshifter = !ctrl.serrate;
|
||||
vactivelines >>= lineshifter;
|
||||
|
||||
minhpass = h_start_clamped ? 0 : 8;
|
||||
maxhpass = hres_clamped ? hres : (hres - 7);
|
||||
|
||||
// run filter update in parallel if enabled
|
||||
if (config.vi.mode == VI_MODE_NORMAL) {
|
||||
fb->valid = vi_process_full(fb);
|
||||
} else {
|
||||
fb->valid = vi_process_fast(fb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vi_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static STRICTINLINE void divot_filter(struct n64video_pixel* final, struct n64video_pixel center, struct n64video_pixel left, struct n64video_pixel right)
|
||||
{
|
||||
*final = center;
|
||||
|
||||
if ((center.a & left.a & right.a) == 7)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((left.r >= center.r && right.r >= left.r) || (left.r >= right.r && center.r >= left.r))
|
||||
final->r = left.r;
|
||||
else if ((right.r >= center.r && left.r >= right.r) || (right.r >= left.r && center.r >= right.r))
|
||||
final->r = right.r;
|
||||
|
||||
if ((left.g >= center.g && right.g >= left.g) || (left.g >= right.g && center.g >= left.g))
|
||||
final->g = left.g;
|
||||
else if ((right.g >= center.g && left.g >= right.g) || (right.g >= left.g && center.g >= right.g))
|
||||
final->g = right.g;
|
||||
|
||||
if ((left.b >= center.b && right.b >= left.b) || (left.b >= right.b && center.b >= left.b))
|
||||
final->b = left.b;
|
||||
else if ((right.b >= center.b && left.b >= right.b) || (right.b >= left.b && center.b >= right.b))
|
||||
final->b = right.b;
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static void vi_fetch_filter16(struct n64video_pixel* res, uint32_t fboffset, uint32_t cur_x, struct vi_reg_ctrl ctrl, uint32_t hres, uint32_t fetchstate)
|
||||
{
|
||||
int r, g, b;
|
||||
uint32_t idx = (fboffset >> 1) + cur_x;
|
||||
uint8_t hval;
|
||||
uint16_t pix;
|
||||
uint32_t cur_cvg;
|
||||
if (ctrl.aa_mode <= VI_AA_RESAMP_EXTRA)
|
||||
{
|
||||
PAIRREAD16(pix, hval, idx);
|
||||
cur_cvg = ((pix & 1) << 2) | hval;
|
||||
}
|
||||
else
|
||||
{
|
||||
RREADIDX16(pix, idx);
|
||||
cur_cvg = 7;
|
||||
}
|
||||
r = RGBA16_R(pix);
|
||||
g = RGBA16_G(pix);
|
||||
b = RGBA16_B(pix);
|
||||
|
||||
if (cur_cvg == 7)
|
||||
{
|
||||
if (ctrl.dither_filter_enable)
|
||||
restore_filter16(&r, &g, &b, fboffset, cur_x, hres, fetchstate);
|
||||
}
|
||||
else
|
||||
{
|
||||
video_filter16(&r, &g, &b, fboffset, cur_x, hres, cur_cvg, fetchstate);
|
||||
}
|
||||
|
||||
|
||||
res->r = (uint8_t)r;
|
||||
res->g = (uint8_t)g;
|
||||
res->b = (uint8_t)b;
|
||||
res->a = (uint8_t)cur_cvg;
|
||||
}
|
||||
|
||||
static void vi_fetch_filter32(struct n64video_pixel* res, uint32_t fboffset, uint32_t cur_x, struct vi_reg_ctrl ctrl, uint32_t hres, uint32_t fetchstate)
|
||||
{
|
||||
int r, g, b;
|
||||
uint32_t pix, addr = (fboffset >> 2) + cur_x;
|
||||
RREADIDX32(pix, addr);
|
||||
uint32_t cur_cvg;
|
||||
if (ctrl.aa_mode <= VI_AA_RESAMP_EXTRA)
|
||||
cur_cvg = (pix >> 5) & 7;
|
||||
else
|
||||
cur_cvg = 7;
|
||||
r = RGBA32_R(pix) & 0xff;
|
||||
g = RGBA32_G(pix) & 0xff;
|
||||
b = RGBA32_B(pix) & 0xff;
|
||||
|
||||
if (cur_cvg == 7)
|
||||
{
|
||||
if (ctrl.dither_filter_enable)
|
||||
restore_filter32(&r, &g, &b, fboffset, cur_x, hres, fetchstate);
|
||||
}
|
||||
else
|
||||
{
|
||||
video_filter32(&r, &g, &b, fboffset, cur_x, hres, cur_cvg, fetchstate);
|
||||
}
|
||||
|
||||
res->r = (uint8_t)r;
|
||||
res->g = (uint8_t)g;
|
||||
res->b = (uint8_t)b;
|
||||
res->a = (uint8_t)cur_cvg;
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static uint8_t gamma_table[0x100];
|
||||
static uint8_t gamma_dither_table[0x4000];
|
||||
|
||||
static uint32_t vi_integer_sqrt(uint32_t a)
|
||||
{
|
||||
unsigned long op = a, res = 0, one = 1 << 30;
|
||||
|
||||
while (one > op)
|
||||
one >>= 2;
|
||||
|
||||
while (one != 0)
|
||||
{
|
||||
if (op >= res + one)
|
||||
{
|
||||
op -= res + one;
|
||||
res += one << 1;
|
||||
}
|
||||
res >>= 1;
|
||||
one >>= 2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static STRICTINLINE void gamma_filters(struct n64video_pixel* pixel, bool gamma_enable, bool gamma_dither_enable, uint32_t* rstate)
|
||||
{
|
||||
int cdith, dith;
|
||||
|
||||
switch((gamma_enable << 1) | gamma_dither_enable)
|
||||
{
|
||||
case 0: // no gamma, no dithering
|
||||
return;
|
||||
case 1: // no gamma, dithering enabled
|
||||
cdith = irand(rstate);
|
||||
dith = cdith & 1;
|
||||
if (pixel->r < 255)
|
||||
pixel->r += (uint8_t)dith;
|
||||
dith = (cdith >> 1) & 1;
|
||||
if (pixel->g < 255)
|
||||
pixel->g += (uint8_t)dith;
|
||||
dith = (cdith >> 2) & 1;
|
||||
if (pixel->b < 255)
|
||||
pixel->b += (uint8_t)dith;
|
||||
break;
|
||||
case 2: // gamma enabled, no dithering
|
||||
pixel->r = gamma_table[pixel->r];
|
||||
pixel->g = gamma_table[pixel->g];
|
||||
pixel->b = gamma_table[pixel->b];
|
||||
break;
|
||||
case 3: // gamma and dithering enabled
|
||||
cdith = irand(rstate);
|
||||
dith = cdith & 0x3f;
|
||||
pixel->r = gamma_dither_table[((pixel->r) << 6)|dith];
|
||||
dith = (cdith >> 6) & 0x3f;
|
||||
pixel->g = gamma_dither_table[((pixel->g) << 6)|dith];
|
||||
dith = ((cdith >> 9) & 0x38) | (cdith & 7);
|
||||
pixel->b = gamma_dither_table[((pixel->b) << 6)|dith];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void vi_gamma_init(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
gamma_table[i] = (uint8_t)vi_integer_sqrt(i << 6);
|
||||
gamma_table[i] <<= 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x4000; i++)
|
||||
{
|
||||
gamma_dither_table[i] = (uint8_t)vi_integer_sqrt(i);
|
||||
gamma_dither_table[i] <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static STRICTINLINE void vi_vl_lerp(struct n64video_pixel* up, struct n64video_pixel down, uint32_t frac)
|
||||
{
|
||||
uint32_t r0, g0, b0;
|
||||
if (!frac)
|
||||
return;
|
||||
|
||||
r0 = up->r;
|
||||
g0 = up->g;
|
||||
b0 = up->b;
|
||||
|
||||
up->r = ((((down.r - r0) * frac + 16) >> 5) + r0) & 0xff;
|
||||
up->g = ((((down.g - g0) * frac + 16) >> 5) + g0) & 0xff;
|
||||
up->b = ((((down.b - b0) * frac + 16) >> 5) + b0) & 0xff;
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,160 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static int vi_restore_table[0x400];
|
||||
|
||||
static STRICTINLINE void restore_filter16(int* r, int* g, int* b, uint32_t fboffset, uint32_t num, uint32_t hres, uint32_t fetchbugstate)
|
||||
{
|
||||
int i;
|
||||
uint32_t idx = (fboffset >> 1) + num;
|
||||
|
||||
uint32_t toleftpix = idx - 1;
|
||||
|
||||
uint32_t leftuppix, leftdownpix, maxpix;
|
||||
|
||||
leftuppix = idx - hres - 1;
|
||||
|
||||
if (fetchbugstate != 1)
|
||||
{
|
||||
leftdownpix = idx + hres - 1;
|
||||
maxpix = idx + hres + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
leftdownpix = toleftpix;
|
||||
maxpix = toleftpix + 2;
|
||||
}
|
||||
|
||||
int rend = *r;
|
||||
int gend = *g;
|
||||
int bend = *b;
|
||||
const int* redptr = &vi_restore_table[(rend << 2) & 0x3e0];
|
||||
const int* greenptr = &vi_restore_table[(gend << 2) & 0x3e0];
|
||||
const int* blueptr = &vi_restore_table[(bend << 2) & 0x3e0];
|
||||
|
||||
uint32_t tempr, tempg, tempb;
|
||||
uint16_t pix;
|
||||
|
||||
const uint32_t dirs[] =
|
||||
{
|
||||
leftuppix, leftuppix + 1, leftuppix + 2, leftdownpix,
|
||||
leftdownpix + 1, maxpix, toleftpix, toleftpix + 2
|
||||
};
|
||||
|
||||
if (rdram_valid_idx16(maxpix) && rdram_valid_idx16(leftuppix))
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
pix = rdram_read_idx16_fast(dirs[i]);
|
||||
tempr = (pix >> 11) & 0x1f;
|
||||
tempg = (pix >> 6) & 0x1f;
|
||||
tempb = (pix >> 1) & 0x1f;
|
||||
rend += redptr[tempr];
|
||||
gend += greenptr[tempg];
|
||||
bend += blueptr[tempb];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
pix = rdram_read_idx16(dirs[i]);
|
||||
tempr = (pix >> 11) & 0x1f;
|
||||
tempg = (pix >> 6) & 0x1f;
|
||||
tempb = (pix >> 1) & 0x1f;
|
||||
rend += redptr[tempr];
|
||||
gend += greenptr[tempg];
|
||||
bend += blueptr[tempb];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*r = rend;
|
||||
*g = gend;
|
||||
*b = bend;
|
||||
}
|
||||
|
||||
static STRICTINLINE void restore_filter32(int* r, int* g, int* b, uint32_t fboffset, uint32_t num, uint32_t hres, uint32_t fetchbugstate)
|
||||
{
|
||||
int i;
|
||||
uint32_t idx = (fboffset >> 2) + num;
|
||||
|
||||
uint32_t toleftpix = idx - 1;
|
||||
|
||||
uint32_t leftuppix, leftdownpix, maxpix;
|
||||
|
||||
leftuppix = idx - hres - 1;
|
||||
|
||||
if (fetchbugstate != 1)
|
||||
{
|
||||
leftdownpix = idx + hres - 1;
|
||||
maxpix = idx +hres + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
leftdownpix = toleftpix;
|
||||
maxpix = toleftpix + 2;
|
||||
}
|
||||
|
||||
int rend = *r;
|
||||
int gend = *g;
|
||||
int bend = *b;
|
||||
const int* redptr = &vi_restore_table[(rend << 2) & 0x3e0];
|
||||
const int* greenptr = &vi_restore_table[(gend << 2) & 0x3e0];
|
||||
const int* blueptr = &vi_restore_table[(bend << 2) & 0x3e0];
|
||||
|
||||
uint32_t tempr, tempg, tempb;
|
||||
uint32_t pix;
|
||||
|
||||
const uint32_t dirs[] =
|
||||
{
|
||||
leftuppix, leftuppix + 1, leftuppix + 2, leftdownpix,
|
||||
leftdownpix + 1, maxpix, toleftpix, toleftpix + 2
|
||||
};
|
||||
|
||||
if (rdram_valid_idx32(maxpix) && rdram_valid_idx32(leftuppix))
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
pix = rdram_read_idx32_fast(dirs[i]);
|
||||
tempr = (pix >> 27) & 0x1f;
|
||||
tempg = (pix >> 19) & 0x1f;
|
||||
tempb = (pix >> 11) & 0x1f;
|
||||
rend += redptr[tempr];
|
||||
gend += greenptr[tempg];
|
||||
bend += blueptr[tempb];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
pix = rdram_read_idx32(dirs[i]);
|
||||
tempr = (pix >> 27) & 0x1f;
|
||||
tempg = (pix >> 19) & 0x1f;
|
||||
tempb = (pix >> 11) & 0x1f;
|
||||
rend += redptr[tempr];
|
||||
gend += greenptr[tempg];
|
||||
bend += blueptr[tempb];
|
||||
}
|
||||
}
|
||||
|
||||
*r = rend;
|
||||
*g = gend;
|
||||
*b = bend;
|
||||
}
|
||||
|
||||
void vi_restore_init()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 0x400; i++)
|
||||
{
|
||||
if (((i >> 5) & 0x1f) < (i & 0x1f))
|
||||
vi_restore_table[i] = 1;
|
||||
else if (((i >> 5) & 0x1f) > (i & 0x1f))
|
||||
vi_restore_table[i] = -1;
|
||||
else
|
||||
vi_restore_table[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,192 @@
|
||||
#ifdef N64VIDEO_C
|
||||
|
||||
static STRICTINLINE void video_max_optimized(uint32_t* pixels, uint32_t* penumin, uint32_t* penumax, int numofels)
|
||||
{
|
||||
int i;
|
||||
int posmax = 0, posmin = 0;
|
||||
uint32_t curpenmax = pixels[0], curpenmin = pixels[0];
|
||||
uint32_t max, min;
|
||||
|
||||
for (i = 1; i < numofels; i++)
|
||||
{
|
||||
if (pixels[i] > pixels[posmax])
|
||||
{
|
||||
curpenmax = pixels[posmax];
|
||||
posmax = i;
|
||||
}
|
||||
else if (pixels[i] < pixels[posmin])
|
||||
{
|
||||
curpenmin = pixels[posmin];
|
||||
posmin = i;
|
||||
}
|
||||
}
|
||||
max = pixels[posmax];
|
||||
min = pixels[posmin];
|
||||
if (curpenmax != max)
|
||||
{
|
||||
for (i = posmax + 1; i < numofels; i++)
|
||||
{
|
||||
if (pixels[i] > curpenmax)
|
||||
curpenmax = pixels[i];
|
||||
}
|
||||
}
|
||||
if (curpenmin != min)
|
||||
{
|
||||
for (i = posmin + 1; i < numofels; i++)
|
||||
{
|
||||
if (pixels[i] < curpenmin)
|
||||
curpenmin = pixels[i];
|
||||
}
|
||||
}
|
||||
*penumax = curpenmax;
|
||||
*penumin = curpenmin;
|
||||
}
|
||||
|
||||
|
||||
static STRICTINLINE void video_filter16(int* endr, int* endg, int* endb, uint32_t fboffset, uint32_t num, uint32_t hres, uint32_t centercvg, uint32_t fetchbugstate)
|
||||
{
|
||||
int i;
|
||||
uint32_t penumaxr, penumaxg, penumaxb, penuminr, penuming, penuminb;
|
||||
uint16_t pix;
|
||||
uint32_t numoffull = 1;
|
||||
uint8_t hidval;
|
||||
uint32_t r, g, b;
|
||||
uint32_t backr[7], backg[7], backb[7];
|
||||
|
||||
r = *endr;
|
||||
g = *endg;
|
||||
b = *endb;
|
||||
|
||||
backr[0] = r;
|
||||
backg[0] = g;
|
||||
backb[0] = b;
|
||||
|
||||
uint32_t idx = (fboffset >> 1) + num;
|
||||
|
||||
uint32_t toleft = idx - 2;
|
||||
uint32_t toright = idx + 2;
|
||||
|
||||
uint32_t leftup, rightup, leftdown, rightdown;
|
||||
|
||||
leftup = idx - hres - 1;
|
||||
rightup = idx - hres + 1;
|
||||
|
||||
if (fetchbugstate != 1)
|
||||
{
|
||||
leftdown = idx + hres - 1;
|
||||
rightdown = idx + hres + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
leftdown = toleft;
|
||||
rightdown = toright;
|
||||
}
|
||||
|
||||
const uint32_t dirs[] = {leftup, rightup, toleft, toright, leftdown, rightdown};
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
rdram_read_pair16(&pix, &hidval, dirs[i]);
|
||||
if (hidval == 3 && (pix & 1))
|
||||
{
|
||||
backr[numoffull] = RGBA16_R(pix);
|
||||
backg[numoffull] = RGBA16_G(pix);
|
||||
backb[numoffull] = RGBA16_B(pix);
|
||||
numoffull++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t colr, colg, colb;
|
||||
|
||||
video_max_optimized(backr, &penuminr, &penumaxr, numoffull);
|
||||
video_max_optimized(backg, &penuming, &penumaxg, numoffull);
|
||||
video_max_optimized(backb, &penuminb, &penumaxb, numoffull);
|
||||
|
||||
uint32_t coeff = 7 - centercvg;
|
||||
colr = penuminr + penumaxr - (r << 1);
|
||||
colg = penuming + penumaxg - (g << 1);
|
||||
colb = penuminb + penumaxb - (b << 1);
|
||||
|
||||
colr = (((colr * coeff) + 4) >> 3) + r;
|
||||
colg = (((colg * coeff) + 4) >> 3) + g;
|
||||
colb = (((colb * coeff) + 4) >> 3) + b;
|
||||
|
||||
*endr = colr & 0xff;
|
||||
*endg = colg & 0xff;
|
||||
*endb = colb & 0xff;
|
||||
}
|
||||
|
||||
static STRICTINLINE void video_filter32(int* endr, int* endg, int* endb, uint32_t fboffset, uint32_t num, uint32_t hres, uint32_t centercvg, uint32_t fetchbugstate)
|
||||
{
|
||||
int i;
|
||||
uint32_t penumaxr, penumaxg, penumaxb, penuminr, penuming, penuminb;
|
||||
uint32_t numoffull = 1;
|
||||
uint32_t pix = 0, pixcvg = 0;
|
||||
uint32_t r, g, b;
|
||||
uint32_t backr[7], backg[7], backb[7];
|
||||
|
||||
r = *endr;
|
||||
g = *endg;
|
||||
b = *endb;
|
||||
|
||||
backr[0] = r;
|
||||
backg[0] = g;
|
||||
backb[0] = b;
|
||||
|
||||
uint32_t idx = (fboffset >> 2) + num;
|
||||
|
||||
uint32_t toleft = idx - 2;
|
||||
uint32_t toright = idx + 2;
|
||||
|
||||
uint32_t leftup, rightup, leftdown, rightdown;
|
||||
|
||||
leftup = idx - hres - 1;
|
||||
rightup = idx - hres + 1;
|
||||
|
||||
if (fetchbugstate != 1)
|
||||
{
|
||||
leftdown = idx + hres - 1;
|
||||
rightdown = idx + hres + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
leftdown = toleft;
|
||||
rightdown = toright;
|
||||
}
|
||||
|
||||
const uint32_t dirs[] = {leftup, rightup, toleft, toright, leftdown, rightdown};
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
pix = rdram_read_idx32(dirs[i]);
|
||||
pixcvg = (pix >> 5) & 7;
|
||||
if (pixcvg == 7)
|
||||
{
|
||||
backr[numoffull] = (pix >> 24) & 0xff;
|
||||
backg[numoffull] = (pix >> 16) & 0xff;
|
||||
backb[numoffull] = (pix >> 8) & 0xff;
|
||||
numoffull++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t colr, colg, colb;
|
||||
|
||||
video_max_optimized(backr, &penuminr, &penumaxr, numoffull);
|
||||
video_max_optimized(backg, &penuming, &penumaxg, numoffull);
|
||||
video_max_optimized(backb, &penuminb, &penumaxb, numoffull);
|
||||
|
||||
uint32_t coeff = 7 - centercvg;
|
||||
colr = penuminr + penumaxr - (r << 1);
|
||||
colg = penuming + penumaxg - (g << 1);
|
||||
colb = penuminb + penumaxb - (b << 1);
|
||||
|
||||
colr = (((colr * coeff) + 4) >> 3) + r;
|
||||
colg = (((colg * coeff) + 4) >> 3) + g;
|
||||
colb = (((colb * coeff) + 4) >> 3) + b;
|
||||
|
||||
*endr = colr & 0xff;
|
||||
*endg = colg & 0xff;
|
||||
*endb = colb & 0xff;
|
||||
}
|
||||
|
||||
#endif // N64VIDEO_C
|
||||
@@ -0,0 +1,192 @@
|
||||
#include "parallel.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <algorithm>
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
class Parallel
|
||||
{
|
||||
public:
|
||||
Parallel(std::uint32_t num_workers)
|
||||
{
|
||||
if (num_workers == 0) {
|
||||
// auto-select number of workers based on the number of cores
|
||||
m_num_workers = std::thread::hardware_concurrency();
|
||||
} else {
|
||||
m_num_workers = std::min(num_workers, PARALLEL_MAX_WORKERS);
|
||||
}
|
||||
|
||||
// mask for m_tasks_done when all workers have finished their task
|
||||
if (m_num_workers == PARALLEL_MAX_WORKERS) {
|
||||
m_all_tasks_done = ~0ULL;
|
||||
} else {
|
||||
m_all_tasks_done = (1ULL << m_num_workers) - 1;
|
||||
}
|
||||
|
||||
// except worker 0, which runs in the main thread
|
||||
m_all_tasks_done--;
|
||||
|
||||
// give workers an empty task
|
||||
m_task = [](std::uint32_t) {};
|
||||
m_accept_work = true;
|
||||
start_work();
|
||||
|
||||
// create worker threads
|
||||
for (std::uint32_t worker_id = 1; worker_id < m_num_workers; worker_id++) {
|
||||
m_workers.emplace_back(std::thread(&Parallel::do_work, this, worker_id));
|
||||
}
|
||||
|
||||
// synchronize workers to prepare them for real tasks
|
||||
wait();
|
||||
}
|
||||
|
||||
~Parallel() {
|
||||
// wait for all workers to finish their current work
|
||||
wait();
|
||||
|
||||
// exit worker main loops
|
||||
m_accept_work = false;
|
||||
start_work();
|
||||
|
||||
// join worker threads to make sure they have finished
|
||||
for (auto& thread : m_workers) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
// destroy all worker threads
|
||||
m_workers.clear();
|
||||
}
|
||||
|
||||
void run(std::function<void(std::uint32_t)>&& task) {
|
||||
// don't allow more tasks if workers are stopping
|
||||
if (!m_accept_work) {
|
||||
throw std::runtime_error("Workers are exiting and no longer accept work");
|
||||
}
|
||||
|
||||
// prepare task for workers and send signal so they start working
|
||||
m_task = std::move(task);
|
||||
start_work();
|
||||
|
||||
// run worker 0 directly on main thread
|
||||
m_task(0);
|
||||
|
||||
// wait for all workers to finish
|
||||
wait();
|
||||
}
|
||||
|
||||
std::uint32_t num_workers() {
|
||||
return m_num_workers;
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void(std::uint32_t)> m_task;
|
||||
std::vector<std::thread> m_workers;
|
||||
std::mutex m_signal_mutex;
|
||||
std::condition_variable m_signal_work;
|
||||
std::condition_variable m_signal_done;
|
||||
std::atomic<uint64_t> m_tasks_done;
|
||||
std::uint64_t m_all_tasks_done;
|
||||
std::atomic<bool> m_accept_work;
|
||||
std::uint32_t m_num_workers;
|
||||
|
||||
void start_work() {
|
||||
std::unique_lock<std::mutex> ul(m_signal_mutex);
|
||||
|
||||
// clear task bits for all workers
|
||||
m_tasks_done = 0;
|
||||
|
||||
// wake up all workers
|
||||
m_signal_work.notify_all();
|
||||
}
|
||||
|
||||
void do_work(std::uint32_t worker_id) {
|
||||
const std::uint64_t worker_mask = 1LL << worker_id;
|
||||
|
||||
while (m_accept_work) {
|
||||
// do the work
|
||||
m_task(worker_id);
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> ul(m_signal_mutex);
|
||||
|
||||
// mark task as done
|
||||
m_tasks_done |= worker_mask;
|
||||
|
||||
// notify main thread
|
||||
m_signal_done.notify_one();
|
||||
#if !defined(ANDROID)
|
||||
// take a break and wait for more work
|
||||
m_signal_work.wait(ul, [worker_mask, this] {
|
||||
return (m_tasks_done & worker_mask) == 0;
|
||||
});
|
||||
}
|
||||
#else
|
||||
//Busy loop wait for a bit to keep cores awake
|
||||
bool workAvailable = false;
|
||||
int count = 0;
|
||||
while (!workAvailable && count++ < 10000) {
|
||||
std::unique_lock<std::mutex> ul(m_signal_mutex);
|
||||
workAvailable = (m_tasks_done & worker_mask) == 0;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> ul(m_signal_mutex);
|
||||
|
||||
// take a break and wait for more work
|
||||
m_signal_work.wait(ul, [worker_mask, this] {
|
||||
return (m_tasks_done & worker_mask) == 0;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void wait() {
|
||||
|
||||
#ifdef ANDROID
|
||||
//Busy loop wait for a bit to keep cores awake
|
||||
bool waitingForWorkDone = true;
|
||||
int count = 0;
|
||||
while (waitingForWorkDone && count++ < 10000) {
|
||||
waitingForWorkDone = m_tasks_done != m_all_tasks_done;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
// wait for all workers to set their task bits
|
||||
std::unique_lock<std::mutex> ul(m_signal_mutex);
|
||||
m_signal_done.wait(ul, [this] {
|
||||
return m_tasks_done == m_all_tasks_done;
|
||||
});
|
||||
}
|
||||
|
||||
void operator=(const Parallel&) = delete;
|
||||
Parallel(const Parallel&) = delete;
|
||||
};
|
||||
|
||||
// C interface for the Parallel class
|
||||
static std::unique_ptr<Parallel> parallel;
|
||||
|
||||
void parallel_init(uint32_t num)
|
||||
{
|
||||
parallel = std::make_unique<Parallel>(num);
|
||||
}
|
||||
|
||||
void parallel_run(void task(uint32_t))
|
||||
{
|
||||
parallel->run(task);
|
||||
}
|
||||
|
||||
uint32_t parallel_num_workers()
|
||||
{
|
||||
return parallel->num_workers();
|
||||
}
|
||||
|
||||
void parallel_close()
|
||||
{
|
||||
parallel.reset();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PARALLEL_MAX_WORKERS 64u
|
||||
|
||||
void parallel_init(uint32_t num);
|
||||
void parallel_run(void task(uint32_t));
|
||||
uint32_t parallel_num_workers();
|
||||
void parallel_close();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#define GIT_BRANCH "@GIT_BRANCH@"
|
||||
#define GIT_TAG "@GIT_TAG@"
|
||||
#define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@"
|
||||
#define GIT_COMMIT_DATE "@GIT_COMMIT_DATE@"
|
||||
|
||||
#define CORE_BASE_NAME "angrylion's RDP Plus"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define CORE_NAME CORE_BASE_NAME " " GIT_TAG " (Debug)"
|
||||
#else
|
||||
#define CORE_NAME CORE_BASE_NAME " " GIT_TAG
|
||||
#endif
|
||||
|
||||
#define CORE_SIMPLE_NAME "angrylion-plus"
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
typedef void (*funcptr)(void);
|
||||
|
||||
funcptr IntGetProcAddress(const char* name);
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/n64video.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void screen_init(struct n64video_config* config);
|
||||
void screen_adjust(int32_t width_out, int32_t height_out, int32_t* width, int32_t* height, int32_t* x, int32_t* y);
|
||||
void screen_update(void);
|
||||
void screen_toggle_fullscreen(void);
|
||||
void screen_close(void);
|
||||
@@ -0,0 +1,336 @@
|
||||
#include "vdac.h"
|
||||
#include "screen.h"
|
||||
#include "core/msg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef GLES
|
||||
#include <GLES3/gl3.h>
|
||||
#define SHADER_HEADER "#version 300 es\nprecision lowp float;\n"
|
||||
#else
|
||||
#include "gl_core_3_3.h"
|
||||
#define SHADER_HEADER "#version 330 core\n"
|
||||
#endif
|
||||
|
||||
#define TEX_FORMAT GL_RGBA
|
||||
#define TEX_TYPE GL_UNSIGNED_BYTE
|
||||
|
||||
static GLuint m_program;
|
||||
static GLuint m_vao;
|
||||
static GLuint m_texture;
|
||||
|
||||
static uint32_t m_tex_width;
|
||||
static uint32_t m_tex_height;
|
||||
|
||||
static uint32_t m_tex_height_out;
|
||||
|
||||
#ifdef _DEBUG
|
||||
static void gl_check_errors(void)
|
||||
{
|
||||
GLenum err;
|
||||
static int32_t invalid_op_count = 0;
|
||||
while ((err = glGetError()) != GL_NO_ERROR) {
|
||||
// if gl_check_errors is called from a thread with no valid
|
||||
// GL context, it would be stuck in an infinite loop here, since
|
||||
// glGetError itself causes GL_INVALID_OPERATION, so check for a few
|
||||
// cycles and abort if there are too many errors of that kind
|
||||
if (err == GL_INVALID_OPERATION) {
|
||||
if (++invalid_op_count >= 100) {
|
||||
msg_error("gl_check_errors: invalid OpenGL context!");
|
||||
}
|
||||
} else {
|
||||
invalid_op_count = 0;
|
||||
}
|
||||
|
||||
char* err_str;
|
||||
switch (err) {
|
||||
case GL_INVALID_OPERATION:
|
||||
err_str = "INVALID_OPERATION";
|
||||
break;
|
||||
case GL_INVALID_ENUM:
|
||||
err_str = "INVALID_ENUM";
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
err_str = "INVALID_VALUE";
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
err_str = "OUT_OF_MEMORY";
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
err_str = "INVALID_FRAMEBUFFER_OPERATION";
|
||||
break;
|
||||
default:
|
||||
err_str = "unknown";
|
||||
}
|
||||
msg_debug("gl_check_errors: %d (%s)", err, err_str);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define gl_check_errors(...)
|
||||
#endif
|
||||
|
||||
static bool gl_shader_load_file(GLuint shader, const char* path)
|
||||
{
|
||||
bool success = false;
|
||||
GLchar* source = NULL;
|
||||
FILE* fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
// fail quietly
|
||||
goto end;
|
||||
}
|
||||
|
||||
// get file size
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint32_t source_size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
// allocate buffer for shader code
|
||||
source = malloc(source_size + 1);
|
||||
if (source == NULL) {
|
||||
msg_error("Can't allocate memory for shader file %s", path);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// read shader code
|
||||
if (fread(source, source_size, 1, fp) != 1) {
|
||||
msg_warning("Can't read shader file %s", path);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// terminate shader code string
|
||||
source[source_size] = 0;
|
||||
|
||||
// send string to OpenGL
|
||||
const GLchar* source_ptr = source;
|
||||
glShaderSource(shader, 1, &source_ptr, NULL);
|
||||
|
||||
success = true;
|
||||
|
||||
end:
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
if (source) {
|
||||
free(source);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static GLuint gl_shader_compile(GLenum type, const GLchar* source, const char* path)
|
||||
{
|
||||
GLuint shader = glCreateShader(type);
|
||||
|
||||
// try to load external shader file first, otherwise use embedded fallback shader
|
||||
if (!gl_shader_load_file(shader, path)) {
|
||||
glShaderSource(shader, 1, &source, NULL);
|
||||
}
|
||||
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint param;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, ¶m);
|
||||
|
||||
if (!param) {
|
||||
GLchar log[4096];
|
||||
glGetShaderInfoLog(shader, sizeof(log), NULL, log);
|
||||
msg_error("%s shader error: %s\n", type == GL_FRAGMENT_SHADER ? "Frag" : "Vert", log);
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static GLuint gl_shader_link(GLuint vert, GLuint frag)
|
||||
{
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, vert);
|
||||
glAttachShader(program, frag);
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint param;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, ¶m);
|
||||
|
||||
if (!param) {
|
||||
GLchar log[4096];
|
||||
glGetProgramInfoLog(program, sizeof(log), NULL, log);
|
||||
msg_error("Shader link error: %s\n", log);
|
||||
}
|
||||
|
||||
glDeleteShader(frag);
|
||||
glDeleteShader(vert);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void vdac_init(struct n64video_config* config)
|
||||
{
|
||||
screen_init(config);
|
||||
|
||||
#ifndef GLES
|
||||
// load OpenGL function pointers
|
||||
ogl_LoadFunctions();
|
||||
#endif
|
||||
|
||||
msg_debug("%s: GL_VERSION='%s'", __FUNCTION__, glGetString(GL_VERSION));
|
||||
msg_debug("%s: GL_VENDOR='%s'", __FUNCTION__, glGetString(GL_VENDOR));
|
||||
msg_debug("%s: GL_RENDERER='%s'", __FUNCTION__, glGetString(GL_RENDERER));
|
||||
msg_debug("%s: GL_SHADING_LANGUAGE_VERSION='%s'", __FUNCTION__, glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
// shader sources for drawing a clipped full-screen triangle. the geometry
|
||||
// is defined by the vertex ID, so a VBO is not required.
|
||||
const GLchar* vert_shader =
|
||||
SHADER_HEADER
|
||||
"out vec2 uv;\n"
|
||||
"void main(void) {\n"
|
||||
" uv = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2);\n"
|
||||
" gl_Position = vec4(uv * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* frag_shader =
|
||||
SHADER_HEADER
|
||||
"in vec2 uv;\n"
|
||||
"layout(location = 0) out vec4 color;\n"
|
||||
"uniform sampler2D tex0;\n"
|
||||
"void main(void) {\n"
|
||||
" color = texture(tex0, uv);\n"
|
||||
"}\n";
|
||||
|
||||
// compile and link OpenGL program
|
||||
GLuint vert = gl_shader_compile(GL_VERTEX_SHADER, vert_shader, "alp_screen.vert");
|
||||
GLuint frag = gl_shader_compile(GL_FRAGMENT_SHADER, frag_shader, "alp_screen.frag");
|
||||
m_program = gl_shader_link(vert, frag);
|
||||
glUseProgram(m_program);
|
||||
|
||||
// prepare dummy VAO
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
// prepare texture
|
||||
glGenTextures(1, &m_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
|
||||
// select interpolation method
|
||||
GLint filter;
|
||||
switch (config->vi.interp) {
|
||||
case VI_INTERP_LINEAR:
|
||||
filter = GL_LINEAR;
|
||||
break;
|
||||
case VI_INTERP_NEAREST:
|
||||
default:
|
||||
filter = GL_NEAREST;
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
|
||||
// check if there was an error when using any of the commands above
|
||||
gl_check_errors();
|
||||
}
|
||||
|
||||
void vdac_read(struct n64video_frame_buffer* fb, bool alpha)
|
||||
{
|
||||
GLint vp[4];
|
||||
glGetIntegerv(GL_VIEWPORT, vp);
|
||||
|
||||
fb->width = vp[2];
|
||||
fb->height = vp[3];
|
||||
fb->pitch = fb->width;
|
||||
|
||||
if (fb->pixels) {
|
||||
glReadPixels(vp[0], vp[1], vp[2], vp[3], alpha ? GL_RGBA : GL_RGB, TEX_TYPE, fb->pixels);
|
||||
}
|
||||
}
|
||||
|
||||
void vdac_write(struct n64video_frame_buffer* fb)
|
||||
{
|
||||
bool buffer_size_changed = m_tex_width != fb->width || m_tex_height != fb->height;
|
||||
|
||||
// check if the framebuffer size has changed
|
||||
if (buffer_size_changed) {
|
||||
m_tex_width = fb->width;
|
||||
m_tex_height = fb->height;
|
||||
|
||||
// set pitch for all unpacking operations
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, fb->pitch);
|
||||
|
||||
// reallocate texture buffer on GPU
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_tex_width,
|
||||
m_tex_height, 0, TEX_FORMAT, TEX_TYPE, fb->pixels);
|
||||
|
||||
msg_debug("%s: resized framebuffer texture: %dx%d", __FUNCTION__, m_tex_width, m_tex_height);
|
||||
} else {
|
||||
// copy local buffer to GPU texture buffer
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_tex_width, m_tex_height,
|
||||
TEX_FORMAT, TEX_TYPE, fb->pixels);
|
||||
}
|
||||
|
||||
// update output size
|
||||
m_tex_height_out = fb->height_out;
|
||||
}
|
||||
|
||||
void vdac_sync(bool valid)
|
||||
{
|
||||
// clear old buffers
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// get current window size and position
|
||||
int32_t win_width;
|
||||
int32_t win_height;
|
||||
int32_t win_x;
|
||||
int32_t win_y;
|
||||
|
||||
screen_adjust(m_tex_width, m_tex_height_out, &win_width, &win_height, &win_x, &win_y);
|
||||
|
||||
// if the screen is invalid or hidden, do nothing
|
||||
if (win_width <= 0 || win_height <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// skip rendering and leave buffer blank if there's no valid input
|
||||
if (!valid) {
|
||||
screen_update();
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t hw = m_tex_height_out * win_width;
|
||||
int32_t wh = m_tex_width * win_height;
|
||||
|
||||
// add letterboxes or pillarboxes if the window has a different aspect ratio
|
||||
// than the current display mode
|
||||
if (hw > wh) {
|
||||
int32_t w_max = wh / m_tex_height_out;
|
||||
win_x += (win_width - w_max) / 2;
|
||||
win_width = w_max;
|
||||
} else if (hw < wh) {
|
||||
int32_t h_max = hw / m_tex_width;
|
||||
win_y += (win_height - h_max) / 2;
|
||||
win_height = h_max;
|
||||
}
|
||||
|
||||
// configure viewport
|
||||
glViewport(win_x, win_y, win_width, win_height);
|
||||
|
||||
// draw fullscreen triangle
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
// check if there was an error when using any of the commands above
|
||||
gl_check_errors();
|
||||
|
||||
// refresh screen with new frame
|
||||
screen_update();
|
||||
}
|
||||
|
||||
void vdac_close(void)
|
||||
{
|
||||
m_tex_width = 0;
|
||||
m_tex_height = 0;
|
||||
|
||||
m_tex_height_out = 0;
|
||||
|
||||
glDeleteTextures(1, &m_texture);
|
||||
glDeleteVertexArrays(1, &m_vao);
|
||||
glDeleteProgram(m_program);
|
||||
|
||||
screen_close();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/n64video.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void vdac_init(struct n64video_config* config);
|
||||
void vdac_read(struct n64video_frame_buffer* fb, bool alpha);
|
||||
void vdac_write(struct n64video_frame_buffer* fb);
|
||||
void vdac_sync(bool invaid);
|
||||
void vdac_close(void);
|
||||
@@ -0,0 +1,90 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-core - m64p_common.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2009 Richard Goedeken *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* This header file defines typedefs for function pointers to common Core
|
||||
* and plugin functions, for use by the front-end and plugin modules to attach
|
||||
* to the dynamic libraries.
|
||||
*/
|
||||
|
||||
#if !defined(M64P_COMMON_H)
|
||||
#define M64P_COMMON_H
|
||||
|
||||
#include "m64p_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* PluginGetVersion()
|
||||
*
|
||||
* This function retrieves version information from a library. This
|
||||
* function is the same for the core library and the plugins.
|
||||
*/
|
||||
typedef m64p_error (*ptr_PluginGetVersion)(m64p_plugin_type *, int *, int *, const char **, int *);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES) || defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *, int *, int *, const char **, int *);
|
||||
#endif
|
||||
|
||||
/* CoreGetAPIVersions()
|
||||
*
|
||||
* This function retrieves API version information from the core.
|
||||
*/
|
||||
typedef m64p_error (*ptr_CoreGetAPIVersions)(int *, int *, int *, int *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL CoreGetAPIVersions(int *, int *, int *, int *);
|
||||
#endif
|
||||
|
||||
/* CoreErrorMessage()
|
||||
*
|
||||
* This function returns a pointer to a NULL-terminated string giving a
|
||||
* human-readable description of the error.
|
||||
*/
|
||||
typedef const char * (*ptr_CoreErrorMessage)(m64p_error);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT const char * CALL CoreErrorMessage(m64p_error);
|
||||
#endif
|
||||
|
||||
/* PluginStartup()
|
||||
*
|
||||
* This function initializes a plugin for use by allocating memory, creating
|
||||
* data structures, and loading the configuration data.
|
||||
*/
|
||||
typedef m64p_error (*ptr_PluginStartup)(m64p_dynlib_handle, void *, void (*)(void *, int, const char *));
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES) || defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle, void *, void (*)(void *, int, const char *));
|
||||
#endif
|
||||
|
||||
/* PluginShutdown()
|
||||
*
|
||||
* This function destroys data structures and releases memory allocated by
|
||||
* the plugin library.
|
||||
*/
|
||||
typedef m64p_error (*ptr_PluginShutdown)(void);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES) || defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL PluginShutdown(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #define M64P_COMMON_H */
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-core - m64p_config.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2009 Richard Goedeken *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* This header file defines typedefs for function pointers to the Core's
|
||||
* configuration handling functions.
|
||||
*/
|
||||
|
||||
#if !defined(M64P_CONFIG_H)
|
||||
#define M64P_CONFIG_H
|
||||
|
||||
#include "m64p_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ConfigListSections()
|
||||
*
|
||||
* This function is called to enumerate the list of Sections in the Mupen64Plus
|
||||
* configuration file. It is expected that there will be a section named "Core"
|
||||
* for core-specific configuration data, "Graphics" for common graphics options,
|
||||
* and one or more sections for each plugin library.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigListSections)(void *, void (*)(void *, const char *));
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigListSections(void *, void (*)(void *, const char *));
|
||||
#endif
|
||||
|
||||
/* ConfigOpenSection()
|
||||
*
|
||||
* This function is used to give a configuration section handle to the front-end
|
||||
* which may be used to read or write configuration parameter values in a given
|
||||
* section of the configuration file.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigOpenSection)(const char *, m64p_handle *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigOpenSection(const char *, m64p_handle *);
|
||||
#endif
|
||||
|
||||
/* ConfigListParameters()
|
||||
*
|
||||
* This function is called to enumerate the list of Parameters in a given
|
||||
* Section of the Mupen64Plus configuration file.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigListParameters)(m64p_handle, void *, void (*)(void *, const char *, m64p_type));
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigListParameters(m64p_handle, void *, void (*)(void *, const char *, m64p_type));
|
||||
#endif
|
||||
|
||||
/* ConfigSaveFile()
|
||||
*
|
||||
* This function saves the entire current Mupen64Plus configuration to disk.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigSaveFile)(void);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigSaveFile(void);
|
||||
#endif
|
||||
|
||||
/* ConfigSaveSection()
|
||||
*
|
||||
* This function saves one section of the current Mupen64Plus configuration to disk.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigSaveSection)(const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigSaveSection(const char *);
|
||||
#endif
|
||||
|
||||
/* ConfigHasUnsavedChanges()
|
||||
*
|
||||
* This function determines if a given Section (or all sections) of the Mupen64Plus Core configuration file has been modified since it was last saved or loaded.
|
||||
*/
|
||||
typedef int (*ptr_ConfigHasUnsavedChanges)(const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT int CALL ConfigHasUnsavedChanges(const char *);
|
||||
#endif
|
||||
|
||||
/* ConfigDeleteSection()
|
||||
*
|
||||
* This function deletes a section from the Mupen64Plus configuration data.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigDeleteSection)(const char *SectionName);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigDeleteSection(const char *SectionName);
|
||||
#endif
|
||||
|
||||
/* ConfigRevertChanges()
|
||||
*
|
||||
* This function reverts changes previously made to one section of the configuration file, so that it will match with the configuration at the last time that it was loaded from or saved to disk.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigRevertChanges)(const char *SectionName);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigRevertChanges(const char *SectionName);
|
||||
#endif
|
||||
|
||||
/* ConfigSetParameter()
|
||||
*
|
||||
* This function sets the value of one of the emulator's configuration
|
||||
* parameters.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigSetParameter)(m64p_handle, const char *, m64p_type, const void *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigSetParameter(m64p_handle, const char *, m64p_type, const void *);
|
||||
#endif
|
||||
|
||||
/* ConfigSetParameterHelp()
|
||||
*
|
||||
* This function sets the help string of one of the emulator's configuration
|
||||
* parameters.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigSetParameterHelp)(m64p_handle, const char *, const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigSetParameterHelp(m64p_handle, const char *, const char *);
|
||||
#endif
|
||||
|
||||
/* ConfigGetParameter()
|
||||
*
|
||||
* This function retrieves the value of one of the emulator's parameters.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigGetParameter)(m64p_handle, const char *, m64p_type, void *, int);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigGetParameter(m64p_handle, const char *, m64p_type, void *, int);
|
||||
#endif
|
||||
|
||||
/* ConfigGetParameterType()
|
||||
*
|
||||
* This function retrieves the type of one of the emulator's parameters.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigGetParameterType)(m64p_handle, const char *, m64p_type *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigGetParameterType(m64p_handle, const char *, m64p_type *);
|
||||
#endif
|
||||
|
||||
/* ConfigGetParameterHelp()
|
||||
*
|
||||
* This function retrieves the help information about one of the emulator's
|
||||
* parameters.
|
||||
*/
|
||||
typedef const char * (*ptr_ConfigGetParameterHelp)(m64p_handle, const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT const char * CALL ConfigGetParameterHelp(m64p_handle, const char *);
|
||||
#endif
|
||||
|
||||
/* ConfigSetDefault***()
|
||||
*
|
||||
* These functions are used to set the value of a configuration parameter if it
|
||||
* is not already present in the configuration file. This may happen if a new
|
||||
* user runs the emulator, or an upgraded module uses a new parameter, or the
|
||||
* user deletes his or her configuration file. If the parameter is already
|
||||
* present in the given section of the configuration file, then no action will
|
||||
* be taken and this function will return successfully.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigSetDefaultInt)(m64p_handle, const char *, int, const char *);
|
||||
typedef m64p_error (*ptr_ConfigSetDefaultFloat)(m64p_handle, const char *, float, const char *);
|
||||
typedef m64p_error (*ptr_ConfigSetDefaultBool)(m64p_handle, const char *, int, const char *);
|
||||
typedef m64p_error (*ptr_ConfigSetDefaultString)(m64p_handle, const char *, const char *, const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigSetDefaultInt(m64p_handle, const char *, int, const char *);
|
||||
EXPORT m64p_error CALL ConfigSetDefaultFloat(m64p_handle, const char *, float, const char *);
|
||||
EXPORT m64p_error CALL ConfigSetDefaultBool(m64p_handle, const char *, int, const char *);
|
||||
EXPORT m64p_error CALL ConfigSetDefaultString(m64p_handle, const char *, const char *, const char *);
|
||||
#endif
|
||||
|
||||
/* ConfigGetParam***()
|
||||
*
|
||||
* These functions retrieve the value of one of the emulator's parameters in
|
||||
* the given section, and return the value directly to the calling function. If
|
||||
* an errors occurs (such as an invalid Section handle, or invalid
|
||||
* configuration parameter name), then an error will be sent to the front-end
|
||||
* via the DebugCallback() function, and either a 0 (zero) or an empty string
|
||||
* will be returned.
|
||||
*/
|
||||
typedef int (*ptr_ConfigGetParamInt)(m64p_handle, const char *);
|
||||
typedef float (*ptr_ConfigGetParamFloat)(m64p_handle, const char *);
|
||||
typedef int (*ptr_ConfigGetParamBool)(m64p_handle, const char *);
|
||||
typedef const char * (*ptr_ConfigGetParamString)(m64p_handle, const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT int CALL ConfigGetParamInt(m64p_handle, const char *);
|
||||
EXPORT float CALL ConfigGetParamFloat(m64p_handle, const char *);
|
||||
EXPORT int CALL ConfigGetParamBool(m64p_handle, const char *);
|
||||
EXPORT const char * CALL ConfigGetParamString(m64p_handle, const char *);
|
||||
#endif
|
||||
|
||||
/* ConfigGetSharedDataFilepath()
|
||||
*
|
||||
* This function is provided to allow a plugin to retrieve a full pathname to a
|
||||
* given shared data file. This type of file is intended to be shared among
|
||||
* multiple users on a system, so it is likely to be read-only.
|
||||
*/
|
||||
typedef const char * (*ptr_ConfigGetSharedDataFilepath)(const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT const char * CALL ConfigGetSharedDataFilepath(const char *);
|
||||
#endif
|
||||
|
||||
/* ConfigGetUserConfigPath()
|
||||
*
|
||||
* This function may be used by the plugins or front-end to get a path to the
|
||||
* directory for storing user-specific configuration files. This will be the
|
||||
* directory where "mupen64plus.cfg" is located.
|
||||
*/
|
||||
typedef const char * (*ptr_ConfigGetUserConfigPath)(void);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT const char * CALL ConfigGetUserConfigPath(void);
|
||||
#endif
|
||||
|
||||
/* ConfigGetUserDataPath()
|
||||
*
|
||||
* This function may be used by the plugins or front-end to get a path to the
|
||||
* directory for storing user-specific data files. This may be used to store
|
||||
* files such as screenshots, saved game states, or hi-res textures.
|
||||
*/
|
||||
typedef const char * (*ptr_ConfigGetUserDataPath)(void);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT const char * CALL ConfigGetUserDataPath(void);
|
||||
#endif
|
||||
|
||||
/* ConfigGetUserCachePath()
|
||||
*
|
||||
* This function may be used by the plugins or front-end to get a path to the
|
||||
* directory for storing cached user-specific data files. Files in this
|
||||
* directory may be deleted by the user to save space, so critical information
|
||||
* should not be stored here. This directory may be used to store files such
|
||||
* as the ROM browser cache.
|
||||
*/
|
||||
typedef const char * (*ptr_ConfigGetUserCachePath)(void);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT const char * CALL ConfigGetUserCachePath(void);
|
||||
#endif
|
||||
|
||||
/* ConfigExternalOpen()
|
||||
*
|
||||
* This function reads the contents of the config file into memory
|
||||
* and returns M64ERR_SUCCESS if successful.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigExternalOpen)(const char *, m64p_handle *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigExternalOpen(const char *, m64p_handle *);
|
||||
#endif
|
||||
|
||||
/* ConfigExternalClose()
|
||||
*
|
||||
* Frees the memory pointer created by ConfigExternalOpen.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigExternalClose)(m64p_handle);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigExternalClose(m64p_handle);
|
||||
#endif
|
||||
|
||||
/* ConfigExternalGetParameter()
|
||||
*
|
||||
* This functions allows a plugin to leverage the built-in ini parser to read
|
||||
* any cfg/ini file. It will return M64ERR_SUCCESS if the item was found.
|
||||
*/
|
||||
typedef m64p_error (*ptr_ConfigExternalGetParameter)(m64p_handle, const char *, const char *, char *, int);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL ConfigExternalGetParameter(m64p_handle, const char *, const char *, char *, int);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #define M64P_CONFIG_H */
|
||||
@@ -0,0 +1,286 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-core - m64p_plugin.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2002 Hacktarux *
|
||||
* Copyright (C) 2009 Richard Goedeken *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#if !defined(M64P_PLUGIN_H)
|
||||
#define M64P_PLUGIN_H
|
||||
|
||||
#include "m64p_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*** Controller plugin's ****/
|
||||
#define PLUGIN_NONE 1
|
||||
#define PLUGIN_MEMPAK 2
|
||||
#define PLUGIN_RUMBLE_PAK 3 /* not implemented for non raw data */
|
||||
#define PLUGIN_TRANSFER_PAK 4 /* not implemented for non raw data */
|
||||
#define PLUGIN_RAW 5 /* the controller plugin is passed in raw data */
|
||||
|
||||
/***** Structures *****/
|
||||
typedef struct {
|
||||
unsigned char * RDRAM;
|
||||
unsigned char * DMEM;
|
||||
unsigned char * IMEM;
|
||||
|
||||
unsigned int * MI_INTR_REG;
|
||||
|
||||
unsigned int * SP_MEM_ADDR_REG;
|
||||
unsigned int * SP_DRAM_ADDR_REG;
|
||||
unsigned int * SP_RD_LEN_REG;
|
||||
unsigned int * SP_WR_LEN_REG;
|
||||
unsigned int * SP_STATUS_REG;
|
||||
unsigned int * SP_DMA_FULL_REG;
|
||||
unsigned int * SP_DMA_BUSY_REG;
|
||||
unsigned int * SP_PC_REG;
|
||||
unsigned int * SP_SEMAPHORE_REG;
|
||||
|
||||
unsigned int * DPC_START_REG;
|
||||
unsigned int * DPC_END_REG;
|
||||
unsigned int * DPC_CURRENT_REG;
|
||||
unsigned int * DPC_STATUS_REG;
|
||||
unsigned int * DPC_CLOCK_REG;
|
||||
unsigned int * DPC_BUFBUSY_REG;
|
||||
unsigned int * DPC_PIPEBUSY_REG;
|
||||
unsigned int * DPC_TMEM_REG;
|
||||
|
||||
void (*CheckInterrupts)(void);
|
||||
void (*ProcessDlistList)(void);
|
||||
void (*ProcessAlistList)(void);
|
||||
void (*ProcessRdpList)(void);
|
||||
void (*ShowCFB)(void);
|
||||
} RSP_INFO;
|
||||
|
||||
typedef struct {
|
||||
unsigned char * HEADER; /* This is the rom header (first 40h bytes of the rom) */
|
||||
unsigned char * RDRAM;
|
||||
unsigned char * DMEM;
|
||||
unsigned char * IMEM;
|
||||
|
||||
unsigned int * MI_INTR_REG;
|
||||
|
||||
unsigned int * DPC_START_REG;
|
||||
unsigned int * DPC_END_REG;
|
||||
unsigned int * DPC_CURRENT_REG;
|
||||
unsigned int * DPC_STATUS_REG;
|
||||
unsigned int * DPC_CLOCK_REG;
|
||||
unsigned int * DPC_BUFBUSY_REG;
|
||||
unsigned int * DPC_PIPEBUSY_REG;
|
||||
unsigned int * DPC_TMEM_REG;
|
||||
|
||||
unsigned int * VI_STATUS_REG;
|
||||
unsigned int * VI_ORIGIN_REG;
|
||||
unsigned int * VI_WIDTH_REG;
|
||||
unsigned int * VI_INTR_REG;
|
||||
unsigned int * VI_V_CURRENT_LINE_REG;
|
||||
unsigned int * VI_TIMING_REG;
|
||||
unsigned int * VI_V_SYNC_REG;
|
||||
unsigned int * VI_H_SYNC_REG;
|
||||
unsigned int * VI_LEAP_REG;
|
||||
unsigned int * VI_H_START_REG;
|
||||
unsigned int * VI_V_START_REG;
|
||||
unsigned int * VI_V_BURST_REG;
|
||||
unsigned int * VI_X_SCALE_REG;
|
||||
unsigned int * VI_Y_SCALE_REG;
|
||||
|
||||
void (*CheckInterrupts)(void);
|
||||
|
||||
/* The GFX_INFO.version parameter was added in version 2.5.1 of the core.
|
||||
Plugins should ensure the core is at least this version before
|
||||
attempting to read GFX_INFO.version. */
|
||||
unsigned int version;
|
||||
/* SP_STATUS_REG and RDRAM_SIZE were added in version 2 of GFX_INFO.version.
|
||||
Plugins should only attempt to read these values if GFX_INFO.version is at least 2. */
|
||||
|
||||
/* The RSP plugin should set (HALT | BROKE | TASKDONE) *before* calling ProcessDList.
|
||||
It should not modify SP_STATUS_REG after ProcessDList has returned.
|
||||
This will allow the GFX plugin to unset these bits if it needs. */
|
||||
unsigned int * SP_STATUS_REG;
|
||||
const unsigned int * RDRAM_SIZE;
|
||||
} GFX_INFO;
|
||||
|
||||
typedef struct {
|
||||
unsigned char * RDRAM;
|
||||
unsigned char * DMEM;
|
||||
unsigned char * IMEM;
|
||||
|
||||
unsigned int * MI_INTR_REG;
|
||||
|
||||
unsigned int * AI_DRAM_ADDR_REG;
|
||||
unsigned int * AI_LEN_REG;
|
||||
unsigned int * AI_CONTROL_REG;
|
||||
unsigned int * AI_STATUS_REG;
|
||||
unsigned int * AI_DACRATE_REG;
|
||||
unsigned int * AI_BITRATE_REG;
|
||||
|
||||
void (*CheckInterrupts)(void);
|
||||
} AUDIO_INFO;
|
||||
|
||||
typedef struct {
|
||||
int Present;
|
||||
int RawData;
|
||||
int Plugin;
|
||||
} CONTROL;
|
||||
|
||||
typedef union {
|
||||
unsigned int Value;
|
||||
struct {
|
||||
unsigned R_DPAD : 1;
|
||||
unsigned L_DPAD : 1;
|
||||
unsigned D_DPAD : 1;
|
||||
unsigned U_DPAD : 1;
|
||||
unsigned START_BUTTON : 1;
|
||||
unsigned Z_TRIG : 1;
|
||||
unsigned B_BUTTON : 1;
|
||||
unsigned A_BUTTON : 1;
|
||||
|
||||
unsigned R_CBUTTON : 1;
|
||||
unsigned L_CBUTTON : 1;
|
||||
unsigned D_CBUTTON : 1;
|
||||
unsigned U_CBUTTON : 1;
|
||||
unsigned R_TRIG : 1;
|
||||
unsigned L_TRIG : 1;
|
||||
unsigned Reserved1 : 1;
|
||||
unsigned Reserved2 : 1;
|
||||
|
||||
signed X_AXIS : 8;
|
||||
signed Y_AXIS : 8;
|
||||
};
|
||||
} BUTTONS;
|
||||
|
||||
typedef struct {
|
||||
CONTROL *Controls; /* A pointer to an array of 4 controllers .. eg:
|
||||
CONTROL Controls[4]; */
|
||||
} CONTROL_INFO;
|
||||
|
||||
/* common plugin function pointer types */
|
||||
typedef void (*ptr_RomClosed)(void);
|
||||
typedef int (*ptr_RomOpen)(void);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES)
|
||||
EXPORT int CALL RomOpen(void);
|
||||
EXPORT void CALL RomClosed(void);
|
||||
#endif
|
||||
|
||||
/* video plugin function pointer types */
|
||||
typedef void (*ptr_ChangeWindow)(void);
|
||||
typedef int (*ptr_InitiateGFX)(GFX_INFO Gfx_Info);
|
||||
typedef void (*ptr_MoveScreen)(int x, int y);
|
||||
typedef void (*ptr_ProcessDList)(void);
|
||||
typedef void (*ptr_ProcessRDPList)(void);
|
||||
typedef void (*ptr_ShowCFB)(void);
|
||||
typedef void (*ptr_UpdateScreen)(void);
|
||||
typedef void (*ptr_ViStatusChanged)(void);
|
||||
typedef void (*ptr_ViWidthChanged)(void);
|
||||
typedef void (*ptr_ReadScreen2)(void *dest, int *width, int *height, int front);
|
||||
typedef void (*ptr_SetRenderingCallback)(void (*callback)(int));
|
||||
typedef void (*ptr_ResizeVideoOutput)(int width, int height);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES)
|
||||
EXPORT void CALL ChangeWindow(void);
|
||||
EXPORT int CALL InitiateGFX(GFX_INFO Gfx_Info);
|
||||
EXPORT void CALL MoveScreen(int x, int y);
|
||||
EXPORT void CALL ProcessDList(void);
|
||||
EXPORT void CALL ProcessRDPList(void);
|
||||
EXPORT void CALL ShowCFB(void);
|
||||
EXPORT void CALL UpdateScreen(void);
|
||||
EXPORT void CALL ViStatusChanged(void);
|
||||
EXPORT void CALL ViWidthChanged(void);
|
||||
EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front);
|
||||
EXPORT void CALL SetRenderingCallback(void (*callback)(int));
|
||||
EXPORT void CALL ResizeVideoOutput(int width, int height);
|
||||
#endif
|
||||
|
||||
/* frame buffer plugin spec extension */
|
||||
typedef struct
|
||||
{
|
||||
unsigned int addr;
|
||||
unsigned int size;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
} FrameBufferInfo;
|
||||
typedef void (*ptr_FBRead)(unsigned int addr);
|
||||
typedef void (*ptr_FBWrite)(unsigned int addr, unsigned int size);
|
||||
typedef void (*ptr_FBGetFrameBufferInfo)(void *p);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES)
|
||||
EXPORT void CALL FBRead(unsigned int addr);
|
||||
EXPORT void CALL FBWrite(unsigned int addr, unsigned int size);
|
||||
EXPORT void CALL FBGetFrameBufferInfo(void *p);
|
||||
#endif
|
||||
|
||||
/* audio plugin function pointers */
|
||||
typedef void (*ptr_AiDacrateChanged)(int SystemType);
|
||||
typedef void (*ptr_AiLenChanged)(void);
|
||||
typedef int (*ptr_InitiateAudio)(AUDIO_INFO Audio_Info);
|
||||
typedef void (*ptr_ProcessAList)(void);
|
||||
typedef void (*ptr_SetSpeedFactor)(int percent);
|
||||
typedef void (*ptr_VolumeUp)(void);
|
||||
typedef void (*ptr_VolumeDown)(void);
|
||||
typedef int (*ptr_VolumeGetLevel)(void);
|
||||
typedef void (*ptr_VolumeSetLevel)(int level);
|
||||
typedef void (*ptr_VolumeMute)(void);
|
||||
typedef const char * (*ptr_VolumeGetString)(void);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES)
|
||||
EXPORT void CALL AiDacrateChanged(int SystemType);
|
||||
EXPORT void CALL AiLenChanged(void);
|
||||
EXPORT int CALL InitiateAudio(AUDIO_INFO Audio_Info);
|
||||
EXPORT void CALL ProcessAList(void);
|
||||
EXPORT void CALL SetSpeedFactor(int percent);
|
||||
EXPORT void CALL VolumeUp(void);
|
||||
EXPORT void CALL VolumeDown(void);
|
||||
EXPORT int CALL VolumeGetLevel(void);
|
||||
EXPORT void CALL VolumeSetLevel(int level);
|
||||
EXPORT void CALL VolumeMute(void);
|
||||
EXPORT const char * CALL VolumeGetString(void);
|
||||
#endif
|
||||
|
||||
/* input plugin function pointers */
|
||||
typedef void (*ptr_ControllerCommand)(int Control, unsigned char *Command);
|
||||
typedef void (*ptr_GetKeys)(int Control, BUTTONS *Keys);
|
||||
typedef void (*ptr_InitiateControllers)(CONTROL_INFO ControlInfo);
|
||||
typedef void (*ptr_ReadController)(int Control, unsigned char *Command);
|
||||
typedef void (*ptr_SDL_KeyDown)(int keymod, int keysym);
|
||||
typedef void (*ptr_SDL_KeyUp)(int keymod, int keysym);
|
||||
typedef void (*ptr_RenderCallback)(void);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES)
|
||||
EXPORT void CALL ControllerCommand(int Control, unsigned char *Command);
|
||||
EXPORT void CALL GetKeys(int Control, BUTTONS *Keys);
|
||||
EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo);
|
||||
EXPORT void CALL ReadController(int Control, unsigned char *Command);
|
||||
EXPORT void CALL SDL_KeyDown(int keymod, int keysym);
|
||||
EXPORT void CALL SDL_KeyUp(int keymod, int keysym);
|
||||
EXPORT void CALL RenderCallback(void);
|
||||
#endif
|
||||
|
||||
/* RSP plugin function pointers */
|
||||
typedef unsigned int (*ptr_DoRspCycles)(unsigned int Cycles);
|
||||
typedef void (*ptr_InitiateRSP)(RSP_INFO Rsp_Info, unsigned int *CycleCount);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES)
|
||||
EXPORT unsigned int CALL DoRspCycles(unsigned int Cycles);
|
||||
EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* M64P_PLUGIN_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-core - m64p_types.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2012 CasualJames *
|
||||
* Copyright (C) 2009 Richard Goedeken *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#if !defined(M64P_TYPES_H)
|
||||
#define M64P_TYPES_H
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* Platform-specific stuff */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
/* necessary headers */
|
||||
#include <stdint.h>
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/* DLL handles and function declaration specifiers */
|
||||
#if defined(WIN32)
|
||||
#define IMPORT extern "C" __declspec(dllimport)
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#define CALL __cdecl
|
||||
typedef HMODULE m64p_dynlib_handle;
|
||||
#else
|
||||
#define IMPORT extern "C"
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
#define CALL
|
||||
typedef void * m64p_dynlib_handle;
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* Structures and Types for Core library API */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
typedef void * m64p_handle;
|
||||
|
||||
typedef void (*m64p_frame_callback)(unsigned int FrameIndex);
|
||||
typedef void (*m64p_input_callback)(void);
|
||||
typedef void (*m64p_audio_callback)(void);
|
||||
typedef void (*m64p_vi_callback)(void);
|
||||
|
||||
typedef enum {
|
||||
M64TYPE_INT = 1,
|
||||
M64TYPE_FLOAT,
|
||||
M64TYPE_BOOL,
|
||||
M64TYPE_STRING
|
||||
} m64p_type;
|
||||
|
||||
typedef enum {
|
||||
M64MSG_ERROR = 1,
|
||||
M64MSG_WARNING,
|
||||
M64MSG_INFO,
|
||||
M64MSG_STATUS,
|
||||
M64MSG_VERBOSE
|
||||
} m64p_msg_level;
|
||||
|
||||
typedef enum {
|
||||
M64ERR_SUCCESS = 0,
|
||||
M64ERR_NOT_INIT, /* Function is disallowed before InitMupen64Plus() is called */
|
||||
M64ERR_ALREADY_INIT, /* InitMupen64Plus() was called twice */
|
||||
M64ERR_INCOMPATIBLE, /* API versions between components are incompatible */
|
||||
M64ERR_INPUT_ASSERT, /* Invalid parameters for function call, such as ParamValue=NULL for GetCoreParameter() */
|
||||
M64ERR_INPUT_INVALID, /* Invalid input data, such as ParamValue="maybe" for SetCoreParameter() to set a BOOL-type value */
|
||||
M64ERR_INPUT_NOT_FOUND, /* The input parameter(s) specified a particular item which was not found */
|
||||
M64ERR_NO_MEMORY, /* Memory allocation failed */
|
||||
M64ERR_FILES, /* Error opening, creating, reading, or writing to a file */
|
||||
M64ERR_INTERNAL, /* Internal error (bug) */
|
||||
M64ERR_INVALID_STATE, /* Current program state does not allow operation */
|
||||
M64ERR_PLUGIN_FAIL, /* A plugin function returned a fatal error */
|
||||
M64ERR_SYSTEM_FAIL, /* A system function call, such as an SDL or file operation, failed */
|
||||
M64ERR_UNSUPPORTED, /* Function call is not supported (ie, core not built with debugger) */
|
||||
M64ERR_WRONG_TYPE /* A given input type parameter cannot be used for desired operation */
|
||||
} m64p_error;
|
||||
|
||||
typedef enum {
|
||||
M64CAPS_DYNAREC = 1,
|
||||
M64CAPS_DEBUGGER = 2,
|
||||
M64CAPS_CORE_COMPARE = 4
|
||||
} m64p_core_caps;
|
||||
|
||||
typedef enum {
|
||||
M64PLUGIN_NULL = 0,
|
||||
M64PLUGIN_RSP = 1,
|
||||
M64PLUGIN_GFX,
|
||||
M64PLUGIN_AUDIO,
|
||||
M64PLUGIN_INPUT,
|
||||
M64PLUGIN_CORE
|
||||
} m64p_plugin_type;
|
||||
|
||||
typedef enum {
|
||||
M64EMU_STOPPED = 1,
|
||||
M64EMU_RUNNING,
|
||||
M64EMU_PAUSED
|
||||
} m64p_emu_state;
|
||||
|
||||
typedef enum {
|
||||
M64VIDEO_NONE = 1,
|
||||
M64VIDEO_WINDOWED,
|
||||
M64VIDEO_FULLSCREEN
|
||||
} m64p_video_mode;
|
||||
|
||||
typedef enum {
|
||||
M64VIDEOFLAG_SUPPORT_RESIZING = 1
|
||||
} m64p_video_flags;
|
||||
|
||||
typedef enum {
|
||||
M64CORE_EMU_STATE = 1,
|
||||
M64CORE_VIDEO_MODE,
|
||||
M64CORE_SAVESTATE_SLOT,
|
||||
M64CORE_SPEED_FACTOR,
|
||||
M64CORE_SPEED_LIMITER,
|
||||
M64CORE_VIDEO_SIZE,
|
||||
M64CORE_AUDIO_VOLUME,
|
||||
M64CORE_AUDIO_MUTE,
|
||||
M64CORE_INPUT_GAMESHARK,
|
||||
M64CORE_STATE_LOADCOMPLETE,
|
||||
M64CORE_STATE_SAVECOMPLETE
|
||||
} m64p_core_param;
|
||||
|
||||
typedef enum {
|
||||
M64CMD_NOP = 0,
|
||||
M64CMD_ROM_OPEN,
|
||||
M64CMD_ROM_CLOSE,
|
||||
M64CMD_ROM_GET_HEADER,
|
||||
M64CMD_ROM_GET_SETTINGS,
|
||||
M64CMD_EXECUTE,
|
||||
M64CMD_STOP,
|
||||
M64CMD_PAUSE,
|
||||
M64CMD_RESUME,
|
||||
M64CMD_CORE_STATE_QUERY,
|
||||
M64CMD_STATE_LOAD,
|
||||
M64CMD_STATE_SAVE,
|
||||
M64CMD_STATE_SET_SLOT,
|
||||
M64CMD_SEND_SDL_KEYDOWN,
|
||||
M64CMD_SEND_SDL_KEYUP,
|
||||
M64CMD_SET_FRAME_CALLBACK,
|
||||
M64CMD_TAKE_NEXT_SCREENSHOT,
|
||||
M64CMD_CORE_STATE_SET,
|
||||
M64CMD_READ_SCREEN,
|
||||
M64CMD_RESET,
|
||||
M64CMD_ADVANCE_FRAME
|
||||
} m64p_command;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
int value;
|
||||
} m64p_cheat_code;
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* Structures to hold ROM image information */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SYSTEM_NTSC = 0,
|
||||
SYSTEM_PAL,
|
||||
SYSTEM_MPAL
|
||||
} m64p_system_type;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t init_PI_BSB_DOM1_LAT_REG; /* 0x00 */
|
||||
uint8_t init_PI_BSB_DOM1_PGS_REG; /* 0x01 */
|
||||
uint8_t init_PI_BSB_DOM1_PWD_REG; /* 0x02 */
|
||||
uint8_t init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */
|
||||
uint32_t ClockRate; /* 0x04 */
|
||||
uint32_t PC; /* 0x08 */
|
||||
uint32_t Release; /* 0x0C */
|
||||
uint32_t CRC1; /* 0x10 */
|
||||
uint32_t CRC2; /* 0x14 */
|
||||
uint32_t Unknown[2]; /* 0x18 */
|
||||
uint8_t Name[20]; /* 0x20 */
|
||||
uint32_t unknown; /* 0x34 */
|
||||
uint32_t Manufacturer_ID; /* 0x38 */
|
||||
uint16_t Cartridge_ID; /* 0x3C - Game serial number */
|
||||
uint16_t Country_code; /* 0x3E */
|
||||
} m64p_rom_header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char goodname[256];
|
||||
char MD5[33];
|
||||
unsigned char savetype;
|
||||
unsigned char status; /* Rom status on a scale from 0-5. */
|
||||
unsigned char players; /* Local players 0-4, 2/3/4 way Netplay indicated by 5/6/7. */
|
||||
unsigned char rumble; /* 0 - No, 1 - Yes boolean for rumble support. */
|
||||
} m64p_rom_settings;
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* Structures and Types for the Debugger */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
typedef enum {
|
||||
M64P_DBG_RUN_STATE = 1,
|
||||
M64P_DBG_PREVIOUS_PC,
|
||||
M64P_DBG_NUM_BREAKPOINTS,
|
||||
M64P_DBG_CPU_DYNACORE,
|
||||
M64P_DBG_CPU_NEXT_INTERRUPT
|
||||
} m64p_dbg_state;
|
||||
|
||||
typedef enum {
|
||||
M64P_DBG_RUNSTATE_PAUSED = 0,
|
||||
M64P_DBG_RUNSTATE_STEPPING,
|
||||
M64P_DBG_RUNSTATE_RUNNING
|
||||
} m64p_dbg_runstate;
|
||||
|
||||
typedef enum {
|
||||
M64P_DBG_MEM_TYPE = 1,
|
||||
M64P_DBG_MEM_FLAGS,
|
||||
M64P_DBG_MEM_HAS_RECOMPILED,
|
||||
M64P_DBG_MEM_NUM_RECOMPILED,
|
||||
M64P_DBG_RECOMP_OPCODE = 16,
|
||||
M64P_DBG_RECOMP_ARGS,
|
||||
M64P_DBG_RECOMP_ADDR
|
||||
} m64p_dbg_mem_info;
|
||||
|
||||
typedef enum {
|
||||
M64P_MEM_NOMEM = 0,
|
||||
M64P_MEM_NOTHING,
|
||||
M64P_MEM_RDRAM,
|
||||
M64P_MEM_RDRAMREG,
|
||||
M64P_MEM_RSPMEM,
|
||||
M64P_MEM_RSPREG,
|
||||
M64P_MEM_RSP,
|
||||
M64P_MEM_DP,
|
||||
M64P_MEM_DPS,
|
||||
M64P_MEM_VI,
|
||||
M64P_MEM_AI,
|
||||
M64P_MEM_PI,
|
||||
M64P_MEM_RI,
|
||||
M64P_MEM_SI,
|
||||
M64P_MEM_FLASHRAMSTAT,
|
||||
M64P_MEM_ROM,
|
||||
M64P_MEM_PIF,
|
||||
M64P_MEM_MI,
|
||||
M64P_MEM_BREAKPOINT
|
||||
} m64p_dbg_mem_type;
|
||||
|
||||
typedef enum {
|
||||
M64P_MEM_FLAG_READABLE = 0x01,
|
||||
M64P_MEM_FLAG_WRITABLE = 0x02,
|
||||
M64P_MEM_FLAG_READABLE_EMUONLY = 0x04, /* the EMUONLY flags signify that emulated code can read/write here, but debugger cannot */
|
||||
M64P_MEM_FLAG_WRITABLE_EMUONLY = 0x08
|
||||
} m64p_dbg_mem_flags;
|
||||
|
||||
typedef enum {
|
||||
M64P_DBG_PTR_RDRAM = 1,
|
||||
M64P_DBG_PTR_PI_REG,
|
||||
M64P_DBG_PTR_SI_REG,
|
||||
M64P_DBG_PTR_VI_REG,
|
||||
M64P_DBG_PTR_RI_REG,
|
||||
M64P_DBG_PTR_AI_REG
|
||||
} m64p_dbg_memptr_type;
|
||||
|
||||
typedef enum {
|
||||
M64P_CPU_PC = 1,
|
||||
M64P_CPU_REG_REG,
|
||||
M64P_CPU_REG_HI,
|
||||
M64P_CPU_REG_LO,
|
||||
M64P_CPU_REG_COP0,
|
||||
M64P_CPU_REG_COP1_DOUBLE_PTR,
|
||||
M64P_CPU_REG_COP1_SIMPLE_PTR,
|
||||
M64P_CPU_REG_COP1_FGR_64,
|
||||
M64P_CPU_TLB
|
||||
} m64p_dbg_cpu_data;
|
||||
|
||||
typedef enum {
|
||||
M64P_BKP_CMD_ADD_ADDR = 1,
|
||||
M64P_BKP_CMD_ADD_STRUCT,
|
||||
M64P_BKP_CMD_REPLACE,
|
||||
M64P_BKP_CMD_REMOVE_ADDR,
|
||||
M64P_BKP_CMD_REMOVE_IDX,
|
||||
M64P_BKP_CMD_ENABLE,
|
||||
M64P_BKP_CMD_DISABLE,
|
||||
M64P_BKP_CMD_CHECK
|
||||
} m64p_dbg_bkp_command;
|
||||
|
||||
#define M64P_MEM_INVALID 0xFFFFFFFF /* invalid memory read will return this */
|
||||
|
||||
#define BREAKPOINTS_MAX_NUMBER 128
|
||||
|
||||
typedef enum {
|
||||
M64P_BKP_FLAG_ENABLED = 0x01,
|
||||
M64P_BKP_FLAG_READ = 0x02,
|
||||
M64P_BKP_FLAG_WRITE = 0x04,
|
||||
M64P_BKP_FLAG_EXEC = 0x08,
|
||||
M64P_BKP_FLAG_LOG = 0x10 /* Log to the console when this breakpoint hits */
|
||||
} m64p_dbg_bkp_flags;
|
||||
|
||||
#define BPT_CHECK_FLAG(a, b) ((a.flags & b) == b)
|
||||
#define BPT_SET_FLAG(a, b) a.flags = (a.flags | b);
|
||||
#define BPT_CLEAR_FLAG(a, b) a.flags = (a.flags & (~b));
|
||||
#define BPT_TOGGLE_FLAG(a, b) a.flags = (a.flags ^ b);
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
uint32_t endaddr;
|
||||
unsigned int flags;
|
||||
} m64p_breakpoint;
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
/* Structures and Types for Core Video Extension API */
|
||||
/* ------------------------------------------------- */
|
||||
|
||||
typedef struct {
|
||||
unsigned int uiWidth;
|
||||
unsigned int uiHeight;
|
||||
} m64p_2d_size;
|
||||
|
||||
typedef enum {
|
||||
M64P_GL_DOUBLEBUFFER = 1,
|
||||
M64P_GL_BUFFER_SIZE,
|
||||
M64P_GL_DEPTH_SIZE,
|
||||
M64P_GL_RED_SIZE,
|
||||
M64P_GL_GREEN_SIZE,
|
||||
M64P_GL_BLUE_SIZE,
|
||||
M64P_GL_ALPHA_SIZE,
|
||||
M64P_GL_SWAP_CONTROL,
|
||||
M64P_GL_MULTISAMPLEBUFFERS,
|
||||
M64P_GL_MULTISAMPLESAMPLES,
|
||||
M64P_GL_CONTEXT_MAJOR_VERSION,
|
||||
M64P_GL_CONTEXT_MINOR_VERSION,
|
||||
M64P_GL_CONTEXT_PROFILE_MASK
|
||||
} m64p_GLattr;
|
||||
|
||||
typedef enum {
|
||||
M64P_GL_CONTEXT_PROFILE_CORE,
|
||||
M64P_GL_CONTEXT_PROFILE_COMPATIBILITY,
|
||||
M64P_GL_CONTEXT_PROFILE_ES
|
||||
} m64p_GLContextType;
|
||||
|
||||
typedef struct {
|
||||
unsigned int Functions;
|
||||
m64p_error (*VidExtFuncInit)(void);
|
||||
m64p_error (*VidExtFuncQuit)(void);
|
||||
m64p_error (*VidExtFuncListModes)(m64p_2d_size *, int *);
|
||||
m64p_error (*VidExtFuncSetMode)(int, int, int, int, int);
|
||||
void * (*VidExtFuncGLGetProc)(const char*);
|
||||
m64p_error (*VidExtFuncGLSetAttr)(m64p_GLattr, int);
|
||||
m64p_error (*VidExtFuncGLGetAttr)(m64p_GLattr, int *);
|
||||
m64p_error (*VidExtFuncGLSwapBuf)(void);
|
||||
m64p_error (*VidExtFuncSetCaption)(const char *);
|
||||
m64p_error (*VidExtFuncToggleFS)(void);
|
||||
m64p_error (*VidExtFuncResizeWindow)(int, int);
|
||||
} m64p_video_extension_functions;
|
||||
|
||||
#endif /* define M64P_TYPES_H */
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-core - m64p_vidext.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2009 Richard Goedeken *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* This header file defines typedefs for function pointers to the core's
|
||||
* video extension functions.
|
||||
*/
|
||||
|
||||
#if !defined(M64P_VIDEXT_H)
|
||||
#define M64P_VIDEXT_H
|
||||
|
||||
#include "m64p_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* VidExt_Init()
|
||||
*
|
||||
* This function should be called from within the InitiateGFX() video plugin
|
||||
* function call. The default SDL implementation of this function simply calls
|
||||
* SDL_InitSubSystem(SDL_INIT_VIDEO). It does not open a rendering window or
|
||||
* switch video modes.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_Init)(void);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_Init(void);
|
||||
#endif
|
||||
|
||||
/* VidExt_Quit()
|
||||
*
|
||||
* This function closes any open rendering window and shuts down the video
|
||||
* system. The default SDL implementation of this function calls
|
||||
* SDL_QuitSubSystem(SDL_INIT_VIDEO). This function should be called from
|
||||
* within the RomClose() video plugin function.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_Quit)(void);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_Quit(void);
|
||||
#endif
|
||||
|
||||
/* VidExt_ListFullscreenModes()
|
||||
*
|
||||
* This function is used to enumerate the available resolutions for fullscreen
|
||||
* video modes. A pointer to an array is passed into the function, which is
|
||||
* then filled with resolution sizes.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_ListFullscreenModes)(m64p_2d_size *, int *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_ListFullscreenModes(m64p_2d_size *, int *);
|
||||
#endif
|
||||
|
||||
/* VidExt_SetVideoMode()
|
||||
*
|
||||
* This function creates a rendering window or switches into a fullscreen
|
||||
* video mode. Any desired OpenGL attributes should be set before calling
|
||||
* this function.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_SetVideoMode)(int, int, int, m64p_video_mode, m64p_video_flags);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_SetVideoMode(int, int, int, m64p_video_mode, m64p_video_flags);
|
||||
#endif
|
||||
|
||||
/* VidExt_ResizeWindow()
|
||||
*
|
||||
* This function resizes the opengl rendering window to match the given size.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_ResizeWindow)(int, int);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_ResizeWindow(int, int);
|
||||
#endif
|
||||
|
||||
/* VidExt_SetCaption()
|
||||
*
|
||||
* This function sets the caption text of the emulator rendering window.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_SetCaption)(const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_SetCaption(const char *);
|
||||
#endif
|
||||
|
||||
/* VidExt_ToggleFullScreen()
|
||||
*
|
||||
* This function toggles between fullscreen and windowed rendering modes.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_ToggleFullScreen)(void);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_ToggleFullScreen(void);
|
||||
#endif
|
||||
|
||||
/* VidExt_GL_GetProcAddress()
|
||||
*
|
||||
* This function is used to get a pointer to an OpenGL extension function. This
|
||||
* is only necessary on the Windows platform, because the OpenGL implementation
|
||||
* shipped with Windows only supports OpenGL version 1.1.
|
||||
*/
|
||||
typedef void * (*ptr_VidExt_GL_GetProcAddress)(const char *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT void * CALL VidExt_GL_GetProcAddress(const char *);
|
||||
#endif
|
||||
|
||||
/* VidExt_GL_SetAttribute()
|
||||
*
|
||||
* This function is used to set certain OpenGL attributes which must be
|
||||
* specified before creating the rendering window with VidExt_SetVideoMode.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_GL_SetAttribute)(m64p_GLattr, int);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_GL_SetAttribute(m64p_GLattr, int);
|
||||
#endif
|
||||
|
||||
/* VidExt_GL_GetAttribute()
|
||||
*
|
||||
* This function is used to get the value of OpenGL attributes. These values may
|
||||
* be changed when calling VidExt_SetVideoMode.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_GL_GetAttribute)(m64p_GLattr, int *);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_GL_GetAttribute(m64p_GLattr, int *);
|
||||
#endif
|
||||
|
||||
/* VidExt_GL_SwapBuffers()
|
||||
*
|
||||
* This function is used to swap the front/back buffers after rendering an
|
||||
* output video frame.
|
||||
*/
|
||||
typedef m64p_error (*ptr_VidExt_GL_SwapBuffers)(void);
|
||||
#if defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL VidExt_GL_SwapBuffers(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #define M64P_VIDEXT_H */
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-video-angrylionplus - plugin.c *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2014 Bobby Smiles *
|
||||
* Copyright (C) 2009 Richard Goedeken *
|
||||
* Copyright (C) 2002 Hacktarux *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#define M64P_PLUGIN_PROTOTYPES 1
|
||||
|
||||
#define KEY_FULLSCREEN "Fullscreen"
|
||||
#define KEY_SCREEN_WIDTH "ScreenWidth"
|
||||
#define KEY_SCREEN_HEIGHT "ScreenHeight"
|
||||
#define KEY_PARALLEL "Parallel"
|
||||
#define KEY_NUM_WORKERS "NumWorkers"
|
||||
|
||||
#define KEY_VI_MODE "ViMode"
|
||||
#define KEY_VI_INTERP "ViInterpolation"
|
||||
#define KEY_VI_WIDESCREEN "ViWidescreen"
|
||||
#define KEY_VI_HIDE_OVERSCAN "ViHideOverscan"
|
||||
|
||||
#define KEY_DP_COMPAT "DpCompat"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "gfx_m64p.h"
|
||||
|
||||
#include "api/m64p_types.h"
|
||||
#include "api/m64p_config.h"
|
||||
|
||||
#include "core/common.h"
|
||||
#include "core/version.h"
|
||||
#include "core/msg.h"
|
||||
|
||||
#include "output/screen.h"
|
||||
#include "output/vdac.h"
|
||||
|
||||
static ptr_ConfigOpenSection ConfigOpenSection = NULL;
|
||||
static ptr_ConfigSaveSection ConfigSaveSection = NULL;
|
||||
static ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL;
|
||||
static ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL;
|
||||
static ptr_ConfigGetParamInt ConfigGetParamInt = NULL;
|
||||
static ptr_ConfigGetParamBool ConfigGetParamBool = NULL;
|
||||
static ptr_PluginGetVersion CoreGetVersion = NULL;
|
||||
|
||||
static bool warn_hle;
|
||||
static bool plugin_initialized;
|
||||
void (*debug_callback)(void *, int, const char *);
|
||||
void *debug_call_context;
|
||||
static struct n64video_config config;
|
||||
|
||||
m64p_dynlib_handle CoreLibHandle;
|
||||
GFX_INFO gfx;
|
||||
void (*render_callback)(int);
|
||||
|
||||
static m64p_handle configVideoGeneral = NULL;
|
||||
static m64p_handle configVideoAngrylionPlus = NULL;
|
||||
|
||||
#define PLUGIN_VERSION 0x000100
|
||||
#define VIDEO_PLUGIN_API_VERSION 0x020200
|
||||
|
||||
extern int32_t win_width;
|
||||
extern int32_t win_height;
|
||||
extern int32_t win_fullscreen;
|
||||
|
||||
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle _CoreLibHandle, void *Context,
|
||||
void (*DebugCallback)(void *, int, const char *))
|
||||
{
|
||||
if (plugin_initialized) {
|
||||
return M64ERR_ALREADY_INIT;
|
||||
}
|
||||
|
||||
/* first thing is to set the callback function for debug info */
|
||||
debug_callback = DebugCallback;
|
||||
debug_call_context = Context;
|
||||
|
||||
CoreLibHandle = _CoreLibHandle;
|
||||
|
||||
ConfigOpenSection = (ptr_ConfigOpenSection)DLSYM(CoreLibHandle, "ConfigOpenSection");
|
||||
ConfigSaveSection = (ptr_ConfigSaveSection)DLSYM(CoreLibHandle, "ConfigSaveSection");
|
||||
ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt)DLSYM(CoreLibHandle, "ConfigSetDefaultInt");
|
||||
ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool)DLSYM(CoreLibHandle, "ConfigSetDefaultBool");
|
||||
ConfigGetParamInt = (ptr_ConfigGetParamInt)DLSYM(CoreLibHandle, "ConfigGetParamInt");
|
||||
ConfigGetParamBool = (ptr_ConfigGetParamBool)DLSYM(CoreLibHandle, "ConfigGetParamBool");
|
||||
|
||||
ConfigOpenSection("Video-General", &configVideoGeneral);
|
||||
ConfigOpenSection("Video-Angrylion-Plus", &configVideoAngrylionPlus);
|
||||
|
||||
ConfigSetDefaultBool(configVideoGeneral, KEY_FULLSCREEN, 0, "Use fullscreen mode if True, or windowed mode if False");
|
||||
ConfigSetDefaultInt(configVideoGeneral, KEY_SCREEN_WIDTH, 640, "Width of output window or fullscreen width");
|
||||
ConfigSetDefaultInt(configVideoGeneral, KEY_SCREEN_HEIGHT, 480, "Height of output window or fullscreen height");
|
||||
|
||||
CoreGetVersion = (ptr_PluginGetVersion)DLSYM(CoreLibHandle, "PluginGetVersion");
|
||||
|
||||
n64video_config_init(&config);
|
||||
|
||||
ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_PARALLEL, config.parallel, "Distribute rendering between multiple processors if True");
|
||||
ConfigSetDefaultInt(configVideoAngrylionPlus, KEY_NUM_WORKERS, config.num_workers, "Rendering Workers (0=Use all logical processors)");
|
||||
ConfigSetDefaultInt(configVideoAngrylionPlus, KEY_VI_MODE, config.vi.mode, "VI mode (0=Filtered, 1=Unfiltered, 2=Depth, 3=Coverage)");
|
||||
ConfigSetDefaultInt(configVideoAngrylionPlus, KEY_VI_INTERP, config.vi.interp, "Scaling interpolation type (0=NN, 1=Linear)");
|
||||
ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_VI_WIDESCREEN, config.vi.widescreen, "Use anamorphic 16:9 output mode if True");
|
||||
ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_VI_HIDE_OVERSCAN, config.vi.hide_overscan, "Hide overscan area in filteded mode if True");
|
||||
ConfigSetDefaultInt(configVideoAngrylionPlus, KEY_DP_COMPAT, config.dp.compat, "Compatibility mode (0=Fast 1=Moderate 2=Slow");
|
||||
|
||||
ConfigSaveSection("Video-General");
|
||||
ConfigSaveSection("Video-Angrylion-Plus");
|
||||
|
||||
plugin_initialized = true;
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
EXPORT m64p_error CALL PluginShutdown(void)
|
||||
{
|
||||
if (!plugin_initialized) {
|
||||
return M64ERR_NOT_INIT;
|
||||
}
|
||||
|
||||
/* reset some local variable */
|
||||
debug_callback = NULL;
|
||||
debug_call_context = NULL;
|
||||
|
||||
plugin_initialized = false;
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)
|
||||
{
|
||||
/* set version info */
|
||||
if (PluginType != NULL) {
|
||||
*PluginType = M64PLUGIN_GFX;
|
||||
}
|
||||
|
||||
if (PluginVersion != NULL) {
|
||||
*PluginVersion = PLUGIN_VERSION;
|
||||
}
|
||||
|
||||
if (APIVersion != NULL) {
|
||||
*APIVersion = VIDEO_PLUGIN_API_VERSION;
|
||||
}
|
||||
|
||||
if (PluginNamePtr != NULL) {
|
||||
*PluginNamePtr = CORE_NAME;
|
||||
}
|
||||
|
||||
if (Capabilities != NULL) {
|
||||
*Capabilities = 0;
|
||||
}
|
||||
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info)
|
||||
{
|
||||
gfx = Gfx_Info;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT void CALL MoveScreen (int xpos, int ypos)
|
||||
{
|
||||
UNUSED(xpos);
|
||||
UNUSED(ypos);
|
||||
}
|
||||
|
||||
EXPORT void CALL ProcessDList(void)
|
||||
{
|
||||
if (!warn_hle) {
|
||||
msg_warning("HLE video emulation not supported, please use a LLE RSP plugin like mupen64plus-rsp-cxd4");
|
||||
warn_hle = true;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void CALL ProcessRDPList(void)
|
||||
{
|
||||
n64video_process_list();
|
||||
}
|
||||
|
||||
EXPORT int CALL RomOpen (void)
|
||||
{
|
||||
win_fullscreen = ConfigGetParamBool(configVideoGeneral, KEY_FULLSCREEN);
|
||||
win_width = ConfigGetParamInt(configVideoGeneral, KEY_SCREEN_WIDTH);
|
||||
win_height = ConfigGetParamInt(configVideoGeneral, KEY_SCREEN_HEIGHT);
|
||||
|
||||
config.parallel = ConfigGetParamBool(configVideoAngrylionPlus, KEY_PARALLEL);
|
||||
config.num_workers = ConfigGetParamInt(configVideoAngrylionPlus, KEY_NUM_WORKERS);
|
||||
config.vi.mode = ConfigGetParamInt(configVideoAngrylionPlus, KEY_VI_MODE);
|
||||
config.vi.interp = ConfigGetParamInt(configVideoAngrylionPlus, KEY_VI_INTERP);
|
||||
config.vi.widescreen = ConfigGetParamBool(configVideoAngrylionPlus, KEY_VI_WIDESCREEN);
|
||||
config.vi.hide_overscan = ConfigGetParamBool(configVideoAngrylionPlus, KEY_VI_HIDE_OVERSCAN);
|
||||
|
||||
config.dp.compat = ConfigGetParamInt(configVideoAngrylionPlus, KEY_DP_COMPAT);
|
||||
|
||||
config.gfx.rdram = gfx.RDRAM;
|
||||
|
||||
int core_version;
|
||||
CoreGetVersion(NULL, &core_version, NULL, NULL, NULL);
|
||||
if (core_version >= 0x020501) {
|
||||
config.gfx.rdram_size = *gfx.RDRAM_SIZE;
|
||||
} else {
|
||||
config.gfx.rdram_size = RDRAM_MAX_SIZE;
|
||||
}
|
||||
|
||||
config.gfx.dmem = gfx.DMEM;
|
||||
config.gfx.mi_intr_reg = (uint32_t*)gfx.MI_INTR_REG;
|
||||
config.gfx.mi_intr_cb = gfx.CheckInterrupts;
|
||||
|
||||
config.gfx.vi_reg = (uint32_t**)&gfx.VI_STATUS_REG;
|
||||
config.gfx.dp_reg = (uint32_t**)&gfx.DPC_START_REG;
|
||||
|
||||
n64video_init(&config);
|
||||
vdac_init(&config);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT void CALL RomClosed (void)
|
||||
{
|
||||
vdac_close();
|
||||
n64video_close();
|
||||
}
|
||||
|
||||
EXPORT void CALL ShowCFB (void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL UpdateScreen (void)
|
||||
{
|
||||
struct n64video_frame_buffer fb;
|
||||
n64video_update_screen(&fb);
|
||||
|
||||
if (fb.valid) {
|
||||
vdac_write(&fb);
|
||||
}
|
||||
|
||||
vdac_sync(fb.valid);
|
||||
}
|
||||
|
||||
EXPORT void CALL ViStatusChanged (void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL ViWidthChanged (void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL ChangeWindow(void)
|
||||
{
|
||||
screen_toggle_fullscreen();
|
||||
}
|
||||
|
||||
EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front)
|
||||
{
|
||||
UNUSED(front);
|
||||
|
||||
struct n64video_frame_buffer fb = { 0 };
|
||||
fb.pixels = dest;
|
||||
vdac_read(&fb, false);
|
||||
|
||||
*width = fb.width;
|
||||
*height = fb.height;
|
||||
}
|
||||
|
||||
EXPORT void CALL SetRenderingCallback(void (*callback)(int))
|
||||
{
|
||||
render_callback = callback;
|
||||
}
|
||||
|
||||
EXPORT void CALL ResizeVideoOutput(int width, int height)
|
||||
{
|
||||
win_width = width;
|
||||
win_height = height;
|
||||
}
|
||||
|
||||
EXPORT void CALL FBWrite(unsigned int addr, unsigned int size)
|
||||
{
|
||||
UNUSED(addr);
|
||||
UNUSED(size);
|
||||
}
|
||||
|
||||
EXPORT void CALL FBRead(unsigned int addr)
|
||||
{
|
||||
UNUSED(addr);
|
||||
}
|
||||
|
||||
EXPORT void CALL FBGetFrameBufferInfo(void *pinfo)
|
||||
{
|
||||
UNUSED(pinfo);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/n64video.h"
|
||||
#include "api/m64p_plugin.h"
|
||||
#include "api/m64p_common.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DLSYM(a, b) GetProcAddress(a, b)
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#define DLSYM(a, b) dlsym(a, b)
|
||||
#endif
|
||||
|
||||
extern GFX_INFO gfx;
|
||||
extern m64p_dynlib_handle CoreLibHandle;
|
||||
extern void(*render_callback)(int);
|
||||
extern void (*debug_callback)(void *, int, const char *);
|
||||
extern void *debug_call_context;
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "core/msg.h"
|
||||
#include "core/version.h"
|
||||
#include "gfx_m64p.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MSG_BUFFER_LEN 256
|
||||
|
||||
void msg_error(const char * err, ...)
|
||||
{
|
||||
if (debug_callback == NULL)
|
||||
return;
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, err);
|
||||
char buf[MSG_BUFFER_LEN];
|
||||
vsprintf(buf, err, arg);
|
||||
|
||||
(*debug_callback)(debug_call_context, M64MSG_ERROR, buf);
|
||||
|
||||
va_end(arg);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void msg_warning(const char* err, ...)
|
||||
{
|
||||
if (debug_callback == NULL)
|
||||
return;
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, err);
|
||||
char buf[MSG_BUFFER_LEN];
|
||||
vsprintf(buf, err, arg);
|
||||
|
||||
(*debug_callback)(debug_call_context, M64MSG_WARNING, buf);
|
||||
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
void msg_debug(const char* err, ...)
|
||||
{
|
||||
if (debug_callback == NULL)
|
||||
return;
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, err);
|
||||
char buf[MSG_BUFFER_LEN];
|
||||
vsprintf(buf, err, arg);
|
||||
|
||||
(*debug_callback)(debug_call_context, M64MSG_VERBOSE, buf);
|
||||
|
||||
va_end(arg);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "gfx_m64p.h"
|
||||
#include "api/m64p_vidext.h"
|
||||
|
||||
#include "core/common.h"
|
||||
#include "core/msg.h"
|
||||
|
||||
#include "output/screen.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* definitions of pointers to Core video extension functions */
|
||||
static ptr_VidExt_Init CoreVideo_Init = NULL;
|
||||
static ptr_VidExt_Quit CoreVideo_Quit = NULL;
|
||||
static ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes = NULL;
|
||||
static ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode = NULL;
|
||||
static ptr_VidExt_SetCaption CoreVideo_SetCaption = NULL;
|
||||
static ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen = NULL;
|
||||
static ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow = NULL;
|
||||
static ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress = NULL;
|
||||
static ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute = NULL;
|
||||
static ptr_VidExt_GL_GetAttribute CoreVideo_GL_GetAttribute = NULL;
|
||||
static ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers = NULL;
|
||||
|
||||
// framebuffer texture states
|
||||
int32_t win_width;
|
||||
int32_t win_height;
|
||||
int32_t win_fullscreen;
|
||||
|
||||
void* IntGetProcAddress(const char *name)
|
||||
{
|
||||
return CoreVideo_GL_GetProcAddress(name);
|
||||
}
|
||||
|
||||
void screen_init(struct n64video_config* config)
|
||||
{
|
||||
UNUSED(config);
|
||||
|
||||
/* Get the core Video Extension function pointers from the library handle */
|
||||
CoreVideo_Init = (ptr_VidExt_Init) DLSYM(CoreLibHandle, "VidExt_Init");
|
||||
CoreVideo_Quit = (ptr_VidExt_Quit) DLSYM(CoreLibHandle, "VidExt_Quit");
|
||||
CoreVideo_ListFullscreenModes = (ptr_VidExt_ListFullscreenModes) DLSYM(CoreLibHandle, "VidExt_ListFullscreenModes");
|
||||
CoreVideo_SetVideoMode = (ptr_VidExt_SetVideoMode) DLSYM(CoreLibHandle, "VidExt_SetVideoMode");
|
||||
CoreVideo_SetCaption = (ptr_VidExt_SetCaption) DLSYM(CoreLibHandle, "VidExt_SetCaption");
|
||||
CoreVideo_ToggleFullScreen = (ptr_VidExt_ToggleFullScreen) DLSYM(CoreLibHandle, "VidExt_ToggleFullScreen");
|
||||
CoreVideo_ResizeWindow = (ptr_VidExt_ResizeWindow) DLSYM(CoreLibHandle, "VidExt_ResizeWindow");
|
||||
CoreVideo_GL_GetProcAddress = (ptr_VidExt_GL_GetProcAddress) DLSYM(CoreLibHandle, "VidExt_GL_GetProcAddress");
|
||||
CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) DLSYM(CoreLibHandle, "VidExt_GL_SetAttribute");
|
||||
CoreVideo_GL_GetAttribute = (ptr_VidExt_GL_GetAttribute) DLSYM(CoreLibHandle, "VidExt_GL_GetAttribute");
|
||||
CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) DLSYM(CoreLibHandle, "VidExt_GL_SwapBuffers");
|
||||
|
||||
CoreVideo_Init();
|
||||
|
||||
#ifndef GLES
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_PROFILE_MASK, M64P_GL_CONTEXT_PROFILE_CORE);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
#else
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_PROFILE_MASK, M64P_GL_CONTEXT_PROFILE_ES);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
#endif
|
||||
|
||||
CoreVideo_SetVideoMode(win_width, win_height, 0, win_fullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, M64VIDEOFLAG_SUPPORT_RESIZING);
|
||||
}
|
||||
|
||||
void screen_adjust(int32_t width_out, int32_t height_out, int32_t* width, int32_t* height, int32_t* x, int32_t* y)
|
||||
{
|
||||
UNUSED(width_out);
|
||||
UNUSED(height_out);
|
||||
|
||||
*width = win_width;
|
||||
*height = win_height;
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
}
|
||||
|
||||
void screen_update(void)
|
||||
{
|
||||
(*render_callback)(1);
|
||||
CoreVideo_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
void screen_toggle_fullscreen(void)
|
||||
{
|
||||
CoreVideo_ToggleFullScreen();
|
||||
}
|
||||
|
||||
void screen_close(void)
|
||||
{
|
||||
CoreVideo_Quit();
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
#include "config.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "core/common.h"
|
||||
#include "core/version.h"
|
||||
#include "core/n64video.h"
|
||||
#include "output/screen.h"
|
||||
#include "output/vdac.h"
|
||||
|
||||
#include <Commctrl.h>
|
||||
#include <Shlwapi.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SECTION_GENERAL "General"
|
||||
#define SECTION_VIDEO_INTERFACE "VideoInterface"
|
||||
#define SECTION_DISPLAY_PROCESSOR "DisplayProcessor"
|
||||
|
||||
#define KEY_GEN_PARALLEL "parallel"
|
||||
#define KEY_GEN_NUM_WORKERS "num_workers"
|
||||
|
||||
#define KEY_VI_MODE "mode"
|
||||
#define KEY_VI_INTERP "interpolation"
|
||||
#define KEY_VI_WIDESCREEN "widescreen"
|
||||
#define KEY_VI_HIDE_OVERSCAN "hide_overscan"
|
||||
#define KEY_VI_EXCLUSIVE "exclusive"
|
||||
#define KEY_VI_VSYNC "vsync"
|
||||
|
||||
#define KEY_DP_COMPAT "compat"
|
||||
|
||||
#define CONFIG_FILE_NAME CORE_SIMPLE_NAME "-config.ini"
|
||||
|
||||
#define CONFIG_DLG_INIT_CHECKBOX(id, var, config) \
|
||||
var = GetDlgItem(hwnd, id); \
|
||||
SendMessage(var, BM_SETCHECK, (WPARAM)config, 0);
|
||||
|
||||
static HINSTANCE inst;
|
||||
static struct n64video_config config;
|
||||
static bool config_stale;
|
||||
static char config_path[MAX_PATH + 1];
|
||||
|
||||
static HWND dlg_combo_vi_mode;
|
||||
static HWND dlg_combo_vi_interp;
|
||||
static HWND dlg_check_trace;
|
||||
static HWND dlg_check_multithread;
|
||||
static HWND dlg_check_vi_widescreen;
|
||||
static HWND dlg_check_vi_overscan;
|
||||
static HWND dlg_check_vi_exclusive;
|
||||
static HWND dlg_check_vi_vsync;
|
||||
static HWND dlg_combo_dp_compat;
|
||||
static HWND dlg_spin_workers;
|
||||
static HWND dlg_edit_workers;
|
||||
|
||||
static void config_dialog_update_multithread(void)
|
||||
{
|
||||
BOOL check = (BOOL)SendMessage(dlg_check_multithread, BM_GETCHECK, 0, 0);
|
||||
EnableWindow(dlg_spin_workers, check);
|
||||
EnableWindow(dlg_edit_workers, check);
|
||||
EnableWindow(dlg_combo_dp_compat, check);
|
||||
}
|
||||
|
||||
static void config_dialog_update_vi_mode(void)
|
||||
{
|
||||
LRESULT sel = SendMessage(dlg_combo_vi_mode, CB_GETCURSEL, 0, 0);
|
||||
EnableWindow(dlg_check_vi_overscan, sel == VI_MODE_NORMAL);
|
||||
}
|
||||
|
||||
static void config_dialog_fill_combo(HWND dialog, char** entries, size_t num_entries, uint32_t selected)
|
||||
{
|
||||
SendMessage(dialog, CB_RESETCONTENT, 0, 0);
|
||||
for (size_t i = 0; i < num_entries; i++) {
|
||||
SendMessage(dialog, CB_ADDSTRING, i, (LPARAM)entries[i]);
|
||||
}
|
||||
SendMessage(dialog, CB_SETCURSEL, (WPARAM)selected, 0);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK config_dialog_proc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
UNUSED(lParam);
|
||||
|
||||
switch (iMessage) {
|
||||
case WM_INITDIALOG: {
|
||||
SetWindowText(hwnd, CORE_BASE_NAME " Config");
|
||||
|
||||
config_load();
|
||||
|
||||
char* vi_mode_strings[] = {
|
||||
"Filtered", // VI_MODE_NORMAL
|
||||
"Unfiltered", // VI_MODE_COLOR
|
||||
"Depth", // VI_MODE_DEPTH
|
||||
"Coverage" // VI_MODE_COVERAGE
|
||||
};
|
||||
|
||||
dlg_combo_vi_mode = GetDlgItem(hwnd, IDC_COMBO_VI_MODE);
|
||||
config_dialog_fill_combo(dlg_combo_vi_mode, vi_mode_strings, VI_MODE_NUM, config.vi.mode);
|
||||
|
||||
char* vi_interp_strings[] = {
|
||||
"Nearest-neighbor", // VI_INTERP_NEAREST
|
||||
"Linear" // VI_INTERP_LINEAR
|
||||
};
|
||||
|
||||
dlg_combo_vi_interp = GetDlgItem(hwnd, IDC_COMBO_VI_INTERP);
|
||||
config_dialog_fill_combo(dlg_combo_vi_interp, vi_interp_strings, VI_INTERP_NUM, config.vi.interp);
|
||||
|
||||
char* dp_compat_strings[] = {
|
||||
"Fast, most glitches", // DP_COMPAT_LOW
|
||||
"Moderate, some glitches", // DP_COMPAT_MEDIUM
|
||||
"Slow, few glitches" // DP_COMPAT_HIGH
|
||||
};
|
||||
|
||||
dlg_combo_dp_compat = GetDlgItem(hwnd, IDC_COMBO_DP_COMPAT);
|
||||
config_dialog_fill_combo(dlg_combo_dp_compat, dp_compat_strings, DP_COMPAT_NUM, config.dp.compat);
|
||||
|
||||
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_MULTITHREAD, dlg_check_multithread, config.parallel);
|
||||
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_WIDESCREEN, dlg_check_vi_widescreen, config.vi.widescreen);
|
||||
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_OVERSCAN, dlg_check_vi_overscan, config.vi.hide_overscan);
|
||||
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_EXCLUSIVE, dlg_check_vi_exclusive, config.vi.exclusive);
|
||||
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_VSYNC, dlg_check_vi_vsync, config.vi.vsync);
|
||||
|
||||
dlg_edit_workers = GetDlgItem(hwnd, IDC_EDIT_WORKERS);
|
||||
SetDlgItemInt(hwnd, IDC_EDIT_WORKERS, config.num_workers, FALSE);
|
||||
|
||||
dlg_spin_workers = GetDlgItem(hwnd, IDC_SPIN_WORKERS);
|
||||
SendMessage(dlg_spin_workers, UDM_SETRANGE, 0, MAKELPARAM(128, 0));
|
||||
|
||||
// update enabled/disabled state
|
||||
config_dialog_update_multithread();
|
||||
config_dialog_update_vi_mode();
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_COMMAND: {
|
||||
WORD cmdid = LOWORD(wParam);
|
||||
switch (cmdid) {
|
||||
// disable or enable multithreading options when the checkbox is
|
||||
// checked or unchecked
|
||||
case IDC_CHECK_MULTITHREAD:
|
||||
config_dialog_update_multithread();
|
||||
break;
|
||||
|
||||
// disable overscan option if a non-compatible mode is selected
|
||||
case IDC_COMBO_VI_MODE:
|
||||
switch (HIWORD(wParam)) {
|
||||
case CBN_SELCHANGE:
|
||||
config_dialog_update_vi_mode();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// button events
|
||||
case IDOK:
|
||||
case IDAPPLY:
|
||||
config.vi.mode = SendMessage(dlg_combo_vi_mode, CB_GETCURSEL, 0, 0);
|
||||
config.vi.interp = SendMessage(dlg_combo_vi_interp, CB_GETCURSEL, 0, 0);
|
||||
config.vi.widescreen = SendMessage(dlg_check_vi_widescreen, BM_GETCHECK, 0, 0);
|
||||
config.vi.hide_overscan = SendMessage(dlg_check_vi_overscan, BM_GETCHECK, 0, 0);
|
||||
config.vi.exclusive = SendMessage(dlg_check_vi_exclusive, BM_GETCHECK, 0, 0);
|
||||
config.vi.vsync = SendMessage(dlg_check_vi_vsync, BM_GETCHECK, 0, 0);
|
||||
config.dp.compat = SendMessage(dlg_combo_dp_compat, CB_GETCURSEL, 0, 0);
|
||||
config.parallel = SendMessage(dlg_check_multithread, BM_GETCHECK, 0, 0);
|
||||
config.num_workers = GetDlgItemInt(hwnd, IDC_EDIT_WORKERS, FALSE, FALSE);
|
||||
config_stale = true;
|
||||
config_save();
|
||||
|
||||
// don't close dialog if "Apply" was pressed
|
||||
if (cmdid == IDAPPLY) {
|
||||
break;
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(hwnd, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void config_handle(const char* key, const char* value, const char* section)
|
||||
{
|
||||
if (!_strcmpi(section, SECTION_GENERAL)) {
|
||||
if (!_strcmpi(key, KEY_GEN_PARALLEL)) {
|
||||
config.parallel = strtol(value, NULL, 0) != 0;
|
||||
}
|
||||
if (!_strcmpi(key, KEY_GEN_NUM_WORKERS)) {
|
||||
config.num_workers = strtoul(value, NULL, 0);
|
||||
}
|
||||
} else if (!_strcmpi(section, SECTION_VIDEO_INTERFACE)) {
|
||||
if (!_strcmpi(key, KEY_VI_MODE)) {
|
||||
config.vi.mode = strtol(value, NULL, 0);
|
||||
} else if (!_strcmpi(key, KEY_VI_INTERP)) {
|
||||
config.vi.interp = strtol(value, NULL, 0);
|
||||
} else if (!_strcmpi(key, KEY_VI_WIDESCREEN)) {
|
||||
config.vi.widescreen = strtol(value, NULL, 0) != 0;
|
||||
} else if (!_strcmpi(key, KEY_VI_HIDE_OVERSCAN)) {
|
||||
config.vi.hide_overscan = strtol(value, NULL, 0) != 0;
|
||||
} else if (!_strcmpi(key, KEY_VI_EXCLUSIVE)) {
|
||||
config.vi.exclusive = strtol(value, NULL, 0) != 0;
|
||||
} else if (!_strcmpi(key, KEY_VI_VSYNC)) {
|
||||
config.vi.vsync = strtol(value, NULL, 0) != 0;
|
||||
}
|
||||
} else if (!_strcmpi(section, SECTION_DISPLAY_PROCESSOR)) {
|
||||
if (!_strcmpi(key, KEY_DP_COMPAT)) {
|
||||
config.dp.compat = strtol(value, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void config_init(HINSTANCE hInst)
|
||||
{
|
||||
inst = hInst;
|
||||
config_path[0] = 0;
|
||||
|
||||
// create path to config file relative to the DLL path
|
||||
GetModuleFileName(inst, config_path, sizeof(config_path));
|
||||
PathRemoveFileSpec(config_path);
|
||||
PathAppend(config_path, CONFIG_FILE_NAME);
|
||||
|
||||
// load default config
|
||||
n64video_config_init(&config);
|
||||
}
|
||||
|
||||
void config_dialog(HWND hParent)
|
||||
{
|
||||
DialogBox(inst, MAKEINTRESOURCE(IDD_DIALOG1), hParent, config_dialog_proc);
|
||||
}
|
||||
|
||||
struct n64video_config* config_get(void)
|
||||
{
|
||||
return &config;
|
||||
}
|
||||
|
||||
bool config_load()
|
||||
{
|
||||
FILE* fp = fopen(config_path, "r");
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char line[128];
|
||||
char section[128];
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
// remove newline characters
|
||||
size_t trim_pos = strcspn(line, "\r\n");
|
||||
line[trim_pos] = 0;
|
||||
|
||||
// ignore blank lines
|
||||
size_t len = strlen(line);
|
||||
if (!len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// key-values
|
||||
char* eq_ptr = strchr(line, '=');
|
||||
if (eq_ptr) {
|
||||
*eq_ptr = 0;
|
||||
char* key = line;
|
||||
char* value = eq_ptr + 1;
|
||||
config_handle(key, value, section);
|
||||
continue;
|
||||
}
|
||||
|
||||
// sections
|
||||
if (line[0] == '[' && line[len - 1] == ']') {
|
||||
section[0] = 0;
|
||||
strncat(section, line + 1, len - 2);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void config_write_section(FILE* fp, const char* section)
|
||||
{
|
||||
fprintf(fp, "[%s]\n", section);
|
||||
}
|
||||
|
||||
static void config_write_uint32(FILE* fp, const char* key, uint32_t value)
|
||||
{
|
||||
fprintf(fp, "%s=%u\n", key, value);
|
||||
}
|
||||
|
||||
static void config_write_int32(FILE* fp, const char* key, int32_t value)
|
||||
{
|
||||
fprintf(fp, "%s=%d\n", key, value);
|
||||
}
|
||||
|
||||
bool config_save(void)
|
||||
{
|
||||
FILE* fp = fopen(config_path, "w");
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
config_write_section(fp, SECTION_GENERAL);
|
||||
config_write_int32(fp, KEY_GEN_PARALLEL, config.parallel);
|
||||
config_write_uint32(fp, KEY_GEN_NUM_WORKERS, config.num_workers);
|
||||
fputs("\n", fp);
|
||||
|
||||
config_write_section(fp, SECTION_VIDEO_INTERFACE);
|
||||
config_write_int32(fp, KEY_VI_MODE, config.vi.mode);
|
||||
config_write_int32(fp, KEY_VI_INTERP, config.vi.interp);
|
||||
config_write_int32(fp, KEY_VI_WIDESCREEN, config.vi.widescreen);
|
||||
config_write_int32(fp, KEY_VI_HIDE_OVERSCAN, config.vi.hide_overscan);
|
||||
config_write_int32(fp, KEY_VI_EXCLUSIVE, config.vi.exclusive);
|
||||
config_write_int32(fp, KEY_VI_VSYNC, config.vi.vsync);
|
||||
fputs("\n", fp);
|
||||
|
||||
config_write_section(fp, SECTION_DISPLAY_PROCESSOR);
|
||||
config_write_int32(fp, KEY_DP_COMPAT, config.dp.compat);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void config_update(void)
|
||||
{
|
||||
if (config_stale) {
|
||||
vdac_close();
|
||||
screen_close();
|
||||
n64video_close();
|
||||
|
||||
n64video_init(&config);
|
||||
screen_init(&config);
|
||||
vdac_init(&config);
|
||||
|
||||
config_stale = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/n64video.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
void config_init(HINSTANCE hInst);
|
||||
void config_dialog(HWND hParent);
|
||||
struct n64video_config* config_get(void);
|
||||
bool config_load(void);
|
||||
bool config_save(void);
|
||||
void config_update(void);
|
||||
Binary file not shown.
@@ -0,0 +1,337 @@
|
||||
#include "gfx_1.3.h"
|
||||
#include "config.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "core/common.h"
|
||||
#include "core/n64video.h"
|
||||
#include "core/version.h"
|
||||
#include "core/msg.h"
|
||||
|
||||
#include "output/screen.h"
|
||||
#include "output/vdac.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
GFX_INFO gfx;
|
||||
static bool m_warn_hle;
|
||||
static char m_screenshot_path[MAX_PATH];
|
||||
|
||||
static bool is_valid_ptr(void *ptr, uint32_t bytes)
|
||||
{
|
||||
SIZE_T dwSize;
|
||||
MEMORY_BASIC_INFORMATION meminfo;
|
||||
if (!ptr) {
|
||||
return false;
|
||||
}
|
||||
memset(&meminfo, 0x00, sizeof(meminfo));
|
||||
dwSize = VirtualQuery(ptr, &meminfo, sizeof(meminfo));
|
||||
if (!dwSize) {
|
||||
return false;
|
||||
}
|
||||
if (MEM_COMMIT != meminfo.State) {
|
||||
return false;
|
||||
}
|
||||
if (!(meminfo.Protect & (PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY))) {
|
||||
return false;
|
||||
}
|
||||
if (bytes > meminfo.RegionSize) {
|
||||
return false;
|
||||
}
|
||||
if ((uint64_t)((char*)ptr - (char*)meminfo.BaseAddress) > (uint64_t)(meminfo.RegionSize - bytes)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static char filter_char(char c)
|
||||
{
|
||||
// only allow valid ASCII chars
|
||||
if (c & 0x80) {
|
||||
return ' ';
|
||||
}
|
||||
|
||||
// only allow certain ASCII chars
|
||||
if (!isalnum(c) && c != '_' && c != '-') {
|
||||
return ' ';
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static char* get_rom_name(void)
|
||||
{
|
||||
static char rom_name[128];
|
||||
|
||||
// copy game name from ROM header, which is encoded in Shift_JIS.
|
||||
// most games just use the ASCII subset, so filter out the rest.
|
||||
// TODO: convert Shift_JIS string to UTF-16 for Win32 API?
|
||||
int i = 0;
|
||||
for (; i < 20; i++) {
|
||||
rom_name[i] = filter_char(gfx.HEADER[(32 + i) ^ BYTE_ADDR_XOR]);
|
||||
}
|
||||
|
||||
// make sure there's at least one whitespace that will terminate the string
|
||||
// below
|
||||
rom_name[i] = ' ';
|
||||
|
||||
// trim trailing whitespaces
|
||||
for (; i > 0; i--) {
|
||||
if (rom_name[i] != ' ') {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
// game title is empty or invalid, use safe fallback using the
|
||||
// four-character game ID
|
||||
for (; i < 4; i++) {
|
||||
rom_name[i] = filter_char(gfx.HEADER[(59 + i) ^ BYTE_ADDR_XOR]);
|
||||
}
|
||||
}
|
||||
|
||||
// terminate string
|
||||
rom_name[i] = '\0';
|
||||
|
||||
return rom_name;
|
||||
}
|
||||
|
||||
static void mi_intr(void)
|
||||
{
|
||||
gfx.CheckInterrupts();
|
||||
config_update();
|
||||
}
|
||||
|
||||
static void write_screenshot(char* path)
|
||||
{
|
||||
struct n64video_frame_buffer fb = { 0 };
|
||||
vdac_read(&fb, true);
|
||||
|
||||
// prepare bitmap headers
|
||||
BITMAPINFOHEADER ihdr = {0};
|
||||
ihdr.biSize = sizeof(ihdr);
|
||||
ihdr.biWidth = fb.width;
|
||||
ihdr.biHeight = fb.height;
|
||||
ihdr.biPlanes = 1;
|
||||
ihdr.biBitCount = 32;
|
||||
ihdr.biSizeImage = fb.width * fb.height * sizeof(int32_t);
|
||||
|
||||
BITMAPFILEHEADER fhdr = {0};
|
||||
fhdr.bfType = 'B' | ('M' << 8);
|
||||
fhdr.bfOffBits = sizeof(fhdr) + sizeof(ihdr) + 10;
|
||||
fhdr.bfSize = ihdr.biSizeImage + fhdr.bfOffBits;
|
||||
|
||||
FILE* fp = fopen(path, "wb");
|
||||
|
||||
if (!fp) {
|
||||
msg_warning("Can't open screenshot file %s!", path);
|
||||
return;
|
||||
}
|
||||
|
||||
// write bitmap headers
|
||||
fwrite(&fhdr, sizeof(fhdr), 1, fp);
|
||||
fwrite(&ihdr, sizeof(ihdr), 1, fp);
|
||||
|
||||
// write bitmap contents
|
||||
fseek(fp, fhdr.bfOffBits, SEEK_SET);
|
||||
|
||||
fb.pixels = malloc(ihdr.biSizeImage);
|
||||
vdac_read(&fb, true);
|
||||
|
||||
// convert RGBA to BGRA
|
||||
for (uint32_t i = 0; i < fb.width * fb.height; i++) {
|
||||
struct n64video_pixel* pixel = &fb.pixels[i];
|
||||
uint8_t tmp = pixel->r;
|
||||
pixel->r = pixel->b;
|
||||
pixel->b = tmp;
|
||||
}
|
||||
|
||||
fwrite(fb.pixels, ihdr.biSizeImage, 1, fp);
|
||||
free(fb.pixels);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
UNUSED(lpvReserved);
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
config_init(hinstDLL);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
EXPORT void CALL CaptureScreen(char* directory)
|
||||
{
|
||||
char* rom_name = get_rom_name();
|
||||
|
||||
for (int32_t i = 0; i < 10000; i++) {
|
||||
sprintf(m_screenshot_path, "%s\\%s_%04d.bmp", directory, rom_name, i);
|
||||
DWORD dwAttrib = GetFileAttributes(m_screenshot_path);
|
||||
if (dwAttrib == INVALID_FILE_ATTRIBUTES || (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void CALL ChangeWindow(void)
|
||||
{
|
||||
screen_toggle_fullscreen();
|
||||
}
|
||||
|
||||
EXPORT void CALL CloseDLL(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL DllAbout(HWND hParent)
|
||||
{
|
||||
UNUSED(hParent);
|
||||
|
||||
msg_warning(
|
||||
CORE_NAME "\n\n"
|
||||
"Branch: " GIT_BRANCH "\n"
|
||||
"Commit hash: " GIT_COMMIT_HASH "\n"
|
||||
"Commit date: " GIT_COMMIT_DATE "\n"
|
||||
"Build date: " __DATE__ " " __TIME__ "\n\n"
|
||||
"https://github.com/ata4/angrylion-rdp-plus"
|
||||
);
|
||||
}
|
||||
|
||||
EXPORT void CALL DllConfig(HWND hParent)
|
||||
{
|
||||
config_dialog(hParent);
|
||||
}
|
||||
|
||||
EXPORT void CALL ReadScreen(void **dest, long *width, long *height)
|
||||
{
|
||||
UNUSED(dest);
|
||||
UNUSED(width);
|
||||
UNUSED(height);
|
||||
}
|
||||
|
||||
EXPORT void CALL DrawScreen(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL GetDllInfo(PLUGIN_INFO* PluginInfo)
|
||||
{
|
||||
PluginInfo->Version = 0x0103;
|
||||
PluginInfo->Type = PLUGIN_TYPE_GFX;
|
||||
sprintf(PluginInfo->Name, CORE_NAME);
|
||||
|
||||
PluginInfo->NormalMemory = TRUE;
|
||||
PluginInfo->MemoryBswaped = TRUE;
|
||||
}
|
||||
|
||||
EXPORT BOOL CALL InitiateGFX(GFX_INFO Gfx_Info)
|
||||
{
|
||||
gfx = Gfx_Info;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
EXPORT void CALL MoveScreen(int xpos, int ypos)
|
||||
{
|
||||
UNUSED(xpos);
|
||||
UNUSED(ypos);
|
||||
}
|
||||
|
||||
EXPORT void CALL ProcessDList(void)
|
||||
{
|
||||
if (!m_warn_hle) {
|
||||
msg_warning("Please disable 'Graphic HLE' in the plugin settings.");
|
||||
m_warn_hle = true;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void CALL ProcessRDPList(void)
|
||||
{
|
||||
n64video_process_list();
|
||||
}
|
||||
|
||||
EXPORT void CALL RomClosed(void)
|
||||
{
|
||||
vdac_close();
|
||||
n64video_close();
|
||||
}
|
||||
|
||||
EXPORT void CALL RomOpen(void)
|
||||
{
|
||||
config_load();
|
||||
struct n64video_config* config = config_get();
|
||||
|
||||
config->gfx.rdram = gfx.RDRAM;
|
||||
config->gfx.rdram_size = RDRAM_MAX_SIZE;
|
||||
|
||||
// Zilmar's API doesn't provide a way to check the amount of RDRAM available.
|
||||
// It can only be 4 MiB or 8 MiB, so check if the last 16 bytes of the provided
|
||||
// buffer in the 8 MiB range are valid. If not, it must be 4 MiB.
|
||||
if (!is_valid_ptr(&gfx.RDRAM[0x7f0000], 16)) {
|
||||
config->gfx.rdram_size /= 2;
|
||||
}
|
||||
|
||||
config->gfx.dmem = gfx.DMEM;
|
||||
config->gfx.mi_intr_reg = (uint32_t*)gfx.MI_INTR_REG;
|
||||
config->gfx.mi_intr_cb = mi_intr;
|
||||
|
||||
config->gfx.vi_reg = (uint32_t**)&gfx.VI_STATUS_REG;
|
||||
config->gfx.dp_reg = (uint32_t**)&gfx.DPC_START_REG;
|
||||
|
||||
n64video_init(config);
|
||||
vdac_init(config);
|
||||
}
|
||||
|
||||
EXPORT void CALL ShowCFB(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL UpdateScreen(void)
|
||||
{
|
||||
struct n64video_frame_buffer fb;
|
||||
n64video_update_screen(&fb);
|
||||
|
||||
if (fb.valid) {
|
||||
vdac_write(&fb);
|
||||
}
|
||||
|
||||
vdac_sync(fb.valid);
|
||||
|
||||
// write screenshot file if requested
|
||||
if (m_screenshot_path[0]) {
|
||||
write_screenshot(m_screenshot_path);
|
||||
m_screenshot_path[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void CALL ViStatusChanged(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL ViWidthChanged(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL FBWrite(DWORD addr, DWORD val)
|
||||
{
|
||||
UNUSED(addr);
|
||||
UNUSED(val);
|
||||
}
|
||||
|
||||
EXPORT void CALL FBWList(FrameBufferModifyEntry *plist, DWORD size)
|
||||
{
|
||||
UNUSED(plist);
|
||||
UNUSED(size);
|
||||
}
|
||||
|
||||
EXPORT void CALL FBRead(DWORD addr)
|
||||
{
|
||||
UNUSED(addr);
|
||||
}
|
||||
|
||||
EXPORT void CALL FBGetFrameBufferInfo(void *pinfo)
|
||||
{
|
||||
UNUSED(pinfo);
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
/**********************************************************************************
|
||||
Common gfx plugin spec, version #1.3 maintained by zilmar (zilmar@emulation64.com)
|
||||
|
||||
All questions or suggestions should go through the mailing list.
|
||||
http://www.egroups.com/group/Plugin64-Dev
|
||||
***********************************************************************************
|
||||
|
||||
Notes:
|
||||
------
|
||||
|
||||
Setting the approprate bits in the MI_INTR_REG and calling CheckInterrupts which
|
||||
are both passed to the DLL in InitiateGFX will generate an Interrupt from with in
|
||||
the plugin.
|
||||
|
||||
The Setting of the RSP flags and generating an SP interrupt should not be done in
|
||||
the plugin
|
||||
|
||||
**********************************************************************************/
|
||||
#ifndef _GFX_H_INCLUDED__
|
||||
#define _GFX_H_INCLUDED__
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Plugin types */
|
||||
#define PLUGIN_TYPE_GFX 2
|
||||
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#define CALL _cdecl
|
||||
|
||||
/***** Structures *****/
|
||||
typedef struct {
|
||||
WORD Version; /* Set to 0x0103 */
|
||||
WORD Type; /* Set to PLUGIN_TYPE_GFX */
|
||||
char Name[100]; /* Name of the DLL */
|
||||
|
||||
/* If DLL supports memory these memory options then set them to TRUE or FALSE
|
||||
if it does not support it */
|
||||
BOOL NormalMemory; /* a normal BYTE array */
|
||||
BOOL MemoryBswaped; /* a normal BYTE array where the memory has been pre
|
||||
bswap on a dword (32 bits) boundry */
|
||||
} PLUGIN_INFO;
|
||||
|
||||
typedef struct {
|
||||
HWND hWnd; /* Render window */
|
||||
HWND hStatusBar; /* if render window does not have a status bar then this is NULL */
|
||||
|
||||
BOOL MemoryBswaped; // If this is set to TRUE, then the memory has been pre
|
||||
// bswap on a dword (32 bits) boundry
|
||||
// eg. the first 8 bytes are stored like this:
|
||||
// 4 3 2 1 8 7 6 5
|
||||
|
||||
BYTE * HEADER; // This is the rom header (first 40h bytes of the rom
|
||||
// This will be in the same memory format as the rest of the memory.
|
||||
BYTE * RDRAM;
|
||||
BYTE * DMEM;
|
||||
BYTE * IMEM;
|
||||
|
||||
DWORD * MI_INTR_REG;
|
||||
|
||||
DWORD * DPC_START_REG;
|
||||
DWORD * DPC_END_REG;
|
||||
DWORD * DPC_CURRENT_REG;
|
||||
DWORD * DPC_STATUS_REG;
|
||||
DWORD * DPC_CLOCK_REG;
|
||||
DWORD * DPC_BUFBUSY_REG;
|
||||
DWORD * DPC_PIPEBUSY_REG;
|
||||
DWORD * DPC_TMEM_REG;
|
||||
|
||||
DWORD * VI_STATUS_REG;
|
||||
DWORD * VI_ORIGIN_REG;
|
||||
DWORD * VI_WIDTH_REG;
|
||||
DWORD * VI_INTR_REG;
|
||||
DWORD * VI_V_CURRENT_LINE_REG;
|
||||
DWORD * VI_TIMING_REG;
|
||||
DWORD * VI_V_SYNC_REG;
|
||||
DWORD * VI_H_SYNC_REG;
|
||||
DWORD * VI_LEAP_REG;
|
||||
DWORD * VI_H_START_REG;
|
||||
DWORD * VI_V_START_REG;
|
||||
DWORD * VI_V_BURST_REG;
|
||||
DWORD * VI_X_SCALE_REG;
|
||||
DWORD * VI_Y_SCALE_REG;
|
||||
|
||||
void (*CheckInterrupts)( void );
|
||||
} GFX_INFO;
|
||||
|
||||
/******************************************************************
|
||||
Function: CaptureScreen
|
||||
Purpose: This function dumps the current frame to a file
|
||||
input: pointer to the directory to save the file to
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL CaptureScreen ( char * Directory );
|
||||
|
||||
/******************************************************************
|
||||
Function: ChangeWindow
|
||||
Purpose: to change the window between fullscreen and window
|
||||
mode. If the window was in fullscreen this should
|
||||
change the screen to window mode and vice vesa.
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL ChangeWindow (void);
|
||||
|
||||
/******************************************************************
|
||||
Function: CloseDLL
|
||||
Purpose: This function is called when the emulator is closing
|
||||
down allowing the dll to de-initialise.
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL CloseDLL (void);
|
||||
|
||||
/******************************************************************
|
||||
Function: DllAbout
|
||||
Purpose: This function is optional function that is provided
|
||||
to give further information about the DLL.
|
||||
input: a handle to the window that calls this function
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL DllAbout ( HWND hParent );
|
||||
|
||||
/******************************************************************
|
||||
Function: DllConfig
|
||||
Purpose: This function is optional function that is provided
|
||||
to allow the user to configure the dll
|
||||
input: a handle to the window that calls this function
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL DllConfig ( HWND hParent );
|
||||
|
||||
/******************************************************************
|
||||
Function: DllTest
|
||||
Purpose: This function is optional function that is provided
|
||||
to allow the user to test the dll
|
||||
input: a handle to the window that calls this function
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL DllTest ( HWND hParent );
|
||||
|
||||
|
||||
EXPORT void CALL ReadScreen(void **dest, long *width, long *height);
|
||||
|
||||
/******************************************************************
|
||||
Function: DrawScreen
|
||||
Purpose: This function is called when the emulator receives a
|
||||
WM_PAINT message. This allows the gfx to fit in when
|
||||
it is being used in the desktop.
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL DrawScreen (void);
|
||||
|
||||
/******************************************************************
|
||||
Function: GetDllInfo
|
||||
Purpose: This function allows the emulator to gather information
|
||||
about the dll by filling in the PluginInfo structure.
|
||||
input: a pointer to a PLUGIN_INFO stucture that needs to be
|
||||
filled by the function. (see def above)
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo );
|
||||
|
||||
/******************************************************************
|
||||
Function: InitiateGFX
|
||||
Purpose: This function is called when the DLL is started to give
|
||||
information from the emulator that the n64 graphics
|
||||
uses. This is not called from the emulation thread.
|
||||
Input: Gfx_Info is passed to this function which is defined
|
||||
above.
|
||||
Output: TRUE on success
|
||||
FALSE on failure to initialise
|
||||
|
||||
** note on interrupts **:
|
||||
To generate an interrupt set the appropriate bit in MI_INTR_REG
|
||||
and then call the function CheckInterrupts to tell the emulator
|
||||
that there is a waiting interrupt.
|
||||
*******************************************************************/
|
||||
EXPORT BOOL CALL InitiateGFX (GFX_INFO Gfx_Info);
|
||||
|
||||
/******************************************************************
|
||||
Function: MoveScreen
|
||||
Purpose: This function is called in response to the emulator
|
||||
receiving a WM_MOVE passing the xpos and ypos passed
|
||||
from that message.
|
||||
input: xpos - the x-coordinate of the upper-left corner of the
|
||||
client area of the window.
|
||||
ypos - y-coordinate of the upper-left corner of the
|
||||
client area of the window.
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL MoveScreen (int xpos, int ypos);
|
||||
|
||||
/******************************************************************
|
||||
Function: ProcessDList
|
||||
Purpose: This function is called when there is a Dlist to be
|
||||
processed. (High level GFX list)
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL ProcessDList(void);
|
||||
|
||||
/******************************************************************
|
||||
Function: ProcessRDPList
|
||||
Purpose: This function is called when there is a Dlist to be
|
||||
processed. (Low level GFX list)
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL ProcessRDPList(void);
|
||||
|
||||
/******************************************************************
|
||||
Function: RomClosed
|
||||
Purpose: This function is called when a rom is closed.
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL RomClosed (void);
|
||||
|
||||
/******************************************************************
|
||||
Function: RomOpen
|
||||
Purpose: This function is called when a rom is open. (from the
|
||||
emulation thread)
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL RomOpen (void);
|
||||
|
||||
/******************************************************************
|
||||
Function: ShowCFB
|
||||
Purpose: Useally once Dlists are started being displayed, cfb is
|
||||
ignored. This function tells the dll to start displaying
|
||||
them again.
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL ShowCFB (void);
|
||||
|
||||
/******************************************************************
|
||||
Function: UpdateScreen
|
||||
Purpose: This function is called in response to a vsync of the
|
||||
screen were the VI bit in MI_INTR_REG has already been
|
||||
set
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL UpdateScreen (void);
|
||||
|
||||
/******************************************************************
|
||||
Function: ViStatusChanged
|
||||
Purpose: This function is called to notify the dll that the
|
||||
ViStatus registers value has been changed.
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL ViStatusChanged (void);
|
||||
|
||||
/******************************************************************
|
||||
Function: ViWidthChanged
|
||||
Purpose: This function is called to notify the dll that the
|
||||
ViWidth registers value has been changed.
|
||||
input: none
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL ViWidthChanged (void);
|
||||
|
||||
|
||||
/******************************************************************
|
||||
Function: FrameBufferWrite
|
||||
Purpose: This function is called to notify the dll that the
|
||||
frame buffer has been modified by CPU at the given address.
|
||||
input: addr rdram address
|
||||
val val
|
||||
size 1 = BYTE, 2 = WORD, 4 = DWORD
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL FBWrite(DWORD, DWORD);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD addr;
|
||||
DWORD val;
|
||||
DWORD size; // 1 = BYTE, 2 = WORD, 4=DWORD
|
||||
} FrameBufferModifyEntry;
|
||||
|
||||
/******************************************************************
|
||||
Function: FrameBufferWriteList
|
||||
Purpose: This function is called to notify the dll that the
|
||||
frame buffer has been modified by CPU at the given address.
|
||||
input: FrameBufferModifyEntry *plist
|
||||
size = size of the plist, max = 1024
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL FBWList(FrameBufferModifyEntry *plist, DWORD size);
|
||||
|
||||
/******************************************************************
|
||||
Function: FrameBufferRead
|
||||
Purpose: This function is called to notify the dll that the
|
||||
frame buffer memory is beening read at the given address.
|
||||
DLL should copy content from its render buffer to the frame buffer
|
||||
in N64 RDRAM
|
||||
DLL is responsible to maintain its own frame buffer memory addr list
|
||||
DLL should copy 4KB block content back to RDRAM frame buffer.
|
||||
Emulator should not call this function again if other memory
|
||||
is read within the same 4KB range
|
||||
input: addr rdram address
|
||||
val val
|
||||
size 1 = BYTE, 2 = WORD, 4 = DWORD
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL FBRead(DWORD addr);
|
||||
|
||||
/************************************************************************
|
||||
Function: FBGetFrameBufferInfo
|
||||
Purpose: This function is called by the emulator core to retrieve depth
|
||||
buffer information from the video plugin in order to be able
|
||||
to notify the video plugin about CPU depth buffer read/write
|
||||
operations
|
||||
|
||||
size:
|
||||
= 1 byte
|
||||
= 2 word (16 bit) <-- this is N64 default depth buffer format
|
||||
= 4 dword (32 bit)
|
||||
|
||||
when depth buffer information is not available yet, set all values
|
||||
in the FrameBufferInfo structure to 0
|
||||
|
||||
input: FrameBufferInfo *pinfo
|
||||
pinfo is pointed to a FrameBufferInfo structure which to be
|
||||
filled in by this function
|
||||
output: Values are return in the FrameBufferInfo structure
|
||||
************************************************************************/
|
||||
EXPORT void CALL FBGetFrameBufferInfo(void *pinfo);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif //_GFX_H_INCLUDED__
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "core/msg.h"
|
||||
#include "core/version.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define MSG_BUFFER_LEN 256
|
||||
|
||||
void msg_error(const char * err, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, err);
|
||||
char buf[MSG_BUFFER_LEN];
|
||||
vsprintf_s(buf, sizeof(buf), err, arg);
|
||||
MessageBoxA(0, buf, CORE_SIMPLE_NAME ": fatal error", MB_OK);
|
||||
va_end(arg);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void msg_warning(const char* err, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, err);
|
||||
char buf[MSG_BUFFER_LEN];
|
||||
vsprintf_s(buf, sizeof(buf), err, arg);
|
||||
MessageBoxA(0, buf, CORE_SIMPLE_NAME ": warning", MB_OK);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
void msg_debug(const char* err, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, err);
|
||||
char buf[MSG_BUFFER_LEN];
|
||||
vsprintf_s(buf, sizeof(buf), err, arg);
|
||||
strcat_s(buf, sizeof(buf), "\n");
|
||||
OutputDebugStringA(buf);
|
||||
va_end(arg);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,305 @@
|
||||
#include "gfx_1.3.h"
|
||||
|
||||
#include "wgl_ext.h"
|
||||
|
||||
#include "output/screen.h"
|
||||
#include "output/gl_proc.h"
|
||||
#include "core/common.h"
|
||||
#include "core/msg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern GFX_INFO gfx;
|
||||
|
||||
// default size of the window
|
||||
#define WINDOW_DEFAULT_WIDTH 640
|
||||
#define WINDOW_DEFAULT_HEIGHT 480
|
||||
|
||||
// previous size of the window
|
||||
static int32_t m_win_width;
|
||||
static int32_t m_win_height;
|
||||
|
||||
// context states
|
||||
static HDC m_dc;
|
||||
static HGLRC m_glrc;
|
||||
static HGLRC m_glrc_core;
|
||||
static bool m_fullscreen;
|
||||
|
||||
// config states
|
||||
static bool m_exclusive;
|
||||
|
||||
// Win32 helpers
|
||||
void win32_client_resize(HWND hWnd, HWND hStatus, int32_t nWidth, int32_t nHeight)
|
||||
{
|
||||
RECT rclient;
|
||||
if (!GetClientRect(hWnd, &rclient)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RECT rwin;
|
||||
if (!GetWindowRect(hWnd, &rwin)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RECT rstatus;
|
||||
if (hStatus && GetClientRect(hStatus, &rstatus)) {
|
||||
rclient.bottom -= rstatus.bottom;
|
||||
}
|
||||
|
||||
POINT pdiff;
|
||||
pdiff.x = (rwin.right - rwin.left) - rclient.right;
|
||||
pdiff.y = (rwin.bottom - rwin.top) - rclient.bottom;
|
||||
|
||||
MoveWindow(hWnd, rwin.left, rwin.top, nWidth + pdiff.x, nHeight + pdiff.y, TRUE);
|
||||
}
|
||||
|
||||
static int TestPointer(const PROC pTest)
|
||||
{
|
||||
if (!pTest) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptrdiff_t iTest = (ptrdiff_t)pTest;
|
||||
|
||||
return iTest != 1 && iTest != 2 && iTest != 3 && iTest != -1;
|
||||
}
|
||||
|
||||
funcptr IntGetProcAddress(const char* name)
|
||||
{
|
||||
PROC pFunc = wglGetProcAddress((LPCSTR)name);
|
||||
if (TestPointer(pFunc)) {
|
||||
return (funcptr)pFunc;
|
||||
}
|
||||
HMODULE glMod = GetModuleHandleA("OpenGL32.dll");
|
||||
if (glMod == NULL) {
|
||||
return (funcptr)glMod;
|
||||
} else {
|
||||
return (funcptr)GetProcAddress(glMod, (LPCSTR)name);
|
||||
}
|
||||
}
|
||||
|
||||
void screen_init(struct n64video_config* config)
|
||||
{
|
||||
m_exclusive = config->vi.exclusive;
|
||||
|
||||
// reset windowed size state
|
||||
m_win_width = 0;
|
||||
m_win_height = 0;
|
||||
|
||||
// make window resizable for the user
|
||||
if (!m_fullscreen) {
|
||||
LONG style = GetWindowLong(gfx.hWnd, GWL_STYLE);
|
||||
|
||||
if ((style & (WS_SIZEBOX | WS_MAXIMIZEBOX)) == 0) {
|
||||
style |= WS_SIZEBOX | WS_MAXIMIZEBOX;
|
||||
SetWindowLong(gfx.hWnd, GWL_STYLE, style);
|
||||
|
||||
// Fix client size after changing the window style, otherwise the PJ64
|
||||
// menu will be displayed incorrectly.
|
||||
// For some reason, this needs to be called twice, probably because the
|
||||
// style set above isn't applied immediately.
|
||||
for (int i = 0; i < 2; i++) {
|
||||
win32_client_resize(gfx.hWnd, gfx.hStatusBar, WINDOW_DEFAULT_WIDTH, WINDOW_DEFAULT_HEIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PIXELFORMATDESCRIPTOR win_pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR), 1,
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
|
||||
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
|
||||
32, // Colordepth of the framebuffer.
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
24, // Number of bits for the depthbuffer
|
||||
8, // Number of bits for the stencilbuffer
|
||||
0, // Number of Aux buffers in the framebuffer.
|
||||
PFD_MAIN_PLANE, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
m_dc = GetDC(gfx.hWnd);
|
||||
if (!m_dc) {
|
||||
msg_error("Can't get device context.");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t win_pf = ChoosePixelFormat(m_dc, &win_pfd);
|
||||
if (!win_pf) {
|
||||
msg_error("Can't choose pixel format.");
|
||||
return;
|
||||
}
|
||||
SetPixelFormat(m_dc, win_pf, &win_pfd);
|
||||
|
||||
// create legacy context, required for wglGetProcAddress to work properly
|
||||
m_glrc = wglCreateContext(m_dc);
|
||||
if (!m_glrc || !wglMakeCurrent(m_dc, m_glrc)) {
|
||||
msg_error("Can't create OpenGL context.");
|
||||
return;
|
||||
}
|
||||
|
||||
// load wgl extension
|
||||
wgl_LoadFunctions(m_dc);
|
||||
|
||||
// attributes for a 3.3 core profile without all the legacy stuff
|
||||
GLint attribs[] = {
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0
|
||||
};
|
||||
|
||||
// create the actual context
|
||||
m_glrc_core = wglCreateContextAttribsARB(m_dc, m_glrc, attribs);
|
||||
if (!m_glrc_core || !wglMakeCurrent(m_dc, m_glrc_core)) {
|
||||
// rendering probably still works with the legacy context, so just send
|
||||
// a warning
|
||||
msg_warning("Can't create OpenGL 3.3 core context.");
|
||||
}
|
||||
|
||||
// enable or disable vsync
|
||||
wglSwapIntervalEXT(config->vi.vsync ? 1 : 0);
|
||||
}
|
||||
|
||||
void screen_adjust(int32_t width_out, int32_t height_out, int32_t* width, int32_t* height, int32_t* x, int32_t* y)
|
||||
{
|
||||
UNUSED(width_out);
|
||||
UNUSED(height_out);
|
||||
|
||||
// get size of window
|
||||
RECT rect;
|
||||
if (!GetClientRect(gfx.hWnd, &rect)) {
|
||||
// window handle invalid?
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// status bar covers the client area, so exclude it from calculation
|
||||
RECT statusrect;
|
||||
SetRectEmpty(&statusrect);
|
||||
|
||||
if (gfx.hStatusBar && GetClientRect(gfx.hStatusBar, &statusrect)) {
|
||||
rect.bottom -= statusrect.bottom;
|
||||
}
|
||||
|
||||
int32_t win_width = rect.right - rect.left;
|
||||
int32_t win_height = rect.bottom - rect.top;
|
||||
|
||||
// default to bottom left corner of the window above the status bar
|
||||
int32_t win_x = 0;
|
||||
int32_t win_y = statusrect.bottom;
|
||||
|
||||
// adjust windowed size after the output size has changed so that
|
||||
// the output remains pixel-perfect until the user changes the window size
|
||||
if (win_width != win_width || win_height != win_height) {
|
||||
int32_t win_width_tmp = win_width = win_width;
|
||||
int32_t win_height_tmp = win_height = win_height;
|
||||
|
||||
// double resolution for very small frame sizes, typically when
|
||||
// unfiltered option is enabled
|
||||
if (win_width_tmp <= 320) {
|
||||
win_width_tmp <<= 1;
|
||||
win_height_tmp <<= 1;
|
||||
}
|
||||
|
||||
WINDOWPLACEMENT wndpl = { 0 };
|
||||
GetWindowPlacement(gfx.hWnd, &wndpl);
|
||||
|
||||
// only fix size if windowed and not maximized
|
||||
if (!m_fullscreen && wndpl.showCmd != SW_MAXIMIZE) {
|
||||
win32_client_resize(gfx.hWnd, gfx.hStatusBar,
|
||||
win_width_tmp, win_height_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
*width = win_width;
|
||||
*height = win_height;
|
||||
*x = win_x;
|
||||
*y = win_y;
|
||||
}
|
||||
|
||||
void screen_update(void)
|
||||
{
|
||||
// don't render when the window is minimized
|
||||
if (!IsIconic(gfx.hWnd)) {
|
||||
// swap front and back buffers
|
||||
SwapBuffers(m_dc);
|
||||
}
|
||||
}
|
||||
|
||||
void screen_toggle_fullscreen(void)
|
||||
{
|
||||
static HMENU old_menu;
|
||||
static LONG old_style;
|
||||
static WINDOWPLACEMENT old_pos;
|
||||
|
||||
m_fullscreen = !m_fullscreen;
|
||||
|
||||
if (m_fullscreen) {
|
||||
// hide curser
|
||||
ShowCursor(FALSE);
|
||||
|
||||
// hide status bar
|
||||
if (gfx.hStatusBar) {
|
||||
ShowWindow(gfx.hStatusBar, SW_HIDE);
|
||||
}
|
||||
|
||||
// disable menu and save it to restore it later
|
||||
old_menu = GetMenu(gfx.hWnd);
|
||||
if (old_menu) {
|
||||
SetMenu(gfx.hWnd, NULL);
|
||||
}
|
||||
|
||||
// save old window position and size
|
||||
GetWindowPlacement(gfx.hWnd, &old_pos);
|
||||
|
||||
// use virtual screen dimensions for fullscreen mode
|
||||
int32_t vs_width = GetSystemMetrics(SM_CXSCREEN);
|
||||
int32_t vs_height = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
// disable all styles to get a borderless window and save it to restore
|
||||
// it later
|
||||
old_style = GetWindowLong(gfx.hWnd, GWL_STYLE);
|
||||
LONG style = WS_VISIBLE;
|
||||
if (m_exclusive) {
|
||||
style |= WS_POPUP;
|
||||
}
|
||||
SetWindowLong(gfx.hWnd, GWL_STYLE, style);
|
||||
|
||||
// resize window so it covers the entire virtual screen
|
||||
SetWindowPos(gfx.hWnd, HWND_TOP, 0, 0, vs_width, vs_height, SWP_SHOWWINDOW);
|
||||
}
|
||||
else {
|
||||
// restore cursor
|
||||
ShowCursor(TRUE);
|
||||
|
||||
// restore status bar
|
||||
if (gfx.hStatusBar) {
|
||||
ShowWindow(gfx.hStatusBar, SW_SHOW);
|
||||
}
|
||||
|
||||
// restore menu
|
||||
if (old_menu) {
|
||||
SetMenu(gfx.hWnd, old_menu);
|
||||
old_menu = NULL;
|
||||
}
|
||||
|
||||
// restore style
|
||||
SetWindowLong(gfx.hWnd, GWL_STYLE, old_style);
|
||||
|
||||
// restore window size and position
|
||||
SetWindowPlacement(gfx.hWnd, &old_pos);
|
||||
}
|
||||
}
|
||||
|
||||
void screen_close(void)
|
||||
{
|
||||
if (m_glrc_core) {
|
||||
wglDeleteContext(m_glrc_core);
|
||||
}
|
||||
|
||||
wglDeleteContext(m_glrc);
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
#include "wgl_ext.h"
|
||||
#include "output/gl_proc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int wgl_ext_EXT_swap_control = wgl_LOAD_FAILED;
|
||||
int wgl_ext_ARB_create_context = wgl_LOAD_FAILED;
|
||||
int wgl_ext_ARB_create_context_profile = wgl_LOAD_FAILED;
|
||||
|
||||
int (CODEGEN_FUNCPTR *_ptrc_wglGetSwapIntervalEXT)(void) = NULL;
|
||||
BOOL (CODEGEN_FUNCPTR *_ptrc_wglSwapIntervalEXT)(int interval) = NULL;
|
||||
|
||||
static int Load_EXT_swap_control(void)
|
||||
{
|
||||
int numFailed = 0;
|
||||
_ptrc_wglGetSwapIntervalEXT = (int (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("wglGetSwapIntervalEXT");
|
||||
if(!_ptrc_wglGetSwapIntervalEXT) numFailed++;
|
||||
_ptrc_wglSwapIntervalEXT = (BOOL (CODEGEN_FUNCPTR *)(int))IntGetProcAddress("wglSwapIntervalEXT");
|
||||
if(!_ptrc_wglSwapIntervalEXT) numFailed++;
|
||||
return numFailed;
|
||||
}
|
||||
|
||||
HGLRC (CODEGEN_FUNCPTR *_ptrc_wglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int * attribList) = NULL;
|
||||
|
||||
static int Load_ARB_create_context(void)
|
||||
{
|
||||
int numFailed = 0;
|
||||
_ptrc_wglCreateContextAttribsARB = (HGLRC (CODEGEN_FUNCPTR *)(HDC, HGLRC, const int *))IntGetProcAddress("wglCreateContextAttribsARB");
|
||||
if(!_ptrc_wglCreateContextAttribsARB) numFailed++;
|
||||
return numFailed;
|
||||
}
|
||||
|
||||
|
||||
static const char * (CODEGEN_FUNCPTR *_ptrc_wglGetExtensionsStringARB)(HDC hdc) = NULL;
|
||||
|
||||
typedef int (*PFN_LOADFUNCPOINTERS)(void);
|
||||
typedef struct wgl_StrToExtMap_s
|
||||
{
|
||||
char *extensionName;
|
||||
int *extensionVariable;
|
||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||
} wgl_StrToExtMap;
|
||||
|
||||
static wgl_StrToExtMap ExtensionMap[3] = {
|
||||
{"WGL_EXT_swap_control", &wgl_ext_EXT_swap_control, Load_EXT_swap_control},
|
||||
{"WGL_ARB_create_context", &wgl_ext_ARB_create_context, Load_ARB_create_context},
|
||||
{"WGL_ARB_create_context_profile", &wgl_ext_ARB_create_context_profile, NULL},
|
||||
};
|
||||
|
||||
static int g_extensionMapSize = 3;
|
||||
|
||||
static wgl_StrToExtMap *FindExtEntry(const char *extensionName)
|
||||
{
|
||||
int loop;
|
||||
wgl_StrToExtMap *currLoc = ExtensionMap;
|
||||
for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
|
||||
{
|
||||
if(strcmp(extensionName, currLoc->extensionName) == 0)
|
||||
return currLoc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ClearExtensionVars(void)
|
||||
{
|
||||
wgl_ext_EXT_swap_control = wgl_LOAD_FAILED;
|
||||
wgl_ext_ARB_create_context = wgl_LOAD_FAILED;
|
||||
wgl_ext_ARB_create_context_profile = wgl_LOAD_FAILED;
|
||||
}
|
||||
|
||||
|
||||
static void LoadExtByName(const char *extensionName)
|
||||
{
|
||||
wgl_StrToExtMap *entry = NULL;
|
||||
entry = FindExtEntry(extensionName);
|
||||
if(entry)
|
||||
{
|
||||
if(entry->LoadExtension)
|
||||
{
|
||||
int numFailed = entry->LoadExtension();
|
||||
if(numFailed == 0)
|
||||
{
|
||||
*(entry->extensionVariable) = wgl_LOAD_SUCCEEDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(entry->extensionVariable) = wgl_LOAD_SUCCEEDED + numFailed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*(entry->extensionVariable) = wgl_LOAD_SUCCEEDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ProcExtsFromExtString(const char *strExtList)
|
||||
{
|
||||
size_t iExtListLen = strlen(strExtList);
|
||||
const char *strExtListEnd = strExtList + iExtListLen;
|
||||
const char *strCurrPos = strExtList;
|
||||
char strWorkBuff[256];
|
||||
|
||||
while(*strCurrPos)
|
||||
{
|
||||
/*Get the extension at our position.*/
|
||||
int iStrLen = 0;
|
||||
const char *strEndStr = strchr(strCurrPos, ' ');
|
||||
int iStop = 0;
|
||||
if(strEndStr == NULL)
|
||||
{
|
||||
strEndStr = strExtListEnd;
|
||||
iStop = 1;
|
||||
}
|
||||
|
||||
iStrLen = (int)((ptrdiff_t)strEndStr - (ptrdiff_t)strCurrPos);
|
||||
|
||||
if(iStrLen > 255)
|
||||
return;
|
||||
|
||||
strncpy(strWorkBuff, strCurrPos, iStrLen);
|
||||
strWorkBuff[iStrLen] = '\0';
|
||||
|
||||
LoadExtByName(strWorkBuff);
|
||||
|
||||
strCurrPos = strEndStr + 1;
|
||||
if(iStop) break;
|
||||
}
|
||||
}
|
||||
|
||||
int wgl_LoadFunctions(HDC hdc)
|
||||
{
|
||||
ClearExtensionVars();
|
||||
|
||||
_ptrc_wglGetExtensionsStringARB = (const char * (CODEGEN_FUNCPTR *)(HDC))IntGetProcAddress("wglGetExtensionsStringARB");
|
||||
if(!_ptrc_wglGetExtensionsStringARB) return wgl_LOAD_FAILED;
|
||||
|
||||
ProcExtsFromExtString((const char *)_ptrc_wglGetExtensionsStringARB(hdc));
|
||||
return wgl_LOAD_SUCCEEDED;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
#ifndef POINTER_C_GENERATED_HEADER_WINDOWSGL_H
|
||||
#define POINTER_C_GENERATED_HEADER_WINDOWSGL_H
|
||||
|
||||
#ifdef __wglext_h_
|
||||
#error Attempt to include auto-generated WGL header after wglext.h
|
||||
#endif
|
||||
|
||||
#define __wglext_h_
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef CODEGEN_FUNCPTR
|
||||
#undef CODEGEN_FUNCPTR
|
||||
#endif /*CODEGEN_FUNCPTR*/
|
||||
#define CODEGEN_FUNCPTR WINAPI
|
||||
|
||||
#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
|
||||
#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
|
||||
|
||||
typedef unsigned int GLenum;
|
||||
typedef unsigned char GLboolean;
|
||||
typedef unsigned int GLbitfield;
|
||||
typedef signed char GLbyte;
|
||||
typedef short GLshort;
|
||||
typedef int GLint;
|
||||
typedef int GLsizei;
|
||||
typedef unsigned char GLubyte;
|
||||
typedef unsigned short GLushort;
|
||||
typedef unsigned int GLuint;
|
||||
typedef float GLfloat;
|
||||
typedef float GLclampf;
|
||||
typedef double GLdouble;
|
||||
typedef double GLclampd;
|
||||
#define GLvoid void
|
||||
|
||||
#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/
|
||||
|
||||
|
||||
#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
|
||||
#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
|
||||
|
||||
|
||||
#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/
|
||||
|
||||
|
||||
struct _GPU_DEVICE {
|
||||
DWORD cb;
|
||||
CHAR DeviceName[32];
|
||||
CHAR DeviceString[128];
|
||||
DWORD Flags;
|
||||
RECT rcVirtualScreen;
|
||||
};
|
||||
DECLARE_HANDLE(HPBUFFERARB);
|
||||
DECLARE_HANDLE(HPBUFFEREXT);
|
||||
DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
|
||||
DECLARE_HANDLE(HPVIDEODEV);
|
||||
DECLARE_HANDLE(HGPUNV);
|
||||
DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
|
||||
typedef struct _GPU_DEVICE *PGPU_DEVICE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
extern int wgl_ext_EXT_swap_control;
|
||||
extern int wgl_ext_ARB_create_context;
|
||||
extern int wgl_ext_ARB_create_context_profile;
|
||||
|
||||
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||
#define WGL_CONTEXT_FLAGS_ARB 0x2094
|
||||
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
|
||||
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
|
||||
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define WGL_ERROR_INVALID_VERSION_ARB 0x2095
|
||||
|
||||
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
|
||||
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
|
||||
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||
#define WGL_ERROR_INVALID_PROFILE_ARB 0x2096
|
||||
|
||||
#ifndef WGL_EXT_swap_control
|
||||
#define WGL_EXT_swap_control 1
|
||||
extern int (CODEGEN_FUNCPTR *_ptrc_wglGetSwapIntervalEXT)(void);
|
||||
#define wglGetSwapIntervalEXT _ptrc_wglGetSwapIntervalEXT
|
||||
extern BOOL (CODEGEN_FUNCPTR *_ptrc_wglSwapIntervalEXT)(int interval);
|
||||
#define wglSwapIntervalEXT _ptrc_wglSwapIntervalEXT
|
||||
#endif /*WGL_EXT_swap_control*/
|
||||
|
||||
#ifndef WGL_ARB_create_context
|
||||
#define WGL_ARB_create_context 1
|
||||
extern HGLRC (CODEGEN_FUNCPTR *_ptrc_wglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int * attribList);
|
||||
#define wglCreateContextAttribsARB _ptrc_wglCreateContextAttribsARB
|
||||
#endif /*WGL_ARB_create_context*/
|
||||
|
||||
|
||||
enum wgl_LoadStatus
|
||||
{
|
||||
wgl_LOAD_FAILED = 0,
|
||||
wgl_LOAD_SUCCEEDED = 1,
|
||||
};
|
||||
|
||||
int wgl_LoadFunctions(HDC hdc);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#endif /*POINTER_C_GENERATED_HEADER_WINDOWSGL_H*/
|
||||
Reference in new issue
Block a user