Goodbye, old friend... Remove zzogl from master branch (#3614)

* cmake: Remove zzogl from cmake.

* cmake/build: Remove GLSL_API and EGL_API flags.

Only used in zzogl.

* linux various: Remove zzogl.

* sln: Remove zzogl from old plugins solution.

* zzogl: Remove source files.

* debian: Exclude zzogl from copyright.

* linux various: Remove glsl2h.pl

Used only in zzogl?

* linux various: Remove zzogl code from validate_glsl.sh

* debian: Remove zzogl mentions in create built tarball.

* gitignore: Remove zzogl paths.
This commit is contained in:
lightningterror 2020-08-22 05:41:45 +02:00 committed by GitHub
parent 328e358b21
commit f6c138ca7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
132 changed files with 21 additions and 66831 deletions

1
.gitignore vendored
View File

@ -22,7 +22,6 @@
!/plugins/zerogs/dx/x86-32.asm
!/plugins/zerogs/dx/x86-64.asm
!/plugins/zerogs/opengl/x86-32.asm
!/plugins/zzogl-pg/opengl/x86-32.asm
*.VC.db
*.VC.VC.opendb

View File

@ -204,8 +204,6 @@ for ARG in "$@"; do
--rel|--release ) flags="$flags -DCMAKE_BUILD_TYPE=Release" ; build="$root/build_rel";;
--prof ) flags="$flags -DCMAKE_BUILD_TYPE=Prof" ; build="$root/build_prof";;
--strip ) flags="$flags -DCMAKE_BUILD_STRIP=TRUE" ;;
--glsl ) flags="$flags -DGLSL_API=TRUE" ;;
--egl ) flags="$flags -DEGL_API=TRUE" ;;
--sdl12 ) flags="$flags -DSDL2_API=FALSE" ;;
--extra ) flags="$flags -DEXTRA_PLUGINS=TRUE" ;;
--asan ) flags="$flags -DUSE_ASAN=TRUE" ;;
@ -239,8 +237,6 @@ for ARG in "$@"; do
echo "--no-simd : Only allow sse2"
echo
echo "** Developer option **"
echo "--glsl : Replace CG backend of ZZogl by GLSL"
echo "--egl : Replace GLX by EGL (ZZogl plugin)"
echo "--cross-multilib: Build a 32bit PCSX2 on a 64bit machine using multilib."
echo "--opencl : Enable experimental OpenCL support"
echo

View File

@ -33,8 +33,6 @@ option(USE_VTUNE "Plug VTUNE to profile GSdx JIT.")
#-------------------------------------------------------------------------------
# Graphical option
#-------------------------------------------------------------------------------
option(GLSL_API "Replace ZZogl CG backend by GLSL (experimental option)")
option(EGL_API "Use EGL on ZZogl/GSdx (experimental/developer option)")
option(OPENCL_API "Add OpenCL support on GSdx")
option(REBUILD_SHADER "Rebuild GLSL/CG shader (developer option)")
option(BUILD_REPLAY_LOADERS "Build GS replayer to ease testing (developer option)")

View File

@ -10,11 +10,6 @@ set(msg_dep_onepad "check these libraries -> sdl2, X11, gtk2")
set(msg_dep_spu2x "check these libraries -> soundtouch (>=1.5), alsa, portaudio (optional, >=1.9), sdl (>=1.2), pcsx2 common libs")
set(msg_dep_zerospu2 "check these libraries -> soundtouch (>=1.5), alsa")
set(msg_dep_dev "check these libraries -> gtk2, pcap, libxml2")
if(GLSL_API)
set(msg_dep_zzogl "check these libraries -> glew, jpeg (>=6.2), opengl, X11, pcsx2 common libs")
else(GLSL_API)
set(msg_dep_zzogl "check these libraries -> glew, jpeg (>=6.2), opengl, X11, nvidia-cg-toolkit (>=2.1), pcsx2 common libs")
endif()
macro(print_dep str dep)
if (PACKAGE_MODE)
@ -157,7 +152,7 @@ endif()
# -X11
# -zlib
#---------------------------------------
if(OPENGL_FOUND AND X11_FOUND AND GTKn_FOUND AND ZLIB_FOUND AND PNG_FOUND AND FREETYPE_FOUND AND LIBLZMA_FOUND AND ((EGL_FOUND AND X11_XCB_FOUND) OR NOT EGL_API))
if(OPENGL_FOUND AND X11_FOUND AND GTKn_FOUND AND ZLIB_FOUND AND PNG_FOUND AND FREETYPE_FOUND AND LIBLZMA_FOUND AND EGL_FOUND AND X11_XCB_FOUND)
set(GSdx TRUE)
elseif(NOT EXISTS "${CMAKE_SOURCE_DIR}/plugins/GSdx")
set(GSdx FALSE)
@ -187,28 +182,6 @@ if(EXTRA_PLUGINS)
endif()
#---------------------------------------
#---------------------------------------
# zzogl-pg
#---------------------------------------
# requires: -GLEW
# -OpenGL
# -X11
# -CG (only with cg build)
# -JPEG
# -common_libs
#---------------------------------------
if(EXTRA_PLUGINS)
if((GLEW_FOUND AND OPENGL_FOUND AND X11_FOUND AND JPEG_FOUND AND common_libs AND GTKn_FOUND) AND (CG_FOUND OR GLSL_API))
set(zzogl TRUE)
elseif(NOT EXISTS "${CMAKE_SOURCE_DIR}/plugins/zzogl-pg")
set(zzogl FALSE)
else()
set(zzogl FALSE)
print_dep("Skip build of zzogl: missing dependencies" "${msg_dep_zzogl}")
endif()
endif()
#---------------------------------------
#---------------------------------------
# PadNull
#---------------------------------------

View File

@ -12,7 +12,7 @@ Files: pcsx2/* common/* plugins/spu2-x/* plugins/PadNull/Pad* plugins/USBnull/*
Copyright: 2002-2012 PCSX2 Dev Team
License: LGPL-3+
Files: pcsx2/Mdec.cpp pcsx2/Mdec.h pcsx2/RDebug/deci2_drfp.cpp pcsx2/IPU/mpeg2lib/* pcsx2/cheatscpp.h common/include/api/* plugins/onepad/* plugins/PadNull/Linux/* plugins/SPU2null/* plugins/FWnull/FW.cpp plugins/zerospu2/* plugins/zzogl-pg/* plugins/GSnull/Registers.h plugins/GSnull/Linux/Linux* plugins/GSnull/Linux/Config* plugins/dev9null/DEV9.h plugins/dev9null/Config.*
Files: pcsx2/Mdec.cpp pcsx2/Mdec.h pcsx2/RDebug/deci2_drfp.cpp pcsx2/IPU/mpeg2lib/* pcsx2/cheatscpp.h common/include/api/* plugins/onepad/* plugins/PadNull/Linux/* plugins/SPU2null/* plugins/FWnull/FW.cpp plugins/zerospu2/* plugins/GSnull/Registers.h plugins/GSnull/Linux/Linux* plugins/GSnull/Linux/Config* plugins/dev9null/DEV9.h plugins/dev9null/Config.*
Copyright: 2002-2012 PCSX2 Dev Team
License: GPL-2+
@ -20,22 +20,10 @@ Files: plugins/spu2-x/src/Spu2replay.* plugins/spu2-x/src/Decode* plugins/spu2-x
Copyright: 2002-2012 PCSX2 Dev Team
License: LGPL-2.1+
Files: plugins/zzogl-pg/opengl/glprocs.*
Copyright: 1991-2000 Silicon Graphics, Inc
License: SGI FREE SOFTWARE LICENSE B 2.0
Files: common/src/Utilities/vssprintf.cpp
Copyright: 2002 Michael Ringgaard
License: BSD-3-Clause
Files: plugins/zzogl-pg/opengl/zpipe.cpp
Copyright: not applicable
License: public-domain
Author's Note:
zpipe.c: example of proper use of zlib's inflate() and deflate()
Not copyrighted -- provided to the public domain
Version 1.4 11 December 2005 Mark Adler
License: LGPL-3 or LGPL-3+
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free

View File

@ -100,7 +100,6 @@ remove_remaining_non_free_file()
{
echo "Remove remaining non free file. TODO UPSTREAM"
rm -fr $LOCAL_REPO/plugins/GSdx/baseclasses
rm -f $LOCAL_REPO/plugins/zzogl-pg/opengl/Win32/aviUtil.h
rm -f $LOCAL_REPO/common/src/Utilities/x86/MemcpyFast.cpp
}
remove_dot_git()

View File

@ -51,7 +51,6 @@ files=`git diff --name-only --diff-filter=ACMRT $diff_range -- $PWD | \
grep -v "${1}plugins/USBqemu/" | \
grep -v "${1}plugins/zerogs/" | \
grep -v "${1}plugins/zerospu2/" | \
grep -v "${1}plugins/zzogl-pg/" | \
\
grep -v "/resource.h" | \
grep -v "3rdparty/" | \

View File

@ -1,116 +0,0 @@
#!/usr/bin/perl
# PCSX2 - PS2 Emulator for PCs
# Copyright (C) 2002-2014 PCSX2 Dev Team
#
# PCSX2 is free software: you can redistribute it and/or modify it under the terms
# of the GNU Lesser General Public License as published by the Free Software Found-
# ation, either version 3 of the License, or (at your option) any later version.
#
# PCSX2 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 PCSX2.
# If not, see <http://www.gnu.org/licenses/>.
use strict;
use warnings;
use File::Spec;
use File::Basename;
use File::Copy;
use Cwd 'abs_path';
# Allow to use the script without the module. I don't want a full PERL as a dependency of PCSX2!
my $g_disable_md5 = 0;
eval {
require Digest::file;
require Digest::MD5;
Digest::file->import(qw/digest_file_hex/);
Digest::MD5->import(qw/md5_hex/);
1;
} or do {
$g_disable_md5 = 1;
print "Disable MD5\n";
};
########################
# ZZOGL
########################
my @zz_res = qw/ps2hw_gl4.glsl/;
my $zz_path = File::Spec->catdir(dirname(abs_path($0)), "..", "plugins", "zzogl-pg", "opengl");
my $zz_out = File::Spec->catdir($zz_path, "ps2hw_gl4.h");
glsl2h($zz_path, $zz_out, \@zz_res);
sub glsl2h {
my $in_dir = shift;
my $out_file = shift;
my $glsl_files = shift;
my $include = "";
if ($in_dir =~ /GSdx/) {
$include = "#include \"stdafx.h\""
}
my $header = <<EOS;
/*
* This file was generated by ./linux_various/glsl2h.pl script. Don't edit it manually !
*
* GLSL input directory: $in_dir
* GLSL input files: @$glsl_files
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
$include
EOS
my $data = $header;
foreach my $file (@{$glsl_files}) {
my $name = $file;
$name =~ s/\./_/;
$data .= "\nstatic const char* const $name =\n";
open(my $GLSL, File::Spec->catfile($in_dir, $file)) or die "$! : $file";
my $line;
while(defined($line = <$GLSL>)) {
chomp $line;
$line =~ s/\\/\\\\/g;
$line =~ s/"/\\"/g;
$data .= "\t\"$line\\n\"\n";
}
$data .= "\t;\n";
}
# Rewriting the file will trigger a relink (even if the content is the
# same). So we check first the content with md5 digest
if ( -e $out_file and not $g_disable_md5) {
my $old_md5 = digest_file_hex($out_file, "MD5");
my $new_md5 = md5_hex($data);
if ($old_md5 ne $new_md5) {
open(my $H, ">$out_file") or die;
print $H $data;
}
} else {
open(my $H, ">$out_file") or die;
print $H $data;
}
}

View File

@ -38,7 +38,6 @@ Help:
--input <file> : input glsl file (mandatory)
--macro <name> <value> : set a macro. Can be repeated
--entry <name> : set an entry point. Note: print the ASM output of the program
--test_ZZ : test of zzogl glsl file
--test_dx : test of gsdx glsl file
--nofrag : disable fragment processing
--novert : disable vertex processing
@ -52,7 +51,6 @@ case $1 in
--input|--i) INPUT=$2; shift 2;;
--macro|--m) MACRO="${MACRO}#define $2 $3\n"; shift 3;;
--entry|--e) ENTRY="-entry $2";shift 2;;
--test_ZZ ) TEST_ZZOGL=1; shift 1;;
--test_dx ) TEST_GSDX=1; shift 1;;
--nofrag) NOFRAG=1; shift 1;;
--novert) NOVERT=1; shift 1;;
@ -116,13 +114,7 @@ fragment_test()
# Main
######################################################
if [ "$TEST_ZZOGL" = '1' ] ; then
./validate_glsl.sh --input $INPUT --novert --m TEST_AEM 1
./validate_glsl.sh --input $INPUT --novert --m REGION_REPEAT 1
./validate_glsl.sh --input $INPUT --novert --m EXACT_COLOR 1
./validate_glsl.sh --input $INPUT --m WRITE_DEPTH 1
./validate_glsl.sh --input $INPUT
elif [ "$TEST_GSDX" = '1' ] ; then
if [ "$TEST_GSDX" = '1' ] ; then
echo "not yet implemented"
# A very big shader example (124 instructions!)
./validate_glsl.sh --input $INPUT --novert --entry ps_main --macro PS_TCC 0 --macro PS_TFX 0 --macro PS_IIP 1 --macro PS_ATST 4 --macro PS_FST 1 --macro PS_BLEND 4 --macro PS_COLCLIP 3 --macro PS_SHUFFLE 1 --macro PS_LTF 1 --macro PS_FMT 6 --macro PS_AEM 0 --macro PS_FBMASK 1 --macro PS_FOG 1 --macro PS_WMS 2 --macro PS_WMT 3

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio Version 16
VisualStudioVersion = 16.0.30104.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdparty", "3rdparty", "{78EBE642-7A4D-4EA7-86BE-5639C6646C38}"
ProjectSection(SolutionItems) = preProject
@ -42,8 +42,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utilities", "common\build\U
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "3rdparty\libjpeg\libjpeg.vcxproj", "{BC236261-77E8-4567-8D09-45CD02965EB6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZZOgl", "plugins\zzogl-pg\opengl\Win32\zerogsogl.vcxproj", "{2D4E85B2-F47F-4D65-B091-701E5C031DAC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "USBqemu", "plugins\USBqemu\Win32\USBqemu.vcxproj", "{E613DA9F-41B4-4613-9911-E418EF5533BC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wx30_base", "3rdparty\wxwidgets3.0\build\msw\wx30_base.vcxproj", "{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}"
@ -123,15 +121,18 @@ Global
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.ActiveCfg = Release|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.Build.0 = Release|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.ActiveCfg = Release|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Debug|Win32.ActiveCfg = Debug|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Debug|Win32.Build.0 = Debug|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Debug|x64.ActiveCfg = Debug|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Devel|Win32.ActiveCfg = Devel|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Devel|Win32.Build.0 = Devel|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Devel|x64.ActiveCfg = Devel|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Release|Win32.ActiveCfg = Release|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Release|Win32.Build.0 = Release|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Release|x64.ActiveCfg = Release|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Debug|Win32.ActiveCfg = Debug|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Debug|Win32.Build.0 = Debug|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Debug|x64.ActiveCfg = Debug|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Debug|x64.Build.0 = Debug|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Devel|Win32.ActiveCfg = Devel|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Devel|Win32.Build.0 = Devel|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Devel|x64.ActiveCfg = Devel|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Devel|x64.Build.0 = Devel|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Release|Win32.ActiveCfg = Release|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Release|Win32.Build.0 = Release|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Release|x64.ActiveCfg = Release|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Release|x64.Build.0 = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.ActiveCfg = Debug|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.Build.0 = Debug|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.ActiveCfg = Debug|x64
@ -189,18 +190,6 @@ Global
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|Win32.Build.0 = Release|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|x64.ActiveCfg = Release|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|x64.Build.0 = Release|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Debug|Win32.ActiveCfg = Debug|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Debug|Win32.Build.0 = Debug|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Debug|x64.ActiveCfg = Debug|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Debug|x64.Build.0 = Debug|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Devel|Win32.ActiveCfg = Devel|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Devel|Win32.Build.0 = Devel|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Devel|x64.ActiveCfg = Devel|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Devel|x64.Build.0 = Devel|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Release|Win32.ActiveCfg = Release|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Release|Win32.Build.0 = Release|Win32
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Release|x64.ActiveCfg = Release|x64
{E613DA9F-41B4-4613-9911-E418EF5533BC}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -214,12 +203,14 @@ Global
{7F059854-568D-4E08-9D00-1E78E203E4DC} = {703FD00B-D7A0-41E3-BD03-CEC86B385DAF}
{4639972E-424E-4E13-8B07-CA403C481346} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
{BC236261-77E8-4567-8D09-45CD02965EB6} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{2D4E85B2-F47F-4D65-B091-701E5C031DAC} = {703FD00B-D7A0-41E3-BD03-CEC86B385DAF}
{E613DA9F-41B4-4613-9911-E418EF5533BC} = {703FD00B-D7A0-41E3-BD03-CEC86B385DAF}
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{0FAE817D-9A32-4830-857E-81DA57246E16} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{E613DA9F-41B4-4613-9911-E418EF5533BC} = {703FD00B-D7A0-41E3-BD03-CEC86B385DAF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7AD976E7-4CAF-4011-B089-995E8A908BB0}
EndGlobalSection
EndGlobal

View File

@ -61,7 +61,3 @@ endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/USBnull" AND USBnull)
add_subdirectory(USBnull)
endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/zzogl-pg" AND zzogl)
add_subdirectory(zzogl-pg/opengl)
endif()

View File

@ -1,237 +0,0 @@
if (openSUSE)
# openSUSE don't install wx in a standard library system
# path. Let's bypass the dynamic linker and hardcode the path.
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON)
endif()
# Check that people use the good file
if(NOT TOP_CMAKE_WAS_SOURCED)
message(FATAL_ERROR "
You did not 'cmake' the good CMakeLists.txt file. Use the one in the top dir.
It is advice to delete all wrongly generated cmake stuff => CMakeFiles & CMakeCache.txt")
endif(NOT TOP_CMAKE_WAS_SOURCED)
# Allow to build the shader files
if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders" AND REBUILD_SHADER AND NOT GLSL_API)
add_subdirectory(ZeroGSShaders)
endif(EXISTS "${CMAKE_SOURCE_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders" AND REBUILD_SHADER AND NOT GLSL_API)
# plugin name
set(Output zzogl-0.4.0)
set(CommonFlags
-DZEROGS_SSE2
-fno-strict-aliasing
-Wstrict-aliasing # Allow to track strict aliasing issue.
-Wunused-variable
-Wno-parentheses
# Mute the warnings about the huge classes we initialise with memset.
-Wno-class-memaccess
)
#Clang doesn't support a few common flags that GCC does.
if(NOT USE_CLANG)
set(zzoglFinalFlags
${zzoglFinalFlags}
${CommonFlags} -fno-regmove
)
endif(NOT USE_CLANG)
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(zzoglFinalFlags
${zzoglFinalFlags}
${CommonFlags} -g -Wall -D_DEBUG
)
elseif(CMAKE_BUILD_TYPE STREQUAL Devel)
set(zzoglFinalFlags
${zzoglFinalFlags}
${CommonFlags} -g -W -DZEROGS_DEVBUILD -fvisibility=hidden
)
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
set(zzoglFinalFlags
${zzoglFinalFlags}
${CommonFlags} -W -fvisibility=hidden
)
endif()
# Select the shader API
if(GLSL_API)
set(zzoglFinalFlags
${zzoglFinalFlags}
-DGLSL4_API -DOGL4_LOG
)
#-DGLSL_API
else(GLSL_API)
set(zzoglFinalFlags
${zzoglFinalFlags}
-DNVIDIA_CG_API
)
endif(GLSL_API)
# Select the EGL API
if(EGL_API AND EGL_FOUND)
if (EGL_GL_CONTEXT_SUPPORT)
set(zzoglFinalFlags
${zzoglFinalFlags}
-DEGL_API
)
else()
message(WARNING "Current EGL implementation doesn't support openGL context. Fallback to standard GLX.")
endif()
endif()
# zzogl sources
set(zzoglSources
GifTransfer.cpp
#GLWin32.cpp
GLWinX11.cpp
GSDump.cpp
GSmain.cpp
HostMemory.cpp
Mem.cpp
Mem_Swizzle.cpp
Mem_Tables.cpp
Profile.cpp
rasterfont.cpp
Regs.cpp
targets.cpp
zerogs.cpp
zpipe.cpp
ZZDepthTargets.cpp
ZZMemoryTargets.cpp
ZZRenderTargets.cpp
ZZClut.cpp
ZZHacks.cpp
ZZKeyboard.cpp
ZZoglDrawing.cpp
ZZLog.cpp
ZZoglCreate.cpp
ZZoglCRTC.cpp
ZZoglFlush.cpp
ZZoglFlushHack.cpp
ZZoglMem.cpp
ZZoglSave.cpp
ZZoglShaders.cpp
ZZoglShadersGLSL.cpp
ZZoglShadersGLSL4.cpp
ZZoglShoots.cpp
ZZoglVB.cpp
)
# zzogl headers
set(zzoglHeaders
common.h
CRC.h
GifTransfer.h
# glprocs.h
GS.h
GSDump.h
HostMemory.h
ps2hw_gl4.h
Mem.h
Mem_Swizzle.h
Mem_Transmit.h
Profile.h
rasterfont.h
Regs.h
targets.h
Util.h
x86.h
zerogs.h
zpipe.h
ZZClut.h
ZZoglFlush.h
ZZGl.h
ZZHacks.h
ZZoglDrawing.h
ZZLog.h
ZZoglCRTC.h
ZZoglMath.h
ZZoglMem.h
ZZoglShaders.h
ZZoglShoots.h
ZZoglVB.h
)
# zzogl shader sources
set(zzoglShaderSources
ctx0/ps2hw_ctx.fx
ctx1/ps2hw_ctx.fx)
# zzogl Linux sources
set(zzoglLinuxSources
Linux/Conf.cpp
Linux/Linux.cpp)
# zzogl Linux headers
set(zzoglLinuxHeaders
Linux/Linux.h)
set(zzoglFinalSources
${zzoglSources}
${zzoglHeaders}
${zzoglShaderSources}
${zzoglLinuxSources}
${zzoglLinuxHeaders}
)
set(zzoglFinalLibs
Utilities_NO_TLS
${OPENGL_LIBRARIES}
)
# add additional include directories
include_directories(Linux)
# Generate Glsl header file. Protect with REBUILD_SHADER to avoid build-dependency on PERL
if (REBUILD_SHADER)
add_custom_command(OUTPUT ps2hw_gl4.h COMMAND perl ${CMAKE_SOURCE_DIR}/linux_various/glsl2h.pl)
endif()
if(EGL_API AND EGL_FOUND AND EGL_GL_CONTEXT_SUPPORT)
set(zzoglFinalLibs
${zzoglFinalLibs}
${EGL_LIBRARIES}
)
endif()
if(NOT GLSL_API)
set(zzoglFinalLibs
${zzoglFinalLibs}
${CG_LIBRARIES}
)
endif(NOT GLSL_API)
set(zzoglFinalLibs
${zzoglFinalLibs}
${GLEW_LIBRARY}
${X11_LIBRARIES}
${JPEG_LIBRARIES}
${GTK2_LIBRARIES}
${ZLIB_LIBRARIES}
${LIBC_LIBRARIES}
)
add_pcsx2_plugin(${Output} "${zzoglFinalSources}" "${zzoglFinalLibs}" "${zzoglFinalFlags}")
# Trick that allow to compile zzogl with GSOPEN2 and the replayer with GSOPEN
set_target_properties(${Output} PROPERTIES COMPILE_DEFINITIONS USE_GSOPEN2)
if(NOT GLSL_API AND NOT REBUILD_SHADER)
if(PACKAGE_MODE)
install(FILES ${CMAKE_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.dat DESTINATION ${PLUGIN_DIR})
else()
install(FILES ${CMAKE_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.dat DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
endif()
endif()
################################### Replay Loader
if(BUILD_REPLAY_LOADERS)
set(Replay pcsx2_ZZReplayLoader)
set(zzoglReplayLoaderFinalSources
${zzoglFinalSources}
linux_replay.cpp
)
add_pcsx2_executable(${Replay} "${zzoglReplayLoaderFinalSources}" "${zzoglFinalLibs}" "${zzoglFinalFlags}")
endif(BUILD_REPLAY_LOADERS)

View File

@ -1,408 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef CRC_H_INCLUDED
#define CRC_H_INCLUDED
#include "ZZHacks.h"
// CRC Information
enum Title_Info
{
Unknown_Title,
MetalSlug6,
TomoyoAfter,
Clannad,
Lamune,
KyuuketsuKitanMoonties,
PiaCarroteYoukosoGPGakuenPrincess,
KazokuKeikakuKokoroNoKizuna,
DuelSaviorDestiny,
FFX,
FFX2,
FFXII,
ShadowHearts,
Okami,
MetalGearSolid3,
DBZBT2,
DBZBT3,
SFEX3,
Bully,
BullyCC,
SoTC,
OnePieceGrandAdventure,
OnePieceGrandBattle,
ICO,
GT4,
WildArms4,
WildArms5,
Manhunt2,
CrashBandicootWoC,
ResidentEvil4,
Spartan,
AceCombat4,
Drakengard2,
Tekken5,
IkkiTousen,
GodOfWar,
GodOfWar2,
JackieChanAdv,
HarvestMoon,
NamcoXCapcom,
GiTS,
Onimusha3,
MajokkoALaMode2,
TalesOfAbyss,
SonicUnleashed,
SimpsonsGame,
Genji,
StarOcean3,
ValkyrieProfile2,
RadiataStories,
SMTNocturne,
SMTDDS1,
SMTDDS2,
RozenMaidenGebetGarden,
Xenosaga,
Espgaluda,
OkageShadowKing,
ShadowTheHedgehog,
AtelierIris1,
AtelierIris2,
AtelierIris3,
AtelierJudie,
AtelierLilie,
AtelierViorate,
ArTonelico1,
ArTonelico2,
ManaKhemia1,
ManaKhemia2,
DarkCloud1,
DarkCloud2,
GhostInTheShell,
TitleCount,
Disgaea,
Disgaea2,
Gradius,
KingdomHearts,
KingdomHeartsFM,
KingdomHearts2,
KingdomHearts2FM,
KingdomHeartsCOM,
Tekken4,
Kaena,
Sims_The_Urbz,
MarvelxCapcom2,
NeoPets_Darkest_Faerie,
CrashnBurn,
Xenosaga2,
HauntingGround,
NightmareBeforeChristmas,
PowershotPinball,
BioHazard4,
NUMBER_OF_TITLES
};
enum Region_Info
{
Unknown_Region,
US,
EU,
JP,
JPUNDUB,
RU,
FR,
DE,
IT,
ES,
ASIA,
RegionCount,
};
struct Game_Info
{
u32 crc;
Title_Info title;
Region_Info region;
u32 flags;
s32 v_thresh, t_thresh;
};
static const Game_Info crc_game_list[] =
{
// This section is straight from GSdx. Ones that also have ZZOgl hacks are commented out.
{0x00000000, Unknown_Title, Unknown_Region, 0, -1, -1},
{0x2113EA2E, MetalSlug6, Unknown_Region, 0, -1, -1},
{0x42E05BAF, TomoyoAfter, JP, 0, -1, -1},
{0x7800DC84, Clannad, JP, 0, -1, -1},
{0xA6167B59, Lamune, JP, 0, -1, -1},
{0xDDB59F46, KyuuketsuKitanMoonties, JP, 0, -1, -1},
{0xC8EE2562, PiaCarroteYoukosoGPGakuenPrincess, JP, 0, -1, -1},
{0x6CF94A43, KazokuKeikakuKokoroNoKizuna, JP, 0, -1, -1},
{0xEDAF602D, DuelSaviorDestiny, JP, 0, -1, -1},
{0xa39517ab, FFX, EU, 0, -1, -1},
{0xa39517ae, FFX, FR, 0, -1, -1},
{0x941bb7d9, FFX, DE, 0, -1, -1},
{0xa39517a9, FFX, IT, 0, -1, -1},
{0x941bb7de, FFX, ES, 0, -1, -1},
{0xb4414ea1, FFX, RU, 0, -1, -1},
{0xee97db5b, FFX, RU, 0, -1, -1},
{0xaec495cc, FFX, RU, 0, -1, -1},
{0xbb3d833a, FFX, US, 0, -1, -1},
{0x6a4efe60, FFX, JP, 0, -1, -1},
{0x3866ca7e, FFX, ASIA, 0, -1, -1}, // int.
{0x658597e2, FFX, JP, 0, -1, -1}, // int.
{0x9aac5309, FFX2, EU, 0, -1, -1},
{0x9aac530c, FFX2, FR, 0, -1, -1},
{0x9aac530a, FFX2, FR, 0, -1, -1}, // ?
{0x9aac530d, FFX2, DE, 0, -1, -1},
{0x9aac530b, FFX2, IT, 0, -1, -1},
{0x48fe0c71, FFX2, US, 0, -1, -1},
{0xe1fd9a2d, FFX2, JP, 0, -1, -1}, // int.
{0x78da0252, FFXII, EU, 0, -1, -1},
{0xc1274668, FFXII, EU, 0, -1, -1},
{0xdc2a467e, FFXII, EU, 0, -1, -1},
{0xca284668, FFXII, EU, 0, -1, -1},
{0x280AD120, FFXII, JP, 0, -1, -1},
{0x08C1ED4D, HauntingGround, Unknown_Region, 0, -1, -1},
{0x2CD5794C, HauntingGround, EU, 0, -1, -1},
{0x867BB945, HauntingGround, JP, 0, -1, -1},
{0xE263BC4B, HauntingGround, JP, 0, -1, -1},
{0x901AAC09, HauntingGround, US, 0, -1, -1},
{0x8BE3D7B2, ShadowHearts, Unknown_Region, 0, -1, -1},
{0xDEFA4763, ShadowHearts, US, 0, -1, -1},
//{0x21068223, Okami, US, 0, -1, -1},
//{0x891f223f, Okami, FR, 0, -1, -1},
//{0xC5DEFEA0, Okami, JP, 0, -1, -1},
{0x053D2239, MetalGearSolid3, US, 0, -1, -1},
{0x086273D2, MetalGearSolid3, FR, 0, -1, -1},
{0x26A6E286, MetalGearSolid3, EU, 0, -1, -1},
{0xAA31B5BF, MetalGearSolid3, Unknown_Region, 0, -1, -1},
{0x9F185CE1, MetalGearSolid3, Unknown_Region, 0, -1, -1},
{0x98D4BC93, MetalGearSolid3, EU, 0, -1, -1},
{0x86BC3040, MetalGearSolid3, US, 0, -1, -1}, //Subsistance disc 1
{0x0481AD8A, MetalGearSolid3, JP, 0, -1, -1},
{0x79ED26AD, MetalGearSolid3, EU, 0, -1, -1},
{0x5E31EA42, MetalGearSolid3, EU, 0, -1, -1},
{0xD7ED797D, MetalGearSolid3, EU, 0, -1, -1},
{0x278722BF, DBZBT2, US, 0, -1, -1},
{0xFE961D28, DBZBT2, US, 0, -1, -1},
{0x0393B6BE, DBZBT2, EU, 0, -1, -1},
{0xE2F289ED, DBZBT2, JP, 0, -1, -1}, // Sparking Neo!
{0x35AA84D1, DBZBT2, Unknown_Region, 0, -1, -1},
{0x428113C2, DBZBT3, US, 0, -1, -1},
{0xA422BB13, DBZBT3, EU, 0, -1, -1},
{0x983C53D2, DBZBT3, Unknown_Region, 0, -1, -1},
{0x983C53D3, DBZBT3, Unknown_Region, 0, -1, -1},
{0x72B3802A, SFEX3, US, 0, -1, -1},
{0x71521863, SFEX3, US, 0, -1, -1},
{0x28703748, Bully, US, 0, -1, -1},
{0xC78A495D, BullyCC, US, 0, -1, -1},
{0xC19A374E, SoTC, US, 0, -1, -1},
{0x7D8F539A, SoTC, EU, 0, -1, -1},
{0x3122B508, OnePieceGrandAdventure, US, 0, -1, -1},
{0x8DF14A24, OnePieceGrandAdventure, EU, 0, -1, -1},
{0xB049DD5E, OnePieceGrandBattle, US, 0, -1, -1},
{0x5D02CC5B, OnePieceGrandBattle, Unknown_Region, 0, -1, -1},
{0x6F8545DB, ICO, US, 0, -1, -1},
{0xB01A4C95, ICO, JP, 0, -1, -1},
{0x5C991F4E, ICO, Unknown_Region, 0, -1, -1},
// FIXME multiple CRC
{0x7ACF7E03, ICO, Unknown_Region, 0, -1, -1},
{0xAEAD1CA3, GT4, JP, 0, -1, -1},
{0x44A61C8F, GT4, Unknown_Region, 0, -1, -1},
{0x0086E35B, GT4, Unknown_Region, 0, -1, -1},
{0x77E61C8A, GT4, Unknown_Region, 0, -1, -1},
{0xC164550A, WildArms5, JPUNDUB, 0, -1, -1},
{0xC1640D2C, WildArms5, US, 0, -1, -1},
{0x0FCF8FE4, WildArms5, EU, 0, -1, -1},
{0x2294D322, WildArms5, JP, 0, -1, -1},
{0x565B6170, WildArms5, JP, 0, -1, -1},
{0xBBC3EFFA, WildArms4, US, 0, -1, -1},
{0xBBC396EC, WildArms4, US, 0, -1, -1}, //hmm such a small diff in the CRC..
{0x8B029334, Manhunt2, Unknown_Region, 0, -1, -1},
{0x09F49E37, CrashBandicootWoC, Unknown_Region, 0, -1, -1},
{0x013E349D, ResidentEvil4, US, 0, -1, -1},
{0x6BA2F6B9, ResidentEvil4, Unknown_Region, 0, -1, -1},
{0x60FA8C69, ResidentEvil4, JP, 0, -1, -1},
{0x72E1E60E, Spartan, Unknown_Region, 0, -1, -1},
{0x5ED8FB53, AceCombat4, JP, 0, -1, -1},
{0x1B9B7563, AceCombat4, Unknown_Region, 0, -1, -1},
{0xEC432B24, Drakengard2, Unknown_Region, 0, -1, -1},
{0xFC46EA61, Tekken5, JP, 0, -1, -1},
{0x1F88EE37, Tekken5, Unknown_Region, 0, -1, -1},
{0x652050D2, Tekken5, Unknown_Region, 0, -1, -1},
{0x9E98B8AE, IkkiTousen, JP, 0, -1, -1},
//{0xD6385328, GodOfWar, US, 0, -1, -1},
//{0xFB0E6D72, GodOfWar, EU, 0, -1, -1},
//{0xEB001875, GodOfWar, EU, 0, -1, -1},
//{0xA61A4C6D, GodOfWar, Unknown_Region, 0, -1, -1},
//{0xE23D532B, GodOfWar, Unknown_Region, 0, -1, -1},
//{0xDF1AF973, GodOfWar, Unknown_Region, 0, -1, -1},
//{0xD6385328, GodOfWar, Unknown_Region, 0, -1, -1},
{0x2F123FD8, GodOfWar2, RU, 0, -1, -1},
{0x2F123FD8, GodOfWar2, US, 0, -1, -1},
{0x44A8A22A, GodOfWar2, EU, 0, -1, -1},
{0x4340C7C6, GodOfWar2, Unknown_Region, 0, -1, -1},
{0xF8CD3DF6, GodOfWar2, Unknown_Region, 0, -1, -1},
{0x0B82BFF7, GodOfWar2, Unknown_Region, 0, -1, -1},
{0x5D482F18, JackieChanAdv, Unknown_Region, 0, -1, -1},
//{0xf0a6d880, HarvestMoon, US, 0, -1, -1},
{0x75c01a04, NamcoXCapcom, US, 0, -1, -1},
{0xBF6F101F, GiTS, US, 0, -1, -1},
{0xA5768F53, GiTS, JP, 0, -1, -1},
{0x6BF11378, Onimusha3, US, 0, -1, -1},
{0xF442260C, MajokkoALaMode2, JP, 0, -1, -1},
{0x14FE77F7, TalesOfAbyss, US, 0, -1, -1},
{0x045D77E9, TalesOfAbyss, JPUNDUB, 0, -1, -1},
{0xAA5EC3A3, TalesOfAbyss, JP, 0, -1, -1},
//{0xFB236A46, SonicUnleashed, US, 0, -1, -1},
{0x4C7BB3C8, SimpsonsGame, Unknown_Region, 0, -1, -1},
{0x4C94B32C, SimpsonsGame, Unknown_Region, 0, -1, -1},
{0xD71B57F4, Genji, Unknown_Region, 0, -1, -1},
{0x23A97857, StarOcean3, US, 0, -1, -1},
{0xBEC32D49, StarOcean3, JP, 0, -1, -1},
{0x8192A241, StarOcean3, JP, 0, -1, -1}, //NTSC JP special directors cut limited extra sugar on top edition (the special one :p)
{0x23A97857, StarOcean3, JPUNDUB, 0, -1, -1},
{0xCC96CE93, ValkyrieProfile2, US, 0, -1, -1},
{0x774DE8E2, ValkyrieProfile2, JP, 0, -1, -1},
{0x04CCB600, ValkyrieProfile2, EU, 0, -1, -1},
{0xB65E141B, ValkyrieProfile2, EU, 0, -1, -1}, // PAL German
{0x47B9B2FD, RadiataStories, US, 0, -1, -1},
{0xE8FCF8EC, SMTNocturne, US, 0, -1, -1}, // GSdx saves/reloads z buffer around shadow drawing, same issue with all the SMT games following
{0xF0A31EE3, SMTNocturne, EU, 0, -1, -1}, // SMTNocturne (Lucifers Call in EU)
{0xAE0DE7B7, SMTNocturne, EU, 0, -1, -1}, // SMTNocturne (Lucifers Call in EU)
{0xD60DA6D4, SMTNocturne, JP, 0, -1, -1}, // SMTNocturne
{0x0e762e8d, SMTNocturne, JP, 0, -1, -1}, // SMTNocturne Maniacs
{0x47BA9034, SMTNocturne, JP, 0, -1, -1}, // SMTNocturne Maniacs Chronicle
{0xD7273511, SMTDDS1, US, 0, -1, -1}, // SMT Digital Devil Saga
{0x1683A6BE, SMTDDS1, EU, 0, -1, -1}, // SMT Digital Devil Saga
{0x44865CE1, SMTDDS1, JP, 0, -1, -1}, // SMT Digital Devil Saga
{0xD382C164, SMTDDS2, US, 0, -1, -1}, // SMT Digital Devil Saga 2
{0xD568B684, SMTDDS2, EU, 0, -1, -1}, // SMT Digital Devil Saga 2
{0xE47C1A9C, SMTDDS2, JP, 0, -1, -1}, // SMT Digital Devil Saga 2
{0x0B8AB37B, RozenMaidenGebetGarden, JP, 0, -1, -1},
// And these are here for ZZogl hacks.
{0xA3D63039, Xenosaga, JP, GAME_DOPARALLELCTX, 64, 32},
{0x0E7807B2, Xenosaga, US, GAME_DOPARALLELCTX, 64, 32},
{0x7D2FE035, Espgaluda, JP, 0/*GAME_BIGVALIDATE*/, 24, -1},
{0x21068223, Okami, US, GAME_XENOSPECHACK, -1, -1},
{0x891f223f, Okami, FR, GAME_XENOSPECHACK, -1, -1},
{0xC5DEFEA0, Okami, JP, GAME_XENOSPECHACK, -1, -1},
{0xe0426fc6, OkageShadowKing, Unknown_Region, GAME_XENOSPECHACK, -1, -1},
{0xD6385328, GodOfWar, US, GAME_FULL16BITRES, -1, -1},
{0xFB0E6D72, GodOfWar, EU, GAME_FULL16BITRES, -1, -1},
{0xEB001875, GodOfWar, EU, GAME_FULL16BITRES, -1, -1},
{0xA61A4C6D, GodOfWar, Unknown_Region, GAME_FULL16BITRES, -1, -1},
{0xE23D532B, GodOfWar, Unknown_Region, GAME_FULL16BITRES, -1, -1},
{0xDF1AF973, GodOfWar, Unknown_Region, GAME_FULL16BITRES, -1, -1},
{0xD6385328, GodOfWar, Unknown_Region, GAME_FULL16BITRES, -1, -1},
//{0x2F123FD8, GodOfWar2, Unknown_Region, GAME_FULL16BITRES, -1, -1},
//{0x44A8A22A, GodOfWar2, Unknown_Region, GAME_FULL16BITRES, -1, -1},
//{0x4340C7C6, GodOfWar2, Unknown_Region, GAME_FULL16BITRES, -1, -1},
//{0xF8CD3DF6, GodOfWar2, Unknown_Region, GAME_FULL16BITRES, -1, -1},
//{0x0B82BFF7, GodOfWar2, Unknown_Region, GAME_FULL16BITRES, -1, -1},
{0xF0A6D880, HarvestMoon, US, GAME_NOSTENCIL, -1, -1},
//{0x304C115C, HarvestMoon, Unknown, GAME_NOSTENCIL, -1, -1},
{0xFB236A46, SonicUnleashed, US, GAME_FASTUPDATE | GAME_NOALPHAFAIL, -1, -1},
{0xa5d29941, ShadowTheHedgehog, US, GAME_FASTUPDATE | GAME_NOALPHAFAIL, -1, -1},
{0x7acf7e03, AtelierIris1, Unknown_Region, GAME_GUSTHACK, -1, -1},
{0xF0457CEF, AtelierIris1, Unknown_Region, GAME_GUSTHACK, -1, -1},
{0xE3981DBB, AtelierIris1, US, GAME_GUSTHACK, -1, -1},
{0x9AC65D6A, AtelierIris2, US, GAME_GUSTHACK, -1, -1},
{0x4CCC9212, AtelierIris3, US, GAME_GUSTHACK, -1, -1},
{0xCA295E61, AtelierIris3, JP, GAME_GUSTHACK, -1, -1},
//{0x4437F4B1, ArTonelico1, US, GAME_GUSTHACK, -1, -1},
{0xF95F37EE, ArTonelico2, US, GAME_GUSTHACK, -1, -1},
{0xF46142D3, ArTonelico2, JPUNDUB, GAME_GUSTHACK, -1, -1},
// According to Zeydlitz, Mana Khemia no longer needs the Gust Hack.
//{0x77b0236f, ManaKhemia1, US, GAME_GUSTHACK, -1, -1},
//{0x433951e7, ManaKhemia2, US, GAME_GUSTHACK, -1, -1},
//{0xda11c6d4, AtelierJudie, JP, GAME_GUSTHACK, -1, -1},
//{0x3e72c085, AtelierLilie, JP, GAME_GUSTHACK, -1, -1},
//{0x6eac076b, AtelierViorate, JP, GAME_GUSTHACK, -1, -1},
{0xbaa8dd8, DarkCloud1, US, GAME_NOTARGETRESOLVE, -1, -1},
{0xA5C05C78, DarkCloud1, Unknown_Region, GAME_NOTARGETRESOLVE, -1, -1},
//{0x1DF41F33, DarkCloud2, US, 0, -1, -1},
{0x95cc86ef, GhostInTheShell, Unknown_Region, GAME_NOALPHAFAIL, -1, -1}
// Game settings that used to be in the Patches folder. Commented out until I decide what to do with them.
// {0x951555A0, Disgaea2, US, GAME_NODEPTHRESOLVE, -1, -1},
// {0x4334E17D, Disgaea2, JP, GAME_NODEPTHRESOLVE, -1, -1},
//
// {0x5EB127E7, Gradius, JP, GAME_INTERLACE2X, -1, -1},
// {0x6ADBC24B, Gradius, EU, GAME_INTERLACE2X, -1, -1},
// {0xF22CDDAF, Gradius, US, GAME_INTERLACE2X, -1, -1},
//
// {0xF52FB2BE, KingdomHearts, EU, GAME_QUICKRESOLVE1, -1, -1},
// {0xAE3EAA05, KingdomHearts, DE, GAME_QUICKRESOLVE1, -1, -1},
// {0xF6DC728D, KingdomHearts, FR, GAME_QUICKRESOLVE1, -1, -1},
// {0x0F6B6315, KingdomHearts, US, GAME_QUICKRESOLVE1, -1, -1},
// {0x3E68955A, KingdomHeartsFM, JP, GAME_QUICKRESOLVE1, -1, -1},
//
// {0xC398F477, KingdomHearts2, EU, GAME_NODEPTHRESOLVE, -1, -1},
// {0xDA0535FD, KingdomHearts2, US, GAME_NODEPTHRESOLVE, -1, -1},
// {0x93F8A60B, KingdomHearts2, JP, GAME_NODEPTHRESOLVE, -1, -1},
// {0xF266B00B, KingdomHearts2FM, JP, GAME_NODEPTHRESOLVE, -1, -1},
//
// //The patch claimed to stop characters appearing as wigs on GeForce 8x00 series cards (Disable Alpha Testing)
// {0x2251E14D, Tekken4, EU, GAME_NOALPHATEST, -1, -1},
//
// // This one is supposed to fix a refresh bug.
// {0x51F91783, Kaena, JP, GAME_NOTARGETRESOLVE, -1, -1},
//
// {0xDEFA4763, ShadowHearts, EU, GAME_NODEPTHRESOLVE | GAME_NOQUICKRESOLVE | GAME_NOTARGETRESOLVE | GAME_AUTORESET, -1, -1},
// {0x8BE3D7B2, ShadowHearts, US, GAME_NODEPTHUPDATE | GAME_AUTORESET | GAME_NOQUICKRESOLVE, -1, -1},
//
// {0x015314A2, Sims_The_Urbz, US, GAME_NOQUICKRESOLVE, -1, -1},
//
// // "Required fixes to visuals"
// {0x086273D2, MetalGearSolid3, US, GAME_FULL16BITRES | GAME_NODEPTHRESOLVE, -1, -1},
//
// {0x4D228733, MarvelxCapcom2, US, GAME_QUICKRESOLVE1, -1, -1},
// {0x934F9081, NeoPets_Darkest_Faerie, US, GAME_RESOLVEPROMOTED | GAME_FULL16BITRES | GAME_NODEPTHRESOLVE, -1, -1},
//
// {0x21068223, Okami, US, GAME_FULL16BITRES|GAME_NODEPTHRESOLVE|GAME_FASTUPDATE, -1, -1},
// {0xC5DEFEA0, Okami, JP, GAME_FULL16BITRES|GAME_NODEPTHRESOLVE|GAME_FASTUPDATE, -1, -1},
//
// // Speed up
// {0x6BA2F6B9, ResidentEvil4, EU, GAME_NOTARGETRESOLVE | GAME_32BITTARGS, -1, -1},
// {0x013E349D, ResidentEvil4, US, GAME_NOTARGETCLUT, -1, -1},
//
// {0x2088950A, Xenosaga2, JP, GAME_FULL16BITRES | GAME_NODEPTHRESOLVE, -1, -1},
// {0x901AAC09, HauntingGround, US, GAME_FULL16BITRES | GAME_NODEPTHRESOLVE, -1, -1},
// {0x625AF967, NightmareBeforeChristmas, JP, GAME_TEXAHACK, -1, -1},
//
// {0x3CFE3B37, PowershotPinball, EU, GAME_AUTORESET, -1, -1},
// {0x60FA8C69, BioHazard4, JP, GAME_NOTARGETCLUT, -1, -1}
// End of game settings from the patch folder.
};
#define GAME_INFO_INDEX (sizeof(crc_game_list)/sizeof(Game_Info))
#endif // CRC_H_INCLUDED

View File

@ -1,151 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef GLWIN_H_INCLUDED
#define GLWIN_H_INCLUDED
#ifdef _WIN32
#define GL_WIN32_WINDOW
#define WGL_API
#else
#define GL_X11_WINDOW
#include <stdlib.h>
#include <X11/Xlib.h>
#ifdef EGL_API
#include <EGL/egl.h>
#include <EGL/eglext.h>
#else
#define GLX_API
#include <GL/glx.h>
#endif
#endif
// FIX compilation issue with Mesa 10
// Note it might be possible to do better with the right include
// in the rigth order but I don't have time
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#undef CreateWindow // Undo Windows.h global namespace pollution
#ifdef GLX_API
typedef void (APIENTRYP _PFNSWAPINTERVAL)(int);
#endif
extern void SetDeviceSize(int nNewWidth, int nNewHeight);
extern void OnFKey(int key, int shift);
class GLWindow
{
private:
#if defined(GL_X11_WINDOW)
void GetWindowSize();
void PrintProtocolVersion();
#endif
bool CreateContextGL(int, int);
bool CreateContextGL();
#ifdef GLX_API
Display *NativeDisplay;
Window NativeWindow;
GLXContext glxContext;
_PFNSWAPINTERVAL swapinterval;
#endif
#ifdef EGL_API
EGLNativeWindowType NativeWindow;
EGLNativeDisplayType NativeDisplay;
EGLDisplay eglDisplay;
EGLSurface eglSurface;
EGLContext eglContext;
EGLBoolean OpenEGLDisplay();
void CloseEGLDisplay();
#endif
#ifdef WGL_API
HWND NativeWindow;
HDC NativeDisplay; // hDC // Private GDI Device Context
HGLRC wglContext; // hRC // Permanent Rendering Context
bool OpenWGLDisplay();
void CloseWGLDisplay();
#endif
bool vsync_supported;
public:
char title[256];
Size backbuffer;
void SwapGLBuffers();
bool ReleaseContext();
bool CreateWindow(void *pDisplay);
void CloseWindow();
bool DisplayWindow(int _width, int _height);
void SetTitle(char *strtitle);
void ProcessEvents();
void* GetProcAddress(const char* function);
void SetVsync(bool enable);
void InitVsync(bool extension); // dummy in EGL
void UpdateWindowSize(int nNewWidth, int nNewHeight)
{
FUNCLOG
backbuffer.w = std::max(nNewWidth, 16);
backbuffer.h = std::max(nNewHeight, 16);
if (!(conf.fullscreen()))
{
conf.width = nNewWidth;
conf.height = nNewHeight;
}
}
GLWindow() {
#ifdef WGL_API
NativeWindow = NULL;
NativeDisplay = NULL;
wglContext = NULL;
#endif
}
};
extern GLWindow GLWin;
#endif // GLWIN_H_INCLUDED

View File

@ -1,435 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "GS.h"
#include "GLWin.h"
#ifdef GL_WIN32_WINDOW
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static int nWindowWidth = 0, nWindowHeight = 0;
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
// switch(wParam) {
// case VK_ESCAPE:
// SendMessage(hWnd, WM_DESTROY, 0L, 0L);
// break;
// }
break;
case WM_SIZE:
nWindowWidth = lParam & 0xffff;
nWindowHeight = lParam >> 16;
GLWin.UpdateWindowSize(nWindowWidth, nWindowHeight);
break;
case WM_SIZING:
// if button is 0, then just released so can resize
if (GetSystemMetrics(SM_SWAPBUTTON) ? !GetAsyncKeyState(VK_RBUTTON) : !GetAsyncKeyState(VK_LBUTTON))
{
SetDeviceSize(nWindowWidth, nWindowHeight);
}
break;
case WM_SETCURSOR:
SetCursor(NULL);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
bool GLWindow::CreateWindow(void *pDisplay)
{
RECT rc, rcdesktop;
rc.left = 0;
rc.top = 0;
rc.right = conf.width;
rc.bottom = conf.height;
WNDCLASSEX wc;
HINSTANCE hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
DWORD dwExStyle, dwStyle;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window
wc.lpfnWndProc = (WNDPROC) MsgProc; // MsgProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = NULL;
wc.hIconSm = NULL; // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = L"PS2EMU_ZEROGS"; // Set The Class Name
RegisterClassEx(&wc);
if (conf.fullscreen())
{
dwExStyle = WS_EX_APPWINDOW;
dwStyle = WS_POPUP;
}
else
{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle = WS_OVERLAPPEDWINDOW | WS_BORDER;
}
dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
AdjustWindowRectEx(&rc, dwStyle, false, dwExStyle);
GetWindowRect(GetDesktopWindow(), &rcdesktop);
NativeWindow = CreateWindowEx( dwExStyle, // Extended Style For The Window
L"PS2EMU_ZEROGS", // Class Name
L"ZZOgl", // Window Title
dwStyle, // Selected Window Style
(rcdesktop.right - (rc.right - rc.left)) / 2, // Window Position
(rcdesktop.bottom - (rc.bottom - rc.top)) / 2, // Window Position
rc.right - rc.left, // Calculate Adjusted Window Width
rc.bottom - rc.top, // Calculate Adjusted Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL); // Don't Pass Anything To WM_CREATE
if (NativeWindow == NULL)
{
ZZLog::Error_Log("Failed to create window. Exiting...");
return false;
}
if (pDisplay != NULL) *(HWND*)pDisplay = NativeWindow;
// set just in case
SetWindowLongPtr(NativeWindow, GWLP_WNDPROC, (LPARAM)(WNDPROC)MsgProc);
ShowWindow(NativeWindow, SW_SHOWDEFAULT);
UpdateWindow(NativeWindow);
SetFocus(NativeWindow);
if (pDisplay == NULL) ZZLog::Error_Log("Failed to create window. Exiting...");
return (pDisplay != NULL);
}
bool GLWindow::ReleaseContext()
{
if (wglContext) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL, L"Release Of DC And RC Failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(wglContext)) // Are We Able To Delete The RC?
{
MessageBox(NULL, L"Release Rendering Context Failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
wglContext = NULL; // Set RC To NULL
}
CloseWGLDisplay();
return true;
}
void GLWindow::CloseWindow()
{
if (NativeWindow != NULL)
{
DestroyWindow(NativeWindow);
NativeWindow = NULL;
}
}
bool GLWindow::DisplayWindow(int _width, int _height)
{
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT rcdesktop;
GetWindowRect(GetDesktopWindow(), &rcdesktop);
if (conf.fullscreen())
{
backbuffer.w = rcdesktop.right - rcdesktop.left;
backbuffer.h = rcdesktop.bottom - rcdesktop.top;
dwExStyle = WS_EX_APPWINDOW;
dwStyle = WS_POPUP;
ShowCursor(false);
}
else
{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle = WS_OVERLAPPEDWINDOW;
backbuffer.w = _width;
backbuffer.h = _height;
}
dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = backbuffer.w;
rc.bottom = backbuffer.h;
AdjustWindowRectEx(&rc, dwStyle, false, dwExStyle);
int X = (rcdesktop.right - rcdesktop.left) / 2 - (rc.right - rc.left) / 2;
int Y = (rcdesktop.bottom - rcdesktop.top) / 2 - (rc.bottom - rc.top) / 2;
SetWindowLong(NativeWindow, GWL_STYLE, dwStyle);
SetWindowLong(NativeWindow, GWL_EXSTYLE, dwExStyle);
SetWindowPos(NativeWindow, HWND_TOP, X, Y, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW);
if (conf.fullscreen())
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = backbuffer.w;
dmScreenSettings.dmPelsHeight = backbuffer.h;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
if (MessageBox(NULL,
L"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?",
L"NeHe GL",
MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
conf.setFullscreen(false);
else
return false;
}
}
else
{
// change to default resolution
ChangeDisplaySettings(NULL, 0);
}
if (!OpenWGLDisplay()) return false;
if (!CreateContextGL()) return false;
UpdateWindow(NativeWindow);
return true;
}
bool GLWindow::OpenWGLDisplay()
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // 8bit Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // 24Bit Z-Buffer (Depth Buffer)
8, // 8bit Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(NativeDisplay = GetDC(NativeWindow)))
{
MessageBox(NULL, L"(1) Can't Create A GL Device Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
if (!(PixelFormat = ChoosePixelFormat(NativeDisplay, &pfd)))
{
MessageBox(NULL, L"(2) Can't Find A Suitable PixelFormat.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
if (!SetPixelFormat(NativeDisplay, PixelFormat, &pfd))
{
MessageBox(NULL, L"(3) Can't Set The PixelFormat.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
return true;
}
void GLWindow::CloseWGLDisplay()
{
if (NativeDisplay && !ReleaseDC(NativeWindow, NativeDisplay)) // Are We Able To Release The DC
{
MessageBox(NULL, L"Release Device Context Failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
NativeDisplay = NULL; // Set DC To NULL
}
}
bool GLWindow::CreateContextGL()
{
return CreateContextGL(2, 0);
}
bool GLWindow::CreateContextGL(int major, int minor)
{
if (major <= 2) {
if (!(wglContext = wglCreateContext(NativeDisplay)))
{
MessageBox(NULL, L"(4) Can't Create A GL Rendering Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
if (!wglMakeCurrent(NativeDisplay, wglContext))
{
MessageBox(NULL, L"(5) Can't Activate The GL Rendering Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
} else {
// todo
return false;
}
return true;
}
void GLWindow::SwapGLBuffers()
{
static u32 lastswaptime = 0;
if (glGetError() != GL_NO_ERROR) ZZLog::Debug_Log("glError before swap!");
SwapBuffers(NativeDisplay);
lastswaptime = timeGetTime();
}
void GLWindow::SetTitle(char *strtitle)
{
if (!conf.fullscreen()) SetWindowText(NativeWindow, wxString::FromUTF8(strtitle));
}
extern void ChangeDeviceSize(int nNewWidth, int nNewHeight);
void GLWindow::ProcessEvents()
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (1)
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
switch (msg.message)
{
case WM_KEYDOWN :
int my_KeyEvent = msg.wParam;
bool my_bShift = !!(GetKeyState(VK_SHIFT) & 0x8000);
switch (msg.wParam)
{
case VK_F5:
case VK_F6:
case VK_F7:
case VK_F9:
OnFKey(msg.wParam - VK_F1 + 1, my_bShift);
break;
case VK_ESCAPE:
if (conf.fullscreen())
{
// destroy that msg
conf.setFullscreen(false);
ChangeDeviceSize(conf.width, conf.height);
UpdateWindow(NativeWindow);
continue; // so that msg doesn't get sent
}
else
{
SendMessage(NativeWindow, WM_DESTROY, 0, 0);
return;
}
break;
}
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
break;
}
}
if ((GetKeyState(VK_MENU) & 0x8000) && (GetKeyState(VK_RETURN) & 0x8000))
{
conf.zz_options.fullscreen = !conf.zz_options.fullscreen;
SetDeviceSize(
(conf.fullscreen()) ? 1280 : conf.width,
(conf.fullscreen()) ? 960 : conf.height);
}
}
void* GLWindow::GetProcAddress(const char* function)
{
return (void*)wglGetProcAddress(function);
}
void GLWindow::InitVsync(bool extension)
{
vsync_supported = extension;
}
void GLWindow::SetVsync(bool enable)
{
if (vsync_supported) {
wglSwapIntervalEXT(0);
}
}
#endif

View File

@ -1,508 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "Util.h"
#include "GLWin.h"
#if defined(GL_X11_WINDOW)
#ifdef EGL_API
// Need at least MESA 9.0 (plan for october/november 2012)
// So force the destiny to at least check the compilation
#ifndef EGL_KHR_create_context
#define EGL_KHR_create_context 1
#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
#define EGL_CONTEXT_FLAGS_KHR 0x30FC
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#endif
#endif
#ifdef USE_GSOPEN2
bool GLWindow::CreateWindow(void *pDisplay)
{
bool ret = true;
NativeWindow = (Window)*((u32*)(pDisplay)+1);
// Do not take the display which come from pcsx2 neither change it.
// You need a new one to do the operation in the GS thread
NativeDisplay = XOpenDisplay(NULL);
if (!NativeDisplay) ret = false;
#ifdef EGL_API
if (!OpenEGLDisplay()) ret = false;
#endif
return ret;
}
#else
bool GLWindow::CreateWindow(void *pDisplay)
{
bool ret = true;
// init support of multi thread
if (!XInitThreads())
ZZLog::Error_Log("Failed to init the xlib concurent threads");
NativeDisplay = XOpenDisplay(NULL);
if (!NativeDisplay) ret = false;
if (pDisplay == NULL)
{
ZZLog::Error_Log("Failed to create window. Exiting...");
return false;
}
// Allow pad to use the display
*(Display**)pDisplay = NativeDisplay;
// Pad can use the window to grab the input. For the moment just set to 0 to avoid
// to grab an unknow window... Anyway GSopen1 might be dropped in the future
*((u32*)(pDisplay)+1) = 0;
#ifdef EGL_API
if (!OpenEGLDisplay()) ret = false;
#endif
return ret;
}
#endif
#ifdef EGL_API
EGLBoolean GLWindow::OpenEGLDisplay()
{
// Create an EGL display from the native display
eglDisplay = eglGetDisplay((EGLNativeDisplayType)NativeDisplay);
if ( eglDisplay == EGL_NO_DISPLAY ) return EGL_FALSE;
if ( !eglInitialize(eglDisplay, NULL, NULL) ) return EGL_FALSE;
return EGL_TRUE;
}
#endif
#ifdef EGL_API
void GLWindow::CloseEGLDisplay()
{
eglTerminate(eglDisplay);
}
#endif
bool GLWindow::ReleaseContext()
{
bool status = true;
#ifdef GLX_API
if (!NativeDisplay) return status;
// free the context
if (glxContext)
{
if (!glXMakeCurrent(NativeDisplay, None, NULL)) {
ZZLog::Error_Log("GLX: Could not release drawing context.");
status = false;
}
glXDestroyContext(NativeDisplay, glxContext);
glxContext = NULL;
}
#endif
#ifdef EGL_API
eglReleaseThread();
#endif
return status;
}
void GLWindow::CloseWindow()
{
SaveConfig();
if (!NativeDisplay) return;
#ifdef EGL_API
CloseEGLDisplay();
#endif
XCloseDisplay(NativeDisplay);
NativeDisplay = NULL;
}
void GLWindow::GetWindowSize()
{
if (!NativeDisplay or !NativeWindow) return;
u32 depth = 0;
#ifdef GLX_API
unsigned int borderDummy;
Window winDummy;
s32 xDummy;
s32 yDummy;
u32 width;
u32 height;
XLockDisplay(NativeDisplay);
XGetGeometry(NativeDisplay, NativeWindow, &winDummy, &xDummy, &yDummy, &width, &height, &borderDummy, &depth);
XUnlockDisplay(NativeDisplay);
#endif
// FIXME: Not sure it works but that could remove latest X11 bits.
#ifdef EGL_API
int width;
int height;
eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &width);
eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &height);
#endif
// update the gl buffer size
UpdateWindowSize(width, height);
#ifndef USE_GSOPEN2
// too verbose!
ZZLog::Dev_Log("Resolution %dx%d. Depth %d bpp. Position (%d,%d)", width, height, depth, conf.x, conf.y);
#endif
}
void GLWindow::PrintProtocolVersion()
{
#ifdef GLX_API
int glxMajorVersion, glxMinorVersion;
glXQueryVersion(NativeDisplay, &glxMajorVersion, &glxMinorVersion);
if (glXIsDirect(NativeDisplay, glxContext))
ZZLog::Error_Log("glX-Version %d.%d with Direct Rendering", glxMajorVersion, glxMinorVersion);
else
ZZLog::Error_Log("glX-Version %d.%d with Indirect Rendering !!! It will be slow", glxMajorVersion, glxMinorVersion);
#endif
#ifdef EGL_API
ZZLog::Error_Log("EGL: %s : %s", eglQueryString(eglDisplay, EGL_VENDOR) , eglQueryString(eglDisplay, EGL_VERSION) );
ZZLog::Error_Log("EGL: extensions supported: %s", eglQueryString(eglDisplay, EGL_EXTENSIONS));
#endif
}
#ifdef GLX_API
bool GLWindow::CreateContextGL(int major, int minor)
{
if (!NativeDisplay) return false;
// Get visual information
int attrListDbl[] =
{
// GLX_X_RENDERABLE: If True is specified, then only frame buffer configurations that have associated X
// visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. The default value is GLX_DONT_CARE.
GLX_X_RENDERABLE , True,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_DOUBLEBUFFER , True,
None
};
// Attribute are very sensible to the various implementation (intel, nvidia, amd)
// Nvidia and Intel doesn't support previous attributes for opengl2.0
int attrListDbl_2_0[] =
{
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_DEPTH_SIZE, 24,
None
};
// Only keep for older card but NVIDIA and AMD both drop the support of those cards
if (major <= 2) {
XVisualInfo *vi = glXChooseVisual(NativeDisplay, DefaultScreen(NativeDisplay), attrListDbl_2_0);
if (vi == NULL) return false;
glxContext = glXCreateContext(NativeDisplay, vi, NULL, GL_TRUE);
XFree(vi);
if (!glxContext) return false;
glXMakeCurrent(NativeDisplay, NativeWindow, glxContext);
return true;
}
PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)GetProcAddress("glXChooseFBConfig");
int fbcount = 0;
GLXFBConfig *fbc = glXChooseFBConfig(NativeDisplay, DefaultScreen(NativeDisplay), attrListDbl, &fbcount);
if (!fbc || fbcount < 1) {
ZZLog::Error_Log("GLX: failed to find a framebuffer");
return false;
}
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)GetProcAddress("glXCreateContextAttribsARB");
if (!glXCreateContextAttribsARB) return false;
// Create a context
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, major,
GLX_CONTEXT_MINOR_VERSION_ARB, minor,
// Keep compatibility for old cruft
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
//GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
// FIXME : Request a debug context to ease opengl development
#if (defined(ZEROGS_DEVBUILD) || defined(_DEBUG)) && defined(OGL4_LOG)
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
#endif
None
};
glxContext = glXCreateContextAttribsARB(NativeDisplay, fbc[0], 0, true, context_attribs);
if (!glxContext) {
ZZLog::Error_Log("GLX: failed to create an opengl context");
return false;
}
XSync( NativeDisplay, false);
if (!glXMakeCurrent(NativeDisplay, NativeWindow, glxContext)) {
ZZLog::Error_Log("GLX: failed to attach the opengl context");
return false;
}
return true;
}
#endif
bool GLWindow::CreateContextGL()
{
bool ret;
#if defined(OGL4_LOG) || defined(GLSL4_API)
// We need to define a debug context. So we need at a 3.0 context (if not 3.2 actually)
ret = CreateContextGL(3, 3);
#else
// FIXME there was some issue with previous context creation on Geforce7. Code was rewritten
// for GSdx unfortunately it was not tested on Geforce7 so keep the 2.0 context for now.
// Note: Geforce 6&7 was dropped from nvidia driver (2012)
#if 0
ret = CreateContextGL(3, 0)
if (! ret )
ret = CreateContextGL(2, 0);
#else
ret = CreateContextGL(2, 0);
#endif
#endif
return ret;
}
#ifdef EGL_API
bool GLWindow::CreateContextGL(int major, int minor)
{
EGLConfig eglConfig;
EGLint numConfigs;
EGLint contextAttribs[] =
{
EGL_CONTEXT_MAJOR_VERSION_KHR, major,
EGL_CONTEXT_MINOR_VERSION_KHR, minor,
// Keep compatibility for old cruft
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
//EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
// FIXME : Request a debug context to ease opengl development
#if defined(ZEROGS_DEVBUILD) || defined(_DEBUG)
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR,
#endif
EGL_NONE
};
EGLint attrList[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
eglBindAPI(EGL_OPENGL_API);
if ( !eglChooseConfig(eglDisplay, attrList, &eglConfig, 1, &numConfigs) )
{
ZZLog::Error_Log("EGL: Failed to get a frame buffer config!");
return EGL_FALSE;
}
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, NativeWindow, NULL);
if ( eglSurface == EGL_NO_SURFACE )
{
ZZLog::Error_Log("EGL: Failed to get a window surface");
return EGL_FALSE;
}
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs );
if ( eglContext == EGL_NO_CONTEXT )
{
ZZLog::Error_Log("EGL: Failed to create the context");
ZZLog::Error_Log("EGL STATUS: %x", eglGetError());
return EGL_FALSE;
}
if ( !eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) )
{
return EGL_FALSE;
}
return EGL_TRUE;
}
#endif
#ifdef USE_GSOPEN2
bool GLWindow::DisplayWindow(int _width, int _height)
{
GetWindowSize();
if ( !CreateContextGL() ) return false;
PrintProtocolVersion();
return true;
}
#else
bool GLWindow::DisplayWindow(int _width, int _height)
{
backbuffer.w = _width;
backbuffer.h = _height;
NativeWindow = XCreateSimpleWindow(NativeDisplay, DefaultRootWindow(NativeDisplay), conf.x, conf.y, backbuffer.w, backbuffer.h, 0, 0, 0);
// Draw the window
XMapRaised(NativeDisplay, NativeWindow);
XSync(NativeDisplay, false);
if ( !CreateContextGL() ) return false;
PrintProtocolVersion();
GetWindowSize();
return true;
}
#endif
void* GLWindow::GetProcAddress(const char *function)
{
#ifdef EGL_API
return (void*)eglGetProcAddress(function);
#endif
#ifdef GLX_API
return (void*)glXGetProcAddress((const GLubyte*)function);
#endif
}
void GLWindow::SwapGLBuffers()
{
if (glGetError() != GL_NO_ERROR) ZZLog::Debug_Log("glError before swap!");
ZZLog::Check_GL_Error();
#ifdef GLX_API
glXSwapBuffers(NativeDisplay, NativeWindow);
#endif
#ifdef EGL_API
eglSwapBuffers(eglDisplay, eglSurface);
#endif
// glClear(GL_COLOR_BUFFER_BIT);
}
void GLWindow::InitVsync(bool extension)
{
#ifdef GLX_API
vsync_supported = false;
if (extension) {
swapinterval = (_PFNSWAPINTERVAL)GetProcAddress("glXSwapInterval");
if (!swapinterval)
swapinterval = (_PFNSWAPINTERVAL)GetProcAddress("glXSwapIntervalSGI");
if (!swapinterval)
swapinterval = (_PFNSWAPINTERVAL)GetProcAddress("glXSwapIntervalEXT");
if (swapinterval) {
swapinterval(0);
vsync_supported = true;
} else {
ZZLog::Error_Log("GLX: No support for SwapInterval (framerate clamped to monitor refresh rate),");
}
}
#endif
}
void GLWindow::SetVsync(bool enable)
{
fprintf(stderr, "change vsync %d\n", enable);
#ifdef EGL_API
eglSwapInterval(eglDisplay, enable);
#endif
#ifdef GLX_API
if (vsync_supported && swapinterval) {
swapinterval(enable);
}
#endif
}
u32 THR_KeyEvent = 0; // Value for key event processing between threads
bool THR_bShift = false;
bool THR_bCtrl = false;
void GLWindow::ProcessEvents()
{
FUNCLOG
#ifdef USE_GSOPEN2
GetWindowSize();
#endif
if (THR_KeyEvent) // This value was passed from GSKeyEvents which could be in another thread
{
int my_KeyEvent = THR_KeyEvent;
bool my_bShift = THR_bShift;
bool my_bCtrl = THR_bCtrl;
THR_KeyEvent = 0;
switch (my_KeyEvent)
{
case XK_F5:
case XK_F6:
case XK_F7:
case XK_F9:
// Note: to avoid some clash with PCSX2 shortcut in GSOpen2.
// GS shortcut will only be activated when ctrl is press
if (my_bCtrl)
OnFKey(my_KeyEvent - XK_F1 + 1, my_bShift);
break;
}
}
}
// ************************** Function that are useless in GSopen2 (GSopen 1 is only used with the debug replayer)
void GLWindow::SetTitle(char *strtitle) { }
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +0,0 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "GSDump.h"
GSDump::GSDump()
: m_gs(NULL)
, m_frames(0)
{
}
GSDump::~GSDump()
{
Close();
}
void GSDump::Open(const string& fn, u32 crc, const freezeData& fd, u8* regs)
{
if (m_gs) return;
m_gs = fopen(fn.c_str(), "wb");
m_frames = 0;
if(m_gs)
{
fwrite(&crc, 4, 1, m_gs);
fwrite(&fd.size, 4, 1, m_gs);
fwrite(fd.data, fd.size, 1, m_gs);
fwrite(regs, 0x2000, 1, m_gs);
}
}
void GSDump::Close()
{
if(m_gs) {
fclose(m_gs);
m_gs = NULL;
fprintf(stderr, "Closing GS dump");
}
}
void GSDump::Transfer(int index, const u32* mem, size_t size, u32 real_size)
{
if(m_gs && size > 0)
{
fputc(0, m_gs);
fputc(index, m_gs);
fwrite(&size, 4, 1, m_gs);
fwrite(&real_size, 4, 1, m_gs);
fwrite(mem, size, 1, m_gs);
}
}
void GSDump::ReadFIFO(u32 size)
{
if(m_gs && size > 0)
{
fputc(2, m_gs);
fwrite(&size, 4, 1, m_gs);
}
}
void GSDump::VSync(int field, bool last, u8* regs)
{
if(m_gs)
{
fputc(3, m_gs);
fwrite(regs, 0x2000, 1, m_gs);
fputc(1, m_gs);
fwrite(&field, 4, 1, m_gs);
if((++m_frames & 1) == 0 && last)
{
Close();
}
}
}

View File

@ -1,65 +0,0 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "Util.h"
using namespace std;
/*
Dump file format:
- [crc/4] [state size/4] [state data/size] [PMODE/0x2000] [id/1] [data/?] .. [id/1] [data/?]
Transfer data (id == 0)
- [0/1] [path index/1] [size/4] [data/size]
VSync data (id == 1)
- [1/1] [field/1]
ReadFIFO2 data (id == 2)
- [2/1] [size/?]
Regs data (id == 3)
- [PMODE/0x2000]
*/
class GSDump
{
FILE* m_gs;
int m_frames;
public:
GSDump();
virtual ~GSDump();
void Open(const string& fn, u32 crc, const freezeData& fd, u8* regs);
void Close();
void ReadFIFO(u32 size);
void Transfer(int index, const u32* mem, size_t size, u32 real_size);
void VSync(int field, bool last, u8* regs);
operator bool() {return m_gs != NULL;}
};
extern GSDump g_dump;

View File

@ -1,75 +0,0 @@
/*
* Copyright (C) 2011-2011 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
// Note: it is same code that was developed for GSdx plugin
#pragma once
#ifdef GLSL4_API
class GSUniformBufferOGL {
GLuint buffer; // data object
GLuint index; // GLSL slot
uint size; // size of the data
const GLenum target;
public:
GSUniformBufferOGL(GLuint index, uint size) : index(index)
, size(size)
,target(GL_UNIFORM_BUFFER)
{
glGenBuffers(1, &buffer);
bind();
allocate();
attach();
}
void bind()
{
glBindBuffer(target, buffer);
}
void allocate()
{
glBufferData(target, size, NULL, GL_STREAM_DRAW);
}
void attach()
{
glBindBufferBase(target, index, buffer);
}
void upload(const void* src)
{
// uint32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
// uint8* dst = (uint8*) glMapBufferRange(target, 0, size, flags);
// memcpy(dst, src, size);
// glUnmapBuffer(target);
// glMapBufferRange allow to set various parameter but the call is
// synchronous whereas glBufferSubData could be asynchronous.
// TODO: investigate the extension ARB_invalidate_subdata
glBufferSubData(target, 0, size, src);
}
~GSUniformBufferOGL() {
glDeleteBuffers(1, &buffer);
}
};
#endif

View File

@ -1,287 +0,0 @@
/*
* Copyright (C) 2011-2011 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
// Note: it is same code that was developed for GSdx plugin
#pragma once
#ifdef GLSL4_API
struct GSInputLayoutOGL {
GLuint index;
GLint size;
GLenum type;
GLboolean normalize;
GLsizei stride;
const GLvoid* offset;
};
class GSBufferOGL {
const size_t m_stride;
size_t m_start;
size_t m_count;
size_t m_limit;
const GLenum m_target;
GLuint m_buffer;
public:
GSBufferOGL(GLenum target, size_t stride) :
m_stride(stride)
, m_start(0)
, m_count(0)
, m_limit(0)
, m_target(target)
{
glGenBuffers(1, &m_buffer);
// Opengl works best with 1-4MB buffer.
m_limit = 2 * 1024 * 1024 / m_stride;
}
~GSBufferOGL() { glDeleteBuffers(1, &m_buffer); }
void allocate() { allocate(m_limit); }
void allocate(size_t new_limit)
{
m_start = 0;
m_limit = new_limit;
glBufferData(m_target, m_limit * m_stride, NULL, GL_STREAM_DRAW);
}
void bind()
{
glBindBuffer(m_target, m_buffer);
}
void upload(const void* src, uint32 count)
{
#if 0
// Upload the data to the buffer
void* dst;
if (Map(&dst, count)) {
// FIXME which one to use
// GSVector4i::storent(dst, src, m_count * m_stride);
memcpy(dst, src, m_stride*m_count);
Unmap();
}
#else
m_count = count;
// Current GPU buffer is really too small need to allocate a new one
if (m_count > m_limit) {
allocate(std::max<int>(m_count * 3 / 2, m_limit));
} else if (m_count > (m_limit - m_start) ) {
// Not enough left free room. Just go back at the beginning
m_start = 0;
// Orphan the buffer to avoid synchronization
allocate(m_limit);
}
glBufferSubData(m_target, m_stride * m_start, m_stride * m_count, src);
#endif
}
bool Map(void** pointer, uint32 count ) {
m_count = count;
// Note: For an explanation of the map flag
// see http://www.opengl.org/wiki/Buffer_Object_Streaming
uint32 map_flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
// Current GPU buffer is really too small need to allocate a new one
if (m_count > m_limit) {
allocate(std::max<int>(m_count * 3 / 2, m_limit));
} else if (m_count > (m_limit - m_start) ) {
// Not enough left free room. Just go back at the beginning
m_start = 0;
// Tell the driver that it can orphan previous buffer and restart from a scratch buffer.
// Technically the buffer will not be accessible by the application anymore but the
// GL will effectively remove it when draws call are finised.
map_flags |= GL_MAP_INVALIDATE_BUFFER_BIT;
} else {
// Tell the driver that it doesn't need to contain any valid buffer data, and that you promise to write the entire range you map
map_flags |= GL_MAP_INVALIDATE_RANGE_BIT;
}
// Upload the data to the buffer
*pointer = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags);
return true;
}
void Unmap() { glUnmapBuffer(m_target); }
void EndScene()
{
m_start += m_count;
m_count = 0;
}
void Draw(GLenum mode)
{
glDrawArrays(mode, m_start, m_count);
}
void Draw(GLenum mode, GLint basevertex)
{
glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex);
}
void Draw(GLenum mode, GLint basevertex, int offset, int count)
{
glDrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex);
}
size_t GetStart() { return m_start; }
void debug()
{
fprintf(stderr, "data buffer: start %d, count %d\n", m_start, m_count);
}
};
class GSVertexBufferStateOGL {
GSBufferOGL *m_vb;
GSBufferOGL *m_ib;
GLuint m_va;
GLenum m_topology;
// DEBUG
vector<GSInputLayoutOGL> layout_store;
public:
GSVertexBufferStateOGL(size_t stride, GSInputLayoutOGL* layout, uint32 layout_nbr)
{
glGenVertexArrays(1, &m_va);
layout_store.clear();
m_vb = new GSBufferOGL(GL_ARRAY_BUFFER, stride);
m_ib = new GSBufferOGL(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32));
bind();
// Note: index array are part of the VA state so it need to be bind only once.
m_ib->bind();
m_vb->allocate();
m_ib->allocate();
set_internal_format(layout, layout_nbr);
}
void bind()
{
glBindVertexArray(m_va);
m_vb->bind();
}
void set_internal_format()
{
for (vector<GSInputLayoutOGL>::iterator it = layout_store.begin(); it != layout_store.end(); it++)
set_internal_format(*it);
}
void set_internal_format(GSInputLayoutOGL& layout) {
// Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer
glEnableVertexAttribArray(layout.index);
switch (layout.type) {
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
case GL_SHORT:
case GL_INT:
// Rule: when shader use integral (not normalized) you must use glVertexAttribIPointer (note the extra I)
if (layout.normalize == false)
glVertexAttribIPointer(layout.index, layout.size, layout.type, layout.stride, layout.offset);
else
glVertexAttribPointer(layout.index, layout.size, layout.type, layout.normalize, layout.stride, layout.offset);
break;
default:
glVertexAttribPointer(layout.index, layout.size, layout.type, layout.normalize, layout.stride, layout.offset);
break;
}
}
void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr)
{
for (uint i = 0; i < layout_nbr; i++) {
// DEBUG
layout_store.push_back(layout[i]);
set_internal_format(layout[i]);
}
}
void EndScene()
{
m_vb->EndScene();
m_ib->EndScene();
}
void DrawPrimitive() { m_vb->Draw(m_topology); }
void DrawIndexedPrimitive() { m_ib->Draw(m_topology, m_vb->GetStart() ); }
void DrawIndexedPrimitive(int offset, int count) { m_ib->Draw(m_topology, m_vb->GetStart(), offset, count ); }
void SetTopology(GLenum topology) { m_topology = topology; }
void UploadVB(const void* vertices, size_t count) { m_vb->upload(vertices, count); }
void UploadIB(const void* index, size_t count) { m_ib->upload(index, count); }
bool MapVB(void **pointer, size_t count) { return m_vb->Map(pointer, count); }
void UnmapVB() { m_vb->Unmap(); }
~GSVertexBufferStateOGL()
{
glDeleteVertexArrays(1, &m_va);
delete m_vb;
delete m_ib;
}
void debug()
{
string topo;
switch (m_topology) {
case GL_POINTS:
topo = "point";
break;
case GL_LINES:
topo = "line";
break;
case GL_TRIANGLES:
topo = "triangle";
break;
case GL_TRIANGLE_STRIP:
topo = "triangle strip";
break;
}
m_vb->debug();
m_ib->debug();
fprintf(stderr, "primitives of %s\n", topo.c_str());
}
};
#endif

View File

@ -1,837 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "Util.h"
#include "GS.h"
#include "Profile.h"
#include "GLWin.h"
#include "ZZoglFlushHack.h"
#include "ZZoglShaders.h"
using namespace std;
extern void SaveSnapshot(const char* filename);
#ifdef _MSC_VER
#pragma warning(disable:4244)
#endif
GLWindow GLWin;
GSinternal gs;
GSconf conf;
GSDump g_dump;
int ppf, g_GSMultiThreaded, CurrentSavestate = 0;
int g_LastCRC = 0, g_TransferredToGPU = 0, s_frameskipping = 0;
int g_SkipFlushFrame = 0;
GetSkipCount GetSkipCount_Handler = 0;
int UPDATE_FRAMES = 16, g_nFrame = 0, g_nRealFrame = 0;
float fFPS = 0;
void (*GSirq)();
u8* g_pBasePS2Mem = NULL;
wxString s_strIniPath(L"inis"); // Air's new ini path (r2361)
bool SaveStateExists = true; // We could not know save slot status before first change occured
const char* SaveStateFile = NULL; // Name of SaveFile for access check.
extern const char* s_aa[5];
extern const char* pbilinear[];
// statistics
u32 g_nGenVars = 0, g_nTexVars = 0, g_nAlphaVars = 0, g_nResolve = 0;
#define VER 4
const unsigned char zgsversion = PS2E_GS_VERSION;
unsigned char zgsrevision = 0; // revision and build gives plugin version
unsigned char zgsbuild = VER;
unsigned char zgsminor = 0;
#ifdef _DEBUG
const char *libraryName = "ZZ Ogl PG (Debug) ";
#elif defined(ZEROGS_DEVBUILD)
const char *libraryName = "ZZ Ogl PG (Dev)";
#else
const char *libraryName = "ZZ Ogl PG ";
#endif
extern int g_nPixelShaderVer, g_nFrameRender, g_nFramesSkipped;
extern void WriteAA();
extern void WriteBilinear();
extern void ZZDestroy();
extern bool ZZCreate(int width, int height);
extern void ZZGSStateReset();
extern int ZZSave(s8* pbydata);
extern bool ZZLoad(s8* pbydata);
// switches the render target to the real target, flushes the current render targets and renders the real image
extern void RenderCRTC();
#if defined(_WIN32) && defined(_DEBUG)
HANDLE g_hCurrentThread = NULL;
#endif
extern int VALIDATE_THRESH;
extern u32 TEXDESTROY_THRESH;
EXPORT_C_(u32) PS2EgetLibType()
{
return PS2E_LT_GS;
}
EXPORT_C_(const char*) PS2EgetLibName()
{
return libraryName;
}
EXPORT_C_(u32) PS2EgetLibVersion2(u32 type)
{
return (zgsversion << 16) | (zgsrevision << 8) | zgsbuild | (zgsminor << 24);
}
EXPORT_C_(void) GSsetBaseMem(void* pmem)
{
g_pBasePS2Mem = (u8*)pmem;
}
EXPORT_C_(void) GSsetSettingsDir(const char* dir)
{
s_strIniPath = (dir == NULL) ? wxString(L"inis") : wxString(dir, wxConvFile);
}
EXPORT_C_(void) GSsetLogDir(const char* dir)
{
ZZLog::SetDir(dir);
}
EXPORT_C_(void) GSsetGameCRC(int crc, int options)
{
// build a list of function pointer for GetSkipCount (SkipDraw)
static GetSkipCount GSC_list[NUMBER_OF_TITLES];
static bool inited = false;
if (!inited)
{
inited = true;
memset(GSC_list, 0, sizeof(GSC_list));
GSC_list[Okami] = GSC_Okami;
GSC_list[MetalGearSolid3] = GSC_MetalGearSolid3;
GSC_list[DBZBT2] = GSC_DBZBT2;
GSC_list[DBZBT3] = GSC_DBZBT3;
GSC_list[SFEX3] = GSC_SFEX3;
GSC_list[Bully] = GSC_Bully;
GSC_list[BullyCC] = GSC_BullyCC;
GSC_list[SoTC] = GSC_SoTC;
GSC_list[OnePieceGrandAdventure] = GSC_OnePieceGrandAdventure;
GSC_list[OnePieceGrandBattle] = GSC_OnePieceGrandBattle;
GSC_list[ICO] = GSC_ICO;
GSC_list[GT4] = GSC_GT4;
GSC_list[WildArms4] = GSC_WildArms4;
GSC_list[WildArms5] = GSC_WildArms5;
GSC_list[Manhunt2] = GSC_Manhunt2;
GSC_list[CrashBandicootWoC] = GSC_CrashBandicootWoC;
GSC_list[ResidentEvil4] = GSC_ResidentEvil4;
GSC_list[Spartan] = GSC_Spartan;
GSC_list[AceCombat4] = GSC_AceCombat4;
GSC_list[Drakengard2] = GSC_Drakengard2;
GSC_list[Tekken5] = GSC_Tekken5;
GSC_list[IkkiTousen] = GSC_IkkiTousen;
GSC_list[GodOfWar] = GSC_GodOfWar;
GSC_list[GodOfWar2] = GSC_GodOfWar2;
GSC_list[GiTS] = GSC_GiTS;
GSC_list[Onimusha3] = GSC_Onimusha3;
GSC_list[TalesOfAbyss] = GSC_TalesOfAbyss;
GSC_list[SonicUnleashed] = GSC_SonicUnleashed;
GSC_list[Genji] = GSC_Genji;
GSC_list[StarOcean3] = GSC_StarOcean3;
GSC_list[ValkyrieProfile2] = GSC_ValkyrieProfile2;
GSC_list[RadiataStories] = GSC_RadiataStories;
}
// TEXDESTROY_THRESH starts out at 16.
VALIDATE_THRESH = 8;
conf.mrtdepth = (conf.settings().disable_mrt_depth != 0);
if (!conf.mrtdepth)
ZZLog::WriteLn("Disabling MRT depth writing.");
else
ZZLog::WriteLn("Enabling MRT depth writing.");
bool CRCValueChanged = (g_LastCRC != crc);
g_LastCRC = crc;
if (crc != 0) ZZLog::WriteLn("Current game CRC is %x.", crc);
if (CRCValueChanged && (crc != 0))
{
for (u32 i = 0; i < GAME_INFO_INDEX; i++)
{
if (crc_game_list[i].crc == (u32)crc)
{
ZZLog::WriteLn("Found CRC[%x] in crc game list.", crc);
if (crc_game_list[i].v_thresh > 0)
{
VALIDATE_THRESH = crc_game_list[i].v_thresh;
ZZLog::WriteLn("Setting VALIDATE_THRESH to %d", VALIDATE_THRESH);
}
if (crc_game_list[i].t_thresh > 0)
{
TEXDESTROY_THRESH = crc_game_list[i].t_thresh;
ZZLog::WriteLn("Setting TEXDESTROY_THRESH to %d", TEXDESTROY_THRESH);
}
// FIXME need to check SkipDraw is positive (enabled by users)
GetSkipCount_Handler = GSC_list[crc_game_list[i].title];
if (!conf.disableHacks)
{
conf.def_hacks._u32 |= crc_game_list[i].flags;
ListHacks();
}
return;
}
}
}
ListHacks();
}
EXPORT_C_(void) GSsetFrameSkip(int frameskip)
{
FUNCLOG
s_frameskipping |= frameskip;
if (frameskip && g_nFrameRender > 1)
{
SetFrameSkip(true);
}
else if (!frameskip && g_nFrameRender <= 0)
{
SetFrameSkip(false);
}
}
EXPORT_C_(void) GSreset()
{
FUNCLOG
memset(&gs, 0, sizeof(gs));
ZZGSStateReset();
gs.prac = 1;
prim = &gs._prim[0];
gs.transferring = false;
gs.q = 1;
}
EXPORT_C_(void) GSgifSoftReset(u32 mask)
{
FUNCLOG
if (mask & 1) memset(&gs.path[0], 0, sizeof(gs.path[0]));
if (mask & 2) memset(&gs.path[1], 0, sizeof(gs.path[1]));
if (mask & 4) memset(&gs.path[2], 0, sizeof(gs.path[2]));
gs.transferring = false;
gs.q = 1;
}
EXPORT_C_(s32) GSinit()
{
FUNCLOG
ZZLog::Open();
ZZLog::WriteLn("Calling GSinit.");
WriteTempRegs();
GSreset();
ZZLog::WriteLn("GSinit finished.");
return 0;
}
__forceinline void InitMisc()
{
WriteBilinear();
WriteAA();
InitProfile();
InitPath();
ResetRegs();
}
EXPORT_C_(s32) GSopen(void *pDsp, const char *Title, int multithread)
{
FUNCLOG
g_GSMultiThreaded = multithread;
ZZLog::WriteLn("Calling GSopen.");
#if defined(_WIN32) && defined(_DEBUG)
g_hCurrentThread = GetCurrentThread();
#endif
LoadConfig();
strcpy(GLWin.title, Title);
ZZLog::GS_Log("Using %s:%d.%d.%d.", libraryName, zgsrevision, zgsbuild, zgsminor);
ZZLog::WriteLn("Creating ZZOgl window.");
if ((!GLWin.CreateWindow(pDsp)) || (!ZZCreate(conf.width, conf.height))) return -1;
ZZLog::WriteLn("Initialization successful.");
InitMisc();
ZZLog::GS_Log("GSopen finished.");
return 0;
}
#ifdef USE_GSOPEN2
EXPORT_C_(s32) GSopen2( void* pDsp, u32 flags )
{
FUNCLOG
g_GSMultiThreaded = true;
ZZLog::WriteLn("Calling GSopen2.");
#if defined(_WIN32) && defined(_DEBUG)
g_hCurrentThread = GetCurrentThread();
#endif
LoadConfig();
ZZLog::GS_Log("Using %s:%d.%d.%d.", libraryName, zgsrevision, zgsbuild, zgsminor);
ZZLog::WriteLn("Capturing ZZOgl window.");
if ((!GLWin.CreateWindow(pDsp)) || (!ZZCreate(conf.width, conf.height))) return -1;
ZZLog::WriteLn("Initialization successful.");
InitMisc();
ZZLog::GS_Log("GSopen2 finished.");
ZZLog::Check_GL_Error();
return 0;
}
#endif
EXPORT_C_(void) GSshutdown()
{
FUNCLOG
ZZLog::Close();
}
EXPORT_C_(void) GSclose()
{
FUNCLOG
// Clean shader. Must be done before the context is delete
ZZshExitCleaning();
ZZDestroy();
GLWin.CloseWindow();
// Free alocated memory. We could close plugin without closing pcsx2, so we SHOULD free all allocated resources
SaveStateFile = NULL;
SaveStateExists = true; // default value
g_LastCRC = 0;
}
EXPORT_C_(void) GSirqCallback(void (*callback)())
{
FUNCLOG
GSirq = callback;
}
EXPORT_C_(void) GSwriteCSR(u32 write)
{
FUNCLOG
gs.CSRw = write;
}
#ifdef _WIN32
#define access _access
#endif
EXPORT_C_(void) GSchangeSaveState(int newstate, const char* filename)
{
FUNCLOG
char str[255];
sprintf(str, "save state %d", newstate);
ZZAddMessage(str);
CurrentSavestate = newstate;
SaveStateFile = filename;
SaveStateExists = (access(SaveStateFile, 0) == 0);
}
static bool get_snapshot_filename(char *filename, const char* path, const char* extension)
{
FUNCLOG
FILE *bmpfile;
u32 snapshotnr = 0;
// increment snapshot value & try to get filename
for (;;)
{
snapshotnr++;
sprintf(filename, "%s/snap%03d.%s", path, snapshotnr, extension);
bmpfile = fopen(filename, "rb");
if (bmpfile == NULL) break;
fclose(bmpfile);
}
// try opening new snapshot file
if ((bmpfile = fopen(filename, "wb")) == NULL)
{
char strdir[255];
sprintf(strdir, "%s", path);
#ifdef _WIN32
CreateDirectory(wxString::FromUTF8(strdir), NULL);
#else
mkdir(path, 0777);
#endif
if ((bmpfile = fopen(filename, "wb")) == NULL) return false;
}
fclose(bmpfile);
return true;
}
EXPORT_C_(void) GSmakeSnapshot(char *path)
{
FUNCLOG
char filename[256];
if (get_snapshot_filename(filename, (const char*)path, (conf.zz_options.tga_snap) ? "bmp" : "jpg"))
SaveSnapshot(filename);
}
// I'll probably move this somewhere else later, but it's got a ton of dependencies.
static __forceinline void SetGSTitle()
{
char strtitle[256];
#if !defined(ZEROGS_DEVBUILD)
const char* g_pShaders[4] = { "full", "reduced", "accurate", "accurate-reduced" };
const char* g_pInterlace[3] = { "interlace 0 |", "interlace 1 |", "" };
const char* g_pBilinear[3] = { "", "bilinear |", "forced bilinear |" };
if (SaveStateFile != NULL && !SaveStateExists)
SaveStateExists = (access(SaveStateFile, 0) == 0);
else
SaveStateExists = true;
sprintf(strtitle, "ZZ Open GL 0.%d.%d | %.1f fps | %s%s%s savestate %d%s | shaders %s | (%.1f)", zgsbuild, zgsminor, fFPS,
g_pInterlace[conf.interlace], g_pBilinear[conf.bilinear], (conf.aa ? s_aa[conf.aa] : ""),
CurrentSavestate, (SaveStateExists ? "" : "*"),
g_pShaders[g_nPixelShaderVer], (ppf&0xfffff) / (float)UPDATE_FRAMES);
#else
sprintf(strtitle, "%d | %.1f fps (sk:%d%%) | g: %.1f, t: %.1f, a: %.1f, r: %.1f | p: %.1f | tex: %d %d (%d kbpf)", g_nFrame, fFPS,
100*g_nFramesSkipped / g_nFrame,
g_nGenVars / (float)UPDATE_FRAMES, g_nTexVars / (float)UPDATE_FRAMES, g_nAlphaVars / (float)UPDATE_FRAMES,
g_nResolve / (float)UPDATE_FRAMES, (ppf&0xfffff) / (float)UPDATE_FRAMES,
g_MemTargs.listTargets.size(), g_MemTargs.listClearedTargets.size(), g_TransferredToGPU >> 10);
//_snprintf(strtitle, 512, "%x %x", *(int*)(g_pbyGSMemory + 256 * 0x3e0c + 4), *(int*)(g_pbyGSMemory + 256 * 0x3e04 + 4));
#endif
// if( g_nFrame > 100 && fFPS > 60.0f ) {
// ZZLog::Debug_Log("Set profile.");
// g_bWriteProfile = 1;
// }
GLWin.SetTitle(strtitle);
}
// This isn't implemented for some reason? Adding a field for it for the moment, till I get a chance to look closer.
EXPORT_C_(void) GSsetVsync(int enabled)
{
FUNCLOG
ZZLog::Debug_Log("Setting VSync to 0x%x.", enabled);
gs.vsync = enabled;
GLWin.SetVsync(enabled);
}
EXPORT_C_(void) GSvsync(int current_interlace)
{
FUNCLOG
//ZZLog::GS_Log("Calling GSvsync.");
static u32 dwTime = timeGetTime();
static int nToNextUpdate = 1;
#ifdef _DEBUG
if (conf.dump & 0x1) {
freezeData fd;
fd.size = ZZSave(NULL);
s8* payload = (s8*)malloc(fd.size);
fd.data = payload;
ZZSave(fd.data);
char filename[256];
// FIXME, there is probably a better solution than /tmp ...
// A possibility will be to save the path from GSmakeSnapshot but you still need to call
// GSmakeSnapshot first.
if (get_snapshot_filename(filename, "/tmp", "gs"))
g_dump.Open(filename, g_LastCRC, fd, g_pBasePS2Mem);
conf.dump--;
free(payload);
}
g_dump.VSync(current_interlace, (conf.dump == 0), g_pBasePS2Mem);
#endif
GL_REPORT_ERRORD();
g_nRealFrame++;
// The value passed seems to either be 0 or 0x2000, and we want 0 or 1. Perhaps !! would be better...
gs.interlace = !current_interlace;
RenderCRTC();
GLWin.ProcessEvents();
if (--nToNextUpdate <= 0)
{
u32 d = timeGetTime();
fFPS = UPDATE_FRAMES * 1000.0f / (float)max(d - dwTime, (u32)1);
dwTime = d;
g_nFrame += UPDATE_FRAMES;
#ifndef USE_GSOPEN2
// let PCSX2 manage the title
SetGSTitle();
#endif
// if( g_nFrame > 100 && fFPS > 60.0f ) {
// ZZLog::Debug_Log("Set profile.");
// g_bWriteProfile = 1;
// }
if (fFPS < 16)
UPDATE_FRAMES = 4;
else if (fFPS < 32)
UPDATE_FRAMES = 8;
else
UPDATE_FRAMES = 16;
nToNextUpdate = UPDATE_FRAMES;
ppf = 0;
g_TransferredToGPU = 0;
g_nGenVars = 0;
g_nTexVars = 0;
g_nAlphaVars = 0;
g_nResolve = 0;
g_nFramesSkipped = 0;
g_SkipFlushFrame = 0;
}
#if defined(ZEROGS_DEVBUILD)
if (g_bWriteProfile)
{
//g_bWriteProfile = 0;
DVProfWrite("prof.txt", UPDATE_FRAMES);
DVProfClear();
}
#endif
GL_REPORT_ERRORD();
}
EXPORT_C_(void) GSreadFIFO(u64 *pMem)
{
FUNCLOG
//ZZLog::GS_Log("Calling GSreadFIFO.");
#ifdef _DEBUG
g_dump.ReadFIFO(1);
#endif
TransferLocalHost((u32*)pMem, 1);
}
EXPORT_C_(void) GSreadFIFO2(u64 *pMem, int qwc)
{
FUNCLOG
//ZZLog::GS_Log("Calling GSreadFIFO2.");
#ifdef _DEBUG
g_dump.ReadFIFO(qwc);
#endif
TransferLocalHost((u32*)pMem, qwc);
}
EXPORT_C_(int) GSsetupRecording(int start, void* pData)
{
FUNCLOG
if (start)
StartCapture();
else
StopCapture();
return 1;
}
EXPORT_C_(s32) GSfreeze(int mode, freezeData *data)
{
FUNCLOG
switch (mode)
{
case FREEZE_LOAD:
if (!ZZLoad(data->data)) ZZLog::Error_Log("GS: Bad load format!");
g_nRealFrame += 100;
break;
case FREEZE_SAVE:
ZZSave(data->data);
break;
case FREEZE_SIZE:
data->size = ZZSave(NULL);
break;
default:
break;
}
return 0;
}
#ifdef __linux__
void _fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
static uint32 read_cnt = 0;
read_cnt++;
size_t result = fread(ptr, size, nmemb, stream);
if (result != nmemb) {
fprintf(stderr, "Read error\n");
exit(read_cnt);
}
}
struct Packet
{
u8 type, param;
u32 size, addr;
u32 real_size;
vector<u32> buff;
};
EXPORT_C_(void) GSReplay(char* lpszCmdLine)
{
if(FILE* fp = fopen(lpszCmdLine, "rb"))
{
GSinit();
u8 regs[0x2000];
GSsetBaseMem(regs);
//s_vsync = !!theApp.GetConfig("vsync", 0);
void* hWnd = NULL;
const char* title = "replayer";
GSopen((void**)&hWnd, (char*)title, 0);
u32 crc;
_fread(&crc, 4, 1, fp);
GSsetGameCRC(crc, 0);
freezeData fd;
_fread(&fd.size, 4, 1, fp);
fd.data = new s8[fd.size];
_fread(fd.data, fd.size, 1, fp);
GSfreeze(FREEZE_LOAD, &fd);
delete [] fd.data;
_fread(regs, 0x2000, 1, fp);
GSvsync(1);
list<Packet*> packets;
vector<u8> buff;
int type;
while((type = fgetc(fp)) != EOF)
{
Packet* p = new Packet();
p->type = (u8)type;
switch(type)
{
case 0:
p->param = (u8)fgetc(fp);
_fread(&p->size, 4, 1, fp);
_fread(&p->real_size, 4, 1, fp);
switch(p->param)
{
case 0:
p->buff.resize(0x4000);
//p->addr = 0x4000 - p->size;
//fread(&p->buff[p->addr], p->size, 1, fp);
_fread(&p->buff[0], p->size, 1, fp);
break;
case 1:
case 2:
case 3:
p->buff.resize(p->size);
_fread(&p->buff[0], p->size, 1, fp);
break;
}
break;
case 1:
_fread(&p->param, 4, 1, fp);
//p->param = (u8)fgetc(fp);
break;
case 2:
_fread(&p->size, 4, 1, fp);
break;
case 3:
p->buff.resize(0x2000);
_fread(&p->buff[0], 0x2000, 1, fp);
break;
default: assert(0);
}
packets.push_back(p);
}
sleep(1);
//while(IsWindowVisible(hWnd))
//FIXME map?
int finished = 2;
while(finished > 0)
{
unsigned long start = timeGetTime();
unsigned long frame_number = 0;
for(list<Packet*>::iterator i = packets.begin(); i != packets.end(); i++)
{
Packet* p = *i;
switch(p->type)
{
case 0:
//fprintf(stderr, "TRANSFER %d size %d\n", p->param, p->real_size);
switch(p->param)
{
//case 0: GSgifTransfer1((u32*)&p->buff[0], p->addr); break;
case 0: GSgifTransfer0((u32*)&p->buff[0], p->real_size); break;
case 1: GSgifTransfer2((u32*)&p->buff[0], p->real_size); break;
case 2: GSgifTransfer3((u32*)&p->buff[0], p->real_size); break;
case 3: GSgifTransfer((u32*)&p->buff[0], p->real_size); break;
}
break;
case 1:
GSvsync(p->param);
frame_number++;
break;
case 2:
if(buff.size() < p->size) buff.resize(p->size);
// FIXME
// GSreadFIFO2(&buff[0], p->size / 16);
fprintf(stderr, "GSreadFIFO2 not yet implemented");
break;
case 3:
memcpy(regs, &p->buff[0], 0x2000);
break;
}
}
unsigned long end = timeGetTime();
fprintf(stderr, "The %ld frames of the scene was render on %ldms\n", frame_number, end - start);
fprintf(stderr, "A means of %fms by frame (limit 16ms/f)\n", (float)(end - start)/(float)frame_number);
sleep(1);
finished--;
}
for(list<Packet*>::iterator i = packets.begin(); i != packets.end(); i++)
{
delete *i;
}
packets.clear();
sleep(1);
GSclose();
GSshutdown();
fclose(fp);
}
}
#endif

View File

@ -1,298 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "GS.h"
#include "Mem.h"
#include "GifTransfer.h"
#ifdef _DEBUG
static int path1_count = 0;
#endif
static int nPath3Hack = 0;
EXPORT_C_(void) GSgetLastTag(u64* ptag)
{
FUNCLOG
*(u32*)ptag = nPath3Hack;
nPath3Hack = 0;
}
#ifdef _WIN32
// for debug assertion checks (thread affinity checks)
extern HANDLE g_hCurrentThread;
#endif
__forceinline void gifTransferLog(int index, const u32 *pMem, u32 size)
{
#ifdef DEBUG_TRANSFER
if (conf.log)
{
static int nSaveIndex = 0;
ZZLog::Debug_Log("%d: p:%d %x", nSaveIndex++, index + 1, size);
int vals[4] = {0};
for (u32 i = 0; i < size; i++)
{
for (u32 j = 0; j < 4; ++j)
vals[j] ^= pMem[4*i+j];
}
ZZLog::Debug_Log("%x %x %x %x", vals[0], vals[1], vals[2], vals[3]);
}
#endif
}
extern int g_GSMultiThreaded;
template<int index> void _GSgifTransfer(const u32 *pMem, u32 size)
{
FUNCLOG
pathInfo *path = &gs.path[index];
#ifdef _WIN32
assert(g_hCurrentThread == GetCurrentThread());
#endif
#ifdef _DEBUG
gifTransferLog(index, pMem, size);
const u32* start = pMem;
u32 size_arg = size;
#endif
while (size > 0)
{
//LOG(_T("Transfer(%08x, %d) START\n"), pMem, size);
if (path->nloop == 0)
{
path->setTag(pMem);
pMem += 4;
size--;
// eeuser 7.2.2. GIFtag: "... when NLOOP is 0, the GIF does not output anything, and
// values other than the EOP field are disregarded."
if (path->nloop > 0)
{
gs.q = 1.0f;
if (path->tag.PRE && (path->tag.FLG == GIF_FLG_PACKED))
{
u64 tagprim = path->tag.PRIM;
GIFRegHandlerPRIM((u32*)&tagprim);
}
}
}
else
{
switch (path->mode)
{
case GIF_FLG_PACKED:
{
// Needs to be looked at.
// first try a shortcut for a very common case
if (path->adonly && size >= path->nloop)
{
size -= path->nloop;
do
{
GIFPackedRegHandlerA_D(pMem);
pMem += 4; //sizeof(GIFPackedReg)/4;
}
while(--path->nloop > 0);
break;
}
do
{
u32 reg = path->GetReg();
g_GIFPackedRegHandlers[reg](pMem);
pMem += 4; //sizeof(GIFPackedReg)/4;
size--;
}
while (path->StepReg() && (size > 0));
break;
}
case GIF_FLG_REGLIST:
{
// Needs to be looked at.
//ZZLog::GS_Log("%8.8x%8.8x %d L", ((u32*)&gs.regs)[1], *(u32*)&gs.regs, path->tag.nreg/4);
size *= 2;
do
{
g_GIFRegHandlers[path->GetReg()](pMem);
pMem += 2;
size--;
}
while (path->StepReg() && (size > 0));
if (size & 1) pMem += 2;
size /= 2;
break;
}
case GIF_FLG_IMAGE: // FROM_VFRAM
case GIF_FLG_IMAGE2: // Used in the DirectX version, so we'll use it here too.
{
int len = min(size, path->nloop);
//ZZLog::Error_Log("GIF_FLG_IMAGE(%d)=%d", gs.imageTransfer, len);
if (gs.transferring)
{
switch (gs.imageTransfer)
{
case XFER_HOST_TO_LOCAL:
TransferHostLocal(pMem, len * 4);
break;
case XFER_LOCAL_TO_HOST:
// This can't happen; downloads can not be started or performed as part of
// a GIFtag operation. They're an entirely separate process that can only be
// done through the ReverseFIFO transfer (aka ReadFIFO). --air
assert(0);
//TransferLocalHost(pMem, len);
break;
case XFER_LOCAL_TO_LOCAL:
//TransferLocalLocal();
break;
case XFER_DEACTIVATED:
//assert(0);
break;
default:
//assert(0);
break;
}
}
pMem += len * 4;
path->nloop -= len;
size -= len;
break;
}
default: // GIF_IMAGE
ZZLog::GS_Log("*** WARNING **** Unexpected GIFTag flag.");
assert(0);
path->nloop = 0;
break;
}
}
if (index == 0)
{
if (path->tag.EOP && path->nloop == 0)
{
break;
}
}
}
#ifdef _DEBUG
g_dump.Transfer(index, start, pMem - start + 4, size_arg);
#endif
// This is the case when not all data was readed from one try: VU1 has too much data.
// So we should redo reading from the start.
if (index == 0)
{
if (size == 0 && path->nloop > 0)
{
if (g_GSMultiThreaded)
{
path->nloop = 0;
}
else
{
_GSgifTransfer<0>(pMem - 0x4000, 0x4000 / 16);
}
}
}
}
// Used for replay
void GSgifTransfer0(u32 *pMem, u32 addr)
{
_GSgifTransfer<0>(pMem, addr);
}
EXPORT_C_(void) GSgifTransfer1(u32 *pMem, u32 addr)
{
FUNCLOG
//ZZLog::GS_Log("GSgifTransfer1 0x%x (mode %d).", addr, path->mode);
#ifdef _DEBUG
ZZLog::Prim_Log("count: %d\n", path1_count);
path1_count++;
#endif
_GSgifTransfer<0>((u32*)((u8*)pMem + addr), (0x4000 - addr) / 16);
}
EXPORT_C_(void) GSgifTransfer2(u32 *pMem, u32 size)
{
FUNCLOG
//ZZLog::GS_Log("GSgifTransfer2 size = %lx (mode %d, gs.path2.tag.nloop = %d).", size, gs.path[1].mode, gs.path[1].tag.nloop);
_GSgifTransfer<1>(const_cast<u32*>(pMem), size);
}
EXPORT_C_(void) GSgifTransfer3(u32 *pMem, u32 size)
{
FUNCLOG
//ZZLog::GS_Log("GSgifTransfer3 size = %lx (mode %d, gs.path3.tag.nloop = %d).", size, gs.path[2].mode, gs.path[2].tag.nloop);
_GSgifTransfer<2>(const_cast<u32*>(pMem), size);
}
EXPORT_C_(void) GSgifTransfer(const u32 *pMem, u32 size)
{
FUNCLOG
//ZZLog::GS_Log("GSgifTransfer3 size = %lx (mode %d, gs.path3.tag.nloop = %d).", size, gs.path[2].mode, gs.path[2].tag.nloop);
_GSgifTransfer<3>(pMem, size);
}
void InitPath()
{
gs.path[0].mode = gs.path[1].mode = gs.path[2].mode = gs.path[3].mode = 0;
}

View File

@ -1,134 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef GIFTRANSFER_H_INCLUDED
#define GIFTRANSFER_H_INCLUDED
#include "Util.h"
#include "GS.h"
#include "Regs.h"
enum GIF_FLG
{
GIF_FLG_PACKED = 0,
GIF_FLG_REGLIST = 1,
GIF_FLG_IMAGE = 2,
GIF_FLG_IMAGE2 = 3
};
//
// GIFTag
union GIFTag
{
u64 ai64[2];
u32 ai32[4];
struct
{
u32 NLOOP : 15;
u32 EOP : 1;
u32 _PAD1 : 16;
u32 _PAD2 : 14;
u32 PRE : 1;
u32 PRIM : 11;
u32 FLG : 2; // enum GIF_FLG
u32 NREG : 4;
u64 REGS : 64;
};
void set(const u32 *data)
{
for (int i = 0; i <= 3; i++)
{
ai32[i] = data[i];
}
}
GIFTag(u32 *data)
{
set(data);
}
GIFTag(){ ai64[0] = 0; ai64[1] = 0; }
};
// EE part. Data transfer packet description
typedef struct
{
u32 mode;
int reg;
u64 regs;
u32 nloop;
int eop;
int nreg;
u32 adonly;
GIFTag tag;
void setTag(const u32 *data)
{
tag.set(data);
nloop = tag.NLOOP;
eop = tag.EOP;
mode = tag.FLG;
adonly = false;
// Hmm....
nreg = tag.NREG << 2;
if (nreg == 0) nreg = 64;
regs = tag.REGS;
reg = 0;
if ((nreg == 4) && (regs == GIF_REG_A_D)) adonly = true;
// ZZLog::GS_Log("GIFtag: %8.8lx_%8.8lx_%8.8lx_%8.8lx: EOP=%d, NLOOP=%x, FLG=%x, NREG=%d, PRE=%d",
// data[3], data[2], data[1], data[0],
// path->eop, path->nloop, mode, path->nreg, tag.PRE);
}
u32 GetReg()
{
return (regs >> reg) & 0xf;
}
bool StepReg()
{
reg += 4;
if (reg == nreg)
{
reg = 0;
nloop--;
if (nloop == 0) return false;
}
return true;
}
} pathInfo;
extern void _GSgifPacket(pathInfo *path, const u32 *pMem);
extern void _GSgifRegList(pathInfo *path, const u32 *pMem);
extern void GSgifTransfer0(u32* pMem, u32 addr);
extern GIFRegHandler g_GIFPackedRegHandlers[];
extern GIFRegHandler g_GIFRegHandlers[];
extern void InitPath();
#endif // GIFTRANSFER_H_INCLUDED

View File

@ -1,620 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "GS.h"
#include <stdlib.h>
#include "Mem.h"
#include "x86.h"
#include "targets.h"
#include "ZZoglVB.h"
// flush current vertices, call before setting new registers (the main render method)
extern void Flush(int context);
u8* g_pbyGSMemory = NULL; // 4Mb GS system mem
void GSMemory::init()
{
const u32 mem_size = MEMORY_END + 0x10000; // leave some room for out of range accesses (saves on the checks)
// clear
g_pbyGSMemory = (u8*)_aligned_malloc(mem_size, 1024);
memset(g_pbyGSMemory, 0, mem_size);
}
void GSMemory::destroy()
{
_aligned_free(g_pbyGSMemory);
g_pbyGSMemory = NULL;
}
u8* GSMemory::get()
{
return g_pbyGSMemory;
}
u8* GSMemory::get(u32 addr)
{
return &g_pbyGSMemory[addr*8];
}
u8* GSMemory::get_raw(u32 addr)
{
return &g_pbyGSMemory[addr];
}
u8* g_pbyGSClut = NULL; // ZZ
void GSClut::init()
{
g_pbyGSClut = (u8*)_aligned_malloc(256 * 8, 1024); // need 512 alignment!
memset(g_pbyGSClut, 0, 256*8);
}
void GSClut::destroy()
{
_aligned_free(g_pbyGSClut);
g_pbyGSClut = NULL;
}
u8* GSClut::get()
{
return g_pbyGSClut;
}
u8* GSClut::get(u32 addr)
{
return &g_pbyGSClut[addr*8];
}
u8* GSClut::get_raw(u32 addr)
{
return &g_pbyGSClut[addr];
}
extern _getPixelAddress getPixelFun[64];
extern CRangeManager s_RangeMngr; // manages overwritten memory
extern void ResolveInRange(int start, int end);
static vector<u8> s_vTempBuffer, s_vTransferCache;
static int gs_imageEnd = 0;
// From the start of monster labs. In all 3 cases, psm == 0.
// ZZogl-PG: GetRectMemAddress(0x3f4000, 0x404000, 0x0, 0x0, 0x0, 0x100, 0x40, 0x3f40, 0x100);
// ZZogl-PG: GetRectMemAddress(0x3f8000, 0x408000, 0x0, 0x0, 0x0, 0x100, 0x40, 0x3f80, 0x100);
// ZZogl-PG: GetRectMemAddress(0x3fc000, 0x40c000, 0x0, 0x0, 0x0, 0x100, 0x40, 0x3fc0, 0x100);
void GetRectMemAddress(int& start, int& end, int psm, int x, int y, int w, int h, int bp, int bw)
{
FUNCLOG
u32 bits = 0;
if (m_Blocks[psm].bpp == 0)
{
ZZLog::Error_Log("ZeroGS: Bad psm 0x%x.", psm);
start = 0;
end = MEMORY_END;
return;
}
if (PSMT_ISZTEX(psm))
{
// This still needs an eye kept on it.
const BLOCK& b = m_Blocks[psm];
const int x2 = x + w + b.width - 1;
const int y2 = y + h - 1;
bw = bw / b.width;
start = (bp + ((y / b.height) * bw + (x / b.width)) * 0x20) * 0x100;
end = (bp + ((y2 / b.height) * bw + (x2 / b.width)) * 0x20) * 0x100;
return;
}
bits = PSMT_BITS_NUM(psm);
start = getPixelFun[psm](x, y, bp, bw);
end = getPixelFun[psm](x + w - 1, y + h - 1, bp, bw) + 1;
if (bits > 0)
{
start *= bits;
end *= bits;
}
else
{
start /= 2;
end /= 2;
}
}
// Same as GetRectMemAddress, except that we know x & y are zero, so it's simplified a bit.
void GetRectMemAddressZero(int& start, int& end, int psm, int w, int h, int bp, int bw)
{
FUNCLOG
u32 bits = 0;
if (m_Blocks[psm].bpp == 0)
{
ZZLog::Error_Log("ZeroGS: Bad psm 0x%x.", psm);
start = 0;
end = MEMORY_END;
return;
}
if (PSMT_ISZTEX(psm))
{
// This still needs an eye kept on it.
const BLOCK& b = m_Blocks[psm];
const int x2 = w + b.width - 1;
const int y2 = h - 1;
bw = bw / b.width;
start = bp * 0x100;
end = (bp + ((y2 / b.height) * bw + (x2 / b.width)) * 0x20) * 0x100;
return;
}
bits = PSMT_BITS_NUM(psm);
start = getPixelFun[psm](0, 0, bp, bw);
end = getPixelFun[psm](w - 1, h - 1, bp, bw) + 1;
if (bits > 0)
{
start *= bits;
end *= bits;
}
else
{
start /= 2;
end /= 2;
}
}
void GetRectMemAddress(int& start, int& end, int psm, Point p, Size s, int bp, int bw)
{
GetRectMemAddress(start, end, psm, p.x, p.y, s.w, s.h, bp, bw);
}
void GetRectMemAddress(int& start, int& end, int psm, int x, int y, Size s, int bp, int bw)
{
GetRectMemAddress(start, end, psm, x, y, s.w, s.h, bp, bw);
}
void GetRectMemAddressZero(int& start, int& end, int psm, Size s, int bp, int bw)
{
GetRectMemAddressZero(start, end, psm, s.w, s.h, bp, bw);
}
void InitTransferHostLocal()
{
FUNCLOG
#if defined(_DEBUG)
// Xenosaga 1.
if (gs.trxpos.dx + gs.imageNew.w > gs.dstbuf.bw)
ZZLog::Debug_Log("Transfer error, width exceeded. (0x%x > 0X%x)", gs.trxpos.dx + gs.imageNew.w, gs.dstbuf.bw);
#endif
//bool bHasFlushed = false;
gs.image.x = gs.trxpos.dx;
gs.image.y = gs.trxpos.dy;
gs.imageEnd.x = gs.image.x + gs.imageNew.w;
gs.imageEnd.y = gs.image.y + gs.imageNew.h;
assert(gs.imageEnd.x < 2048 && gs.imageEnd.y < 2048);
// This needs to be looked in to, since psm should *not* be 63.
// hack! viewful joe
if (gs.dstbuf.psm == 63)
{
ZZLog::WriteLn("gs.dstbuf.psm set to 0!");
gs.dstbuf.psm = 0;
}
int start, end;
GetRectMemAddress(start, end, gs.dstbuf.psm, gs.trxpos.dx, gs.trxpos.dy, gs.imageNew, gs.dstbuf.bp, gs.dstbuf.bw);
if (end > MEMORY_END)
{
// Monster Lab - the screwed up title screen
// Init host local out of bounds! (end == 0x404000)
// Init host local out of bounds! (end == 0x408000)
// Init host local out of bounds! (end == 0x40c000)
// MEMORY_END is 0x400000...
ZZLog::Warn_Log("Init host local out of bounds! (end == 0x%x)", end);
//gs.transferring = false;
end = MEMORY_END;
}
gs_imageEnd = end;
if (vb[0].nCount > 0) Flush(0);
if (vb[1].nCount > 0) Flush(1);
//ZZLog::Prim_Log("trans: bp:%x x:%x y:%x w:%x h:%x\n", gs.dstbuf.bp, gs.trxpos.dx, gs.trxpos.dy, gs.imageNew.w, gs.imageNew.h);
}
void TransferHostLocal(const void* pbyMem, u32 nQWordSize)
{
FUNCLOG
int start = -1, end = -1;
GetRectMemAddress(start, end, gs.dstbuf.psm, gs.image, gs.imageNew, gs.dstbuf.bp, gs.dstbuf.bw);
if ((start == -1) || (end == -1)) ZZLog::WriteLn("start == %d, end == %d", start, end);
assert(start < gs_imageEnd);
end = gs_imageEnd;
// sometimes games can decompress to alpha channel of render target only, in this case
// do a resolve right away. wolverine x2
if (((gs.dstbuf.psm == PSMT8H) || (gs.dstbuf.psm == PSMT4HL) || (gs.dstbuf.psm == PSMT4HH)) && !(conf.settings().gust))
{
list<CRenderTarget*> listTransmissionUpdateTargs;
s_RTs.GetTargs(start, end, listTransmissionUpdateTargs);
for (list<CRenderTarget*>::iterator it = listTransmissionUpdateTargs.begin(); it != listTransmissionUpdateTargs.end(); ++it)
{
CRenderTarget* ptarg = *it;
if ((ptarg->status & CRenderTarget::TS_Virtual)) continue;
//ZZLog::Error_Log("Resolving to alpha channel.");
ptarg->Resolve();
}
}
s_RangeMngr.Insert(start, min(end, start + (int)nQWordSize*16));
const u8* porgend = (const u8*)pbyMem + 4 * nQWordSize;
if (s_vTransferCache.size() > 0)
{
int imagecache = s_vTransferCache.size();
s_vTempBuffer.resize(imagecache + nQWordSize*4);
memcpy(&s_vTempBuffer[0], &s_vTransferCache[0], imagecache);
memcpy(&s_vTempBuffer[imagecache], pbyMem, nQWordSize*4);
pbyMem = (const void*) & s_vTempBuffer[0];
porgend = &s_vTempBuffer[0] + s_vTempBuffer.size();
int wordinc = imagecache / 4;
if ((nQWordSize * 4 + imagecache) / 3 == ((nQWordSize + wordinc) * 4) / 3)
{
// can use the data
nQWordSize += wordinc;
}
}
int leftover = m_Blocks[gs.dstbuf.psm].TransferHostLocal(pbyMem, nQWordSize);
if (leftover > 0)
{
// copy the last gs.image24bitOffset to the cache
s_vTransferCache.resize(leftover);
memcpy(&s_vTransferCache[0], porgend - leftover, leftover);
}
else
{
s_vTransferCache.resize(0);
}
#if defined(_DEBUG)
if (g_bSaveTrans)
{
tex0Info t;
t.tbp0 = gs.dstbuf.bp;
t.tw = gs.imageNew.w;
t.th = gs.imageNew.h;
t.tbw = gs.dstbuf.bw;
t.psm = gs.dstbuf.psm;
SaveTex(&t, 0);
}
#endif
}
void InitTransferLocalHost()
{
FUNCLOG
assert(gs.trxpos.sx + gs.imageNew.w <= 2048 && gs.trxpos.sy + gs.imageNew.h <= 2048);
#if defined(_DEBUG)
if (gs.trxpos.sx + gs.imageNew.w > gs.srcbuf.bw)
ZZLog::Debug_Log("Transfer error, width exceeded. (0x%x > 0x%x)", gs.trxpos.sx + gs.imageNew.w, gs.srcbuf.bw);
#endif
gs.image.x = gs.trxpos.sx;
gs.image.y = gs.trxpos.sy;
gs.imageEnd.x = gs.image.x + gs.imageNew.w;
gs.imageEnd.y = gs.image.y + gs.imageNew.h;
s_vTransferCache.resize(0);
int start, end;
GetRectMemAddress(start, end, gs.srcbuf.psm, gs.trxpos.sx, gs.trxpos.sy, gs.imageNew, gs.srcbuf.bp, gs.srcbuf.bw);
ResolveInRange(start, end);
}
template <class T>
void TransferLocalHost(void* pbyMem, u32 nQWordSize, int& x, int& y, u8 *pstart)
{
_readPixel_0 rp = readPixelFun_0[gs.srcbuf.psm];
int i = x, j = y;
T* pbuf = (T*)pbyMem;
u32 nSize = nQWordSize * 16 / sizeof(T);
for (; i < gs.imageEnd.y; ++i)
{
for (; j < gs.imageEnd.x && nSize > 0; ++j, --nSize)
{
*pbuf++ = rp(pstart, j % 2048, i % 2048, gs.srcbuf.bw);
}
if (j >= gs.imageEnd.x)
{
assert(j == gs.imageEnd.x);
j = gs.trxpos.sx;
}
else
{
assert(nSize == 0);
break;
}
}
}
void TransferLocalHost_24(void* pbyMem, u32 nQWordSize, int& x, int& y, u8 *pstart)
{
_readPixel_0 rp = readPixelFun_0[gs.srcbuf.psm];
int i = x, j = y;
u8* pbuf = (u8*)pbyMem;
u32 nSize = nQWordSize * 16 / 3;
for (; i < gs.imageEnd.y; ++i)
{
for (; j < gs.imageEnd.x && nSize > 0; ++j, --nSize)
{
u32 p = rp(pstart, j % 2048, i % 2048, gs.srcbuf.bw);
pbuf[0] = (u8)p;
pbuf[1] = (u8)(p >> 8);
pbuf[2] = (u8)(p >> 16);
pbuf += 3;
}
if (j >= gs.imageEnd.x)
{
assert(j == gs.imageEnd.x);
j = gs.trxpos.sx;
}
else
{
assert(nSize == 0);
break;
}
}
}
// left/right, top/down
void TransferLocalHost(void* pbyMem, u32 nQWordSize)
{
FUNCLOG
assert(gs.imageTransfer == XFER_LOCAL_TO_HOST);
u8* pstart = g_pbyGSMemory + 256 * gs.srcbuf.bp;
switch(PSMT_BITMODE(gs.srcbuf.psm))
{
case 0:
TransferLocalHost<u32>(pbyMem, nQWordSize, gs.image.y, gs.image.x, pstart);
break;
case 1:
TransferLocalHost_24(pbyMem, nQWordSize, gs.image.y, gs.image.x, pstart);
break;
case 2:
TransferLocalHost<u16>(pbyMem, nQWordSize, gs.image.y, gs.image.x, pstart);
break;
case 3:
TransferLocalHost<u8>(pbyMem, nQWordSize, gs.image.y, gs.image.x, pstart);
break;
default:
assert(0);
break;
}
if (gs.image.y >= gs.imageEnd.y)
{
ZZLog::Error_Log("gs.image.y >= gs.imageEnd.y!");
assert(gs.image.y == gs.imageEnd.y);
gs.transferring = false;
}
}
__forceinline void _TransferLocalLocal()
{
//ZZLog::Error_Log("TransferLocalLocal(0x%x, 0x%x)", gs.srcbuf.psm, gs.dstbuf.psm);
_writePixel_0 wp = writePixelFun_0[gs.srcbuf.psm];
_readPixel_0 rp = readPixelFun_0[gs.dstbuf.psm];
u8* pSrcBuf = g_pbyGSMemory + gs.srcbuf.bp * 256;
u8* pDstBuf = g_pbyGSMemory + gs.dstbuf.bp * 256;
u32 widthlimit = 4;
u32 maxX = gs.trxpos.sx + gs.imageNew.w;
u32 maxY = gs.trxpos.sy + gs.imageNew.h;
if (PSMT_BITMODE(gs.srcbuf.psm) == 0) widthlimit = 2;
if ((gs.imageNew.w & widthlimit) != 0) return;
for(u32 i = gs.trxpos.sy, i2 = gs.trxpos.dy; i < maxY; i++, i2++)
{
for(u32 j = gs.trxpos.sx, j2 = gs.trxpos.dx; j < maxX; j += widthlimit, j2 += widthlimit)
{
wp(pDstBuf, j2%2048, i2%2048,
rp(pSrcBuf, j%2048, i%2048, gs.srcbuf.bw), gs.dstbuf.bw);
wp(pDstBuf, (j2+1)%2048, i2%2048,
rp(pSrcBuf, (j+1)%2048, i%2048, gs.srcbuf.bw), gs.dstbuf.bw);
if (widthlimit > 2)
{
// Then widthlimit == 4.
wp(pDstBuf, (j2+2)%2048, i2%2048,
rp(pSrcBuf, (j+2)%2048, i%2048, gs.srcbuf.bw), gs.dstbuf.bw);
wp(pDstBuf, (j2+3)%2048, i2%2048,
rp(pSrcBuf, (j+3)%2048, i%2048, gs.srcbuf.bw), gs.dstbuf.bw);
}
}
}
}
__forceinline void _TransferLocalLocal_4()
{
//ZZLog::Error_Log("TransferLocalLocal_4(0x%x, 0x%x)", gs.srcbuf.psm, gs.dstbuf.psm);
_getPixelAddress_0 gsp = getPixelFun_0[gs.srcbuf.psm];
_getPixelAddress_0 gdp = getPixelFun_0[gs.dstbuf.psm];
u8* pSrcBuf = g_pbyGSMemory + gs.srcbuf.bp * 256;
u8* pDstBuf = g_pbyGSMemory + gs.dstbuf.bp * 256;
u32 maxX = gs.trxpos.sx + gs.imageNew.w;
u32 maxY = gs.trxpos.sy + gs.imageNew.h;
assert((gs.imageNew.w % 8) == 0);
for(u32 i = gs.trxpos.sy, i2 = gs.trxpos.dy; i < maxY; ++i, ++i2)
{
for(u32 j = gs.trxpos.sx, j2 = gs.trxpos.dx; j < maxX; j += 8, j2 += 8)
{
/* NOTE: the 2 conseq 4bit values are in NOT in the same byte */
u32 read = gsp(j%2048, i%2048, gs.srcbuf.bw);
u32 write = gdp(j2%2048, i2%2048, gs.dstbuf.bw);
pDstBuf[write] = (pDstBuf[write]&0xf0)|(pSrcBuf[read]&0x0f);
read = gsp((j+1)%2048, i%2048, gs.srcbuf.bw);
write = gdp((j2+1)%2048, i2%2048, gs.dstbuf.bw);
pDstBuf[write] = (pDstBuf[write]&0x0f)|(pSrcBuf[read]&0xf0);
read = gsp((j+2)%2048, i%2048, gs.srcbuf.bw);
write = gdp((j2+2)%2048, i2%2048, gs.dstbuf.bw);
pDstBuf[write] = (pDstBuf[write]&0xf0)|(pSrcBuf[read]&0x0f);
read = gsp((j+3)%2048, i%2048, gs.srcbuf.bw);
write = gdp((j2+3)%2048, i2%2048, gs.dstbuf.bw);
pDstBuf[write] = (pDstBuf[write]&0x0f)|(pSrcBuf[read]&0xf0);
read = gsp((j+4)%2048, i%2048, gs.srcbuf.bw);
write = gdp((j2+4)%2048, i2%2048, gs.dstbuf.bw);
pDstBuf[write] = (pDstBuf[write]&0xf0)|(pSrcBuf[read]&0x0f);
read = gsp((j+5)%2048, i%2048, gs.srcbuf.bw);
write = gdp((j2+5)%2048, i2%2048, gs.dstbuf.bw);
pDstBuf[write] = (pDstBuf[write]&0x0f)|(pSrcBuf[read]&0xf0);
read = gsp((j+6)%2048, i%2048, gs.srcbuf.bw);
write = gdp((j2+6)%2048, i2%2048, gs.dstbuf.bw);
pDstBuf[write] = (pDstBuf[write]&0xf0)|(pSrcBuf[read]&0x0f);
read = gsp((j+7)%2048, i%2048, gs.srcbuf.bw);
write = gdp((j2+7)%2048, i2%2048, gs.dstbuf.bw);
pDstBuf[write] = (pDstBuf[write]&0x0f)|(pSrcBuf[read]&0xf0);
}
}
}
// dir depends on trxpos.dirx & trxpos.diry
void TransferLocalLocal()
{
FUNCLOG
//ZZLog::Error_Log("I'z in your code, transferring your memory...");
assert(gs.imageTransfer == XFER_LOCAL_TO_LOCAL);
assert(gs.trxpos.sx + gs.imageNew.w < 2048 && gs.trxpos.sy + gs.imageNew.h < 2048);
assert(gs.trxpos.dx + gs.imageNew.w < 2048 && gs.trxpos.dy + gs.imageNew.h < 2048);
assert((gs.srcbuf.psm&0x7) == (gs.dstbuf.psm&0x7));
if (gs.trxpos.sx + gs.imageNew.w > gs.srcbuf.bw)
ZZLog::Debug_Log("Transfer error, src width exceeded.(0x%x > 0x%x)", gs.trxpos.sx + gs.imageNew.w, gs.srcbuf.bw);
if (gs.trxpos.dx + gs.imageNew.w > gs.dstbuf.bw)
ZZLog::Debug_Log("Transfer error, dst width exceeded.(0x%x > 0x%x)", gs.trxpos.dx + gs.imageNew.w, gs.dstbuf.bw);
int srcstart, srcend, dststart, dstend;
GetRectMemAddress(srcstart, srcend, gs.srcbuf.psm, gs.trxpos.sx, gs.trxpos.sy, gs.imageNew, gs.srcbuf.bp, gs.srcbuf.bw);
GetRectMemAddress(dststart, dstend, gs.dstbuf.psm, gs.trxpos.dx, gs.trxpos.dy, gs.imageNew, gs.dstbuf.bp, gs.dstbuf.bw);
// resolve the targs
ResolveInRange(srcstart, srcend);
list<CRenderTarget*> listTargs;
s_RTs.GetTargs(dststart, dstend, listTargs);
for (list<CRenderTarget*>::iterator it = listTargs.begin(); it != listTargs.end(); ++it)
{
if (!((*it)->status & CRenderTarget::TS_Virtual))
{
(*it)->Resolve();
//(*it)->status |= CRenderTarget::TS_NeedUpdate;
}
}
if (PSMT_BITMODE(gs.srcbuf.psm) != 4)
{
_TransferLocalLocal();
}
else
{
_TransferLocalLocal_4();
}
g_MemTargs.ClearRange(dststart, dstend);
#ifdef ZEROGS_DEVBUILD
if (g_bSaveTrans)
{
tex0Info t;
t.tbp0 = gs.dstbuf.bp;
t.tw = gs.imageNew.w;
t.th = gs.imageNew.h;
t.tbw = gs.dstbuf.bw;
t.psm = gs.dstbuf.psm;
SaveTex(&t, 0);
t.tbp0 = gs.srcbuf.bp;
t.tw = gs.imageNew.w;
t.th = gs.imageNew.h;
t.tbw = gs.srcbuf.bw;
t.psm = gs.srcbuf.psm;
SaveTex(&t, 0);
}
#endif
}

View File

@ -1,114 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef HOSTMEMORY_H_INCLUDED
#define HOSTMEMORY_H_INCLUDED
#include "GLWin.h"
#define MEMORY_END 0x00400000
extern int GPU_TEXWIDTH;
extern u8* g_pBasePS2Mem;
extern u8* g_pbyGSMemory;
class GSMemory
{
public:
void init();
void destroy();
u8* get();
u8* get(u32 addr);
u8* get_raw(u32 addr);
};
extern u8* g_pbyGSClut; // the temporary clut buffer
class GSClut
{
public:
void init();
void destroy();
u8* get();
u8* get(u32 addr);
u8* get_raw(u32 addr);
};
class ZeroGSInit
{
public:
ZeroGSInit()
{
const u32 mem_size = MEMORY_END + 0x10000; // leave some room for out of range accesses (saves on the checks)
// clear
g_pbyGSMemory = (u8*)_aligned_malloc(mem_size, 1024);
memset(g_pbyGSMemory, 0, mem_size);
g_pbyGSClut = (u8*)_aligned_malloc(256 * 8, 1024); // need 512 alignment!
memset(g_pbyGSClut, 0, 256*8);
memset(&GLWin, 0, sizeof(GLWin));
}
~ZeroGSInit()
{
_aligned_free(g_pbyGSMemory);
g_pbyGSMemory = NULL;
_aligned_free(g_pbyGSClut);
g_pbyGSClut = NULL;
}
};
// The size in bytes of x strings (of texture).
inline int MemorySize(int x)
{
return 4 * GPU_TEXWIDTH * x;
}
// Return the address in memory of data block for string x.
inline u8* MemoryAddress(int x)
{
return g_pbyGSMemory + MemorySize(x);
}
template <u32 mult>
inline u8* _MemoryAddress(int x)
{
return g_pbyGSMemory + mult * x;
}
extern void GetRectMemAddress(int& start, int& end, int psm, int x, int y, int w, int h, int bp, int bw);
extern void GetRectMemAddress(int& start, int& end, int psm, Point p, Size s, int bp, int bw);
extern void GetRectMemAddress(int& start, int& end, int psm, int x, int y, Size s, int bp, int bw);
extern void GetRectMemAddressZero(int& start, int& end, int psm, int w, int h, int bp, int bw);
extern void GetRectMemAddressZero(int& start, int& end, int psm, Size s, int bp, int bw);
// called when trxdir is accessed. If host is involved, transfers memory to temp buffer byTransferBuf.
// Otherwise performs the transfer. TODO: Perhaps divide the transfers into chunks?
extern void InitTransferHostLocal();
extern void TransferHostLocal(const void* pbyMem, u32 nQWordSize);
extern void InitTransferLocalHost();
extern void TransferLocalHost(void* pbyMem, u32 nQWordSize);
extern void TransferLocalLocal();
#endif // HOSTMEMORY_H_INCLUDED

View File

@ -1,133 +0,0 @@
/* GSsoft
* Copyright (C) 2002-2004 GSsoft Team
*
* 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
*/
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "GS.h"
#include "Utilities/Path.h"
void SaveConfig()
{
const wxString iniFile_s(Path::Combine(s_strIniPath, L"zzogl-pg.ini"));
std::string iniFile = std::string(iniFile_s.mb_str());
FILE* f = fopen(iniFile.c_str(), "w");
if (f == NULL)
{
ZZLog::Error_Log("Failed to open '%s'", iniFile.c_str());
return;
}
fprintf(f, "interlace = %hhx\n", conf.interlace);
fprintf(f, "mrtdepth = %hhx\n", conf.mrtdepth);
fprintf(f, "zzoptions = %x\n", conf.zz_options._u32);
fprintf(f, "options = %x\n", conf.hacks._u32);
fprintf(f, "bilinear = %hhx\n", conf.bilinear);
fprintf(f, "aliasing = %hhx\n", conf.aa);
fprintf(f, "width = %x\n", conf.width);
fprintf(f, "height = %x\n", conf.height);
fprintf(f, "x = %x\n", conf.x);
fprintf(f, "y = %x\n", conf.y);
fprintf(f, "log = %x\n", conf.log);
fprintf(f, "skipdraw = %x\n", conf.SkipDraw);
fprintf(f, "disablehacks = %x\n", conf.disableHacks);
fclose(f);
}
void LoadConfig()
{
int err = 0;
memset(&conf, 0, sizeof(conf));
conf.interlace = 0; // on, mode 1
conf.mrtdepth = 1;
conf.bilinear = 1;
conf.log = 1;
conf.SkipDraw = 0;
conf.width = 800;
conf.height = 600;
conf.disableHacks = 0;
const wxString iniFile_s(Path::Combine(s_strIniPath, L"zzogl-pg.ini"));
std::string iniFile = std::string(iniFile_s.mb_str());
FILE* f = fopen(iniFile.c_str(), "r");
if (f == NULL)
{
ZZLog::Error_Log("Failed to open '%s'", iniFile.c_str());
SaveConfig();//save and return
return;
}
err = fscanf(f, "interlace = %hhx\n", &conf.interlace);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "mrtdepth = %hhx\n", &conf.mrtdepth);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "zzoptions = %x\n", &conf.zz_options._u32);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "options = %x\n", &conf.hacks._u32);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "bilinear = %hhx\n", &conf.bilinear);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "aliasing = %hhx\n", &conf.aa);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "width = %x\n", &conf.width);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "height = %x\n", &conf.height);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "x = %x\n", &conf.x);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "y = %x\n", &conf.y);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "log = %x\n", &conf.log);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "skipdraw = %x\n", &conf.SkipDraw);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
err = fscanf(f, "disablehacks = %x\n", &conf.disableHacks);
if (err != 1) ZZLog::Error_Log("Failed to read zzogl option");
fclose(f);
// turn off all hacks by default
conf.setWireframe(false);
conf.setCaptureAvi(false);
conf.setLoaded(true);
conf.isWideScreen = conf.widescreen();
// filter bad files
if (conf.interlace > 2) conf.interlace = 0;
if (conf.aa > 4) conf.aa = 0;
if (conf.width <= 0 || conf.height <= 0)
{
conf.width = 800;
conf.height = 600;
}
if (conf.x < 0 || conf.y < 0)
{
conf.x = 0;
conf.y = 0;
}
}

View File

@ -1,545 +0,0 @@
/* ZeroGS
* Copyright (C) 2002-2004 GSsoft Team
*
* 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
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <dlfcn.h>
#include "GS.h"
#include "Linux.h"
#include "GLWin.h"
#include <map>
extern u32 THR_KeyEvent; // value for passing out key events beetwen threads
extern bool THR_bShift;
extern bool THR_bCtrl;
static map<string, confOptsStruct> mapConfOpts;
static gameHacks tempHacks;
GtkWidget *zz_gtk_hbox_new(int padding)
{
#if GTK_MAJOR_VERSION < 3
return gtk_hbox_new(false, padding);
#else
return gtk_box_new(GTK_ORIENTATION_HORIZONTAL, padding);
#endif
}
GtkWidget *zz_gtk_vbox_new(int padding)
{
#if GTK_MAJOR_VERSION < 3
return gtk_vbox_new(false, padding);
#else
return gtk_box_new(GTK_ORIENTATION_VERTICAL, padding);
#endif
}
EXPORT_C_(void) GSkeyEvent(keyEvent *ev)
{
switch (ev->evt)
{
case KEYPRESS:
switch (ev->key)
{
case XK_F5:
case XK_F6:
case XK_F7:
case XK_F9:
THR_KeyEvent = ev->key;
break;
case XK_Shift_L:
case XK_Shift_R:
THR_bShift = true;
break;
case XK_Control_L:
case XK_Control_R:
THR_bCtrl = true;
break;
}
break;
case KEYRELEASE:
switch (ev->key)
{
case XK_Shift_L:
case XK_Shift_R:
THR_bShift = false;
break;
case XK_Control_L:
case XK_Control_R:
THR_bCtrl = false;
break;
}
}
}
void add_map_entry(u32 option, const char *key, const char *desc)
{
confOpts.value = option;
confOpts.desc = desc;
mapConfOpts[key] = confOpts;
}
void CreateGameHackTable(GtkWidget *treeview, gameHacks hacks)
{
char descbuf[255];
bool itval;
GtkCellRenderer *treerend;
GtkListStore *treestore;//Gets typecast as GtkTreeModel as needed.
GtkTreeIter treeiter;
GtkTreeViewColumn *treecol;
//--------- Let's build a treeview for our advanced options! --------//
treestore = gtk_list_store_new(2, G_TYPE_BOOLEAN, G_TYPE_STRING);
//setup columns in treeview
//COLUMN 0 is the checkboxes
treecol = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(treecol, "Select");
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), treecol);
treerend = gtk_cell_renderer_toggle_new();
gtk_tree_view_column_pack_start(treecol, treerend, true);
gtk_tree_view_column_add_attribute(treecol, treerend, "active", 0);//link 'active' attrib to first column of model
g_object_set(treerend, "activatable", true, NULL);//set 'activatable' attrib true by default for all rows regardless of model.
g_signal_connect(treerend, "toggled", (GCallback) OnToggle_advopts, treestore);//set a global callback, we also pass a reference to our treestore.
//COLUMN 1 is the text descriptions
treecol = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(treecol, "Description");
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), treecol);
treerend = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(treecol, treerend, true);
gtk_tree_view_column_add_attribute(treecol, treerend, "text", 1);//link 'text' attrib to second column of model
//setup the model with all our rows of option data
mapConfOpts.clear();
add_map_entry(GAME_TEXTURETARGS, "00000001", "Tex Target checking - 00000001\nLego Racers");
add_map_entry(GAME_AUTORESET, "00000002", "Auto reset targs - 00000002\nUse when game is slow and toggling AA fixes it. Samurai Warriors. (Automatically on for Shadow Hearts)");
add_map_entry(GAME_INTERLACE2X, "00000004", "Interlace 2X - 00000004\nFixes 2x bigger screen. Gradius 3.");
//GAME_TEXAHACK (still implemented)
add_map_entry(GAME_NOTARGETRESOLVE, "00000010", "No target resolves - 00000010\nStops all resolving of targets. Try this first for really slow games. (Automatically on for Dark Cloud 1.)");
add_map_entry(GAME_EXACTCOLOR, "00000020", "Exact color testing - 00000020\nFixes overbright or shadow/black artifacts. Crash 'n Burn.");
//add_map_entry(GAME_NOCOLORCLAMP, "00000040", "No color clamping - 00000040\nSpeeds up games, but might be too bright or too dim.");
//GAME_FFXHACK
add_map_entry(GAME_NOALPHAFAIL, "00000100", "Alpha Fail hack - 00000100\nRemove vertical stripes or other coloring artifacts. Breaks Persona 4 and MGS3. (Automatically on for Sonic Unleashed, Shadow the Hedgehog, & Ghost in the Shell.)");
add_map_entry(GAME_NODEPTHUPDATE, "00000200", "Disable depth updates - 00000200");
add_map_entry(GAME_QUICKRESOLVE1, "00000400", "Resolve Hack #1 - 00000400\n Speeds some games. Kingdom Hearts.");
add_map_entry(GAME_NOQUICKRESOLVE, "00000800", "Resolve Hack #2 - 00000800\nShadow Hearts, Urbz. Destroys FFX.");
add_map_entry(GAME_NOTARGETCLUT, "00001000", "No target CLUT - 00001000\nResident Evil 4, or foggy scenes.");
add_map_entry(GAME_NOSTENCIL, "00002000", "Disable stencil buffer - 00002000\nUsually safe to do for simple scenes. Harvest Moon.");
//GAME_VSSHACKOFF (still implemented)
add_map_entry(GAME_NODEPTHRESOLVE, "00008000", "No depth resolve - 00008000\nMight give z buffer artifacts.");
add_map_entry(GAME_FULL16BITRES, "00010000", "Full 16 bit resolution - 00010000\nUse when half the screen is missing.");
add_map_entry(GAME_RESOLVEPROMOTED, "00020000", "Resolve Hack #3 - 00020000\nNeopets");
add_map_entry(GAME_FASTUPDATE, "00040000", "Fast Update - 00040000\n Speeds some games. Needed for Sonic Unleashed. Okami.");
add_map_entry(GAME_NOALPHATEST, "00080000", "Disable alpha testing - 00080000");
add_map_entry(GAME_DISABLEMRTDEPTH, "00100000", "Enable Multiple RTs - 00100000");
//GAME_32BITTARGS
//GAME_PATH3HACK
//GAME_DOPARALLELCTX
add_map_entry(GAME_XENOSPECHACK, "01000000", "Specular Highlights - 01000000\nMakes graphics faster by removing highlights. (Automatically on for Xenosaga, Okami, & Okage.)");
//add_map_entry(GAME_PARTIALPOINTERS, "02000000", "Partial targets - 02000000");
add_map_entry(GAME_PARTIALDEPTH, "04000000", "Partial depth - 04000000");
//GAME_REGETHACK (commented out in code)
add_map_entry(GAME_GUSTHACK, "10000000", "Gust fix - 10000000. Makes gust games cleaner and faster. (Automatically on for most Gust games)");
add_map_entry(GAME_NOLOGZ, "20000000", "No logarithmic Z - 20000000. Could decrease number of Z-artifacts.");
add_map_entry(GAME_AUTOSKIPDRAW, "40000000", "Remove blur effect on some games\nSlow games.");
for (map<string, confOptsStruct>::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it)
{
gtk_list_store_append(treestore, &treeiter);//new row
itval = (hacks._u32 & it->second.value) ? true : false;
if (conf.def_hacks._u32 & it->second.value)
{
snprintf(descbuf, 254, "*%s", it->second.desc);
}
else
{
snprintf(descbuf, 254, "%s", it->second.desc);
}
gtk_list_store_set(treestore, &treeiter, 0, itval, 1, descbuf, -1);
}
gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(treestore));//NB: store is cast as tree model.
g_object_unref(treestore);//allow model to be destroyed when the tree is destroyed.
//don't select/highlight rows
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_NONE);
//------treeview done -------//
}
void SaveGameHackTable(GtkWidget *treeview, gameHacks& hacks)
{
GtkTreeModel *treemodel;
GtkTreeIter treeiter;
gboolean treeoptval;
//------- get advanced options from the treeview model -------//
treemodel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
gtk_tree_model_get_iter_first(treemodel, &treeiter);
hacks._u32 = 0;
for (map<string, confOptsStruct>::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it)
{
treeoptval = false;
gtk_tree_model_get(treemodel, &treeiter, 0, &treeoptval, -1);
if (treeoptval) hacks._u32 |= it->second.value;
gtk_tree_model_iter_next(treemodel, &treeiter);
}
//---------- done getting advanced options ---------//
}
void OnToggle_advopts(GtkCellRendererToggle *cell, gchar *path, gpointer user_data)
{
GtkTreeIter treeiter;
gboolean val;
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(user_data), &treeiter, path);
gtk_tree_model_get(GTK_TREE_MODEL(user_data), &treeiter, 0, &val, -1);
val = !val;
gtk_list_store_set(GTK_LIST_STORE(user_data), &treeiter, 0, val, -1);
}
void DisplayAdvancedDialog()
{
GtkWidget *dialog;
GtkWidget *advanced_frame, *advanced_box;
#if GTK_MAJOR_VERSION < 3
GtkWidget *advanced_scroll;
#endif
GtkWidget *tree;
dialog = gtk_dialog_new_with_buttons ("Advanced", NULL,
(GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
"_Cancel", GTK_RESPONSE_REJECT,
"_OK", GTK_RESPONSE_ACCEPT,
NULL);
// A good value for the height would be 1000 instead of 800 but I'm afraid that some people still use small screen...
gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 800);
tree = gtk_tree_view_new();
CreateGameHackTable(tree, tempHacks);
advanced_frame = gtk_frame_new("Advanced Settings:");
#if GTK_MAJOR_VERSION < 3
advanced_box = gtk_vbox_new(false, 5);
advanced_scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(advanced_scroll), tree);
gtk_box_pack_start(GTK_BOX(advanced_box), advanced_scroll, true, true, 2);
#else
advanced_box = gtk_grid_new();
gtk_widget_set_hexpand (tree, TRUE);
gtk_widget_set_halign (tree, GTK_ALIGN_CENTER);
gtk_widget_set_vexpand (tree, TRUE);
gtk_widget_set_valign (tree, GTK_ALIGN_CENTER);
gtk_grid_attach (GTK_GRID (advanced_box), tree, 0, 0, 1, 1);
#endif
gtk_container_add(GTK_CONTAINER(advanced_frame), advanced_box);
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), advanced_frame);
gtk_widget_show_all(dialog);
gtk_dialog_run(GTK_DIALOG(dialog));
SaveGameHackTable(tree, tempHacks);
gtk_widget_destroy(dialog);
}
void DisplayDialog()
{
int return_value;
GtkWidget *dialog;
GtkWidget *main_frame, *main_box;
GtkWidget *option_frame, *option_box;
GtkWidget *log_check, *dis_hacks_check;
GtkWidget *int_label, *int_box, *int_holder;
GtkWidget *bilinear_label, *bilinear_box, *bilinear_holder;
GtkWidget *aa_label, *aa_box, *aa_holder;
GtkWidget *snap_label, *snap_box, *snap_holder;
GtkWidget *fullscreen_label, *widescreen_check;
GtkWidget *advanced_button;
GtkWidget *separator;
GtkWidget *skipdraw_label, *skipdraw_text, *skipdraw_holder, *warning_label;
if (!(conf.loaded())) LoadConfig();
/* Create the widgets */
dialog = gtk_dialog_new_with_buttons(
"ZZOgl PG Config",
NULL, /* parent window*/
(GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
"Cancel",
GTK_RESPONSE_REJECT,
"OK",
GTK_RESPONSE_ACCEPT,
NULL);
log_check = gtk_check_button_new_with_label("Logging");
gtk_widget_set_tooltip_text(log_check, "Used for Debugging.");
int_label = gtk_label_new("Interlacing:");
int_box = gtk_combo_box_text_new();
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(int_box), "No Interlacing");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(int_box), "Interlace 0");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(int_box), "Interlace 1");
gtk_combo_box_set_active(GTK_COMBO_BOX(int_box), conf.interlace);
gtk_widget_set_tooltip_text(int_box, "Toggled by pressing F5 when running.");
int_holder = zz_gtk_hbox_new(5);
gtk_box_pack_start(GTK_BOX(int_holder), int_label, false, false, 2);
gtk_box_pack_start(GTK_BOX(int_holder), int_box, false, false, 2);
bilinear_label = gtk_label_new("Bilinear Filtering:");
bilinear_box = gtk_combo_box_text_new();
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(bilinear_box), "Off");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(bilinear_box), "Normal");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(bilinear_box), "Forced");
gtk_combo_box_set_active(GTK_COMBO_BOX(bilinear_box), conf.bilinear);
gtk_widget_set_tooltip_text(bilinear_box, "Best quality is off. Turn on for speed. Toggled by pressing Shift + F5 when running.");
bilinear_holder = zz_gtk_hbox_new(5);
gtk_box_pack_start(GTK_BOX(bilinear_holder), bilinear_label, false, false, 2);
gtk_box_pack_start(GTK_BOX(bilinear_holder), bilinear_box, false, false, 2);
aa_label = gtk_label_new("Anti-Aliasing:");
aa_box = gtk_combo_box_text_new();
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(aa_box), "1X (None)");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(aa_box), "2X");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(aa_box), "4X");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(aa_box), "8X");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(aa_box), "16X");
gtk_combo_box_set_active(GTK_COMBO_BOX(aa_box), conf.aa);
gtk_widget_set_tooltip_text(aa_box, "Toggled by pressing F6 when running.");
aa_holder = zz_gtk_hbox_new(5);
gtk_box_pack_start(GTK_BOX(aa_holder), aa_label, false, false, 2);
gtk_box_pack_start(GTK_BOX(aa_holder), aa_box, false, false, 2);
snap_label = gtk_label_new("Snapshot format:");
snap_box = gtk_combo_box_text_new();
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(snap_box), "JPEG");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(snap_box), "TIFF");
gtk_combo_box_set_active(GTK_COMBO_BOX(snap_box), conf.zz_options.tga_snap);
snap_holder = zz_gtk_hbox_new(5);
gtk_box_pack_start(GTK_BOX(snap_holder), snap_label, false, false, 2);
gtk_box_pack_start(GTK_BOX(snap_holder), snap_box, false, false, 2);
widescreen_check = gtk_check_button_new_with_label("Widescreen");
gtk_widget_set_tooltip_text(widescreen_check, "Force a 4:3 ration when disabled");
fullscreen_label = gtk_label_new("Press Alt-Enter for Fullscreen.");
gtk_label_set_single_line_mode(GTK_LABEL(fullscreen_label), false);
advanced_button = gtk_button_new_with_label("Advanced...");
dis_hacks_check = gtk_check_button_new_with_label("Disable Automatic Hacks");
gtk_widget_set_tooltip_text(dis_hacks_check, "Used for testing how useful hacks that are on automatically are.");
#ifdef ZEROGS_DEVBUILD
#if GTK_MAJOR_VERSION < 3
separator = gtk_hseparator_new();
#else
separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
#endif
skipdraw_label = gtk_label_new("Skipdraw:");
skipdraw_text = gtk_entry_new();
warning_label = gtk_label_new("Experimental!!");
char buf[5];
sprintf(buf, "%d", conf.SkipDraw);
gtk_entry_set_text(GTK_ENTRY(skipdraw_text), buf);
skipdraw_holder = zz_gtk_hbox_new(5);
gtk_box_pack_start(GTK_BOX(skipdraw_holder), skipdraw_label, false, false, 2);
gtk_box_pack_start(GTK_BOX(skipdraw_holder), skipdraw_text, false, false, 2);
#endif
main_box = zz_gtk_hbox_new(5);
main_frame = gtk_frame_new("ZZOgl PG Config");
gtk_container_add(GTK_CONTAINER(main_frame), main_box);
option_box = zz_gtk_vbox_new(5);
option_frame = gtk_frame_new("");
gtk_container_add(GTK_CONTAINER(option_frame), option_box);
gtk_frame_set_shadow_type(GTK_FRAME(option_frame), GTK_SHADOW_NONE);
gtk_box_pack_start(GTK_BOX(option_box), log_check, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), bilinear_holder, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), int_holder, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), aa_holder, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), snap_holder, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), widescreen_check, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), advanced_button, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), dis_hacks_check, false, false, 2);
#ifdef ZEROGS_DEVBUILD
gtk_box_pack_start(GTK_BOX(option_box), separator, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), warning_label, false, false, 2);
gtk_box_pack_start(GTK_BOX(option_box), skipdraw_holder, false, false, 2);
#endif
gtk_box_pack_start(GTK_BOX(option_box), fullscreen_label, false, false, 2);
gtk_box_pack_start(GTK_BOX(main_box), option_frame, false, false, 2);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(log_check), conf.log);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widescreen_check), (conf.widescreen()));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dis_hacks_check), (conf.disableHacks));
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), main_frame);
g_signal_connect_swapped(advanced_button, "clicked", G_CALLBACK(DisplayAdvancedDialog), advanced_button);
tempHacks = conf.hacks;
gtk_widget_show_all(dialog);
return_value = gtk_dialog_run(GTK_DIALOG(dialog));
if (return_value == GTK_RESPONSE_ACCEPT)
{
ZZOptions fake_options;
if (gtk_combo_box_get_active(GTK_COMBO_BOX(int_box)) != -1)
conf.interlace = gtk_combo_box_get_active(GTK_COMBO_BOX(int_box));
if (gtk_combo_box_get_active(GTK_COMBO_BOX(aa_box)) != -1)
conf.aa = gtk_combo_box_get_active(GTK_COMBO_BOX(aa_box));
if (gtk_combo_box_get_active(GTK_COMBO_BOX(bilinear_box)) != -1)
conf.bilinear = gtk_combo_box_get_active(GTK_COMBO_BOX(bilinear_box));
conf.log = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(log_check));
fake_options.widescreen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widescreen_check));
fake_options.tga_snap = gtk_combo_box_get_active(GTK_COMBO_BOX(snap_box));
#ifdef ZEROGS_DEVBUILD
conf.SkipDraw = atoi((char*)gtk_entry_get_text(GTK_ENTRY(skipdraw_text)));
#endif
conf.zz_options = fake_options;
conf.hacks = tempHacks;
conf.disableHacks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dis_hacks_check));
GSsetGameCRC(g_LastCRC, conf.hacks._u32);
SaveConfig();
}
gtk_widget_destroy(dialog);
}
EXPORT_C_(void) GSconfigure()
{
char strcurdir[256];
if (getcwd(strcurdir, 256) == NULL) {
fprintf(stderr, "Failed to get current working directory\n");
return;
}
if (!(conf.loaded())) LoadConfig();
DisplayDialog();
}
void SysMessage(const char *fmt, ...)
{
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
GtkWidget *dialog;
dialog = gtk_message_dialog_new(NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
"%s", msg);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
EXPORT_C_(void) GSabout()
{
SysMessage("ZZOgl PG: by Zeydlitz (PG version worked on by arcum42, gregory, and the pcsx2 development team). Based off of ZeroGS, by zerofrog.");
}
EXPORT_C_(s32) GStest()
{
return 0;
}
void *SysLoadLibrary(char *lib)
{
return dlopen(lib, RTLD_NOW | RTLD_GLOBAL);
}
void *SysLoadSym(void *lib, char *sym)
{
void *ret = dlsym(lib, sym);
if (ret == NULL) ZZLog::Debug_Log("null: %s", sym);
return dlsym(lib, sym);
}
char *SysLibError()
{
return dlerror();
}
void SysCloseLibrary(void *lib)
{
dlclose(lib);
}

View File

@ -1,31 +0,0 @@
/*
* Copyright (C) 2002-2004 GSsoft Team
*
* 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
*/
#ifndef __LINUX_H__
#define __LINUX_H__
struct confOptsStruct
{
int value;
const char *desc;
} confOpts;
void OnToggle_advopts(GtkCellRendererToggle *cell, gchar *path, gpointer user_data);
#endif

View File

@ -1,373 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "GS.h"
#include "Mem.h"
#include "targets.h"
#include "x86.h"
#include "Util.h"
#include "Mem_Transmit.h"
#include "Mem_Swizzle.h"
#ifdef ZZNORMAL_MEMORY
BLOCK m_Blocks[0x40]; // do so blocks are indexable
PCSX2_ALIGNED16(u32 tempblock[64]);
// Add a bunch of local variables that used to be in the TransferHostLocal
// functions, in order to de-macro the TransmitHostLocal macros.
// May be in a class or namespace eventually.
int tempX, tempY;
int pitch, area, fracX;
int nSize;
u8* pstart;
// ------------------------
// | Y |
// ------------------------
// | block | |
// | aligned area | X |
// | | |
// ------------------------
// | Y |
// ------------------------
template <class T>
static __forceinline const T* AlignOnBlockBoundry(TransferData data, TransferFuncts fun, Point alignedPt, int& endY, const T* pbuf)
{
bool bCanAlign = ((MOD_POW2(gs.trxpos.dx, data.blockwidth) == 0) && (gs.image.x == gs.trxpos.dx) &&
(alignedPt.y > endY) && (alignedPt.x > gs.trxpos.dx));
if ((gs.imageEnd.x - gs.trxpos.dx) % data.widthlimit)
{
/* hack */
int testwidth = (int)nSize -
(gs.imageEnd.y - gs.image.y) * (gs.imageEnd.x - gs.trxpos.dx)
+ (gs.image.x - gs.trxpos.dx);
if ((testwidth <= data.widthlimit) && (testwidth >= -data.widthlimit))
{
/* don't transfer */
/*ZZLog::Debug_Log("Bad texture %s: %d %d %d", #psm, gs.trxpos.dx, gs.imageEnd.x, nQWordSize);*/
//ZZLog::Error_Log("Bad texture: testwidth = %d; data.widthlimit = %d", testwidth, data.widthlimit);
gs.transferring = false;
}
bCanAlign = false;
}
/* first align on block boundary */
if (MOD_POW2(gs.image.y, data.blockheight) || !bCanAlign)
{
u32 transwidth;
if (!bCanAlign)
endY = gs.imageEnd.y; /* transfer the whole image */
else
assert(endY < gs.imageEnd.y); /* part of alignment condition */
if (((gs.imageEnd.x - gs.trxpos.dx) % data.widthlimit) || ((gs.imageEnd.x - gs.image.x) % data.widthlimit))
{
/* transmit with a width of 1 */
transwidth = (1 + (gs.dstbuf.psm == PSMT4));
}
else
{
transwidth = data.widthlimit;
}
pbuf = TransmitHostLocalY<T>(data.psm, fun.wp, transwidth, endY, pbuf);
if (pbuf == NULL) return NULL;
if (nSize == 0 || tempY == gs.imageEnd.y) return NULL;
}
return pbuf;
}
template <class T>
static __forceinline const T* TransferAligningToBlocks(TransferData data, TransferFuncts fun, Point alignedPt, const T* pbuf)
{
bool bAligned;
const u32 TSize = sizeof(T);
_SwizzleBlock swizzle;
/* can align! */
pitch = gs.imageEnd.x - gs.trxpos.dx;
area = pitch * data.blockheight;
fracX = gs.imageEnd.x - alignedPt.x;
/* on top of checking whether pbuf is aligned, make sure that the width is at least aligned to its limits (due to bugs in pcsx2) */
bAligned = !((uptr)pbuf & 0xf) && (TransPitch(pitch, data.transfersize) & 0xf) == 0;
if (bAligned || ((gs.dstbuf.psm == PSMCT24) || (gs.dstbuf.psm == PSMT8H) || (gs.dstbuf.psm == PSMT4HH) || (gs.dstbuf.psm == PSMT4HL)))
swizzle = (fun.Swizzle);
else
swizzle = (fun.Swizzle_u);
//Transfer aligning to blocks.
for (; tempY < alignedPt.y && nSize >= area; tempY += data.blockheight, nSize -= area)
{
for (int tempj = gs.trxpos.dx; tempj < alignedPt.x; tempj += data.blockwidth, pbuf += TransPitch(data.blockwidth, data.transfersize) / TSize)
{
u8 *temp = pstart + fun.gp(tempj, tempY, gs.dstbuf.bw) * data.blockbits / 8;
swizzle(temp, (u8*)pbuf, TransPitch(pitch, data.transfersize));
}
#ifdef ZEROGS_SSE2
// Note: swizzle function uses some non temporal move (mm_stream) instruction.
// store fence insures that previous store are finish before execute new one.
_mm_sfence();
#endif
/* transfer the rest */
if (alignedPt.x < gs.imageEnd.x)
{
pbuf = TransmitHostLocalX<T>(data.psm, fun.wp, data.widthlimit, data.blockheight, alignedPt.x, pbuf);
if (pbuf == NULL) return NULL;
pbuf -= TransPitch((alignedPt.x - gs.trxpos.dx), data.transfersize) / TSize;
}
else
{
pbuf += (data.blockheight - 1) * TransPitch(pitch, data.transfersize) / TSize;
}
tempX = gs.trxpos.dx;
}
return pbuf;
}
static __forceinline int FinishTransfer(TransferData data, int nLeftOver)
{
if (tempY >= gs.imageEnd.y)
{
assert( gs.transferring == false || tempY == gs.imageEnd.y);
gs.transferring = false;
/*int start, end;
GetRectMemAddress(start, end, gs.dstbuf.psm, gs.trxpos.dx, gs.trxpos.dy, gs.imageNew, gs.dstbuf.bp, gs.dstbuf.bw);
g_MemTargs.ClearRange(start, end);*/
}
else
{
/* update new params */
gs.image.y = tempY;
gs.image.x = tempX;
}
return (nSize * TransPitch(2, data.transfersize) + nLeftOver) / 2;
}
template <class T>
static __forceinline int RealTransfer(u32 psm, const void* pbyMem, u32 nQWordSize)
{
assert(gs.imageTransfer == XFER_HOST_TO_LOCAL);
TransferData data = tData[psm];
TransferFuncts fun(psm);
pstart = g_pbyGSMemory + gs.dstbuf.bp * 256;
const T* pbuf = (const T*)pbyMem;
const int tp2 = TransPitch(2, data.transfersize);
int nLeftOver = (nQWordSize * 4 * 2) % tp2;
tempY = gs.image.y;
tempX = gs.image.x;
Point alignedPt;
nSize = (nQWordSize * 4 * 2) / tp2;
nSize = min(nSize, gs.imageNew.w * gs.imageNew.h);
int endY = ROUND_UPPOW2(gs.image.y, data.blockheight);
alignedPt.y = ROUND_DOWNPOW2(gs.imageEnd.y, data.blockheight);
alignedPt.x = ROUND_DOWNPOW2(gs.imageEnd.x, data.blockwidth);
pbuf = AlignOnBlockBoundry<T>(data, fun, alignedPt, endY, pbuf);
if (pbuf == NULL) return FinishTransfer(data, nLeftOver);
pbuf = TransferAligningToBlocks<T>(data, fun, alignedPt, pbuf);
if (pbuf == NULL) return FinishTransfer(data, nLeftOver);
if (TransPitch(nSize, data.transfersize) / 4 > 0)
{
pbuf = TransmitHostLocalY<T>(psm, fun.wp, data.widthlimit, gs.imageEnd.y, pbuf);
if (pbuf == NULL) return FinishTransfer(data, nLeftOver);
/* sometimes wrong sizes are sent (tekken tag) */
assert(gs.transferring == false || TransPitch(nSize, data.transfersize) / 4 <= 2);
}
return FinishTransfer(data, nLeftOver);
}
int TransferHostLocal32(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u32>(PSMCT32, pbyMem, nQWordSize); }
int TransferHostLocal32Z(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u32>(PSMT32Z, pbyMem, nQWordSize); }
int TransferHostLocal24(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u8>(PSMCT24, pbyMem, nQWordSize); }
int TransferHostLocal24Z(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u8>(PSMT24Z, pbyMem, nQWordSize); }
int TransferHostLocal16(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u16>(PSMCT16, pbyMem, nQWordSize); }
int TransferHostLocal16S(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u16>(PSMCT16S, pbyMem, nQWordSize); }
int TransferHostLocal16Z(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u16>(PSMT16Z, pbyMem, nQWordSize); }
int TransferHostLocal16SZ(const void* pbyMem, u32 nQWordSize){ return RealTransfer<u16>(PSMT16SZ, pbyMem, nQWordSize); }
int TransferHostLocal8(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u8>(PSMT8, pbyMem, nQWordSize); }
int TransferHostLocal4(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u8>(PSMT4, pbyMem, nQWordSize); }
int TransferHostLocal8H(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u8>(PSMT8H, pbyMem, nQWordSize); }
int TransferHostLocal4HL(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u8>(PSMT4HL, pbyMem, nQWordSize); }
int TransferHostLocal4HH(const void* pbyMem, u32 nQWordSize) { return RealTransfer<u8>(PSMT4HH, pbyMem, nQWordSize); }
void TransferLocalHost32(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost24(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost16(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost16S(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost8(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost4(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost8H(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost4HL(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost4HH(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost32Z(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost24Z(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost16Z(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost16SZ(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void fill_block(BLOCK b, vector<char>& vBlockData, vector<char>& vBilinearData)
{
float* psrcf = (float*)&vBlockData[0] + b.ox + b.oy * BLOCK_TEXWIDTH;
for(int i = 0; i < b.height; ++i)
{
u32 i_width = i*BLOCK_TEXWIDTH;
for(int j = 0; j < b.width; ++j)
{
/* fill the table */
u32 bt = b.blockTable[(i / b.colheight)*(b.width/b.colwidth) + (j / b.colwidth)];
u32 ct = b.columnTable[(i%b.colheight)*b.colwidth + (j%b.colwidth)];
u32 u = bt * 64 * b.mult + ct;
b.pageTable[i * b.width + j] = u;
psrcf[i_width + j] = (float)(u) / (float)(GPU_TEXWIDTH * b.mult);
}
}
float4* psrcv = (float4*)&vBilinearData[0] + b.ox + b.oy * BLOCK_TEXWIDTH;
for(int i = 0; i < b.height; ++i)
{
u32 i_width = i*BLOCK_TEXWIDTH;
u32 i_width2 = ((i+1)%b.height)*BLOCK_TEXWIDTH;
for(int j = 0; j < b.width; ++j)
{
u32 temp = ((j + 1) % b.width);
float4* pv = &psrcv[i_width + j];
pv->x = psrcf[i_width + j];
pv->y = psrcf[i_width + temp];
pv->z = psrcf[i_width2 + j];
pv->w = psrcf[i_width2 + temp];
}
}
}
void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData)
{
FUNCLOG
vBlockData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * 4);
vBilinearData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * sizeof(float4));
BLOCK b;
memset(m_Blocks, 0, sizeof(m_Blocks));
// 32
b.SetDim(64, 32, 0, 0, 1);
b.SetTable(PSMCT32);
fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMCT32] = b;
m_Blocks[PSMCT32].SetFun(PSMCT32);
// 24 (same as 32 except write/readPixel are different)
m_Blocks[PSMCT24] = b;
m_Blocks[PSMCT24].SetFun(PSMCT24);
// 8H (same as 32 except write/readPixel are different)
m_Blocks[PSMT8H] = b;
m_Blocks[PSMT8H].SetFun(PSMT8H);
m_Blocks[PSMT4HL] = b;
m_Blocks[PSMT4HL].SetFun(PSMT4HL);
m_Blocks[PSMT4HH] = b;
m_Blocks[PSMT4HH].SetFun(PSMT4HH);
// 32z
b.SetDim(64, 32, 64, 0, 1);
b.SetTable(PSMT32Z);
fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT32Z] = b;
m_Blocks[PSMT32Z].SetFun(PSMT32Z);
// 24Z (same as 32Z except write/readPixel are different)
m_Blocks[PSMT24Z] = b;
m_Blocks[PSMT24Z].SetFun(PSMT24Z);
// 16
b.SetDim(64, 64, 0, 32, 2);
b.SetTable(PSMCT16);
fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMCT16] = b;
m_Blocks[PSMCT16].SetFun(PSMCT16);
// 16s
b.SetDim(64, 64, 64, 32, 2);
b.SetTable(PSMCT16S);
fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMCT16S] = b;
m_Blocks[PSMCT16S].SetFun(PSMCT16S);
// 16z
b.SetDim(64, 64, 0, 96, 2);
b.SetTable(PSMT16Z);
fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT16Z] = b;
m_Blocks[PSMT16Z].SetFun(PSMT16Z);
// 16sz
b.SetDim(64, 64, 64, 96, 2);
b.SetTable(PSMT16SZ);
fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT16SZ] = b;
m_Blocks[PSMT16SZ].SetFun(PSMT16SZ);
// 8
b.SetDim(128, 64, 0, 160, 4);
b.SetTable(PSMT8);
fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT8] = b;
m_Blocks[PSMT8].SetFun(PSMT8);
// 4
b.SetDim(128, 128, 0, 224, 8);
b.SetTable(PSMT4);
fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT4] = b;
m_Blocks[PSMT4].SetFun(PSMT4);
}
#endif

View File

@ -1,543 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef __MEM_H__
#define __MEM_H__
#include <assert.h>
#include <vector>
// works only when base is a power of 2
static __forceinline int ROUND_UPPOW2(int val, int base) { return (((val) + (base - 1))&~(base - 1)); }
static __forceinline int ROUND_DOWNPOW2(int val, int base) { return ((val)&~(base - 1)); }
static __forceinline int MOD_POW2(int val, int base) { return ((val)&(base - 1)); }
// d3d texture dims
const int BLOCK_TEXWIDTH = 128;
const int BLOCK_TEXHEIGHT = 512;
// PSM is u6 value, so we MUST guarantee, that we don't crush on incorrect psm.
#define MAX_PSM 64
#define TABLE_WIDTH 8
#ifndef ZZNORMAL_MEMORY
#include "ZZoglMem.h"
#endif
typedef u32(*_getPixelAddress)(int x, int y, u32 bp, u32 bw);
typedef u32(*_getPixelAddress_0)(int x, int y, u32 bw);
typedef void (*_writePixel)(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw);
typedef void (*_writePixel_0)(void* pmem, int x, int y, u32 pixel, u32 bw);
typedef u32(*_readPixel)(const void* pmem, int x, int y, u32 bp, u32 bw);
typedef u32(*_readPixel_0)(const void* pmem, int x, int y, u32 bw);
typedef int (*_TransferHostLocal)(const void* pbyMem, u32 nQWordSize);
typedef void (*_TransferLocalHost)(void* pbyMem, u32 nQWordSize);
typedef void (*_SwizzleBlock)(u8 *dst, u8 *src, int pitch);
extern _getPixelAddress_0 getPixelFun_0[64];
extern _writePixel_0 writePixelFun_0[64];
extern _readPixel_0 readPixelFun_0[64];
extern _writePixel writePixelFun[64];
extern _readPixel readPixelFun[64];
extern _SwizzleBlock swizzleBlockFun[64];
extern _SwizzleBlock swizzleBlockUnFun[64];
extern _TransferHostLocal TransferHostLocalFun[64];
extern _TransferLocalHost TransferLocalHostFun[64];
// Both of the following structs should probably be local class variables or in a namespace,
// but this works for the moment.
struct TransferData
{
// Signed because Visual C++ is weird.
s32 widthlimit;
u32 blockbits;
u32 blockwidth;
u32 blockheight;
u32 transfersize;
u32 psm;
};
#ifdef ZZNORMAL_MEMORY
extern PCSX2_ALIGNED16(u32 tempblock[64]);
struct TransferFuncts
{
_writePixel_0 wp;
_getPixelAddress_0 gp;
_SwizzleBlock Swizzle, Swizzle_u;
__forceinline TransferFuncts(_writePixel_0 writePix, _getPixelAddress_0 readPix, _SwizzleBlock s, _SwizzleBlock su)
{
wp = writePix;
gp = readPix;
Swizzle = s;
Swizzle_u = su;
}
__forceinline TransferFuncts(u32 psm)
{
wp = writePixelFun_0[psm];
gp = getPixelFun_0[psm];
Swizzle = swizzleBlockFun[psm];
Swizzle_u = swizzleBlockUnFun[psm];
}
};
extern TransferData tData[64];
// rest not visible externally
extern u32 g_blockTable32[4][8];
extern u32 g_blockTable32Z[4][8];
extern u32 g_blockTable16[8][4];
extern u32 g_blockTable16S[8][4];
extern u32 g_blockTable16Z[8][4];
extern u32 g_blockTable16SZ[8][4];
extern u32 g_blockTable8[4][8];
extern u32 g_blockTable4[8][4];
extern u32 g_columnTable32[8][8];
extern u32 g_columnTable16[8][16];
extern u32 g_columnTable8[16][16];
extern u32 g_columnTable4[16][32];
extern u32 g_pageTable32[32][64];
extern u32 g_pageTable32Z[32][64];
extern u32 g_pageTable16[64][64];
extern u32 g_pageTable16S[64][64];
extern u32 g_pageTable16Z[64][64];
extern u32 g_pageTable16SZ[64][64];
extern u32 g_pageTable8[64][128];
extern u32 g_pageTable4[128][128];
struct BLOCK
{
BLOCK() { memset(this, 0, sizeof(BLOCK)); }
// shader constants for this block
float4 vTexBlock;
float4 vTexDims;
int width, height; // dims of one page in pixels
int ox, oy, mult;
int bpp;
int colwidth, colheight;
u32* pageTable; // offset inside each page
u32* blockTable;
u32* columnTable;
_getPixelAddress getPixelAddress;
_getPixelAddress_0 getPixelAddress_0;
_writePixel writePixel;
_writePixel_0 writePixel_0;
_readPixel readPixel;
_readPixel_0 readPixel_0;
_TransferHostLocal TransferHostLocal;
_TransferLocalHost TransferLocalHost;
// texture must be of dims BLOCK_TEXWIDTH and BLOCK_TEXHEIGHT
static void FillBlocks(std::vector<char>& vBlockData, std::vector<char>& vBilinearData);
void SetDim(u32 bw, u32 bh, u32 ox2, u32 oy2, u32 mult2)
{
ox = ox2;
oy = oy2;
mult = mult2;
vTexDims = float4(BLOCK_TEXWIDTH/(float)(bw), BLOCK_TEXHEIGHT/(float)bh, 0, 0);
vTexBlock = float4((float)bw/BLOCK_TEXWIDTH, (float)bh/BLOCK_TEXHEIGHT, ((float)ox+0.2f)/BLOCK_TEXWIDTH, ((float)oy+0.05f)/BLOCK_TEXHEIGHT);
width = bw;
height = bh;
colwidth = bh / 4;
colheight = bw / 8;
bpp = 32/mult;
}
void SetFun(u32 psm)
{
writePixel = writePixelFun[psm];
writePixel_0 = writePixelFun_0[psm];
readPixel = readPixelFun[psm];
readPixel_0 = readPixelFun_0[psm];
TransferHostLocal = TransferHostLocalFun[psm];
TransferLocalHost = TransferLocalHostFun[psm];
}
void SetTable(u32 psm)
{
switch (psm) {
case PSMCT32:
assert( sizeof(g_pageTable32) == width * height * sizeof(g_pageTable32[0][0]) );
pageTable = &g_pageTable32[0][0];
blockTable = &g_blockTable32[0][0];
columnTable = &g_columnTable32[0][0];
break;
case PSMT32Z:
assert( sizeof(g_pageTable32Z) == width * height * sizeof(g_pageTable32Z[0][0]) );
pageTable = &g_pageTable32Z[0][0];
blockTable = &g_blockTable32Z[0][0];
columnTable = &g_columnTable32[0][0];
break;
case PSMCT16:
assert( sizeof(g_pageTable16) == width * height * sizeof(g_pageTable16[0][0]) );
pageTable = &g_pageTable16[0][0];
blockTable = &g_blockTable16[0][0];
columnTable = &g_columnTable16[0][0];
break;
case PSMCT16S:
assert( sizeof(g_pageTable16S) == width * height * sizeof(g_pageTable16S[0][0]) );
pageTable = &g_pageTable16S[0][0];
blockTable = &g_blockTable16S[0][0];
columnTable = &g_columnTable16[0][0];
break;
case PSMT16Z:
assert( sizeof(g_pageTable16Z) == width * height * sizeof(g_pageTable16Z[0][0]) );
pageTable = &g_pageTable16Z[0][0];
blockTable = &g_blockTable16Z[0][0];
columnTable = &g_columnTable16[0][0];
break;
case PSMT16SZ:
assert( sizeof(g_pageTable16SZ) == width * height * sizeof(g_pageTable16SZ[0][0]) );
pageTable = &g_pageTable16SZ[0][0];
blockTable = &g_blockTable16SZ[0][0];
columnTable = &g_columnTable16[0][0];
break;
case PSMT8:
assert( sizeof(g_pageTable8) == width * height * sizeof(g_pageTable8[0][0]) );
pageTable = &g_pageTable8[0][0];
blockTable = &g_blockTable8[0][0];
columnTable = &g_columnTable8[0][0];
break;
case PSMT4:
assert( sizeof(g_pageTable4) == width * height * sizeof(g_pageTable4[0][0]) );
pageTable = &g_pageTable4[0][0];
blockTable = &g_blockTable4[0][0];
columnTable = &g_columnTable4[0][0];
break;
default:
pageTable = NULL;
blockTable = NULL;
columnTable = NULL;
break;
}
}
};
extern BLOCK m_Blocks[];
#define getPixelAddress24 getPixelAddress32
#define getPixelAddress24_0 getPixelAddress32_0
#define getPixelAddress8H getPixelAddress32
#define getPixelAddress8H_0 getPixelAddress32_0
#define getPixelAddress4HL getPixelAddress32
#define getPixelAddress4HL_0 getPixelAddress32_0
#define getPixelAddress4HH getPixelAddress32
#define getPixelAddress4HH_0 getPixelAddress32_0
#define getPixelAddress24Z getPixelAddress32Z
#define getPixelAddress24Z_0 getPixelAddress32Z_0
static __forceinline u32 getPixelAddress32(int x, int y, u32 bp, u32 bw)
{
u32 basepage = ((y >> 5) * (bw >> 6)) + (x >> 6);
u32 word = bp * 64 + basepage * 2048 + g_pageTable32[y&31][x&63];
return word;
}
static __forceinline u32 getPixelAddress16(int x, int y, u32 bp, u32 bw)
{
u32 basepage = ((y >> 6) * (bw >> 6)) + (x >> 6);
u32 word = bp * 128 + basepage * 4096 + g_pageTable16[y&63][x&63];
return word;
}
static __forceinline u32 getPixelAddress16S(int x, int y, u32 bp, u32 bw)
{
u32 basepage = ((y >> 6) * (bw >> 6)) + (x >> 6);
u32 word = bp * 128 + basepage * 4096 + g_pageTable16S[y&63][x&63];
return word;
}
static __forceinline u32 getPixelAddress8(int x, int y, u32 bp, u32 bw)
{
u32 basepage = ((y >> 6) * ((bw + 127) >> 7)) + (x >> 7);
u32 word = bp * 256 + basepage * 8192 + g_pageTable8[y&63][x&127];
return word;
}
static __forceinline u32 getPixelAddress4(int x, int y, u32 bp, u32 bw)
{
u32 basepage = ((y >> 7) * ((bw + 127) >> 7)) + (x >> 7);
u32 word = bp * 512 + basepage * 16384 + g_pageTable4[y&127][x&127];
return word;
}
static __forceinline u32 getPixelAddress32Z(int x, int y, u32 bp, u32 bw)
{
u32 basepage = ((y >> 5) * (bw >> 6)) + (x >> 6);
u32 word = bp * 64 + basepage * 2048 + g_pageTable32Z[y&31][x&63];
return word;
}
static __forceinline u32 getPixelAddress16Z(int x, int y, u32 bp, u32 bw)
{
u32 basepage = ((y >> 6) * (bw >> 6)) + (x >> 6);
u32 word = bp * 128 + basepage * 4096 + g_pageTable16Z[y&63][x&63];
return word;
}
static __forceinline u32 getPixelAddress16SZ(int x, int y, u32 bp, u32 bw)
{
u32 basepage = ((y >> 6) * (bw >> 6)) + (x >> 6);
u32 word = bp * 128 + basepage * 4096 + g_pageTable16SZ[y&63][x&63];
return word;
}
///////////////
static __forceinline void writePixel32(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
((u32*)pmem)[getPixelAddress32(x, y, bp, bw)] = pixel;
}
static __forceinline void writePixel24(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
u8 *buf = (u8*) & ((u32*)pmem)[getPixelAddress32(x, y, bp, bw)];
u8 *pix = (u8*) & pixel;
buf[0] = pix[0];
buf[1] = pix[1];
buf[2] = pix[2];
}
static __forceinline void writePixel16(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
((u16*)pmem)[getPixelAddress16(x, y, bp, bw)] = pixel;
}
static __forceinline void writePixel16S(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
((u16*)pmem)[getPixelAddress16S(x, y, bp, bw)] = pixel;
}
static __forceinline void writePixel8(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
((u8*)pmem)[getPixelAddress8(x, y, bp, bw)] = pixel;
}
static __forceinline void writePixel8H(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
((u8*)pmem)[4*getPixelAddress32(x, y, bp, bw)+3] = pixel;
}
static __forceinline void writePixel4(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
u32 addr = getPixelAddress4(x, y, bp, bw);
u8 pix = ((u8*)pmem)[addr/2];
if (addr & 0x1)((u8*)pmem)[addr/2] = (pix & 0x0f) | (pixel << 4);
else ((u8*)pmem)[addr/2] = (pix & 0xf0) | (pixel);
}
static __forceinline void writePixel4HL(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
u8 *p = (u8*)pmem + 4 * getPixelAddress4HL(x, y, bp, bw) + 3;
*p = (*p & 0xf0) | pixel;
}
static __forceinline void writePixel4HH(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
u8 *p = (u8*)pmem + 4 * getPixelAddress4HH(x, y, bp, bw) + 3;
*p = (*p & 0x0f) | (pixel << 4);
}
static __forceinline void writePixel32Z(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
((u32*)pmem)[getPixelAddress32Z(x, y, bp, bw)] = pixel;
}
static __forceinline void writePixel24Z(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
u8 *buf = (u8*)pmem + 4 * getPixelAddress32Z(x, y, bp, bw);
u8 *pix = (u8*) & pixel;
buf[0] = pix[0];
buf[1] = pix[1];
buf[2] = pix[2];
}
static __forceinline void writePixel16Z(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
((u16*)pmem)[getPixelAddress16Z(x, y, bp, bw)] = pixel;
}
static __forceinline void writePixel16SZ(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw)
{
((u16*)pmem)[getPixelAddress16SZ(x, y, bp, bw)] = pixel;
}
///////////////
static __forceinline u32 readPixel32(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u32*)pmem)[getPixelAddress32(x, y, bp, bw)];
}
static __forceinline u32 readPixel24(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u32*)pmem)[getPixelAddress32(x, y, bp, bw)] & 0xffffff;
}
static __forceinline u32 readPixel16(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u16*)pmem)[getPixelAddress16(x, y, bp, bw)];
}
static __forceinline u32 readPixel16S(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u16*)pmem)[getPixelAddress16S(x, y, bp, bw)];
}
static __forceinline u32 readPixel8(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u8*)pmem)[getPixelAddress8(x, y, bp, bw)];
}
static __forceinline u32 readPixel8H(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u8*)pmem)[4*getPixelAddress32(x, y, bp, bw) + 3];
}
static __forceinline u32 readPixel4(const void* pmem, int x, int y, u32 bp, u32 bw)
{
u32 addr = getPixelAddress4(x, y, bp, bw);
u8 pix = ((const u8*)pmem)[addr/2];
if (addr & 0x1)
return pix >> 4;
else
return pix & 0xf;
}
static __forceinline u32 readPixel4HL(const void* pmem, int x, int y, u32 bp, u32 bw)
{
const u8 *p = (const u8*)pmem + 4 * getPixelAddress4HL(x, y, bp, bw) + 3;
return *p & 0x0f;
}
static __forceinline u32 readPixel4HH(const void* pmem, int x, int y, u32 bp, u32 bw)
{
const u8 *p = (const u8*)pmem + 4 * getPixelAddress4HH(x, y, bp, bw) + 3;
return *p >> 4;
}
///////////////
static __forceinline u32 readPixel32Z(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u32*)pmem)[getPixelAddress32Z(x, y, bp, bw)];
}
static __forceinline u32 readPixel24Z(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u32*)pmem)[getPixelAddress32Z(x, y, bp, bw)] & 0xffffff;
}
static __forceinline u32 readPixel16Z(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u16*)pmem)[getPixelAddress16Z(x, y, bp, bw)];
}
static __forceinline u32 readPixel16SZ(const void* pmem, int x, int y, u32 bp, u32 bw)
{
return ((const u16*)pmem)[getPixelAddress16SZ(x, y, bp, bw)];
}
///////////////////////////////
// Functions that take 0 bps //
///////////////////////////////
static __forceinline u32 getPixelAddress32_0(int x, int y, u32 bw) { return getPixelAddress32(x, y, 0, bw); }
static __forceinline u32 getPixelAddress16_0(int x, int y, u32 bw) { return getPixelAddress16(x, y, 0, bw); }
static __forceinline u32 getPixelAddress16S_0(int x, int y, u32 bw) { return getPixelAddress16S(x, y, 0, bw); }
static __forceinline u32 getPixelAddress8_0(int x, int y, u32 bw) { return getPixelAddress8(x, y, 0, bw); }
static __forceinline u32 getPixelAddress4_0(int x, int y, u32 bw) { return getPixelAddress4(x, y, 0, bw); }
static __forceinline u32 getPixelAddress32Z_0(int x, int y, u32 bw) { return getPixelAddress32Z(x, y, 0, bw); }
static __forceinline u32 getPixelAddress16Z_0(int x, int y, u32 bw) { return getPixelAddress16Z(x, y, 0, bw); }
static __forceinline u32 getPixelAddress16SZ_0(int x, int y, u32 bw) { return getPixelAddress16SZ(x, y, 0, bw); }
///////////////
static __forceinline void writePixel32_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel32(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel24_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel24(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel16_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel16(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel16S_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel16S(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel8_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel8(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel8H_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel8H(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel4_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel4(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel4HL_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel4HL(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel4HH_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel4HH(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel32Z_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel32Z(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel24Z_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel24Z(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel16Z_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel16Z(pmem, x, y, pixel, 0, bw); }
static __forceinline void writePixel16SZ_0(void* pmem, int x, int y, u32 pixel, u32 bw) { writePixel16SZ(pmem, x, y, pixel, 0, bw); }
///////////////
static __forceinline u32 readPixel32_0(const void* pmem, int x, int y, u32 bw) { return readPixel32(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel24_0(const void* pmem, int x, int y, u32 bw) { return readPixel24(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel16_0(const void* pmem, int x, int y, u32 bw) { return readPixel16(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel16S_0(const void* pmem, int x, int y, u32 bw) { return readPixel16S(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel8_0(const void* pmem, int x, int y, u32 bw) { return readPixel8(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel8H_0(const void* pmem, int x, int y, u32 bw) { return readPixel8H(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel4_0(const void* pmem, int x, int y, u32 bw) { return readPixel4(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel4HL_0(const void* pmem, int x, int y, u32 bw) { return readPixel4HL(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel4HH_0(const void* pmem, int x, int y, u32 bw) { return readPixel4HH(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel32Z_0(const void* pmem, int x, int y, u32 bw) { return readPixel32Z(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel24Z_0(const void* pmem, int x, int y, u32 bw) { return readPixel24Z(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel16Z_0(const void* pmem, int x, int y, u32 bw) { return readPixel16Z(pmem, x, y, 0, bw); }
static __forceinline u32 readPixel16SZ_0(const void* pmem, int x, int y, u32 bw) { return readPixel16SZ(pmem, x, y, 0, bw); }
///////////////
#endif
extern int TransferHostLocal32(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal32Z(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal24(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal24Z(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal16(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal16S(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal16Z(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal16SZ(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal8(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal4(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal8H(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal4HL(const void* pbyMem, u32 nQWordSize);
extern int TransferHostLocal4HH(const void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost32(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost24(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost16(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost16S(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost8(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost4(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost8H(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost4HL(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost4HH(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost32Z(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost24Z(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost16Z(void* pbyMem, u32 nQWordSize);
extern void TransferLocalHost16SZ(void* pbyMem, u32 nQWordSize);
#endif /* __MEM_H__ */

View File

@ -1,726 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "GS.h"
#include "Mem.h"
#include "Mem_Swizzle.h"
#include "Util.h"
// WARNING a sfence instruction must be call after SwizzleBlock sse2 function
#ifdef ZEROGS_SSE2
static const __aligned16 u32 mask_24b_H[4] = {0xFF000000, 0x0000FFFF, 0xFF000000, 0x0000FFFF};
static const __aligned16 u32 mask_24b_L[4] = {0x00FFFFFF, 0x00000000, 0x00FFFFFF, 0x00000000};
template<bool aligned>
__forceinline void SwizzleBlock32_sse2_I(u8 *dst, u8 *src, int pitch)
{
__m128i src_0;
__m128i src_1;
__m128i src_2;
__m128i src_3;
for (int i=3 ; i >= 0 ; --i) {
// load
if (aligned) {
src_0 = _mm_load_si128((__m128i*)src); // 5 4 1 0
src_1 = _mm_load_si128((__m128i*)(src+16)); // 13 12 9 8
src_2 = _mm_load_si128((__m128i*)(src+pitch)); // 7 6 3 2
src_3 = _mm_load_si128((__m128i*)(src+16+pitch)); // 15 14 11 10
} else {
src_0 = _mm_loadu_si128((__m128i*)src); // 5 4 1 0
src_1 = _mm_loadu_si128((__m128i*)(src+16)); // 13 12 9 8
src_2 = _mm_loadu_si128((__m128i*)(src+pitch)); // 7 6 3 2
src_3 = _mm_loadu_si128((__m128i*)(src+16+pitch)); // 15 14 11 10
}
// Reorder
__m128i dst_0 = _mm_unpacklo_epi64(src_0, src_2); // 3 2 1 0
__m128i dst_1 = _mm_unpackhi_epi64(src_0, src_2); // 7 6 5 4
__m128i dst_2 = _mm_unpacklo_epi64(src_1, src_3); // 11 10 9 8
__m128i dst_3 = _mm_unpackhi_epi64(src_1, src_3); // 15 14 13 12
// store
_mm_stream_si128((__m128i*)dst, dst_0);
_mm_stream_si128(((__m128i*)dst)+1, dst_1);
_mm_stream_si128(((__m128i*)dst)+2, dst_2);
_mm_stream_si128(((__m128i*)dst)+3, dst_3);
// update the pointer
dst += 64;
src += 2*pitch;
}
}
template<bool aligned>
__forceinline void SwizzleBlock16_sse2_I(u8 *dst, u8 *src, int pitch)
{
__m128i src_0_L;
__m128i src_0_H;
__m128i src_2_L;
__m128i src_2_H;
for (int i=3 ; i >= 0 ; --i) {
// load
if (aligned) {
src_0_L = _mm_load_si128((__m128i*)src); // 13L 12L 9L 8L 5L 4L 1L 0L
src_0_H = _mm_load_si128((__m128i*)(src+16)); // 13H 12H 9H 8H 5H 4H 1H 0H
src_2_L = _mm_load_si128((__m128i*)(src+pitch)); // 15L 14L 11L 10L 7L 6L 3L 2L
src_2_H = _mm_load_si128((__m128i*)(src+16+pitch)); // 15H 14H 11H 10H 7H 6H 3H 2H
} else {
src_0_L = _mm_loadu_si128((__m128i*)src); // 13L 12L 9L 8L 5L 4L 1L 0L
src_0_H = _mm_loadu_si128((__m128i*)(src+16)); // 13H 12H 9H 8H 5H 4H 1H 0H
src_2_L = _mm_loadu_si128((__m128i*)(src+pitch)); // 15L 14L 11L 10L 7L 6L 3L 2L
src_2_H = _mm_loadu_si128((__m128i*)(src+16+pitch)); // 15H 14H 11H 10H 7H 6H 3H 2H
}
// Interleave L and H to obtains 32 bits packets
__m128i dst_0_tmp = _mm_unpacklo_epi16(src_0_L, src_0_H); // 5H 5L 4H 4L 1H 1L 0H 0L
__m128i dst_1_tmp = _mm_unpacklo_epi16(src_2_L, src_2_H); // 7H 7L 6H 6L 3H 3L 2H 2L
__m128i dst_2_tmp = _mm_unpackhi_epi16(src_0_L, src_0_H); // 13H 13L 12H 12L 9H 9L 8H 8L
__m128i dst_3_tmp = _mm_unpackhi_epi16(src_2_L, src_2_H); // 15H 15L 14H 14L 11H 11L 10H 10L
// Reorder
__m128i dst_0 = _mm_unpacklo_epi64(dst_0_tmp, dst_1_tmp); // 3 2 1 0
__m128i dst_1 = _mm_unpackhi_epi64(dst_0_tmp, dst_1_tmp); // 7 6 5 4
__m128i dst_2 = _mm_unpacklo_epi64(dst_2_tmp, dst_3_tmp); // 11 10 9 8
__m128i dst_3 = _mm_unpackhi_epi64(dst_2_tmp, dst_3_tmp); // 15 14 13 12
// store
_mm_stream_si128((__m128i*)dst, dst_0);
_mm_stream_si128(((__m128i*)dst)+1, dst_1);
_mm_stream_si128(((__m128i*)dst)+2, dst_2);
_mm_stream_si128(((__m128i*)dst)+3, dst_3);
// update the pointer
dst += 64;
src += 2*pitch;
}
}
// Template the code to improve reuse of code
template<bool aligned, u32 INDEX>
__forceinline void SwizzleColumn8_sse2_I(u8 *dst, u8 *src, int pitch)
{
__m128i src_0;
__m128i src_1;
__m128i src_2;
__m128i src_3;
// load 4 line of 16*8 bits packets
if (aligned) {
src_0 = _mm_load_si128((__m128i*)src);
src_2 = _mm_load_si128((__m128i*)(src+pitch));
src_1 = _mm_load_si128((__m128i*)(src+2*pitch));
src_3 = _mm_load_si128((__m128i*)(src+3*pitch));
} else {
src_0 = _mm_loadu_si128((__m128i*)src);
src_2 = _mm_loadu_si128((__m128i*)(src+pitch));
src_1 = _mm_loadu_si128((__m128i*)(src+2*pitch));
src_3 = _mm_loadu_si128((__m128i*)(src+3*pitch));
}
// shuffle 2 lines to align pixels
if (INDEX == 0 || INDEX == 2) {
src_1 = _mm_shuffle_epi32(src_1, 0xB1); // 13 12 9 8 5 4 1 0 ... (byte 3 & 1)
src_3 = _mm_shuffle_epi32(src_3, 0xB1); // 15 14 11 10 7 6 3 2 ... (byte 3 & 1)
} else if (INDEX == 1 || INDEX == 3) {
src_0 = _mm_shuffle_epi32(src_0, 0xB1); // 13 12 9 8 5 4 1 0 ... (byte 2 & 0)
src_2 = _mm_shuffle_epi32(src_2, 0xB1); // 15 14 11 10 7 6 3 2 ... (byte 2 & 0)
} else {
assert(0);
}
// src_0 = 13 12 9 8 5 4 1 0 ... (byte 2 & 0)
// src_1 = 13 12 9 8 5 4 1 0 ... (byte 3 & 1)
// src_2 = 15 14 11 10 7 6 3 2 ... (byte 2 & 0)
// src_3 = 15 14 11 10 7 6 3 2 ... (byte 3 & 1)
// Interleave byte 1 & 0 to obtain 16 bits packets
__m128i src_0_L = _mm_unpacklo_epi8(src_0, src_1); // 13L 12L 9L 8L 5L 4L 1L 0L
__m128i src_1_L = _mm_unpacklo_epi8(src_2, src_3); // 15L 14L 11L 10L 7L 6L 3L 2L
// Interleave byte 3 & 2 to obtain 16 bits packets
__m128i src_0_H = _mm_unpackhi_epi8(src_0, src_1); // 13H 12H 9H 8H 5H 4H 1H 0H
__m128i src_1_H = _mm_unpackhi_epi8(src_2, src_3); // 15H 14H 11H 10H 7H 6H 3H 2H
// Interleave H and L to obtain 32 bits packets
__m128i dst_0_tmp = _mm_unpacklo_epi16(src_0_L, src_0_H); // 5 4 1 0
__m128i dst_1_tmp = _mm_unpacklo_epi16(src_1_L, src_1_H); // 7 6 3 2
__m128i dst_2_tmp = _mm_unpackhi_epi16(src_0_L, src_0_H); // 13 12 9 8
__m128i dst_3_tmp = _mm_unpackhi_epi16(src_1_L, src_1_H); // 15 14 11 10
// Reorder the 32 bits packets
__m128i dst_0 = _mm_unpacklo_epi64(dst_0_tmp, dst_1_tmp); // 3 2 1 0
__m128i dst_1 = _mm_unpackhi_epi64(dst_0_tmp, dst_1_tmp); // 7 6 5 4
__m128i dst_2 = _mm_unpacklo_epi64(dst_2_tmp, dst_3_tmp); // 11 10 9 8
__m128i dst_3 = _mm_unpackhi_epi64(dst_2_tmp, dst_3_tmp); // 15 14 13 12
// store
_mm_stream_si128((__m128i*)dst, dst_0);
_mm_stream_si128(((__m128i*)dst)+1, dst_1);
_mm_stream_si128(((__m128i*)dst)+2, dst_2);
_mm_stream_si128(((__m128i*)dst)+3, dst_3);
}
template<bool aligned>
__forceinline void SwizzleBlock8_sse2_I(u8 *dst, u8 *src, int pitch)
{
SwizzleColumn8_sse2_I<aligned, 0>(dst, src, pitch);
dst += 64;
src += 4*pitch;
SwizzleColumn8_sse2_I<aligned, 1>(dst, src, pitch);
dst += 64;
src += 4*pitch;
SwizzleColumn8_sse2_I<aligned, 2>(dst, src, pitch);
dst += 64;
src += 4*pitch;
SwizzleColumn8_sse2_I<aligned, 3>(dst, src, pitch);
}
// Template the code to improve reuse of code
template<bool aligned, u32 INDEX>
__forceinline void SwizzleColumn4_sse2_I(u8 *dst, u8 *src, int pitch)
{
__m128i src_0;
__m128i src_1;
__m128i src_2;
__m128i src_3;
// Build a mask (tranform a u32 to a 4 packets u32)
const u32 mask_template = 0x0f0f0f0f;
__m128i mask = _mm_cvtsi32_si128(mask_template);
mask = _mm_shuffle_epi32(mask, 0);
// load 4 line of 32*4 bits packets
if (aligned) {
src_0 = _mm_load_si128((__m128i*)src);
src_2 = _mm_load_si128((__m128i*)(src+pitch));
src_1 = _mm_load_si128((__m128i*)(src+2*pitch));
src_3 = _mm_load_si128((__m128i*)(src+3*pitch));
} else {
src_0 = _mm_loadu_si128((__m128i*)src);
src_2 = _mm_loadu_si128((__m128i*)(src+pitch));
src_1 = _mm_loadu_si128((__m128i*)(src+2*pitch));
src_3 = _mm_loadu_si128((__m128i*)(src+3*pitch));
}
// shuffle 2 lines to align pixels
if (INDEX == 0 || INDEX == 2) {
src_1 = _mm_shufflelo_epi16(src_1, 0xB1);
src_1 = _mm_shufflehi_epi16(src_1, 0xB1); // 13 12 9 8 5 4 1 0 ... (Half-byte 7 & 5 & 3 & 1)
src_3 = _mm_shufflelo_epi16(src_3, 0xB1);
src_3 = _mm_shufflehi_epi16(src_3, 0xB1); // 15 14 11 10 7 6 3 2 ... (Half-byte 7 & 5 & 3 & 1)
} else if (INDEX == 1 || INDEX == 3) {
src_0 = _mm_shufflelo_epi16(src_0, 0xB1);
src_0 = _mm_shufflehi_epi16(src_0, 0xB1); // 13 12 9 8 5 4 1 0 ... (Half-byte 6 & 4 & 2 & 0)
src_2 = _mm_shufflelo_epi16(src_2, 0xB1);
src_2 = _mm_shufflehi_epi16(src_2, 0xB1); // 15 14 11 10 7 6 3 2 ... (Half-byte 6 & 4 & 2 & 0)
} else {
assert(0);
}
// src_0 = 13 12 9 8 5 4 1 0 ... (Half-byte 6 & 4 & 2 & 0)
// src_1 = 13 12 9 8 5 4 1 0 ... (Half-byte 7 & 5 & 3 & 1)
// src_2 = 15 14 11 10 7 6 3 2 ... (Half-byte 6 & 4 & 2 & 0)
// src_3 = 15 14 11 10 7 6 3 2 ... (Half-byte 7 & 5 & 3 & 1)
// ** Interleave Half-byte to obtain 8 bits packets
// Shift value to ease 4 bits filter.
// Note use a packet shift to allow a 4bits shifts
__m128i src_0_shift = _mm_srli_epi64(src_0, 4); // ? 13 12 9 8 5 4 1 ... (Half-byte 6 & 4 & 2 & 0)
__m128i src_1_shift = _mm_slli_epi64(src_1, 4); // 12 9 8 5 4 1 0 ? ... (Half-byte 7 & 5 & 3 & 1)
__m128i src_2_shift = _mm_srli_epi64(src_2, 4); // ? 15 14 11 10 7 6 3 ... (Half-byte 6 & 4 & 2 & 0)
__m128i src_3_shift = _mm_slli_epi64(src_3, 4); // 14 11 10 7 6 3 2 ? ... (Half-byte 7 & 5 & 3 & 1)
// 12 - 8 - 4 - 0 - (HB odd) || - 12 - 8 - 4 - 0 (HB even) => 12 8 4 0 (byte 3 & 2 & 1 & 0)
src_0 = _mm_or_si128(_mm_andnot_si128(mask, src_1_shift), _mm_and_si128(mask, src_0));
// - 13 - 9 - 5 - 1 (HB even) || 13 - 9 - 5 - 1 - (HB odd) => 13 9 5 1 (byte 3 & 2 & 1 & 0)
src_1 = _mm_or_si128(_mm_and_si128(mask, src_0_shift), _mm_andnot_si128(mask, src_1));
// 14 - 10 - 6 - 2 - (HB odd) || - 14 - 10 - 6 - 2 (HB even) => 14 10 6 2 (byte 3 & 2 & 1 & 0)
src_2 = _mm_or_si128(_mm_andnot_si128(mask, src_3_shift), _mm_and_si128(mask, src_2));
// - 15 - 11 - 7 - 3 (HB even) || 15 - 11 - 7 - 3 - (HB odd) => 15 11 7 3 (byte 3 & 2 & 1 & 0)
src_3 = _mm_or_si128(_mm_and_si128(mask, src_2_shift), _mm_andnot_si128(mask, src_3));
// reorder the 8 bits packets
__m128i src_0_tmp = _mm_unpacklo_epi8(src_0, src_1); // 13 12 9 8 5 4 1 0 (byte 1 & 0)
__m128i src_1_tmp = _mm_unpackhi_epi8(src_0, src_1); // 13 12 9 8 5 4 1 0 (byte 3 & 2)
__m128i src_2_tmp = _mm_unpacklo_epi8(src_2, src_3); // 15 14 11 10 7 6 3 2 (byte 1 & 0)
__m128i src_3_tmp = _mm_unpackhi_epi8(src_2, src_3); // 15 14 11 10 7 6 3 2 (byte 3 & 2)
// interleave byte to obtain 32 bits packets
__m128i src_0_L = _mm_unpacklo_epi8(src_0_tmp, src_1_tmp); // 2.13 0.13 2.12 0.12 2.9 0.9 2.8 0.8 2.5 0.5 2.4 0.4 2.1 0.1 2.0 0.0
__m128i src_0_H = _mm_unpackhi_epi8(src_0_tmp, src_1_tmp); // 3.13 1.13 3.12 1.12 3.9 1.9 3.8 1.8 3.5 1.5 3.4 1.4 3.1 1.1 3.0 1.0
__m128i src_1_L = _mm_unpacklo_epi8(src_2_tmp, src_3_tmp); // 2.15 0.15 2.14 0.14 2.11 0.11 2.10 0.10 2.7 0.7 2.6 0.6 2.3 0.3 2.2 0.2
__m128i src_1_H = _mm_unpackhi_epi8(src_2_tmp, src_3_tmp); // 3.15 1.15 3.14 1.14 3.11 1.11 3.10 1.10 3.7 1.7 3.6 1.6 3.3 1.3 3.2 1.2
__m128i dst_0_tmp = _mm_unpacklo_epi8(src_0_L, src_0_H); // 5 4 1 0
__m128i dst_1_tmp = _mm_unpacklo_epi8(src_1_L, src_1_H); // 7 6 3 2
__m128i dst_2_tmp = _mm_unpackhi_epi8(src_0_L, src_0_H); // 13 12 9 8
__m128i dst_3_tmp = _mm_unpackhi_epi8(src_1_L, src_1_H); // 15 14 11 10
// Reorder the 32 bits packets
__m128i dst_0 = _mm_unpacklo_epi64(dst_0_tmp, dst_1_tmp); // 3 2 1 0
__m128i dst_1 = _mm_unpackhi_epi64(dst_0_tmp, dst_1_tmp); // 7 6 5 4
__m128i dst_2 = _mm_unpacklo_epi64(dst_2_tmp, dst_3_tmp); // 11 10 9 8
__m128i dst_3 = _mm_unpackhi_epi64(dst_2_tmp, dst_3_tmp); // 15 14 13 12
// store
_mm_stream_si128((__m128i*)dst, dst_0);
_mm_stream_si128(((__m128i*)dst)+1, dst_1);
_mm_stream_si128(((__m128i*)dst)+2, dst_2);
_mm_stream_si128(((__m128i*)dst)+3, dst_3);
}
template<bool aligned>
__forceinline void SwizzleBlock4_sse2_I(u8 *dst, u8 *src, int pitch)
{
SwizzleColumn4_sse2_I<aligned, 0>(dst, src, pitch);
dst += 64;
src += 4*pitch;
SwizzleColumn4_sse2_I<aligned, 1>(dst, src, pitch);
dst += 64;
src += 4*pitch;
SwizzleColumn4_sse2_I<aligned, 2>(dst, src, pitch);
dst += 64;
src += 4*pitch;
SwizzleColumn4_sse2_I<aligned, 3>(dst, src, pitch);
}
template<bool FOUR_BIT, bool UPPER>
__forceinline void SwizzleBlock8H_4H(u8 *dst, u8 *src, int pitch)
{
__m128i zero_128 = _mm_setzero_si128();
__m128i src_0;
__m128i src_1;
__m128i src_2;
__m128i src_3;
__m128i src_0_init_H;
__m128i src_0_init_L;
__m128i src_2_init_H;
__m128i src_2_init_L;
__m128i src_0_init;
__m128i src_2_init;
__m128i upper_mask = _mm_cvtsi32_si128(0xF0F0F0F0);
// Build the write_mask (tranform a u32 to a 4 packets u32)
__m128i write_mask;
if (FOUR_BIT) {
if (UPPER) write_mask = _mm_cvtsi32_si128(0xF0000000);
else write_mask = _mm_cvtsi32_si128(0x0F000000);
} else {
write_mask = _mm_cvtsi32_si128(0xFF000000);
}
write_mask = _mm_shuffle_epi32(write_mask, 0);
for (int i=3 ; i >= 0 ; --i) {
if (FOUR_BIT) {
src_0_init = _mm_cvtsi32_si128(*(u32*)src);
src_2_init = _mm_cvtsi32_si128(*(u32*)(src + pitch));
} else {
src_0_init = _mm_loadl_epi64((__m128i*)src);
src_2_init = _mm_loadl_epi64((__m128i*)(src + pitch));
}
// Convert to 8 bits
if (FOUR_BIT) {
src_0_init_H = _mm_and_si128(upper_mask, src_0_init);
src_0_init_L = _mm_andnot_si128(upper_mask, src_0_init);
src_2_init_H = _mm_and_si128(upper_mask, src_2_init);
src_2_init_L = _mm_andnot_si128(upper_mask, src_2_init);
if (UPPER) {
src_0_init_L = _mm_slli_epi32(src_0_init_L, 4);
src_2_init_L = _mm_slli_epi32(src_2_init_L, 4);
} else {
src_0_init_H = _mm_srli_epi32(src_0_init_H, 4);
src_2_init_H = _mm_srli_epi32(src_2_init_H, 4);
}
// Repack the src to keep HByte order
src_0_init = _mm_unpacklo_epi8(src_0_init_L, src_0_init_H);
src_2_init = _mm_unpacklo_epi8(src_2_init_L, src_2_init_H);
}
// transform to 16 bits (add 0 in low bits)
src_0_init = _mm_unpacklo_epi8(zero_128, src_0_init);
src_2_init = _mm_unpacklo_epi8(zero_128, src_2_init);
// transform to 32 bits (add 0 in low bits)
src_0 = _mm_unpacklo_epi16(zero_128, src_0_init);
src_1 = _mm_unpackhi_epi16(zero_128, src_0_init);
src_2 = _mm_unpacklo_epi16(zero_128, src_2_init);
src_3 = _mm_unpackhi_epi16(zero_128, src_2_init);
// Reorder the data (same as 32 bits format)
__m128i dst_0 = _mm_unpacklo_epi64(src_0, src_2);
__m128i dst_1 = _mm_unpackhi_epi64(src_0, src_2);
__m128i dst_2 = _mm_unpacklo_epi64(src_1, src_3);
__m128i dst_3 = _mm_unpackhi_epi64(src_1, src_3);
// Load previous value and apply the ~write_mask
__m128i old_dst_0 = _mm_andnot_si128(write_mask, _mm_load_si128((__m128i*)dst));
dst_0 = _mm_or_si128(dst_0, old_dst_0);
__m128i old_dst_1 = _mm_andnot_si128(write_mask, _mm_load_si128(((__m128i*)dst)+1));
dst_1 = _mm_or_si128(dst_1, old_dst_1);
__m128i old_dst_2 = _mm_andnot_si128(write_mask, _mm_load_si128(((__m128i*)dst)+2));
dst_2 = _mm_or_si128(dst_2, old_dst_2);
__m128i old_dst_3 = _mm_andnot_si128(write_mask, _mm_load_si128(((__m128i*)dst)+3));
dst_3 = _mm_or_si128(dst_3, old_dst_3);
// store
_mm_stream_si128((__m128i*)dst, dst_0);
_mm_stream_si128(((__m128i*)dst)+1, dst_1);
_mm_stream_si128(((__m128i*)dst)+2, dst_2);
_mm_stream_si128(((__m128i*)dst)+3, dst_3);
// update the pointer
dst += 64;
src += 2*pitch;
}
}
// special swizzle macros - which I converted to functions.
__forceinline void SwizzleBlock32(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock32_sse2_I<true>(dst, src, pitch);
}
__forceinline void SwizzleBlock24(u8 *dst, u8 *src, int pitch)
{
__m128i mask_H = _mm_load_si128((__m128i*)mask_24b_H);
__m128i mask_L = _mm_load_si128((__m128i*)mask_24b_L);
// Build the write_mask (tranform a u32 to a 4 packets u32)
__m128i write_mask = _mm_cvtsi32_si128(0x00FFFFFF);
write_mask = _mm_shuffle_epi32(write_mask, 0);
for (int i=3 ; i >= 0 ; --i) {
// Note src can be out of bound of GS memory (but there is some spare allocation
// to avoid a tricky corner case)
__m128i src_0 = _mm_loadu_si128((__m128i*)src);
__m128i src_1 = _mm_loadu_si128((__m128i*)(src+12));
__m128i src_2 = _mm_loadu_si128((__m128i*)(src+pitch));
__m128i src_3 = _mm_loadu_si128((__m128i*)(src+pitch+12));
// transform 24 bits value to 32 bits one
// 1/ Align a little the data
src_0 = _mm_slli_si128(src_0, 2);
src_0 = _mm_shufflelo_epi16(src_0, 0x39);
src_1 = _mm_slli_si128(src_1, 2);
src_1 = _mm_shufflelo_epi16(src_1, 0x39);
src_2 = _mm_slli_si128(src_2, 2);
src_2 = _mm_shufflelo_epi16(src_2, 0x39);
src_3 = _mm_slli_si128(src_3, 2);
src_3 = _mm_shufflelo_epi16(src_3, 0x39);
// 2/ Filter the 24 bits pixels & do the conversion
__m128i src_0_H = _mm_and_si128(src_0, mask_H);
__m128i src_0_L = _mm_and_si128(src_0, mask_L);
src_0_H = _mm_slli_si128(src_0_H, 1);
src_0 = _mm_or_si128(src_0_H, src_0_L);
__m128i src_1_H = _mm_and_si128(src_1, mask_H);
__m128i src_1_L = _mm_and_si128(src_1, mask_L);
src_1_H = _mm_slli_si128(src_1_H, 1);
src_1 = _mm_or_si128(src_1_H, src_1_L);
__m128i src_2_H = _mm_and_si128(src_2, mask_H);
__m128i src_2_L = _mm_and_si128(src_2, mask_L);
src_2_H = _mm_slli_si128(src_2_H, 1);
src_2 = _mm_or_si128(src_2_H, src_2_L);
__m128i src_3_H = _mm_and_si128(src_3, mask_H);
__m128i src_3_L = _mm_and_si128(src_3, mask_L);
src_3_H = _mm_slli_si128(src_3_H, 1);
src_3 = _mm_or_si128(src_3_H, src_3_L);
// Reorder the data (same as 32 bits format)
__m128i dst_0 = _mm_unpacklo_epi64(src_0, src_2);
__m128i dst_1 = _mm_unpackhi_epi64(src_0, src_2);
__m128i dst_2 = _mm_unpacklo_epi64(src_1, src_3);
__m128i dst_3 = _mm_unpackhi_epi64(src_1, src_3);
// Load previous value and apply the ~write_mask
__m128i old_dst_0 = _mm_andnot_si128(write_mask, _mm_load_si128((__m128i*)dst));
dst_0 = _mm_or_si128(dst_0, old_dst_0);
__m128i old_dst_1 = _mm_andnot_si128(write_mask, _mm_load_si128(((__m128i*)dst)+1));
dst_1 = _mm_or_si128(dst_1, old_dst_1);
__m128i old_dst_2 = _mm_andnot_si128(write_mask, _mm_load_si128(((__m128i*)dst)+2));
dst_2 = _mm_or_si128(dst_2, old_dst_2);
__m128i old_dst_3 = _mm_andnot_si128(write_mask, _mm_load_si128(((__m128i*)dst)+3));
dst_3 = _mm_or_si128(dst_3, old_dst_3);
// store
_mm_stream_si128((__m128i*)dst, dst_0);
_mm_stream_si128(((__m128i*)dst)+1, dst_1);
_mm_stream_si128(((__m128i*)dst)+2, dst_2);
_mm_stream_si128(((__m128i*)dst)+3, dst_3);
// update the pointer
dst += 64;
src += 2*pitch;
}
}
__forceinline void SwizzleBlock16(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock16_sse2_I<true>(dst, src, pitch);
}
__forceinline void SwizzleBlock8(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock8_sse2_I<true>(dst, src, pitch);
}
__forceinline void SwizzleBlock4(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock4_sse2_I<true>(dst, src, pitch);
}
__forceinline void SwizzleBlock32u(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock32_sse2_I<false>(dst, src, pitch);
}
__forceinline void SwizzleBlock16u(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock16_sse2_I<false>(dst, src, pitch);
}
__forceinline void SwizzleBlock8u(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock8_sse2_I<false>(dst, src, pitch);
}
__forceinline void SwizzleBlock4u(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock4_sse2_I<false>(dst, src, pitch);
}
__forceinline void SwizzleBlock8H(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock8H_4H<false, false>(dst, src, pitch);
}
__forceinline void SwizzleBlock4HH(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock8H_4H<true, true>(dst, src, pitch);
}
__forceinline void SwizzleBlock4HL(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock8H_4H<true, false>(dst, src, pitch);
}
#else
__forceinline void SwizzleBlock32(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock32_c(dst, src, pitch);
}
__forceinline void SwizzleBlock16(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock16_c(dst, src, pitch);
}
__forceinline void SwizzleBlock8(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock8_c(dst, src, pitch);
}
__forceinline void SwizzleBlock4(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock4_c(dst, src, pitch);
}
__forceinline void SwizzleBlock32u(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock32_c(dst, src, pitch);
}
__forceinline void SwizzleBlock16u(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock16_c(dst, src, pitch);
}
__forceinline void SwizzleBlock8u(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock8_c(dst, src, pitch);
}
__forceinline void SwizzleBlock4u(u8 *dst, u8 *src, int pitch)
{
SwizzleBlock4_c(dst, src, pitch);
}
__forceinline void __fastcall SwizzleBlock32_mask(u8* dst, u8* src, int srcpitch, u32 WriteMask)
{
u32* d = &g_columnTable32[0][0];
if (WriteMask == 0xffffffff)
{
for (int j = 0; j < 8; j++, d += 8, src += srcpitch)
for (int i = 0; i < 8; i++)
((u32*)dst)[d[i]] = ((u32*)src)[i];
}
else
{
for (int j = 0; j < 8; j++, d += 8, src += srcpitch)
for (int i = 0; i < 8; i++)
((u32*)dst)[d[i]] = (((u32*)dst)[d[i]] & ~WriteMask) | (((u32*)src)[i] & WriteMask);
}
}
__forceinline void __fastcall SwizzleBlock32_c(u8* dst, u8* src, int srcpitch)
{
SwizzleBlock32_mask(dst, src, srcpitch, 0xffffffff);
}
__forceinline void __fastcall SwizzleBlock16_c(u8* dst, u8* src, int srcpitch)
{
u32* d = &g_columnTable16[0][0];
for (int j = 0; j < 8; j++, d += 16, src += srcpitch)
for (int i = 0; i < 16; i++)
((u16*)dst)[d[i]] = ((u16*)src)[i];
}
__forceinline void __fastcall SwizzleBlock8_c(u8* dst, u8* src, int srcpitch)
{
u32* d = &g_columnTable8[0][0];
for (int j = 0; j < 16; j++, d += 16, src += srcpitch)
for (int i = 0; i < 16; i++)
dst[d[i]] = src[i];
}
__forceinline void __fastcall SwizzleBlock4_c(u8* dst, u8* src, int srcpitch)
{
u32* d = &g_columnTable4[0][0];
for (int j = 0; j < 16; j++, d += 32, src += srcpitch)
{
for (int i = 0; i < 32; i++)
{
u32 addr = d[i];
u8 c = (src[i>>1] >> ((i & 1) << 2)) & 0x0f;
u32 shift = (addr & 1) << 2;
dst[addr >> 1] = (dst[addr >> 1] & (0xf0 >> shift)) | (c << shift);
}
}
}
__forceinline void SwizzleBlock24(u8 *dst, u8 *src, int pitch)
{
u8* pnewsrc = src;
u32* pblock = tempblock;
// Note src can be out of bound of GS memory (but there is some spare allocation
// to avoid a tricky corner case)
for (int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch - 24)
{
for (int bx = 0; bx < 8; ++bx, pnewsrc += 3)
{
pblock[bx] = *(u32*)pnewsrc;
}
}
SwizzleBlock32_mask((u8*)dst, (u8*)tempblock, 32, 0x00ffffff);
}
__forceinline void SwizzleBlock8H(u8 *dst, u8 *src, int pitch)
{
u8* pnewsrc = src;
u32* pblock = tempblock;
for (int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch)
{
u32 u = *(u32*)pnewsrc;
pblock[0] = u << 24;
pblock[1] = u << 16;
pblock[2] = u << 8;
pblock[3] = u;
u = *(u32*)(pnewsrc + 4);
pblock[4] = u << 24;
pblock[5] = u << 16;
pblock[6] = u << 8;
pblock[7] = u;
}
SwizzleBlock32_mask((u8*)dst, (u8*)tempblock, 32, 0xff000000);
}
__forceinline void SwizzleBlock4HH(u8 *dst, u8 *src, int pitch)
{
u8* pnewsrc = src;
u32* pblock = tempblock;
for (int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch)
{
u32 u = *(u32*)pnewsrc;
pblock[0] = u << 28;
pblock[1] = u << 24;
pblock[2] = u << 20;
pblock[3] = u << 16;
pblock[4] = u << 12;
pblock[5] = u << 8;
pblock[6] = u << 4;
pblock[7] = u;
}
SwizzleBlock32_mask((u8*)dst, (u8*)tempblock, 32, 0xf0000000);
}
__forceinline void SwizzleBlock4HL(u8 *dst, u8 *src, int pitch)
{
u8* pnewsrc = src;
u32* pblock = tempblock;
for (int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch)
{
u32 u = *(u32*)pnewsrc;
pblock[0] = u << 24;
pblock[1] = u << 20;
pblock[2] = u << 16;
pblock[3] = u << 12;
pblock[4] = u << 8;
pblock[5] = u << 4;
pblock[6] = u;
pblock[7] = u >> 4;
}
SwizzleBlock32_mask((u8*)dst, (u8*)tempblock, 32, 0x0f000000);
}
#endif

View File

@ -1,63 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef MEM_SWIZZLE_H_INCLUDED
#define MEM_SWIZZLE_H_INCLUDED
#include "GS.h"
#include "Mem.h"
#include "x86.h"
extern __forceinline void SwizzleBlock32(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock16(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock8(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock4(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock32u(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock16u(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock8u(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock4u(u8 *dst, u8 *src, int pitch);
extern __forceinline void __fastcall SwizzleBlock32_c(u8* dst, u8* src, int srcpitch);
extern __forceinline void __fastcall SwizzleBlock16_c(u8* dst, u8* src, int srcpitch);
extern __forceinline void __fastcall SwizzleBlock8_c(u8* dst, u8* src, int srcpitch);
extern __forceinline void __fastcall SwizzleBlock4_c(u8* dst, u8* src, int srcpitch);
// special swizzle macros - which I converted to functions.
extern __forceinline void SwizzleBlock24(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock8H(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock4HH(u8 *dst, u8 *src, int pitch);
extern __forceinline void SwizzleBlock4HL(u8 *dst, u8 *src, int pitch);
#define SwizzleBlock24u SwizzleBlock24
#define SwizzleBlock8Hu SwizzleBlock8H
#define SwizzleBlock4HHu SwizzleBlock4HH
#define SwizzleBlock4HLu SwizzleBlock4HL
#define SwizzleBlock16S SwizzleBlock16
#define SwizzleBlock32Z SwizzleBlock32
#define SwizzleBlock24Z SwizzleBlock24
#define SwizzleBlock16Z SwizzleBlock16
#define SwizzleBlock16SZ SwizzleBlock16
#define SwizzleBlock16Su SwizzleBlock16u
#define SwizzleBlock32Zu SwizzleBlock32u
#define SwizzleBlock24Zu SwizzleBlock24u
#define SwizzleBlock16Zu SwizzleBlock16u
#define SwizzleBlock16SZu SwizzleBlock16u
#endif // MEM_SWIZZLE_H_INCLUDED

View File

@ -1,506 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "GS.h"
#include "Mem.h"
#include "Mem_Swizzle.h"
u32 g_blockTable32[4][8] =
{
{ 0, 1, 4, 5, 16, 17, 20, 21},
{ 2, 3, 6, 7, 18, 19, 22, 23},
{ 8, 9, 12, 13, 24, 25, 28, 29},
{ 10, 11, 14, 15, 26, 27, 30, 31}
};
u32 g_blockTable32Z[4][8] =
{
{ 24, 25, 28, 29, 8, 9, 12, 13},
{ 26, 27, 30, 31, 10, 11, 14, 15},
{ 16, 17, 20, 21, 0, 1, 4, 5},
{ 18, 19, 22, 23, 2, 3, 6, 7}
};
u32 g_blockTable16[8][4] =
{
{ 0, 2, 8, 10 },
{ 1, 3, 9, 11 },
{ 4, 6, 12, 14 },
{ 5, 7, 13, 15 },
{ 16, 18, 24, 26 },
{ 17, 19, 25, 27 },
{ 20, 22, 28, 30 },
{ 21, 23, 29, 31 }
};
u32 g_blockTable16S[8][4] =
{
{ 0, 2, 16, 18 },
{ 1, 3, 17, 19 },
{ 8, 10, 24, 26 },
{ 9, 11, 25, 27 },
{ 4, 6, 20, 22 },
{ 5, 7, 21, 23 },
{ 12, 14, 28, 30 },
{ 13, 15, 29, 31 }
};
u32 g_blockTable16Z[8][4] =
{
{ 24, 26, 16, 18 },
{ 25, 27, 17, 19 },
{ 28, 30, 20, 22 },
{ 29, 31, 21, 23 },
{ 8, 10, 0, 2 },
{ 9, 11, 1, 3 },
{ 12, 14, 4, 6 },
{ 13, 15, 5, 7 }
};
u32 g_blockTable16SZ[8][4] =
{
{ 24, 26, 8, 10 },
{ 25, 27, 9, 11 },
{ 16, 18, 0, 2 },
{ 17, 19, 1, 3 },
{ 28, 30, 12, 14 },
{ 29, 31, 13, 15 },
{ 20, 22, 4, 6 },
{ 21, 23, 5, 7 }
};
u32 g_blockTable8[4][8] =
{
{ 0, 1, 4, 5, 16, 17, 20, 21},
{ 2, 3, 6, 7, 18, 19, 22, 23},
{ 8, 9, 12, 13, 24, 25, 28, 29},
{ 10, 11, 14, 15, 26, 27, 30, 31}
};
u32 g_blockTable4[8][4] =
{
{ 0, 2, 8, 10 },
{ 1, 3, 9, 11 },
{ 4, 6, 12, 14 },
{ 5, 7, 13, 15 },
{ 16, 18, 24, 26 },
{ 17, 19, 25, 27 },
{ 20, 22, 28, 30 },
{ 21, 23, 29, 31 }
};
u32 g_columnTable32[8][8] =
{
{ 0, 1, 4, 5, 8, 9, 12, 13 },
{ 2, 3, 6, 7, 10, 11, 14, 15 },
{ 16, 17, 20, 21, 24, 25, 28, 29 },
{ 18, 19, 22, 23, 26, 27, 30, 31 },
{ 32, 33, 36, 37, 40, 41, 44, 45 },
{ 34, 35, 38, 39, 42, 43, 46, 47 },
{ 48, 49, 52, 53, 56, 57, 60, 61 },
{ 50, 51, 54, 55, 58, 59, 62, 63 },
};
u32 g_columnTable16[8][16] =
{
{ 0, 2, 8, 10, 16, 18, 24, 26,
1, 3, 9, 11, 17, 19, 25, 27 },
{ 4, 6, 12, 14, 20, 22, 28, 30,
5, 7, 13, 15, 21, 23, 29, 31 },
{ 32, 34, 40, 42, 48, 50, 56, 58,
33, 35, 41, 43, 49, 51, 57, 59 },
{ 36, 38, 44, 46, 52, 54, 60, 62,
37, 39, 45, 47, 53, 55, 61, 63 },
{ 64, 66, 72, 74, 80, 82, 88, 90,
65, 67, 73, 75, 81, 83, 89, 91 },
{ 68, 70, 76, 78, 84, 86, 92, 94,
69, 71, 77, 79, 85, 87, 93, 95 },
{ 96, 98, 104, 106, 112, 114, 120, 122,
97, 99, 105, 107, 113, 115, 121, 123 },
{ 100, 102, 108, 110, 116, 118, 124, 126,
101, 103, 109, 111, 117, 119, 125, 127 },
};
u32 g_columnTable8[16][16] =
{
{ 0, 4, 16, 20, 32, 36, 48, 52, // column 0
2, 6, 18, 22, 34, 38, 50, 54 },
{ 8, 12, 24, 28, 40, 44, 56, 60,
10, 14, 26, 30, 42, 46, 58, 62 },
{ 33, 37, 49, 53, 1, 5, 17, 21,
35, 39, 51, 55, 3, 7, 19, 23 },
{ 41, 45, 57, 61, 9, 13, 25, 29,
43, 47, 59, 63, 11, 15, 27, 31 },
{ 96, 100, 112, 116, 64, 68, 80, 84, // column 1
98, 102, 114, 118, 66, 70, 82, 86 },
{ 104, 108, 120, 124, 72, 76, 88, 92,
106, 110, 122, 126, 74, 78, 90, 94 },
{ 65, 69, 81, 85, 97, 101, 113, 117,
67, 71, 83, 87, 99, 103, 115, 119 },
{ 73, 77, 89, 93, 105, 109, 121, 125,
75, 79, 91, 95, 107, 111, 123, 127 },
{ 128, 132, 144, 148, 160, 164, 176, 180, // column 2
130, 134, 146, 150, 162, 166, 178, 182 },
{ 136, 140, 152, 156, 168, 172, 184, 188,
138, 142, 154, 158, 170, 174, 186, 190 },
{ 161, 165, 177, 181, 129, 133, 145, 149,
163, 167, 179, 183, 131, 135, 147, 151 },
{ 169, 173, 185, 189, 137, 141, 153, 157,
171, 175, 187, 191, 139, 143, 155, 159 },
{ 224, 228, 240, 244, 192, 196, 208, 212, // column 3
226, 230, 242, 246, 194, 198, 210, 214 },
{ 232, 236, 248, 252, 200, 204, 216, 220,
234, 238, 250, 254, 202, 206, 218, 222 },
{ 193, 197, 209, 213, 225, 229, 241, 245,
195, 199, 211, 215, 227, 231, 243, 247 },
{ 201, 205, 217, 221, 233, 237, 249, 253,
203, 207, 219, 223, 235, 239, 251, 255 },
};
u32 g_columnTable4[16][32] =
{
{ 0, 8, 32, 40, 64, 72, 96, 104, // column 0
2, 10, 34, 42, 66, 74, 98, 106,
4, 12, 36, 44, 68, 76, 100, 108,
6, 14, 38, 46, 70, 78, 102, 110 },
{ 16, 24, 48, 56, 80, 88, 112, 120,
18, 26, 50, 58, 82, 90, 114, 122,
20, 28, 52, 60, 84, 92, 116, 124,
22, 30, 54, 62, 86, 94, 118, 126 },
{ 65, 73, 97, 105, 1, 9, 33, 41,
67, 75, 99, 107, 3, 11, 35, 43,
69, 77, 101, 109, 5, 13, 37, 45,
71, 79, 103, 111, 7, 15, 39, 47 },
{ 81, 89, 113, 121, 17, 25, 49, 57,
83, 91, 115, 123, 19, 27, 51, 59,
85, 93, 117, 125, 21, 29, 53, 61,
87, 95, 119, 127, 23, 31, 55, 63 },
{ 192, 200, 224, 232, 128, 136, 160, 168, // column 1
194, 202, 226, 234, 130, 138, 162, 170,
196, 204, 228, 236, 132, 140, 164, 172,
198, 206, 230, 238, 134, 142, 166, 174 },
{ 208, 216, 240, 248, 144, 152, 176, 184,
210, 218, 242, 250, 146, 154, 178, 186,
212, 220, 244, 252, 148, 156, 180, 188,
214, 222, 246, 254, 150, 158, 182, 190 },
{ 129, 137, 161, 169, 193, 201, 225, 233,
131, 139, 163, 171, 195, 203, 227, 235,
133, 141, 165, 173, 197, 205, 229, 237,
135, 143, 167, 175, 199, 207, 231, 239 },
{ 145, 153, 177, 185, 209, 217, 241, 249,
147, 155, 179, 187, 211, 219, 243, 251,
149, 157, 181, 189, 213, 221, 245, 253,
151, 159, 183, 191, 215, 223, 247, 255 },
{ 256, 264, 288, 296, 320, 328, 352, 360, // column 2
258, 266, 290, 298, 322, 330, 354, 362,
260, 268, 292, 300, 324, 332, 356, 364,
262, 270, 294, 302, 326, 334, 358, 366 },
{ 272, 280, 304, 312, 336, 344, 368, 376,
274, 282, 306, 314, 338, 346, 370, 378,
276, 284, 308, 316, 340, 348, 372, 380,
278, 286, 310, 318, 342, 350, 374, 382 },
{ 321, 329, 353, 361, 257, 265, 289, 297,
323, 331, 355, 363, 259, 267, 291, 299,
325, 333, 357, 365, 261, 269, 293, 301,
327, 335, 359, 367, 263, 271, 295, 303 },
{ 337, 345, 369, 377, 273, 281, 305, 313,
339, 347, 371, 379, 275, 283, 307, 315,
341, 349, 373, 381, 277, 285, 309, 317,
343, 351, 375, 383, 279, 287, 311, 319 },
{ 448, 456, 480, 488, 384, 392, 416, 424, // column 3
450, 458, 482, 490, 386, 394, 418, 426,
452, 460, 484, 492, 388, 396, 420, 428,
454, 462, 486, 494, 390, 398, 422, 430 },
{ 464, 472, 496, 504, 400, 408, 432, 440,
466, 474, 498, 506, 402, 410, 434, 442,
468, 476, 500, 508, 404, 412, 436, 444,
470, 478, 502, 510, 406, 414, 438, 446 },
{ 385, 393, 417, 425, 449, 457, 481, 489,
387, 395, 419, 427, 451, 459, 483, 491,
389, 397, 421, 429, 453, 461, 485, 493,
391, 399, 423, 431, 455, 463, 487, 495 },
{ 401, 409, 433, 441, 465, 473, 497, 505,
403, 411, 435, 443, 467, 475, 499, 507,
405, 413, 437, 445, 469, 477, 501, 509,
407, 415, 439, 447, 471, 479, 503, 511 },
};
u32 g_pageTable32[32][64];
u32 g_pageTable32Z[32][64];
u32 g_pageTable16[64][64];
u32 g_pageTable16S[64][64];
u32 g_pageTable16Z[64][64];
u32 g_pageTable16SZ[64][64];
u32 g_pageTable8[64][128];
u32 g_pageTable4[128][128];
//maximum PSM is 58, so our arrays have 58 + 1 = 59 elements
// This table is used for fasr access to memory storage data. Field meaning is following:
// 0 -- the number (1 << [psm][0]) is number of pixels per storage format. It's 0 if stored 1 pixel, 1 for 2 pixels (16-bit), 2 for 4 pixels (PSMT8) and 3 for 8 (PSMT4)
// 5 -- is 3 - [psm][0]. Just for speed
// 3, 4 -- size-1 of pageTable for psm. It used to clump x, y otside boundaries.
// 1, 2 -- the number (1 << [psm][1]) and (1 << [psm[2]]) is also size of pageTable. So [psm][3] = (1 << [psm][1]) - 1
// Also note, that [psm][1] = 5 + ([psm][0] + 1) / 2, and [psm][2] = 6 + [psm][0] / 2.
// 6 -- pixel mask, (1 << [psm][5]) - 1, if be used to word, it leave only bytes for pixel formay
// 7 -- starting position of data in word, PSMT8H, 4HL, 4HH are stored data not from the begining.
u32 ZZ_DT[MAX_PSM][TABLE_WIDTH] = {
{0, 5, 6, 31, 63, 3, 0xffffffff, 0}, // 0 PSMCT32
{0, 5, 6, 31, 63, 3, 0x00ffffff, 0}, // 1 PSMCT24
{1, 6, 6, 63, 63, 2, 0x0000ffff, 0}, // 2 PSMCT16
{0, }, // 3
{0, }, // 4
{0, }, // 5
{0, }, // 6
{0, }, // 7
{0, }, // 8
{0, }, // 9
{1, 6, 6, 63, 63, 2, 0x0000ffff, 0}, // 10 PSMCT16S
{0, }, // 11
{0, }, // 12
{0, }, // 13
{0, }, // 14
{0, }, // 15
{0, }, // 16
{0, }, // 17
{0, }, // 18
{2, 6, 7, 63, 127, 1, 0x000000ff, 0}, // 19 PSMT8
{3, 7, 7, 127, 127, 0, 0x0000000f, 0}, // 20 PSMT4
{0, }, // 21
{0, }, // 22
{0, }, // 23
{0, }, // 24
{0, }, // 25
{0, }, // 26
{0, 5, 6, 31, 63, 3, 0x000000ff, 24}, // 27 PSMT8H
{0, }, // 28
{0, }, // 29
{0, }, // 30
{0, }, // 31
{0, }, // 32
{0, }, // 33
{0, }, // 34
{0, }, // 35
{0, 5, 6, 31, 63, 3, 0x0000000f, 24}, // 36 PSMT4HL
{0, }, // 37
{0, }, // 38
{0, }, // 39
{0, }, // 40
{0, }, // 41
{0, }, // 42
{0, }, // 43
{0, 5, 6, 31, 63, 3, 0x0000000f, 28}, // 44 PSMT4HH
{0, }, // 45
{0, }, // 46
{0, }, // 47
{0, 5, 6, 31, 63, 3, 0xffffffff, 0}, // 48 PSMCT32Z
{0, 5, 6, 31, 63, 3, 0x00ffffff, 0}, // 49 PSMCT24Z
{1, 6, 6, 63, 63, 2, 0x0000ffff, 0}, // 50 PSMCT16Z
{0, }, // 51
{0, }, // 52
{0, }, // 53
{0, }, // 54
{0, }, // 55
{0, }, // 56
{0, }, // 57
{1, 6, 6, 63, 63, 2, 0x0000ffff, 0}, // 58 PSMCT16SZ
{0, }, // 59
{0, }, // 60
{0, }, // 61
{0, }, // 62
{0, }, // 63
};
//maxium PSM is 58, so our arrays have 58 + 1 = 59 elements
u32** g_pageTable[MAX_PSM] = {NULL,};
u32** g_blockTable[MAX_PSM] = {NULL, };
u32** g_columnTable[MAX_PSM] = {NULL, };
u32 g_pageTable2[MAX_PSM][127][127] = {0, };
u32** g_pageTableNew[MAX_PSM] = {NULL,};
/* PSM reference array
{ 32, 24, 16, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 16S, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, 8, 4, NULL, NULL, NULL,
NULL, NULL, NULL, 8H, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, 4HL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, 4HH, NULL, NULL, NULL,
32Z, 24Z, 16Z, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 16SZ, NULL, NULL, NULL, NULL, NULL };
*/
const char* psm_name[64] =
{ "PSMCT32", "PSMCT24", "PSMCT16", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, "PSMCT16S", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, "PSMT8", "PSMT4", NULL, NULL, NULL,
NULL, NULL, NULL, "PSMT8H", NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, "PSMT4HL", NULL, NULL, NULL,
NULL, NULL, NULL, NULL, "PSMT4HH", NULL, NULL, NULL,
"PSMT32Z", "PSMT24Z", "PSMT16Z", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, "PSMT16SZ", NULL, NULL, NULL, NULL, NULL };
_SwizzleBlock swizzleBlockFun[64] =
{ SwizzleBlock32, SwizzleBlock24, SwizzleBlock16, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, SwizzleBlock16S, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, SwizzleBlock8, SwizzleBlock4, NULL, NULL, NULL,
NULL, NULL, NULL, SwizzleBlock8H, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, SwizzleBlock4HL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, SwizzleBlock4HH, NULL, NULL, NULL,
SwizzleBlock32Z, SwizzleBlock24Z, SwizzleBlock16Z, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, SwizzleBlock16SZ, NULL, NULL, NULL, NULL, NULL };
_SwizzleBlock swizzleBlockUnFun[64] =
{ SwizzleBlock32u, SwizzleBlock24u, SwizzleBlock16u, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, SwizzleBlock16Su, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, SwizzleBlock8u, SwizzleBlock4u, NULL, NULL, NULL,
NULL, NULL, NULL, SwizzleBlock8Hu, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, SwizzleBlock4HLu, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, SwizzleBlock4HHu, NULL, NULL, NULL,
SwizzleBlock32Zu, SwizzleBlock24Zu, SwizzleBlock16Zu, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, SwizzleBlock16SZu, NULL, NULL, NULL, NULL, NULL };
_getPixelAddress_0 getPixelFun_0[64] =
{
getPixelAddress32_0, getPixelAddress24_0, getPixelAddress16_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, getPixelAddress16S_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, getPixelAddress8_0, getPixelAddress4_0, NULL, NULL, NULL,
NULL, NULL, NULL, getPixelAddress8H_0, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, getPixelAddress4HL_0, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, getPixelAddress4HH_0, NULL, NULL, NULL,
getPixelAddress32Z_0, getPixelAddress24Z_0, getPixelAddress16Z_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, getPixelAddress16SZ_0, NULL, NULL, NULL, NULL, NULL
};
_writePixel_0 writePixelFun_0[64] =
{
writePixel32_0, writePixel24_0, writePixel16_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, writePixel16S_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, writePixel8_0, writePixel4_0, NULL, NULL, NULL,
NULL, NULL, NULL, writePixel8H_0, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, writePixel4HL_0, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, writePixel4HH_0, NULL, NULL, NULL,
writePixel32Z_0, writePixel24Z_0, writePixel16Z_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, writePixel16SZ_0, NULL, NULL, NULL, NULL, NULL
};
_readPixel_0 readPixelFun_0[64] =
{
readPixel32_0, readPixel24_0, readPixel16_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, readPixel16S_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, readPixel8_0, readPixel4_0, NULL, NULL, NULL,
NULL, NULL, NULL, readPixel8H_0, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, readPixel4HL_0, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, readPixel4HH_0, NULL, NULL, NULL,
readPixel32Z_0, readPixel24Z_0, readPixel16Z_0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, readPixel16SZ_0, NULL, NULL, NULL, NULL, NULL
};
_getPixelAddress getPixelFun[64] =
{
getPixelAddress32, getPixelAddress24, getPixelAddress16, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, getPixelAddress16S, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, getPixelAddress8, getPixelAddress4, NULL, NULL, NULL,
NULL, NULL, NULL, getPixelAddress8H, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, getPixelAddress4HL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, getPixelAddress4HH, NULL, NULL, NULL,
getPixelAddress32Z, getPixelAddress24Z, getPixelAddress16Z, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, getPixelAddress16SZ, NULL, NULL, NULL, NULL, NULL
};
_writePixel writePixelFun[64] =
{
writePixel32, writePixel24, writePixel16, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, writePixel16S, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, writePixel8, writePixel4, NULL, NULL, NULL,
NULL, NULL, NULL, writePixel8H, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, writePixel4HL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, writePixel4HH, NULL, NULL, NULL,
writePixel32Z, writePixel24Z, writePixel16Z, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, writePixel16SZ, NULL, NULL, NULL, NULL, NULL
};
_readPixel readPixelFun[64] =
{
readPixel32, readPixel24, readPixel16, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, readPixel16S, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, readPixel8, readPixel4, NULL, NULL, NULL,
NULL, NULL, NULL, readPixel8H, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, readPixel4HL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, readPixel4HH, NULL, NULL, NULL,
readPixel32Z, readPixel24Z, readPixel16Z, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, readPixel16SZ, NULL, NULL, NULL, NULL, NULL
};
_TransferHostLocal TransferHostLocalFun[64] =
{
TransferHostLocal32, TransferHostLocal24, TransferHostLocal16, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, TransferHostLocal16S, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, TransferHostLocal8, TransferHostLocal4, NULL, NULL, NULL,
NULL, NULL, NULL, TransferHostLocal8H, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, TransferHostLocal4HL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, TransferHostLocal4HH, NULL, NULL, NULL,
TransferHostLocal32Z, TransferHostLocal24Z, TransferHostLocal16Z, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, TransferHostLocal16SZ, NULL, NULL, NULL, NULL, NULL
};
_TransferLocalHost TransferLocalHostFun[64] =
{
TransferLocalHost32, TransferLocalHost24, TransferLocalHost16, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, TransferLocalHost16S, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, TransferLocalHost8, TransferLocalHost4, NULL, NULL, NULL,
NULL, NULL, NULL, TransferLocalHost8H, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, TransferLocalHost4HL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, TransferLocalHost4HH, NULL, NULL, NULL,
TransferLocalHost32Z, TransferLocalHost24Z, TransferLocalHost16Z, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, TransferLocalHost16SZ, NULL, NULL, NULL, NULL, NULL
};
#define TD_NULL {0,0,0,0,0,0}
TransferData tData[64] =
{
{2,32,8,8,32,PSMCT32},
{8,32,8,8,24,PSMCT24},
{4,16,16,8,16,PSMCT16},
TD_NULL, TD_NULL, TD_NULL, TD_NULL, TD_NULL,
TD_NULL, TD_NULL,
{4,16,16,8,16,PSMCT16S},
TD_NULL, TD_NULL, TD_NULL, TD_NULL, TD_NULL,
TD_NULL, TD_NULL, TD_NULL,
{4,8,16,16,8,PSMT8},
{8,4,32,16,4,PSMT4},
TD_NULL, TD_NULL, TD_NULL,
TD_NULL, TD_NULL, TD_NULL,
{4,32,8,8,8,PSMT8H},
TD_NULL, TD_NULL, TD_NULL, TD_NULL,
TD_NULL, TD_NULL, TD_NULL, TD_NULL,
{8,32,8,8,4,PSMT4HL},
TD_NULL, TD_NULL, TD_NULL,
TD_NULL, TD_NULL, TD_NULL, TD_NULL,
{8,32,8,8,4,PSMT4HH},
TD_NULL, TD_NULL, TD_NULL,
{2,32,8,8,32,PSMT32Z},
{8,32,8,8,24,PSMT24Z},
{4,16,16,8,16,PSMT16Z},
TD_NULL, TD_NULL, TD_NULL, TD_NULL, TD_NULL,
TD_NULL, TD_NULL,
{4,16,16,8,16,PSMT16SZ},
TD_NULL, TD_NULL, TD_NULL, TD_NULL, TD_NULL
};

View File

@ -1,318 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef MEM_TRANSMIT_H_INCLUDED
#define MEM_TRANSMIT_H_INCLUDED
#include "GS.h"
#include "Mem.h"
extern int tempX, tempY;
extern int pitch, area, fracX;
extern int nSize;
extern u8* pstart;
extern char* psm_name[64];
// transfers whole rows
template <class T>
static __forceinline const T *TransmitHostLocalY_(_writePixel_0 wp, s32 widthlimit, int endY, const T *buf)
{
assert((nSize % widthlimit) == 0 && widthlimit <= 4);
if ((gs.imageEnd.x - gs.trxpos.dx) % widthlimit)
{
// ZZLog::GS_Log("Bad Transmission! %d %d, psm: %d", gs.trxpos.dx, gs.imageEnd.x, gs.dstbuf.psm);
for (; tempY < endY; ++tempY)
{
for (; tempX < gs.imageEnd.x && nSize > 0; tempX += 1, nSize -= 1, buf += 1)
{
/* write as many pixel at one time as possible */
wp(pstart, tempX % 2048, tempY % 2048, buf[0], gs.dstbuf.bw);
}
}
}
for (; tempY < endY; ++tempY)
{
for (; tempX < gs.imageEnd.x && nSize > 0; tempX += widthlimit, nSize -= widthlimit, buf += widthlimit)
{
/* write as many pixel at one time as possible */
if (nSize < widthlimit) return NULL;
wp(pstart, tempX % 2048, tempY % 2048, buf[0], gs.dstbuf.bw);
if (widthlimit > 1)
{
wp(pstart, (tempX + 1) % 2048, tempY % 2048, buf[1], gs.dstbuf.bw);
if (widthlimit > 2)
{
wp(pstart, (tempX + 2) % 2048, tempY % 2048, buf[2], gs.dstbuf.bw);
if (widthlimit > 3)
{
wp(pstart, (tempX + 3) % 2048, tempY % 2048, buf[3], gs.dstbuf.bw);
}
}
}
}
if (tempX >= gs.imageEnd.x)
{
assert(tempX == gs.imageEnd.x);
tempX = gs.trxpos.dx;
}
else
{
assert(gs.transferring == false || nSize*sizeof(T) / 4 == 0);
return NULL;
}
}
return buf;
}
// transfers whole rows
template <class T>
static __forceinline const T *TransmitHostLocalY_24(_writePixel_0 wp, s32 widthlimit, int endY, const T *buf)
{
if (widthlimit != 8 || ((gs.imageEnd.x - gs.trxpos.dx) % widthlimit))
{
//ZZLog::GS_Log("Bad Transmission! %d %d, psm: %d", gs.trxpos.dx, gs.imageEnd.x, gs.dstbuf.psm);
for (; tempY < endY; ++tempY)
{
for (; tempX < gs.imageEnd.x && nSize > 0; tempX += 1, nSize -= 1, buf += 3)
{
wp(pstart, tempX % 2048, tempY % 2048, *(u32*)(buf), gs.dstbuf.bw);
}
if (tempX >= gs.imageEnd.x)
{
assert(gs.transferring == false || tempX == gs.imageEnd.x);
tempX = gs.trxpos.dx;
}
else
{
assert(gs.transferring == false || nSize == 0);
return NULL;
}
}
}
else
{
assert(/*(nSize%widthlimit) == 0 &&*/ widthlimit == 8);
for (; tempY < endY; ++tempY)
{
for (; tempX < gs.imageEnd.x && nSize > 0; tempX += widthlimit, nSize -= widthlimit, buf += 3 * widthlimit)
{
if (nSize < widthlimit) return NULL;
/* write as many pixel at one time as possible */
wp(pstart, tempX % 2048, tempY % 2048, *(u32*)(buf + 0), gs.dstbuf.bw);
wp(pstart, (tempX + 1) % 2048, tempY % 2048, *(u32*)(buf + 3), gs.dstbuf.bw);
wp(pstart, (tempX + 2) % 2048, tempY % 2048, *(u32*)(buf + 6), gs.dstbuf.bw);
wp(pstart, (tempX + 3) % 2048, tempY % 2048, *(u32*)(buf + 9), gs.dstbuf.bw);
wp(pstart, (tempX + 4) % 2048, tempY % 2048, *(u32*)(buf + 12), gs.dstbuf.bw);
wp(pstart, (tempX + 5) % 2048, tempY % 2048, *(u32*)(buf + 15), gs.dstbuf.bw);
wp(pstart, (tempX + 6) % 2048, tempY % 2048, *(u32*)(buf + 18), gs.dstbuf.bw);
wp(pstart, (tempX + 7) % 2048, tempY % 2048, *(u32*)(buf + 21), gs.dstbuf.bw);
}
if (tempX >= gs.imageEnd.x)
{
assert(gs.transferring == false || tempX == gs.imageEnd.x);
tempX = gs.trxpos.dx;
}
else
{
if (nSize < 0)
{
/* extracted too much */
assert((nSize % 3) == 0 && nSize > -24);
tempX += nSize / 3;
nSize = 0;
}
assert(gs.transferring == false || nSize == 0);
return NULL;
}
}
}
return buf;
}
// meant for 4bit transfers
template <class T>
static __forceinline const T *TransmitHostLocalY_4(_writePixel_0 wp, s32 widthlimit, int endY, const T *buf)
{
for (; tempY < endY; ++tempY)
{
for (; tempX < gs.imageEnd.x && nSize > 0; tempX += widthlimit, nSize -= widthlimit)
{
/* write as many pixel at one time as possible */
wp(pstart, tempX % 2048, tempY % 2048, *buf&0x0f, gs.dstbuf.bw);
wp(pstart, (tempX + 1) % 2048, tempY % 2048, *buf >> 4, gs.dstbuf.bw);
buf++;
if (widthlimit > 2)
{
wp(pstart, (tempX + 2) % 2048, tempY % 2048, *buf&0x0f, gs.dstbuf.bw);
wp(pstart, (tempX + 3) % 2048, tempY % 2048, *buf >> 4, gs.dstbuf.bw);
buf++;
if (widthlimit > 4)
{
wp(pstart, (tempX + 4) % 2048, tempY % 2048, *buf&0x0f, gs.dstbuf.bw);
wp(pstart, (tempX + 5) % 2048, tempY % 2048, *buf >> 4, gs.dstbuf.bw);
buf++;
if (widthlimit > 6)
{
wp(pstart, (tempX + 6) % 2048, tempY % 2048, *buf&0x0f, gs.dstbuf.bw);
wp(pstart, (tempX + 7) % 2048, tempY % 2048, *buf >> 4, gs.dstbuf.bw);
buf++;
}
}
}
}
if (tempX >= gs.imageEnd.x)
{
tempX = gs.trxpos.dx;
}
else
{
assert(gs.transferring == false || (nSize / 32) == 0);
return NULL;
}
}
return buf;
}
template <class T>
static __forceinline const T *TransmitHostLocalY(u32 psm, _writePixel_0 wp, s32 widthlimit, int endY, const T *buf)
{
//ZZLog::WriteLn("TransmitHostLocalY: psm == %s, bimode == 0x%x", psm_name[psm], PSMT_BITMODE(psm));
switch (PSMT_BITMODE(psm))
{
case 1:
return TransmitHostLocalY_24<T>(wp, widthlimit, endY, buf);
case 4:
return TransmitHostLocalY_4<T>(wp, widthlimit, endY, buf);
default:
return TransmitHostLocalY_<T>(wp, widthlimit, endY, buf);
}
assert(0);
return NULL;
}
template <class T>
static __forceinline const T *TransmitHostLocalX_(_writePixel_0 wp, u32 widthlimit, u32 blockheight, u32 startX, const T *buf)
{
for (u32 tempi = 0; tempi < blockheight; ++tempi)
{
for (tempX = startX; tempX < gs.imageEnd.x; tempX++, buf++)
{
wp(pstart, tempX % 2048, (tempY + tempi) % 2048, buf[0], gs.dstbuf.bw);
}
buf += pitch - fracX;
}
return buf;
}
// transmit until endX, don't check size since it has already been prevalidated
template <class T>
static __forceinline const T *TransmitHostLocalX_24(_writePixel_0 wp, u32 widthlimit, u32 blockheight, u32 startX, const T *buf)
{
for (u32 tempi = 0; tempi < blockheight; ++tempi)
{
for (tempX = startX; tempX < gs.imageEnd.x; tempX++, buf += 3)
{
wp(pstart, tempX % 2048, (tempY + tempi) % 2048, *(u32*)buf, gs.dstbuf.bw);
}
buf += 3 * (pitch - fracX);
}
return buf;
}
// transmit until endX, don't check size since it has already been prevalidated
template <class T>
static __forceinline const T *TransmitHostLocalX_4(_writePixel_0 wp, u32 widthlimit, u32 blockheight, u32 startX, const T *buf)
{
for (u32 tempi = 0; tempi < blockheight; ++tempi)
{
for (tempX = startX; tempX < gs.imageEnd.x; tempX += 2, buf++)
{
wp(pstart, tempX % 2048, (tempY + tempi) % 2048, buf[0]&0x0f, gs.dstbuf.bw);
wp(pstart, (tempX + 1) % 2048, (tempY + tempi) % 2048, buf[0] >> 4, gs.dstbuf.bw);
}
buf += (pitch - fracX) / 2;
}
return buf;
}
template <class T>
static __forceinline const T *TransmitHostLocalX(u32 psm, _writePixel_0 wp, u32 widthlimit, u32 blockheight, u32 startX, const T *buf)
{
//ZZLog::WriteLn("TransmitHostLocalX: psm == %s, bimode == 0x%x", psm_name[psm], PSMT_BITMODE(psm));
switch (PSMT_BITMODE(psm))
{
case 1:
return TransmitHostLocalX_24<T>(wp, widthlimit, blockheight, startX, buf);
case 4:
return TransmitHostLocalX_4<T>(wp, widthlimit, blockheight, startX, buf);
default:
return TransmitHostLocalX_<T>(wp, widthlimit, blockheight, startX, buf);
}
assert(0);
return NULL;
}
// calculate pitch in source buffer
static __forceinline u32 TransPitch(u32 pitch, u32 size)
{
return pitch * size / 8;
}
static __forceinline u32 TransPitch2(u32 pitch, u32 size)
{
if (size == 4) return pitch / 2;
if (size == 24) return pitch * 3;
return pitch;
}
#endif // MEM_TRANSMIT_H_INCLUDED

View File

@ -1,266 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
////////////////////
// Small profiler //
////////////////////
#include <list>
#include <string>
#include <map>
#include "Profile.h"
#include "Util.h"
using namespace std;
#define GET_PROFILE_TIME() GetCPUTicks()
#if !defined(ZEROGS_DEVBUILD)
#define g_bWriteProfile 0
#else
bool g_bWriteProfile = 0;
#endif
u64 luPerfFreq;
struct DVPROFSTRUCT;
struct DVPROFSTRUCT
{
struct DATA
{
DATA(u64 time, u32 user = 0) : dwTime(time), dwUserData(user) {}
DATA() : dwTime(0), dwUserData(0) {}
u64 dwTime;
u32 dwUserData;
};
~DVPROFSTRUCT()
{
list<DVPROFSTRUCT*>::iterator it = listpChild.begin();
while (it != listpChild.end())
{
safe_delete(*it);
++it;
}
}
list<DATA> listTimes; // before DVProfEnd is called, contains the global time it started
// after DVProfEnd is called, contains the time it lasted
// the list contains all the tracked times
char pname[256];
list<DVPROFSTRUCT*> listpChild; // other profilers called during this profiler period
};
struct DVPROFTRACK
{
u32 dwUserData;
DVPROFSTRUCT::DATA* pdwTime;
DVPROFSTRUCT* pprof;
};
list<DVPROFTRACK> g_listCurTracking; // the current profiling functions, the back element is the
// one that will first get popped off the list when DVProfEnd is called
// the pointer is an element in DVPROFSTRUCT::listTimes
list<DVPROFSTRUCT> g_listProfilers; // the current profilers, note that these are the parents
// any profiler started during the time of another is held in
// DVPROFSTRUCT::listpChild
list<DVPROFSTRUCT*> g_listAllProfilers; // ignores the hierarchy, pointer to elements in g_listProfilers
void DVProfRegister(char* pname)
{
if (!g_bWriteProfile) return;
list<DVPROFSTRUCT*>::iterator it = g_listAllProfilers.begin();
// while(it != g_listAllProfilers.end() ) {
//
// if( _tcscmp(pname, (*it)->pname) == 0 ) {
// (*it)->listTimes.push_back(timeGetTime());
// DVPROFTRACK dvtrack;
// dvtrack.pdwTime = &(*it)->listTimes.back();
// dvtrack.pprof = *it;
// g_listCurTracking.push_back(dvtrack);
// return;
// }
//
// ++it;
// }
// else add in a new profiler to the appropriate parent profiler
DVPROFSTRUCT* pprof = NULL;
if (g_listCurTracking.size() > 0)
{
assert(g_listCurTracking.back().pprof != NULL);
g_listCurTracking.back().pprof->listpChild.push_back(new DVPROFSTRUCT());
pprof = g_listCurTracking.back().pprof->listpChild.back();
}
else
{
g_listProfilers.push_back(DVPROFSTRUCT());
pprof = &g_listProfilers.back();
}
strncpy(pprof->pname, pname, 256);
// setup the profiler for tracking
pprof->listTimes.push_back(DVPROFSTRUCT::DATA(GET_PROFILE_TIME()));
DVPROFTRACK dvtrack;
dvtrack.pdwTime = &pprof->listTimes.back();
dvtrack.pprof = pprof;
dvtrack.dwUserData = 0;
g_listCurTracking.push_back(dvtrack);
// add to all profiler list
g_listAllProfilers.push_back(pprof);
}
void DVProfEnd(u32 dwUserData)
{
if (!g_bWriteProfile)
return;
B_RETURN(g_listCurTracking.size() > 0);
DVPROFTRACK dvtrack = g_listCurTracking.back();
assert(dvtrack.pdwTime != NULL && dvtrack.pprof != NULL);
dvtrack.pdwTime->dwTime = 1000000 * (GET_PROFILE_TIME() - dvtrack.pdwTime->dwTime) / luPerfFreq;
dvtrack.pdwTime->dwUserData = dwUserData;
g_listCurTracking.pop_back();
}
struct DVTIMEINFO
{
DVTIMEINFO() : uInclusive(0), uExclusive(0) {}
u64 uInclusive, uExclusive;
};
map<string, DVTIMEINFO> mapAggregateTimes;
u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident)
{
fprintf(f, "%*s%s - ", ident, "", p->pname);
list<DVPROFSTRUCT::DATA>::iterator ittime = p->listTimes.begin();
u64 utime = 0;
while (ittime != p->listTimes.end())
{
utime += (u32)ittime->dwTime;
if (ittime->dwUserData)
fprintf(f, "time: %d, user: 0x%8.8x", (u32)ittime->dwTime, ittime->dwUserData);
else
fprintf(f, "time: %d", (u32)ittime->dwTime);
++ittime;
}
mapAggregateTimes[p->pname].uInclusive += utime;
fprintf(f, "\n");
list<DVPROFSTRUCT*>::iterator itprof = p->listpChild.begin();
u32 uex = utime;
while (itprof != p->listpChild.end())
{
uex -= (u32)DVProfWriteStruct(f, *itprof, ident + 4);
++itprof;
}
mapAggregateTimes[p->pname].uExclusive += uex;
return utime;
}
void DVProfWrite(const char* pfilename, u32 frames)
{
assert(pfilename != NULL);
FILE* f = fopen(pfilename, "wb");
mapAggregateTimes.clear();
list<DVPROFSTRUCT>::iterator it = g_listProfilers.begin();
while (it != g_listProfilers.end())
{
DVProfWriteStruct(f, &(*it), 0);
++it;
}
{
map<string, DVTIMEINFO>::iterator it;
fprintf(f, "\n\n-------------------------------------------------------------------\n\n");
u64 uTotal[2] = {0};
double fiTotalTime[2];
for (it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it)
{
uTotal[0] += it->second.uExclusive;
uTotal[1] += it->second.uInclusive;
}
fprintf(f, "total times (%d): ex: %Lu ", frames, uTotal[0] / frames);
fprintf(f, "inc: %Lu\n", uTotal[1] / frames);
fiTotalTime[0] = 1.0 / (double)uTotal[0];
fiTotalTime[1] = 1.0 / (double)uTotal[1];
// output the combined times
for (it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it)
{
fprintf(f, "%s - ex: %f inc: %f\n", it->first.c_str(), (double)it->second.uExclusive * fiTotalTime[0],
(double)it->second.uInclusive * fiTotalTime[1]);
}
}
fclose(f);
}
void DVProfClear()
{
g_listCurTracking.clear();
g_listProfilers.clear();
g_listAllProfilers.clear();
}
void InitProfile()
{
luPerfFreq = GetCPUTicks();
}

View File

@ -1,172 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef PROFILE_H_INCLUDED
#define PROFILE_H_INCLUDED
#include "Util.h"
#if !defined(ZEROGS_DEVBUILD)
#define g_bWriteProfile 0
#else
extern bool g_bWriteProfile;
#endif
extern u64 luPerfFreq;
// Copied from Utilities; remove later.
#ifdef __linux__
#include <sys/time.h>
#include <sys/timeb.h> // ftime(), struct timeb
inline unsigned long timeGetTime()
{
timeb t;
ftime(&t);
return (unsigned long)(t.time*1000 + t.millitm);
}
inline unsigned long timeGetPreciseTime()
{
timespec t;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
return t.tv_nsec;
}
static __forceinline void InitCPUTicks()
{
}
static __forceinline u64 GetTickFrequency()
{
return 1000000; // unix measures in microseconds
}
static __forceinline u64 GetCPUTicks()
{
struct timeval t;
gettimeofday(&t, NULL);
return ((u64)t.tv_sec*GetTickFrequency()) + t.tv_usec;
}
#else
static __aligned16 LARGE_INTEGER lfreq;
inline unsigned long timeGetPreciseTime()
{
// Implement later.
return 0;
}
static __forceinline void InitCPUTicks()
{
QueryPerformanceFrequency(&lfreq);
}
static __forceinline u64 GetTickFrequency()
{
return lfreq.QuadPart;
}
static __forceinline u64 GetCPUTicks()
{
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
return count.QuadPart;
}
#endif
// IMPORTANT: For every Register there must be an End
void DVProfRegister(char* pname); // first checks if this profiler exists in g_listProfilers
void DVProfEnd(u32 dwUserData);
void DVProfWrite(const char* pfilename, u32 frames = 0);
void DVProfClear(); // clears all the profilers
#define DVPROFILE
#ifdef DVPROFILE
class DVProfileFunc
{
public:
u32 dwUserData;
DVProfileFunc(char* pname) { DVProfRegister(pname); dwUserData = 0; }
DVProfileFunc(char* pname, u32 dwUserData) : dwUserData(dwUserData) { DVProfRegister(pname); }
~DVProfileFunc() { DVProfEnd(dwUserData); }
};
#else
class DVProfileFunc
{
public:
u32 dwUserData;
static __forceinline DVProfileFunc(char* pname) {}
static __forceinline DVProfileFunc(char* pname, u32 dwUserData) { }
~DVProfileFunc() {}
};
#endif
template <typename T>
class CInterfacePtr
{
public:
inline CInterfacePtr() : ptr(NULL) {}
inline explicit CInterfacePtr(T* newptr) : ptr(newptr) { if (ptr != NULL) ptr->AddRef(); }
inline ~CInterfacePtr() { if (ptr != NULL) ptr->Release(); }
inline T* operator*() { assert(ptr != NULL); return *ptr; }
inline T* operator->() { return ptr; }
inline T* get() { return ptr; }
inline void release()
{
if (ptr != NULL) { ptr->Release(); ptr = NULL; }
}
inline operator T*() { return ptr; }
inline bool operator==(T* rhs) { return ptr == rhs; }
inline bool operator!=(T* rhs) { return ptr != rhs; }
inline CInterfacePtr& operator= (T* newptr)
{
if (ptr != NULL) ptr->Release();
ptr = newptr;
if (ptr != NULL) ptr->AddRef();
return *this;
}
private:
T* ptr;
};
extern void InitProfile();
#endif // PROFILE_H_INCLUDED

View File

@ -1,82 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2012 zeydlitz@gmail.com, arcum42@gmail.com, gregory.hainaut@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "Profile_gl3.h"
GPU_Profile GPU_Timer;
void GPU_Profile::dump(bool flush)
{
u32 high_limit;
if (flush) high_limit = 1;
else high_limit = 1000;
while (datas.size() > high_limit) {
ProfileInfo data_start = datas.front();
datas.pop_front();
ProfileInfo data_stop = datas.front();
datas.pop_front();
u32 gpu_time = read_diff_timers(data_start.timer, data_stop.timer);
#ifdef ENABLE_MARKER
if (GLEW_GREMEDY_string_marker) glStringMarkerGREMEDY(0, format("Time %6dus", gpu_time).c_str());
#else
fprintf(stderr, "Frame %d (%d): %6dus\n", data_start.frame, data_start.draw, gpu_time);
#endif
}
}
void GPU_Profile::create_timer()
{
u32 timer = 0;
#ifdef GLSL4_API
glGenQueries(1, &timer);
glQueryCounter(timer, GL_TIMESTAMP);
#endif
datas.push_back(ProfileInfo(timer, frame, draw));
#ifdef ENABLE_MARKER
dump(true);
#endif
}
u32 GPU_Profile::read_diff_timers(u32 start_timer, u32 stop_timer)
{
#ifdef GLSL4_API
if(!start_timer || !stop_timer) return -1;
int stopTimerAvailable = 0;
while (!stopTimerAvailable)
glGetQueryObjectiv(stop_timer, GL_QUERY_RESULT_AVAILABLE, &stopTimerAvailable);
u64 start, stop = 0;
// Note: timers have a precision of the ns, so you need 64 bits value to avoid overflow!
glGetQueryObjectui64v(start_timer, GL_QUERY_RESULT, &start);
glGetQueryObjectui64v(stop_timer, GL_QUERY_RESULT, &stop);
// delete timer
glDeleteQueries(1, &start_timer);
glDeleteQueries(1, &stop_timer);
return (stop-start)/1000;
#else
return 0;
#endif
}

View File

@ -1,57 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2012 zeydlitz@gmail.com, arcum42@gmail.com, gregory.hainaut@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "Util.h"
#ifndef _PROFILE_GL3_H_
#define _PROFILE_GL3_H_
#define ENABLE_MARKER // Fire some marker for opengl Debugger (apitrace, gdebugger)
class GPU_Profile {
struct ProfileInfo {
u32 timer;
u32 frame;
u32 draw;
ProfileInfo(u32 timer, u32 frame, u32 draw) : timer(timer), frame(frame), draw(draw) {}
ProfileInfo(u32 timer) : timer(timer), frame(0), draw(0) {}
};
std::list<ProfileInfo> datas;
u32 frame;
u32 draw;
public:
GPU_Profile() : frame(0), draw(0) {
datas.clear();
}
void inc_draw() { draw++;}
void inc_frame() { frame++;}
void create_timer();
u32 read_diff_timers(u32 start_timer, u32 stop_timer);
void dump(bool flush = false);
};
extern GPU_Profile GPU_Timer;
#endif

View File

@ -1,13 +0,0 @@
ZeroGS OpenGL
-------------
author: zerofrog (@gmail.com)
ZeroGS heavily uses GPU shaders. All the shaders are written in nVidia's Cg language and can be found in ps2hw.fx.
'Dev' versions of ZeroGS directly read ps2hw.fx
'Release' versions of ZeroGS read a precompiled version of ps2hw.fx from ps2hw.dat. In order to build ps2hw.dat, compile ZeroGSShaders and execute:
./ZeroGSShaders ps2hw.fx ps2hw.dat
For Windows users, once ZeroGSShaders is built, run buildshaders.bat directly. It will update all necessary resource files.
Note that ZeroGSShaders has only been tested in Windows so far, but the Windows ps2hw.dat can be used in linux builds.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,327 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef UTIL_H_INCLUDED
#define UTIL_H_INCLUDED
#ifdef _WIN32
#include <io.h>
#include "Utilities/RedtapeWindows.h"
//#include <windows.h>
//#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include "glprocs.h"
#ifdef ZEROGS_SSE2
#include <emmintrin.h>
#endif
#else // linux basic definitions
#include <sys/stat.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <gtk/gtk.h>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#ifdef ZEROGS_SSE2
#include <immintrin.h>
#endif
#endif
#define GSdefs
//Pcsx2Defs is included in Dependencies.h.
#include "Utilities/Dependencies.h"
#include "CRC.h"
#include "ZZLog.h"
#ifdef _WIN32
// need C definitions -- no mangling please!
extern "C" u32 CALLBACK PS2EgetLibType(void);
extern "C" u32 CALLBACK PS2EgetLibVersion2(u32 type);
extern "C" char* CALLBACK PS2EgetLibName(void);
#endif
// Allow easy copy/past between GSdx and zzogl
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned int uint32;
typedef signed int int32;
typedef unsigned long long uint64;
typedef signed long long int64;
#include "ZZoglMath.h"
#include "Profile.h"
#include "GSDump.h"
#include "Utilities/MemcpyFast.h"
extern wxString s_strIniPath; // Air's new (r2361) new constant for ini file path
static inline std::string format(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
int result = -1, length = 256;
char* buffer = NULL;
while(result == -1)
{
if(buffer) delete [] buffer;
buffer = new char[length + 1];
memset(buffer, 0, length + 1);
result = vsnprintf(buffer, length, fmt, args);
length *= 2;
}
va_end(args);
std::string s(buffer);
delete [] buffer;
return s;
}
typedef struct
{
int x, y, w, h;
} Rect;
typedef struct
{
int x, y;
} Point;
typedef struct
{
int w, h;
} Size;
typedef struct
{
int x0, y0;
int x1, y1;
} Rect2;
typedef struct
{
int x, y, c;
} PointC;
enum GSWindowDim
{
GSDim_640 = 0,
GSDim_800,
GSDim_1024,
GSDim_1280,
};
typedef union
{
struct
{
u32 fullscreen : 1;
u32 tga_snap : 1;
u32 capture_avi : 1;
u32 widescreen : 1;
u32 wireframe : 1;
u32 loaded : 1;
u32 dimensions : 2;
};
u32 _u32;
void ZZOptions(u32 value) { _u32 = value; }
} ZZOptions;
typedef struct
{
u8 mrtdepth; // write color in render target
u8 interlace; // intelacing mode 0, 1, 3-off
u8 aa; // antialiasing 0 - off, 1 - 2x, 2 - 4x, 3 - 8x, 4 - 16x
u8 bilinear; // set to enable bilinear support. 0 - off, 1 -- on, 2 -- force (use for textures that usually need it)
ZZOptions zz_options;
gameHacks hacks; // game options -- different hacks.
gameHacks def_hacks;// default game settings
int width, height; // View target size, has no impact towards speed
int x, y; // Lets try for a persistant window position.
bool isWideScreen; // Widescreen support
u32 SkipDraw;
u32 log;
u32 disableHacks;
int dump;
void incAA() { aa++; if (aa > 4) aa = 0; }
void decAA() { aa--; if (aa > 4) aa = 4; } // u8 is unsigned, so negative value is 255.
gameHacks settings()
{
if (disableHacks)
{
return hacks;
}
else
{
gameHacks tempHack;
tempHack._u32 = (hacks._u32 | def_hacks._u32);
return tempHack;
}
}
bool fullscreen() { return !!(zz_options.fullscreen); }
bool wireframe() { return !!(zz_options.wireframe); }
bool widescreen() { return !!(zz_options.widescreen); }
bool captureAvi() { return !!(zz_options.capture_avi); }
bool loaded() { return !!(zz_options.loaded); }
void setFullscreen(bool flag)
{
zz_options.fullscreen = (flag) ? 1 : 0;
}
void setWireframe(bool flag)
{
zz_options.wireframe = (flag) ? 1 : 0;
}
void setCaptureAvi(bool flag)
{
zz_options.capture_avi = (flag) ? 1 : 0;
}
void setLoaded(bool flag)
{
zz_options.loaded = (flag) ? 1 : 0;
}
void set_dimensions(u32 dim)
{
switch (dim)
{
case GSDim_640:
width = 640;
height = isWideScreen ? 360 : 480;
break;
case GSDim_800:
width = 800;
height = isWideScreen ? 450 : 600;
break;
case GSDim_1024:
width = 1024;
height = isWideScreen ? 576 : 768;
break;
case GSDim_1280:
width = 1280;
height = isWideScreen ? 720 : 960;
break;
default:
width = 800;
height = 600;
break;
}
}
} GSconf;
extern GSconf conf;
// ----------------------- Defines
#define REG64(name) \
union name \
{ \
u64 i64; \
u32 ai32[2]; \
struct { \
#define REG128(name)\
union name \
{ \
u64 ai64[2]; \
u32 ai32[4]; \
struct { \
#define REG64_(prefix, name) REG64(prefix##name)
#define REG128_(prefix, name) REG128(prefix##name)
#define REG_END }; };
#define REG_END2 };
#define REG64_SET(name) \
union name \
{ \
u64 i64; \
u32 ai32[2]; \
#define REG128_SET(name)\
union name \
{ \
u64 ai64[2]; \
u32 ai32[4]; \
#define REG_SET_END };
#define FORIT(it, v) for(it = (v).begin(); it != (v).end(); ++(it))
extern void LoadConfig();
extern void SaveConfig();
extern void (*GSirq)();
extern void *SysLoadLibrary(char *lib); // Loads Library
extern void *SysLoadSym(void *lib, char *sym); // Loads Symbol from Library
extern char *SysLibError(); // Gets previous error loading sysbols
extern void SysCloseLibrary(void *lib); // Closes Library
extern void SysMessage(const char *fmt, ...);
#ifdef ZEROGS_DEVBUILD
extern char EFFECT_NAME[256];
extern char EFFECT_DIR[256];
extern u32 g_nGenVars, g_nTexVars, g_nAlphaVars, g_nResolve;
extern bool g_bSaveTrans, g_bUpdateEffect, g_bSaveTex, g_bSaveResolved;
#endif
extern bool g_bDisplayFPS; // should we display FPS on screen?
#endif // UTIL_H_INCLUDED

View File

@ -1,143 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include <stdlib.h>
#include "GS.h"
#include "Win32.h"
#include "Utilities/Path.h"
extern HINSTANCE hInst;
void SaveConfig()
{
wxChar szValue[256];
const wxString iniFile(Path::Combine(s_strIniPath, L"zzogl-pg.ini"));
wxSprintf(szValue, L"%u", conf.interlace);
WritePrivateProfileString(L"Settings", L"Interlace", szValue, iniFile);
wxSprintf(szValue, L"%u", conf.aa);
WritePrivateProfileString(L"Settings", L"Antialiasing", szValue, iniFile);
wxSprintf(szValue, L"%u", conf.bilinear);
WritePrivateProfileString(L"Settings", L"Bilinear", szValue, iniFile);
wxSprintf(szValue, L"%u", conf.zz_options._u32);
WritePrivateProfileString(L"Settings", L"ZZOptions", szValue, iniFile);
wxSprintf(szValue, L"%u", conf.hacks._u32);
WritePrivateProfileString(L"Settings", L"AdvancedOptions", szValue, iniFile);
wxSprintf(szValue, L"%u", conf.width);
WritePrivateProfileString(L"Settings", L"Width", szValue, iniFile);
wxSprintf(szValue, L"%u", conf.height);
WritePrivateProfileString(L"Settings", L"Height", szValue, iniFile);
wxSprintf(szValue, L"%u", conf.SkipDraw);
WritePrivateProfileString(L"Settings", L"SkipDraw", szValue, iniFile);
}
void LoadConfig()
{
wxChar szValue[256];
unsigned long val;
const wxString iniFile(Path::Combine(s_strIniPath, L"zzogl-pg.ini"));
memset(&conf, 0, sizeof(conf));
conf.interlace = 0; // on, mode 1
conf.mrtdepth = 1;
conf.zz_options._u32 = 0;
conf.hacks._u32 = 0;
conf.bilinear = 1;
conf.width = 640;
conf.height = 480;
conf.SkipDraw = 0;
conf.disableHacks = 0;
FILE *fp = wxFopen(iniFile, L"rt");
if (!fp)
{
SysMessage("Unable to open ZZOgl-PG's ini file!");
CreateDirectory(s_strIniPath, NULL);
SaveConfig();//save and return
return ;
}
fclose(fp);
GetPrivateProfileString(L"Settings", L"Interlace", NULL, szValue, 20, iniFile);
wxString(szValue).ToULong(&val);
conf.interlace = (u8)val;
GetPrivateProfileString(L"Settings", L"Antialiasing", NULL, szValue, 20, iniFile);
wxString(szValue).ToULong(&val);
conf.aa = (u8)val;
GetPrivateProfileString(L"Settings", L"ZZOptions", NULL, szValue, 20, iniFile);
wxString(szValue).ToULong(&val);
conf.zz_options._u32 = val;
GetPrivateProfileString(L"Settings", L"AdvancedOptions", NULL, szValue, 20, iniFile);
wxString(szValue).ToULong(&val);
conf.hacks._u32 = val;
GetPrivateProfileString(L"Settings", L"Bilinear", NULL, szValue, 20, iniFile);
wxString(szValue).ToULong(&val);
conf.bilinear = (u8)val;
GetPrivateProfileString(L"Settings", L"Width", NULL, szValue, 20, iniFile);
wxString(szValue).ToULong(&val);
conf.width = val;
GetPrivateProfileString(L"Settings", L"Height", NULL, szValue, 20, iniFile);
wxString(szValue).ToULong(&val);
conf.height = val;
GetPrivateProfileString(L"Settings", L"SkipDraw", NULL, szValue, 20, iniFile);
wxString(szValue).ToULong(&val);
conf.SkipDraw = val;
if (conf.aa < 0 || conf.aa > 4) conf.aa = 0;
conf.isWideScreen = (conf.widescreen() != 0);
switch (conf.zz_options.dimensions)
{
case GSDim_640:
conf.width = 640;
conf.height = conf.isWideScreen ? 360 : 480;
break;
case GSDim_800:
conf.width = 800;
conf.height = conf.isWideScreen ? 450 : 600;
break;
case GSDim_1024:
conf.width = 1024;
conf.height = conf.isWideScreen ? 576 : 768;
break;
case GSDim_1280:
conf.width = 1280;
conf.height = conf.isWideScreen ? 720 : 960;
break;
}
// turn off all hacks by default
conf.setWireframe(false);
conf.setCaptureAvi(false);
conf.setLoaded(true);
if (conf.width <= 0 || conf.height <= 0)
{
conf.width = 640;
conf.height = 480;
}
}

View File

@ -1,344 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include <stdio.h>
#include "Utilities/RedtapeWindows.h"
#include <windowsx.h>
#include "resrc1.h"
#include "GS.h"
#include "ZZoglShaders.h"
#include "Win32.h"
#include <map>
using namespace std;
extern int g_nPixelShaderVer;
static int prevbilinearfilter;
HINSTANCE hInst = NULL;
void CALLBACK GSkeyEvent(keyEvent *ev)
{
// switch (ev->event) {
// case KEYPRESS:
// switch (ev->key) {
// case VK_PRIOR:
// if (conf.fps) fpspos++; break;
// case VK_NEXT:
// if (conf.fps) fpspos--; break;
// case VK_END:
// if (conf.fps) fpspress = 1; break;
// case VK_DELETE:
// conf.fps = 1 - conf.fps;
// break;
// }
// break;
// }
}
#include "Win32/resource.h"
map<int, int> mapConfOpts;
#define PUT_CONF(id) mapConfOpts[IDC_CONFOPT_##id] = 0x##id;
void OnAdvOK(HWND hW)
{
conf.hacks._u32 = 0;
for (map<int, int>::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it)
{
if (IsDlgButtonChecked(hW, it->first)) conf.hacks._u32 |= it->second;
}
GSsetGameCRC(g_LastCRC, conf.hacks._u32);
SaveConfig();
EndDialog(hW, false);
}
void OnInitAdvDialog(HWND hW)
{
mapConfOpts.clear();
PUT_CONF(00000001);
PUT_CONF(00000002);
PUT_CONF(00000004);
PUT_CONF(00000008);
PUT_CONF(00000010);
PUT_CONF(00000020);
PUT_CONF(00000040);
PUT_CONF(00000080);
PUT_CONF(00000100);
PUT_CONF(00000200);
PUT_CONF(00000400);
PUT_CONF(00000800);
PUT_CONF(00001000);
PUT_CONF(00002000);
PUT_CONF(00004000);
PUT_CONF(00008000);
PUT_CONF(00010000);
PUT_CONF(00020000);
PUT_CONF(00040000);
PUT_CONF(00080000);
PUT_CONF(00100000);
PUT_CONF(00200000);
PUT_CONF(00800000);
PUT_CONF(01000000);
PUT_CONF(02000000);
PUT_CONF(04000000);
PUT_CONF(10000000);
for (map<int, int>::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it)
{
CheckDlgButton(hW, it->first, (conf.settings()._u32 & it->second) ? 1 : 0);
}
}
BOOL CALLBACK AdvancedDialogProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
OnInitAdvDialog(hW);
return true;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
EndDialog(hW, true);
return true;
case IDOK:
OnAdvOK(hW);
return true;
}
}
return false;
}
void CALLBACK AdvancedDialog()
{
DialogBox(hInst,
MAKEINTRESOURCE(IDD_ADV_OPTIONS),
GetActiveWindow(),
(DLGPROC)AdvancedDialogProc);
}
void OnInitConfDialog(HWND hW)
{
if (!(conf.zz_options.loaded)) LoadConfig();
TCHAR *aaName[] = {L"None", L"x2", L"x4", L"x8", L"x16"};
for(int i=0; i<5; i++)
{
ComboBox_AddString(GetDlgItem(hW, IDC_AA_COMBO), (LPARAM)aaName[i]);
}
ComboBox_SelectString(GetDlgItem(hW, IDC_AA_COMBO), -1, (LPARAM)aaName[conf.aa]);
TCHAR *sizeName[] = {L"640 x 480", L"800 x 600", L"1024 x 768", L"1280 x 960"};
for(int i=0; i<4; i++)
{
ComboBox_AddString(GetDlgItem(hW, IDC_WIN_SIZE_COMBO), (LPARAM)sizeName[i]);
}
ComboBox_SelectString(GetDlgItem(hW, IDC_WIN_SIZE_COMBO), -1, (LPARAM)sizeName[conf.zz_options.dimensions]);
CheckDlgButton(hW, IDC_CONFIG_INTERLACE, conf.interlace);
CheckDlgButton(hW, IDC_CONFIG_BILINEAR, conf.bilinear);
CheckDlgButton(hW, IDC_CONFIG_DEPTHWRITE, conf.mrtdepth);
CheckDlgButton(hW, IDC_CONFIG_WIREFRAME, (conf.wireframe()) ? 1 : 0);
CheckDlgButton(hW, IDC_CONFIG_CAPTUREAVI, (conf.captureAvi()) ? 1 : 0);
CheckDlgButton(hW, IDC_CONFIG_FULLSCREEN, (conf.fullscreen()) ? 1 : 0);
CheckDlgButton(hW, IDC_CONFIG_WIDESCREEN, (conf.widescreen()) ? 1 : 0);
CheckDlgButton(hW, IDC_CONFIG_BMPSS, (conf.zz_options.tga_snap) ? 1 : 0);
prevbilinearfilter = conf.bilinear;
}
void OnConfOK(HWND hW)
{
u32 newinterlace = IsDlgButtonChecked(hW, IDC_CONFIG_INTERLACE);
if (!conf.interlace)
conf.interlace = newinterlace;
else if (!newinterlace)
conf.interlace = 2; // off
conf.bilinear = IsDlgButtonChecked(hW, IDC_CONFIG_BILINEAR);
// restore
if (conf.bilinear && prevbilinearfilter) conf.bilinear = prevbilinearfilter;
if (ComboBox_GetCurSel(GetDlgItem(hW, IDC_AA_COMBO)) != -1)
conf.aa = ComboBox_GetCurSel(GetDlgItem(hW, IDC_AA_COMBO));
conf.zz_options._u32 = 0;
conf.zz_options.capture_avi = IsDlgButtonChecked(hW, IDC_CONFIG_CAPTUREAVI) ? 1 : 0;
conf.zz_options.wireframe = IsDlgButtonChecked(hW, IDC_CONFIG_WIREFRAME) ? 1 : 0;
conf.zz_options.fullscreen = IsDlgButtonChecked(hW, IDC_CONFIG_FULLSCREEN) ? 1 : 0;
conf.zz_options.widescreen = IsDlgButtonChecked(hW, IDC_CONFIG_WIDESCREEN) ? 1 : 0;
conf.zz_options.tga_snap = IsDlgButtonChecked(hW, IDC_CONFIG_BMPSS) ? 1 : 0;
if (ComboBox_GetCurSel(GetDlgItem(hW, IDC_WIN_SIZE_COMBO)) == 0)
conf.zz_options.dimensions = GSDim_640;
else if (ComboBox_GetCurSel(GetDlgItem(hW, IDC_WIN_SIZE_COMBO)) == 1)
conf.zz_options.dimensions = GSDim_800;
else if (ComboBox_GetCurSel(GetDlgItem(hW, IDC_WIN_SIZE_COMBO)) == 2)
conf.zz_options.dimensions = GSDim_1024;
else if (ComboBox_GetCurSel(GetDlgItem(hW, IDC_WIN_SIZE_COMBO)) == 3)
conf.zz_options.dimensions = GSDim_1280;
SaveConfig();
EndDialog(hW, false);
}
BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
OnInitConfDialog(hW);
return true;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_AA_COMBO:
break;
case IDC_ADV_BTN:
AdvancedDialog();
return true;
case IDCANCEL:
EndDialog(hW, true);
return true;
case IDOK:
OnConfOK(hW);
return true;
}
}
return false;
}
void CALLBACK GSconfigure()
{
DialogBox(hInst,
MAKEINTRESOURCE(IDD_CONFIG2),
GetActiveWindow(),
(DLGPROC)ConfigureDlgProc);
if (g_nPixelShaderVer == SHADER_REDUCED) conf.bilinear = 0;
}
s32 CALLBACK GStest()
{
return 0;
}
BOOL CALLBACK AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
return true;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
EndDialog(hW, false);
return true;
}
}
return false;
}
void CALLBACK GSabout()
{
DialogBox(hInst,
MAKEINTRESOURCE(IDD_ABOUT),
GetActiveWindow(),
(DLGPROC)AboutDlgProc);
}
bool APIENTRY DllMain(HANDLE hModule, // DLL INIT
DWORD dwReason,
LPVOID lpReserved)
{
hInst = (HINSTANCE)hModule;
return true; // very quick :)
}
static char *err = "Error Loading Symbol";
static int errval;
void *SysLoadLibrary(char *lib)
{
return LoadLibrary(wxString::FromUTF8(lib));
}
void *SysLoadSym(void *lib, char *sym)
{
void *tmp = GetProcAddress((HINSTANCE)lib, sym);
if (tmp == NULL)
errval = 1;
else
errval = 0;
return tmp;
}
char *SysLibError()
{
if (errval) { errval = 0; return err; }
return NULL;
}
void SysCloseLibrary(void *lib)
{
FreeLibrary((HINSTANCE)lib);
}
void SysMessage(const char *fmt, ...)
{
va_list list;
char tmp[512];
va_start(list, fmt);
vsprintf(tmp, fmt, list);
va_end(list);
MessageBox(0, wxString::FromUTF8(tmp), L"ZZOgl-PG Msg", 0);
}

View File

@ -1,28 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef __WIN32_H__
#define __WIN32_H__
#include "resrc1.h"
#include "Win32/resource.h"
BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif /* __WIN32_H__ */

View File

@ -1,488 +0,0 @@
#ifndef __AVIUTIL_H__
#define __AVIUTIL_H__
#define AVIIF_KEYFRAME 0x00000010L // this frame is a key frame.
#include <string>
using namespace std;
#include <memory.h>
#include <mmsystem.h>
#include <vfw.h>
BOOL AVI_Init()
{
/* first let's make sure we are running on 1.1 */
WORD wVer = HIWORD(VideoForWindowsVersion());
if (wVer < 0x010a){
/* oops, we are too old, blow out of here */
//MessageBeep(MB_ICONHAND);
MessageBox(NULL, L"Cant't init AVI File - Video for Windows version is to old", L"Error", MB_OK|MB_ICONSTOP);
return FALSE;
}
AVIFileInit();
return TRUE;
}
BOOL AVI_FileOpenWrite(PAVIFILE * pfile, const char *filename)
{
HRESULT hr = AVIFileOpen(pfile, // returned file pointer
wxString::FromUTF8(filename), // file name
OF_WRITE | OF_CREATE, // mode to open file with
NULL); // use handler determined
// from file extension....
if (hr != AVIERR_OK)
return FALSE;
return TRUE;
}
DWORD getFOURCC(const char* value)
{
if(_stricmp(value, "DIB") == 0)
{
return mmioFOURCC(value[0],value[1],value[2],' ');
}
else if((_stricmp(value, "CVID") == 0)
|| (_stricmp(value, "IV32") == 0)
|| (_stricmp(value, "MSVC") == 0)
|| (_stricmp(value, "IV50") == 0))
{
return mmioFOURCC(value[0],value[1],value[2],value[3]);
}
else
{
return NULL;
}
}
// Fill in the header for the video stream....
// The video stream will run in rate ths of a second....
BOOL AVI_CreateStream(PAVIFILE pfile, PAVISTREAM * ps, int rate, // sample/second
unsigned long buffersize, int rectwidth, int rectheight,
const char* _compressor)
{
AVISTREAMINFO strhdr;
memset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = getFOURCC(_compressor);
//strhdr.fccHandler = 0; // no compression!
//strhdr.fccHandler = mmioFOURCC('D','I','B',' '); // Uncompressed
//strhdr.fccHandler = mmioFOURCC('C','V','I','D'); // Cinpak
//strhdr.fccHandler = mmioFOURCC('I','V','3','2'); // Intel video 3.2
//strhdr.fccHandler = mmioFOURCC('M','S','V','C'); // Microsoft video 1
//strhdr.fccHandler = mmioFOURCC('I','V','5','0'); // Intel video 5.0
//strhdr.dwFlags = AVISTREAMINFO_DISABLED;
//strhdr.dwCaps =
//strhdr.wPriority =
//strhdr.wLanguage =
strhdr.dwScale = 1;
strhdr.dwRate = rate; // rate fps
//strhdr.dwStart =
//strhdr.dwLength =
//strhdr.dwInitialFrames =
strhdr.dwSuggestedBufferSize = buffersize;
strhdr.dwQuality = -1; // use the default
//strhdr.dwSampleSize =
SetRect(&strhdr.rcFrame, 0, 0, // rectangle for stream
(int) rectwidth,
(int) rectheight);
//strhdr.dwEditCount =
//strhdr.dwFormatChangeCount =
//strcpy(strhdr.szName, "Full Frames (Uncompressed)");
// And create the stream;
HRESULT hr = AVIFileCreateStream(pfile, // file pointer
ps, // returned stream pointer
&strhdr); // stream header
if (hr != AVIERR_OK) {
return FALSE;
}
return TRUE;
}
string getFOURCCVAsString(DWORD value)
{
string returnValue = "";
if( value == 0 )
return returnValue;
DWORD ch0 = value & 0x000000FF;
returnValue.push_back((char) ch0);
DWORD ch1 = (value & 0x0000FF00)>>8;
returnValue.push_back((char) ch1);
DWORD ch2 = (value & 0x00FF0000)>>16;
returnValue.push_back((char) ch2);
DWORD ch3 = (value & 0xFF000000)>>24;
returnValue.push_back((char) ch3);
return returnValue;
}
string dumpAVICOMPRESSOPTIONS(AVICOMPRESSOPTIONS opts)
{
char tmp[255];
string returnValue = "Dump of AVICOMPRESSOPTIONS\n";
returnValue += "DWORD fccType = streamtype("; returnValue += getFOURCCVAsString(opts.fccType); returnValue += ")\n";
returnValue += "DWORD fccHandler = "; returnValue += getFOURCCVAsString(opts.fccHandler); returnValue += "\n";
_snprintf(tmp, 255, "DWORD dwKeyFrameEvery = %d\n", opts.dwKeyFrameEvery);
returnValue += tmp;
_snprintf(tmp, 255, "DWORD dwQuality = %d\n", opts.dwQuality);
returnValue += tmp;
_snprintf(tmp, 255, "DWORD dwBytesPerSecond = %d\n", opts.dwBytesPerSecond);
returnValue += tmp;
if((opts.dwFlags & AVICOMPRESSF_DATARATE) == AVICOMPRESSF_DATARATE){strcpy(tmp, "DWORD fccType = AVICOMPRESSF_DATARATE\n");}
else if((opts.dwFlags & AVICOMPRESSF_INTERLEAVE) == AVICOMPRESSF_INTERLEAVE){strcpy(tmp, "DWORD fccType = AVICOMPRESSF_INTERLEAVE\n");}
else if((opts.dwFlags & AVICOMPRESSF_KEYFRAMES) == AVICOMPRESSF_KEYFRAMES){strcpy(tmp, "DWORD fccType = AVICOMPRESSF_KEYFRAMES\n");}
else if((opts.dwFlags & AVICOMPRESSF_VALID) == AVICOMPRESSF_VALID){strcpy(tmp, "DWORD fccType = AVICOMPRESSF_VALID\n");}
else {_snprintf(tmp, 255, "DWORD dwFlags = Unknown(%d)\n", opts.dwFlags);}
returnValue += tmp;
_snprintf(tmp, 255, "LPVOID lpFormat = %d\n", (int)opts.lpFormat);
returnValue += tmp;
_snprintf(tmp, 255, "DWORD cbFormat = %d\n", opts.cbFormat);
returnValue += tmp;
_snprintf(tmp, 255, "LPVOID lpParms = %d\n", (int)opts.lpParms);
returnValue += tmp;
_snprintf(tmp, 255, "DWORD cbParms = %d\n", opts.cbParms);
returnValue += tmp;
_snprintf(tmp, 255, "DWORD dwInterleaveEvery = %d\n", opts.dwInterleaveEvery);
returnValue += tmp;
return returnValue;
}
BOOL AVI_SetOptions(PAVISTREAM * ps, PAVISTREAM * psCompressed, LPBITMAPINFOHEADER lpbi,
const char* _compressor)
{
AVICOMPRESSOPTIONS opts;
AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
memset(&opts, 0, sizeof(opts));
opts.fccType = streamtypeVIDEO;
opts.fccHandler = getFOURCC(_compressor);
//opts.fccHandler = 0;
//opts.fccHandler = mmioFOURCC('D','I','B',' '); // Uncompressed
//opts.fccHandler = mmioFOURCC('C','V','I','D'); // Cinpak
//opts.fccHandler = mmioFOURCC('I','V','3','2'); // Intel video 3.2
//opts.fccHandler = mmioFOURCC('M','S','V','C'); // Microsoft video 1
//opts.fccHandler = mmioFOURCC('I','V','5','0'); // Intel video 5.0
//opts.dwKeyFrameEvery = 5;
//opts.dwQuality
//opts.dwBytesPerSecond
//opts.dwFlags = AVICOMPRESSF_KEYFRAMES;
//opts.lpFormat
//opts.cbFormat
//opts.lpParms
//opts.cbParms
//opts.dwInterleaveEvery
/* display the compression options dialog box if specified compressor is unknown */
if(getFOURCC(_compressor) == NULL)
{
if (!AVISaveOptions(NULL, 0, 1, ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
{
return FALSE;
}
//printf("%s", dumpAVICOMPRESSOPTIONS(opts));
//MessageBox(NULL, dumpAVICOMPRESSOPTIONS(opts).c_str(), "AVICOMPRESSOPTIONS", MB_OK);
}
HRESULT hr = AVIMakeCompressedStream(psCompressed, *ps, &opts, NULL);
if (hr != AVIERR_OK) {
return FALSE;
}
hr = AVIStreamSetFormat(*psCompressed, 0,
lpbi, // stream format
lpbi->biSize // format size
+ lpbi->biClrUsed * sizeof(RGBQUAD)
);
if (hr != AVIERR_OK) {
return FALSE;
}
return TRUE;
}
BOOL AVI_SetText(PAVIFILE pfile, PAVISTREAM psText, char *szText, int width, int height, int TextHeight)
{
// Fill in the stream header for the text stream....
AVISTREAMINFO strhdr;
DWORD dwTextFormat;
// The text stream is in 60ths of a second....
memset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeTEXT;
strhdr.fccHandler = mmioFOURCC('D', 'R', 'A', 'W');
strhdr.dwScale = 1;
strhdr.dwRate = 60;
strhdr.dwSuggestedBufferSize = sizeof(szText);
SetRect(&strhdr.rcFrame, 0, (int) height,
(int) width, (int) height + TextHeight); // #define TEXT_HEIGHT 20
// ....and create the stream.
HRESULT hr = AVIFileCreateStream(pfile, &psText, &strhdr);
if (hr != AVIERR_OK) {
return FALSE;
}
dwTextFormat = sizeof(dwTextFormat);
hr = AVIStreamSetFormat(psText, 0, &dwTextFormat, sizeof(dwTextFormat));
if (hr != AVIERR_OK) {
return FALSE;
}
return TRUE;
}
BOOL AVI_AddFrame(PAVISTREAM psCompressed, int time, LPBITMAPINFOHEADER lpbi)
{
int ImageSize = lpbi->biSizeImage;
if (ImageSize == 0)
{
if (lpbi->biBitCount == 24)
{
ImageSize = lpbi->biWidth * lpbi->biHeight * 3;
}
}
HRESULT hr = AVIStreamWrite(psCompressed, // stream pointer
time, // time of this frame
1, // number to write
(LPBYTE) lpbi + // pointer to data
lpbi->biSize +
lpbi->biClrUsed * sizeof(RGBQUAD),
ImageSize, // lpbi->biSizeImage, // size of this frame
AVIIF_KEYFRAME, // flags....
NULL,
NULL);
if (hr != AVIERR_OK)
{
TCHAR strMsg[255];
_snwprintf(strMsg, 255, L"Error: AVIStreamWrite, error %d",hr);
MessageBox(NULL, strMsg, L"", MB_OK);
return FALSE;
}
return TRUE;
}
BOOL AVI_AddText(PAVISTREAM psText, int time, char *szText)
{
int iLen = (int)strlen(szText);
HRESULT hr = AVIStreamWrite(psText,
time,
1,
szText,
iLen + 1,
AVIIF_KEYFRAME,
NULL,
NULL);
if (hr != AVIERR_OK)
return FALSE;
return TRUE;
}
BOOL AVI_CloseStream(PAVISTREAM ps, PAVISTREAM psCompressed, PAVISTREAM psText)
{
if (ps)
AVIStreamClose(ps);
if (psCompressed)
AVIStreamClose(psCompressed);
if (psText)
AVIStreamClose(psText);
return TRUE;
}
BOOL AVI_CloseFile(PAVIFILE pfile)
{
if (pfile)
AVIFileClose(pfile);
return TRUE;
}
BOOL AVI_Exit()
{
AVIFileExit();
return TRUE;
}
/* Here are the additional functions we need! */
static PAVIFILE pfile = NULL;
static PAVISTREAM ps = NULL;
static PAVISTREAM psCompressed = NULL;
static int avi_count = 0;
// Initialization...
bool START_AVI(const char* file_name)
{
if(! AVI_Init())
{
//printf("Error - AVI_Init()\n");
return false;
}
if(! AVI_FileOpenWrite(&pfile, file_name))
{
//printf("Error - AVI_FileOpenWrite()\n");
return false;
}
return true;
}
bool ADD_FRAME_FROM_DIB_TO_AVI(const char* _compressor, int _frameRate, int width, int height, int bits, void* pdata)
{
if(avi_count == 0)
{
if(! AVI_CreateStream(pfile, &ps, _frameRate,
width*height/bits,
width,
height, _compressor))
{
//printf("Error - AVI_CreateStream()\n");
return false;
}
BITMAPINFOHEADER bi;
memset(&bi, 0, sizeof(bi));
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = height;
bi.biPlanes = 1;
bi.biBitCount = bits;
bi.biCompression = BI_RGB;
bi.biSizeImage = width * height * bits /8;
if(! AVI_SetOptions(&ps, &psCompressed, &bi, _compressor))
{
return false;
}
}
HRESULT hr = AVIStreamWrite(psCompressed, // stream pointer
avi_count, // time of this frame
1, // number to write
pdata,
width*height/8, // lpbi->biSizeImage, // size of this frame
AVIIF_KEYFRAME, // flags....
NULL,
NULL);
if (hr != AVIERR_OK)
{
TCHAR strMsg[255];
_snwprintf(strMsg, 255, L"Error: AVIStreamWrite, error %d",hr);
MessageBox(NULL, strMsg, L"", MB_OK);
return FALSE;
}
avi_count++;
return true;
}
//Now we can add frames
// ie. ADD_FRAME_FROM_DIB_TO_AVI(yourDIB, "CVID", 25);
bool ADD_FRAME_FROM_DIB_TO_AVI(HANDLE dib, const char* _compressor, int _frameRate)
{
LPBITMAPINFOHEADER lpbi;
if(avi_count == 0)
{
lpbi = (LPBITMAPINFOHEADER)GlobalLock(dib);
if(! AVI_CreateStream(pfile, &ps, _frameRate,
(unsigned long) lpbi->biSizeImage,
(int) lpbi->biWidth,
(int) lpbi->biHeight, _compressor))
{
//printf("Error - AVI_CreateStream()\n");
GlobalUnlock(lpbi);
return false;
}
if(! AVI_SetOptions(&ps, &psCompressed, lpbi, _compressor))
{
//printf("Error - AVI_SetOptions()\n");
GlobalUnlock(lpbi);
return false;
}
GlobalUnlock(lpbi);
}
lpbi = (LPBITMAPINFOHEADER)GlobalLock(dib);
if(! AVI_AddFrame(psCompressed, avi_count * 1, lpbi))
{
//printf("Error - AVI_AddFrame()\n");
GlobalUnlock(lpbi);
return false;
}
GlobalUnlock(lpbi);
avi_count++;
return true;
}
// The end...
bool STOP_AVI()
{
if(! AVI_CloseStream(ps, psCompressed, NULL))
{
//printf("Error - AVI_CloseStream()\n");
return false;
}
if(! AVI_CloseFile(pfile))
{
//printf("Error - AVI_CloseFile()\n");
return false;
}
if(! AVI_Exit())
{
//printf("Error - AVI_Exit()\n");
return false;
}
return true;
}
#endif

View File

@ -1,50 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by GSsoftdx.rc
//
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif
#define IDD_CONFIG 101
#define IDD_ABOUT 102
#define IDD_LOGGING 106
#define IDB_ZEROGSLOGO 108
#define IDR_REALPS2_FX 109
#define IDR_SHADERS 110
#define IDC_CHECK1 1000
#define IDC_FULLSCREEN 1000
#define IDC_NAME 1000
#define IDC_LOG 1000
#define IDC_CHECK2 1001
#define IDC_FPSCOUNT 1001
#define IDC_CHECK5 1002
#define IDC_FRAMESKIP 1002
#define IDC_STRETCH 1003
#define IDC_LOGGING 1004
#define IDC_COMBO1 1005
#define IDC_CACHE 1005
#define IDC_CACHESIZE 1006
#define IDC_CHECK3 1007
#define IDC_RECORD 1007
#define IDC_COMBO2 1008
#define IDC_DSPRES 1008
#define IDC_WRES 1008
#define IDC_COMBO3 1009
#define IDC_DDDRV 1009
#define IDC_FRES 1009
#define IDC_COMBO4 1012
#define IDC_CODEC 1012
#define IDC_FILTERS 1014
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 112
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1015
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,88 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by zerogs.rc
//
#define IDC_CONF_DEFAULT 3
#define IDR_DATA1 112
#define IDD_ADV_OPTIONS 113
#define IDD_CONFIG2 114
#define IDC_ABOUTTEXT 1015
#define IDC_CONFIG_AA 1016
#define IDC_CONFIG_INTERLACE 1017
#define IDC_CONFIG_AA3 1018
#define IDC_CONFIG_CAPTUREAVI 1018
#define IDC_CONFIG_CAPTUREAVI2 1019
#define IDC_CONFIG_FULLSCREEN 1019
#define IDC_CONFIG_FULLSCREEN2 1020
#define IDC_CONFIG_FFX 1020
#define IDC_CONFIG_INTERLACE2 1021
#define IDC_CONFIG_DEPTHWRITE 1021
#define IDC_CONFIG_FFX2 1021
#define IDC_CONFIG_BMPSS 1021
#define IDC_CONFIG_AANONE 1022
#define IDC_CONFIG_AA2 1023
#define IDC_RADIO3 1024
#define IDC_CONFIG_AA4 1024
#define IDC_CONFIG_INTERLACE3 1025
#define IDC_CONFIG_BILINEAR 1025
#define IDC_CONF_WIN640 1026
#define IDC_CONF_WIN800 1027
#define IDC_CONF_WIN1024 1028
#define IDC_RADIO5 1029
#define IDC_CONF_WIN1280 1029
#define IDC_CONFIG_CAPTUREAVI3 1030
#define IDC_CONFIG_WIREFRAME 1030
#define IDC_CONFIG_CAPTUREAVI4 1031
#define IDC_CONFIG_CACHEFBP 1031
#define IDC_CONFIG_SHOWFPS 1031
#define IDC_CONFOPT_00100000 1031
#define IDC_CONFOPT_00080000 1032
#define IDC_CONFOPT_00002000 1033
#define IDC_CONFOPT_00001000 1035
#define IDC_CONFOPT_00000200 1037
#define IDC_CONFOPT_00000080 1038
#define IDC_CONFOPT_201 1039
#define IDC_CONFOPT_00000040 1039
#define IDC_CONFOPT_00000020 1040
#define IDC_CONFOPT_00000001 1042
#define IDC_CONFOPT_00000004 1044
#define IDC_CONFOPT_IDS 1045
#define IDC_CONFOPT_00200000 1046
#define IDC_CONFOPT_00004000 1047
#define IDC_BUTTON1 1048
#define IDC_CONFOPT_COMPUTEOR 1048
#define IDC_ADV_BTN 1048
#define IDC_CONFOPT_4001 1049
#define IDC_CONFOPT_00000010 1049
#define IDC_CONFOPT_00008000 1050
#define IDC_CONFOPT_00010000 1052
#define IDC_CONFOPT_00020000 1054
#define IDC_AA_COMBO 1054
#define IDC_CONFOPT_00000002 1055
#define IDC_WIN_SIZE_COMBO 1055
#define IDC_CONFOPT_01000000 1056
#define IDC_CONFOPT_00800000 1057
#define IDC_CONFOPT_00000008 1058
#define IDC_CONFOPT_00000400 1060
#define IDC_CONFOPT_00000800 1061
#define IDC_CONFOPT_NOALPHABLEND30 1062
#define IDC_CONFOPT_00040000 1063
#define IDC_CONFOPT_02000000 1064
#define IDC_CONFOPT_04000000 1065
#define IDC_CONFOPT_00000100 1066
#define IDC_CONFIG_WIDESCREEN 1067
#define IDC_CONFOPT_10000000 1068
#define IDC_CONFOPT_20000000 1069
#define IDC_CONFIG_AA8 2003
#define IDC_CONFIG_AA16 2004
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 116
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1056
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,813 +0,0 @@
#ifndef __wglext_h_
#define __wglext_h_
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2007 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifndef GLAPI
#define GLAPI extern
#endif
/*************************************************************/
/* Header file version number */
/* wglext.h last updated 2009/03/03 */
/* Current version at http://www.opengl.org/registry/ */
#define WGL_WGLEXT_VERSION 12
#ifndef WGL_ARB_buffer_region
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
#endif
#ifndef WGL_ARB_multisample
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
#endif
#ifndef WGL_ARB_extensions_string
#endif
#ifndef WGL_ARB_pixel_format
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
#endif
#ifndef WGL_ARB_make_current_read
#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
#endif
#ifndef WGL_ARB_pbuffer
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
#define WGL_PBUFFER_LARGEST_ARB 0x2033
#define WGL_PBUFFER_WIDTH_ARB 0x2034
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
#define WGL_PBUFFER_LOST_ARB 0x2036
#endif
#ifndef WGL_ARB_render_texture
#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
#define WGL_TEXTURE_FORMAT_ARB 0x2072
#define WGL_TEXTURE_TARGET_ARB 0x2073
#define WGL_MIPMAP_TEXTURE_ARB 0x2074
#define WGL_TEXTURE_RGB_ARB 0x2075
#define WGL_TEXTURE_RGBA_ARB 0x2076
#define WGL_NO_TEXTURE_ARB 0x2077
#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
#define WGL_TEXTURE_1D_ARB 0x2079
#define WGL_TEXTURE_2D_ARB 0x207A
#define WGL_MIPMAP_LEVEL_ARB 0x207B
#define WGL_CUBE_MAP_FACE_ARB 0x207C
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
#define WGL_FRONT_LEFT_ARB 0x2083
#define WGL_FRONT_RIGHT_ARB 0x2084
#define WGL_BACK_LEFT_ARB 0x2085
#define WGL_BACK_RIGHT_ARB 0x2086
#define WGL_AUX0_ARB 0x2087
#define WGL_AUX1_ARB 0x2088
#define WGL_AUX2_ARB 0x2089
#define WGL_AUX3_ARB 0x208A
#define WGL_AUX4_ARB 0x208B
#define WGL_AUX5_ARB 0x208C
#define WGL_AUX6_ARB 0x208D
#define WGL_AUX7_ARB 0x208E
#define WGL_AUX8_ARB 0x208F
#define WGL_AUX9_ARB 0x2090
#endif
#ifndef WGL_ARB_pixel_format_float
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif
#ifndef WGL_ARB_create_context
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define ERROR_INVALID_VERSION_ARB 0x2095
#endif
#ifndef WGL_EXT_make_current_read
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
#endif
#ifndef WGL_EXT_pixel_format
#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
#define WGL_DRAW_TO_WINDOW_EXT 0x2001
#define WGL_DRAW_TO_BITMAP_EXT 0x2002
#define WGL_ACCELERATION_EXT 0x2003
#define WGL_NEED_PALETTE_EXT 0x2004
#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
#define WGL_SWAP_METHOD_EXT 0x2007
#define WGL_NUMBER_OVERLAYS_EXT 0x2008
#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
#define WGL_TRANSPARENT_EXT 0x200A
#define WGL_TRANSPARENT_VALUE_EXT 0x200B
#define WGL_SHARE_DEPTH_EXT 0x200C
#define WGL_SHARE_STENCIL_EXT 0x200D
#define WGL_SHARE_ACCUM_EXT 0x200E
#define WGL_SUPPORT_GDI_EXT 0x200F
#define WGL_SUPPORT_OPENGL_EXT 0x2010
#define WGL_DOUBLE_BUFFER_EXT 0x2011
#define WGL_STEREO_EXT 0x2012
#define WGL_PIXEL_TYPE_EXT 0x2013
#define WGL_COLOR_BITS_EXT 0x2014
#define WGL_RED_BITS_EXT 0x2015
#define WGL_RED_SHIFT_EXT 0x2016
#define WGL_GREEN_BITS_EXT 0x2017
#define WGL_GREEN_SHIFT_EXT 0x2018
#define WGL_BLUE_BITS_EXT 0x2019
#define WGL_BLUE_SHIFT_EXT 0x201A
#define WGL_ALPHA_BITS_EXT 0x201B
#define WGL_ALPHA_SHIFT_EXT 0x201C
#define WGL_ACCUM_BITS_EXT 0x201D
#define WGL_ACCUM_RED_BITS_EXT 0x201E
#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
#define WGL_DEPTH_BITS_EXT 0x2022
#define WGL_STENCIL_BITS_EXT 0x2023
#define WGL_AUX_BUFFERS_EXT 0x2024
#define WGL_NO_ACCELERATION_EXT 0x2025
#define WGL_GENERIC_ACCELERATION_EXT 0x2026
#define WGL_FULL_ACCELERATION_EXT 0x2027
#define WGL_SWAP_EXCHANGE_EXT 0x2028
#define WGL_SWAP_COPY_EXT 0x2029
#define WGL_SWAP_UNDEFINED_EXT 0x202A
#define WGL_TYPE_RGBA_EXT 0x202B
#define WGL_TYPE_COLORINDEX_EXT 0x202C
#endif
#ifndef WGL_EXT_pbuffer
#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
#define WGL_PBUFFER_LARGEST_EXT 0x2033
#define WGL_PBUFFER_WIDTH_EXT 0x2034
#define WGL_PBUFFER_HEIGHT_EXT 0x2035
#endif
#ifndef WGL_EXT_depth_float
#define WGL_DEPTH_FLOAT_EXT 0x2040
#endif
#ifndef WGL_3DFX_multisample
#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
#define WGL_SAMPLES_3DFX 0x2061
#endif
#ifndef WGL_EXT_multisample
#define WGL_SAMPLE_BUFFERS_EXT 0x2041
#define WGL_SAMPLES_EXT 0x2042
#endif
#ifndef WGL_I3D_digital_video_control
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
#endif
#ifndef WGL_I3D_gamma
#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
#endif
#ifndef WGL_I3D_genlock
#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
#endif
#ifndef WGL_I3D_image_buffer
#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
#endif
#ifndef WGL_I3D_swap_frame_lock
#endif
#ifndef WGL_NV_render_depth_texture
#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
#define WGL_DEPTH_COMPONENT_NV 0x20A7
#endif
#ifndef WGL_NV_render_texture_rectangle
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
#endif
#ifndef WGL_ATI_pixel_format_float
#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
#endif
#ifndef WGL_NV_float_buffer
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
#endif
#ifndef WGL_3DL_stereo_control
#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
#endif
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
#endif
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
#endif
#ifndef WGL_NV_present_video
#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
#endif
#ifndef WGL_NV_video_out
#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
#define WGL_VIDEO_OUT_FRAME 0x20C8
#define WGL_VIDEO_OUT_FIELD_1 0x20C9
#define WGL_VIDEO_OUT_FIELD_2 0x20CA
#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
#endif
#ifndef WGL_NV_swap_group
#endif
#ifndef WGL_NV_gpu_affinity
#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
#endif
#ifndef WGL_AMD_gpu_association
#define WGL_GPU_VENDOR_AMD 0x1F00
#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
#define WGL_GPU_RAM_AMD 0x21A3
#define WGL_GPU_CLOCK_AMD 0x21A4
#define WGL_GPU_NUM_PIPES_AMD 0x21A5
#define WGL_GPU_NUM_SIMD_AMD 0x21A6
#define WGL_GPU_NUM_RB_AMD 0x21A7
#define WGL_GPU_NUM_SPI_AMD 0x21A8
#endif
/*************************************************************/
#ifndef WGL_ARB_pbuffer
DECLARE_HANDLE(HPBUFFERARB);
#endif
#ifndef WGL_EXT_pbuffer
DECLARE_HANDLE(HPBUFFEREXT);
#endif
#ifndef WGL_NV_present_video
DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
#endif
#ifndef WGL_NV_video_out
DECLARE_HANDLE(HPVIDEODEV);
#endif
#ifndef WGL_NV_gpu_affinity
DECLARE_HANDLE(HPGPUNV);
DECLARE_HANDLE(HGPUNV);
typedef struct _GPU_DEVICE {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD Flags;
RECT rcVirtualScreen;
} GPU_DEVICE, *PGPU_DEVICE;
#endif
#ifndef WGL_ARB_buffer_region
#define WGL_ARB_buffer_region 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT);
extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE);
extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int);
extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#endif
#ifndef WGL_ARB_multisample
#define WGL_ARB_multisample 1
#endif
#ifndef WGL_ARB_extensions_string
#define WGL_ARB_extensions_string 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern const char * WINAPI wglGetExtensionsStringARB (HDC);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
#endif
#ifndef WGL_ARB_pixel_format
#define WGL_ARB_pixel_format 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *);
extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *);
extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#ifndef WGL_ARB_make_current_read
#define WGL_ARB_make_current_read 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC);
extern HDC WINAPI wglGetCurrentReadDCARB (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
#endif
#ifndef WGL_ARB_pbuffer
#define WGL_ARB_pbuffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *);
extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB);
extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC);
extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB);
extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#endif
#ifndef WGL_ARB_render_texture
#define WGL_ARB_render_texture 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int);
extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int);
extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
#endif
#ifndef WGL_ARB_pixel_format_float
#define WGL_ARB_pixel_format_float 1
#endif
#ifndef WGL_ARB_create_context
#define WGL_ARB_create_context 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HGLRC WINAPI wglCreateContextAttribsARB (HDC, HGLRC, const int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
#endif
#ifndef WGL_EXT_display_color_table
#define WGL_EXT_display_color_table 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort);
extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint);
extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort);
extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
#endif
#ifndef WGL_EXT_extensions_string
#define WGL_EXT_extensions_string 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern const char * WINAPI wglGetExtensionsStringEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
#endif
#ifndef WGL_EXT_make_current_read
#define WGL_EXT_make_current_read 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC);
extern HDC WINAPI wglGetCurrentReadDCEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
#endif
#ifndef WGL_EXT_pbuffer
#define WGL_EXT_pbuffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *);
extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT);
extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC);
extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT);
extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#endif
#ifndef WGL_EXT_pixel_format
#define WGL_EXT_pixel_format 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *);
extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *);
extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#ifndef WGL_EXT_swap_control
#define WGL_EXT_swap_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglSwapIntervalEXT (int);
extern int WINAPI wglGetSwapIntervalEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
#endif
#ifndef WGL_EXT_depth_float
#define WGL_EXT_depth_float 1
#endif
#ifndef WGL_NV_vertex_array_range
#define WGL_NV_vertex_array_range 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat);
extern void WINAPI wglFreeMemoryNV (void *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
#endif
#ifndef WGL_3DFX_multisample
#define WGL_3DFX_multisample 1
#endif
#ifndef WGL_EXT_multisample
#define WGL_EXT_multisample 1
#endif
#ifndef WGL_OML_sync_control
#define WGL_OML_sync_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *);
extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *);
extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64);
extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64);
extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *);
extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#endif
#ifndef WGL_I3D_digital_video_control
#define WGL_I3D_digital_video_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *);
extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
#endif
#ifndef WGL_I3D_gamma
#define WGL_I3D_gamma 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *);
extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *);
extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *);
extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#endif
#ifndef WGL_I3D_genlock
#define WGL_I3D_genlock 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnableGenlockI3D (HDC);
extern BOOL WINAPI wglDisableGenlockI3D (HDC);
extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *);
extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT);
extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *);
extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT);
extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *);
extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT);
extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *);
extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT);
extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *);
extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#endif
#ifndef WGL_I3D_image_buffer
#define WGL_I3D_image_buffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT);
extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID);
extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT);
extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
#endif
#ifndef WGL_I3D_swap_frame_lock
#define WGL_I3D_swap_frame_lock 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnableFrameLockI3D (void);
extern BOOL WINAPI wglDisableFrameLockI3D (void);
extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *);
extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
#endif
#ifndef WGL_I3D_swap_frame_usage
#define WGL_I3D_swap_frame_usage 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetFrameUsageI3D (float *);
extern BOOL WINAPI wglBeginFrameTrackingI3D (void);
extern BOOL WINAPI wglEndFrameTrackingI3D (void);
extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#endif
#ifndef WGL_ATI_pixel_format_float
#define WGL_ATI_pixel_format_float 1
#endif
#ifndef WGL_NV_float_buffer
#define WGL_NV_float_buffer 1
#endif
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_EXT_pixel_format_packed_float 1
#endif
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_EXT_framebuffer_sRGB 1
#endif
#ifndef WGL_NV_present_video
#define WGL_NV_present_video 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern int WINAPI wglEnumerateVideoDevicesNV (HDC, HVIDEOOUTPUTDEVICENV *);
extern BOOL WINAPI wglBindVideoDeviceNV (HDC, unsigned int, HVIDEOOUTPUTDEVICENV, const int *);
extern BOOL WINAPI wglQueryCurrentContextNV (int, int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
#endif
#ifndef WGL_NV_video_out
#define WGL_NV_video_out 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetVideoDeviceNV (HDC, int, HPVIDEODEV *);
extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV);
extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV, HPBUFFERARB, int);
extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB, int);
extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB, int, unsigned long *, BOOL);
extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV, unsigned long *, unsigned long *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#ifndef WGL_NV_swap_group
#define WGL_NV_swap_group 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglJoinSwapGroupNV (HDC, GLuint);
extern BOOL WINAPI wglBindSwapBarrierNV (GLuint, GLuint);
extern BOOL WINAPI wglQuerySwapGroupNV (HDC, GLuint *, GLuint *);
extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC, GLuint *, GLuint *);
extern BOOL WINAPI wglQueryFrameCountNV (HDC, GLuint *);
extern BOOL WINAPI wglResetFrameCountNV (HDC);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
#endif
#ifndef WGL_NV_gpu_affinity
#define WGL_NV_gpu_affinity 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnumGpusNV (UINT, HGPUNV *);
extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV, UINT, PGPU_DEVICE);
extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *);
extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC, UINT, HGPUNV *);
extern BOOL WINAPI wglDeleteDCNV (HDC);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
#endif
#ifndef WGL_AMD_gpu_association
#define WGL_AMD_gpu_association 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern UINT WINAPI wglGetGPUIDsAMD (UINT, UINT *);
extern INT WINAPI wglGetGPUInfoAMD (UINT, int, GLenum, UINT, void *);
extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC);
extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT);
extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT, HGLRC, const int *);
extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC);
extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC);
extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 900 KiB

View File

@ -1,38 +0,0 @@
; Declares the module parameters for the DLL.
;LIBRARY "ZeroGS"
;DESCRIPTION 'ZeroGS dll'
EXPORTS
; Explicit exports can go here
PS2EgetLibType @2
PS2EgetLibName @3
PS2EgetLibVersion2 @4
GSinit @5
GSshutdown @6
GSopen @7
GSclose @8
GSgifTransfer @12
GSgifTransfer1 @13
GSgifTransfer2 @14
GSgifTransfer3 @15
GSreadFIFO @16
GSvsync @17
GSmakeSnapshot @18
GSkeyEvent @19
GSfreeze @20
GSconfigure @21
GStest @22
GSabout @23
GSreadFIFO2 @28
GSirqCallback @29
GSsetBaseMem @30
GSwriteCSR @31
GSchangeSaveState @32
GSreset @33
GSgifSoftReset @34
GSsetFrameSkip @35
GSsetGameCRC @36
GSgetLastTag @37
GSsetupRecording @38
GSsetSettingsDir @39

View File

@ -1,328 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resrc1.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "resource.h"
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_ZEROGSLOGO BITMAP "zerogs.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
//
IDR_SHADERS RCDATA "ps2hw.dat"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CONFIG DIALOGEX 0, 0, 530, 290
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "ZZ OpenGL PG Configuration"
FONT 8, "Tahoma", 0, 0, 0x1
BEGIN
CONTROL "Logging (For Debugging)",1000,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,6,102,10
CONTROL "Interlace Enable (toggle with F5). There are 2 modes + interlace off",IDC_CONFIG_INTERLACE,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,5,64,137,18
CONTROL "Bilinear Filtering (Shift+F5). Best quality is on, turn off for speed.",IDC_CONFIG_BILINEAR,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,5,81,137,18
CONTROL "None",IDC_CONFIG_AANONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,21,38,34,11
CONTROL "2X",IDC_CONFIG_AA2,"Button",BS_AUTORADIOBUTTON,21,48,26,11
CONTROL "4X",IDC_CONFIG_AA4,"Button",BS_AUTORADIOBUTTON,63,38,28,11
CONTROL "8X",IDC_CONFIG_AA8,"Button",BS_AUTORADIOBUTTON,63,48,26,11
CONTROL "16X",IDC_CONFIG_AA16,"Button",BS_AUTORADIOBUTTON,100,42,28,11
CONTROL "Wireframe rendering (F7)",IDC_CONFIG_WIREFRAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,183,96,10
CONTROL "Capture Avi (zerogs.avi) (F12)",IDC_CONFIG_CAPTUREAVI,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,194,109,10
CONTROL "Save Snapshots as BMP(default is JPG)",IDC_CONFIG_BMPSS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,205,141,10
CONTROL "Fullscreen (Alt+Enter),to get out press Alt+Enter again",IDC_CONFIG_FULLSCREEN,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,5,150,135,18
CONTROL "Wide Screen",IDC_CONFIG_WIDESCREEN,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,5,167,109,10
CONTROL "640 x 480",IDC_CONF_WIN640,"Button",BS_AUTORADIOBUTTON | WS_GROUP,17,123,59,8
CONTROL "800 x 600",IDC_CONF_WIN800,"Button",BS_AUTORADIOBUTTON,17,135,59,8
CONTROL "1024 x 768",IDC_CONF_WIN1024,"Button",BS_AUTORADIOBUTTON,82,123,59,8
CONTROL "1280 x 960",IDC_CONF_WIN1280,"Button",BS_AUTORADIOBUTTON,82,135,53,8
GROUPBOX "Anti-aliasing for sharper graphics (F6)",IDC_STATIC,5,21,137,41
GROUPBOX "Default Window Size (no speed impact)",IDC_STATIC,6,111,137,39
LTEXT "Show Frames Per Second (Shift+F7)",IDC_STATIC,15,219,118,20
LTEXT "shortcuts: F6 - next, Shift+F6 - prev",IDC_STATIC,13,28,123,11
GROUPBOX "Advanced Options",IDC_STATIC,150,0,375,272
LTEXT "Each option is presented with a unique ID in hex.",IDC_STATIC,155,10,365,8
LTEXT "Note, setting options here means that they will be ADDED to whatever options are set automatically.",IDC_STATIC,155,20,365,8
CONTROL "Enable Multiple RTS - 00100000",IDC_CONFOPT_00100000,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,155,30,365,8
CONTROL "Disable alpha testing - 00080000",IDC_CONFOPT_00080000,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,155,40,365,8
CONTROL "Disable stencil buffer - 00002000, Usually safe to do for simple scenes. Harvest Moon",IDC_CONFOPT_00002000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,50,365,8
CONTROL "No color clamping - 00000040, Speeds games up but might be too bright or too dim",IDC_CONFOPT_00000040,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,60,365,8
CONTROL "Disable depth updates - 00000200",IDC_CONFOPT_00000200,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,155,70,365,8
CONTROL "No target CLUT - 00001000, Use on RE4, or foggy scenes.",IDC_CONFOPT_00001000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,80,365,8
CONTROL "Alpha Fail hack - 00000100, Remove vertical stripes, coloring artefacts. (Sonic Unleashed, Shadow the Hedgehog, Ghost in the Shell)",IDC_CONFOPT_00000100,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,90,365,16
CONTROL "Exact color testing - 00000020, Fixes overbright or shadow/black artifacts (crash n burn)",IDC_CONFOPT_00000020,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,110,365,8
CONTROL "Tex Target checking - 00000001, Lego racers",IDC_CONFOPT_00000001,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,120,365,8
CONTROL "Interlace 2X - 00000004, Fixes 2x bigger screen (Gradius 3)",IDC_CONFOPT_00000004,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,130,365,8
CONTROL "Resolve Hack #2 - 00000800, Shadow Hearts, Urbz, (Destroys FFX)",IDC_CONFOPT_00000800,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,140,365,8
CONTROL "Fast Update - 00040000, Speeds some games - (Okami, Sonic Unleashed)",35527,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,150,365,8
CONTROL "Partial Depth - 04000000, Tries to save the depth target as much as possible (mgs3)",IDC_CONFOPT_04000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,160,365,8
CONTROL "No target resolves - 00000010, Stops target resolving(try this first for very slow games). (Dark Cloud 1)",IDC_CONFOPT_00000010,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,170,365,8
CONTROL "No logarithmic-Z - 20000000, Decreases number of Z artefacts",IDC_CONFOPT_20000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,180,365,8
CONTROL "No depth resolve - 00008000, Might give z buffer artifacts",IDC_CONFOPT_00008000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,190,365,8
CONTROL "Auto Reset Targs - 00000002, Use when game is slow and toggling AA fixes it (SH, samurai warriors)",IDC_CONFOPT_00000002,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,200,365,8
CONTROL "Full 16 bit resolution - 00010000, Use when half the screen is missing, etc",IDC_CONFOPT_00010000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,210,365,8
CONTROL "Resolve Hack #1 - 00000400, Speeds some games (Kingdom Hearts)",IDC_CONFOPT_00000400,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,220,365,8
CONTROL "Partial Targets - 02000000, Reduces artifacts and speeds up some games (mgs3)",IDC_CONFOPT_02000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,230,365,8
CONTROL "Resolve Hack #3 - 00020000, Neopets",IDC_CONFOPT_00020000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,240,365,8
CONTROL "Specular Highlights - 01000000, Makes xenosaga and Okage graphics faster by removing highlights.",IDC_CONFOPT_01000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,250,365,8
CONTROL "Gust fix - 10000000, Makes gust games cleaner and faster.",IDC_CONFOPT_10000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,260,365,8
DEFPUSHBUTTON "OK",IDOK,5,275,50,12
PUSHBUTTON "Cancel",IDCANCEL,92,275,50,12
PUSHBUTTON "Use Defaults (recommended)",IDC_CONF_DEFAULT,171,275,151,12
EDITTEXT IDC_CONFOPT_IDS,451,275,48,12,ES_AUTOHSCROLL | ES_READONLY
PUSHBUTTON "Compute OR of IDS",IDC_CONFOPT_COMPUTEOR,373,275,73,12
END
IDD_ABOUT DIALOGEX 0, 0, 182, 220
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "GSabout"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,65,199,50,14
LTEXT "ZZogl\n\nauthor: Zeydlitz(@gmail.com)\n\n\nthanks to Gabest for SSE optimizations",IDC_STATIC,7,7,160,47
LTEXT "Static",IDC_ABOUTTEXT,7,65,152,124
END
IDD_LOGGING DIALOG 0, 0, 152, 55
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,40,35,50,14
PUSHBUTTON "Cancel",IDCANCEL,95,35,50,14
CONTROL "Log",IDC_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,15,28,10
END
IDD_ADV_OPTIONS DIALOGEX 0, 0, 391, 308
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Advanced Options"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,279,287,50,14
PUSHBUTTON "Cancel",IDCANCEL,333,287,50,14
GROUPBOX "Advanced Options",IDC_STATIC,7,6,376,276
LTEXT "Each option is presented with a unique ID in hex.",IDC_STATIC,14,15,365,8
LTEXT "Note, setting options here means that they will be ADDED to whatever options are set automatically.",IDC_STATIC,14,25,365,8
CONTROL "Enable Multiple RTS - 00100000",IDC_CONFOPT_00100000,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,36,365,8
CONTROL "Disable alpha testing - 00080000",IDC_CONFOPT_00080000,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,46,365,8
CONTROL "Disable stencil buffer - 00002000, Usually safe to do for simple scenes. Harvest Moon",IDC_CONFOPT_00002000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,56,365,8
CONTROL "No color clamping - 00000040, Speeds games up but might be too bright or too dim",IDC_CONFOPT_00000040,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,66,365,8
CONTROL "Disable depth updates - 00000200",IDC_CONFOPT_00000200,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,76,365,8
CONTROL "No target CLUT - 00001000, Use on RE4, or foggy scenes.",IDC_CONFOPT_00001000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,86,365,8
CONTROL "Alpha Fail hack - 00000100, Remove vertical stripes, coloring artefacts. (Sonic Unleashed, Shadow the Hedgehog, Ghost in the Shell)",IDC_CONFOPT_00000100,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,96,365,16
CONTROL "Exact color testing - 00000020, Fixes overbright or shadow/black artifacts (crash n burn)",IDC_CONFOPT_00000020,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,116,365,8
CONTROL "Tex Target checking - 00000001, Lego racers",IDC_CONFOPT_00000001,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,126,365,8
CONTROL "Interlace 2X - 00000004, Fixes 2x bigger screen (Gradius 3)",IDC_CONFOPT_00000004,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,136,365,8
CONTROL "Resolve Hack #2 - 00000800, Shadow Hearts, Urbz, (Destroys FFX)",IDC_CONFOPT_00000800,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,146,365,8
CONTROL "Fast Update - 00040000, Speeds some games - (Okami, Sonic Unleashed)",35527,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,156,365,8
CONTROL "Partial Depth - 04000000, Tries to save the depth target as much as possible (mgs3)",IDC_CONFOPT_04000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,166,365,8
CONTROL "No target resolves - 00000010, Stops target resolving(try this first for very slow games). (Dark Cloud 1)",IDC_CONFOPT_00000010,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,176,365,8
CONTROL "No logarithmic-Z - 20000000, Decreases number of Z artefacts",IDC_CONFOPT_20000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,186,365,8
CONTROL "No depth resolve - 00008000, Might give z buffer artifacts",IDC_CONFOPT_00008000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,196,365,8
CONTROL "Auto Reset Targs - 00000002, Use when game is slow and toggling AA fixes it (SH, samurai warriors)",IDC_CONFOPT_00000002,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,206,365,8
CONTROL "Full 16 bit resolution - 00010000, Use when half the screen is missing, etc",IDC_CONFOPT_00010000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,216,365,8
CONTROL "Resolve Hack #1 - 00000400, Speeds some games (Kingdom Hearts)",IDC_CONFOPT_00000400,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,226,365,8
CONTROL "Partial Targets - 02000000, Reduces artifacts and speeds up some games (mgs3)",IDC_CONFOPT_02000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,236,365,8
CONTROL "Resolve Hack #3 - 00020000, Neopets",IDC_CONFOPT_00020000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,246,365,8
CONTROL "Specular Highlights - 01000000, Makes xenosaga and Okage graphics faster by removing highlights.",IDC_CONFOPT_01000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,256,365,8
CONTROL "Gust fix - 10000000, Makes gust games cleaner and faster.",IDC_CONFOPT_10000000,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,266,365,8
END
IDD_CONFIG2 DIALOGEX 0, 0, 159, 160
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "ZZOgl Options"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,37,138,50,14
PUSHBUTTON "Cancel",IDCANCEL,91,138,50,14
CONTROL "Logging (For Debugging)",1000,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,102,10
CONTROL "Interlace Enable (toggle with F5). There are 2 modes + interlace off",IDC_CONFIG_INTERLACE,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,32,137,18
CONTROL "Bilinear Filtering (Shift+F5). Best quality is on, turn off for speed.",IDC_CONFIG_BILINEAR,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,50,137,18
CONTROL "Capture Avi (zerogs.avi) (F12)",IDC_CONFIG_CAPTUREAVI,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,82,109,10
CONTROL "Save Snapshots as BMP(default is JPG)",IDC_CONFIG_BMPSS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,93,141,10
CONTROL "Wide Screen",IDC_CONFIG_WIDESCREEN,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,69,109,10
LTEXT "Anti-aliasing",IDC_STATIC,7,20,43,13
PUSHBUTTON "Advanced...",IDC_ADV_BTN,7,118,134,14
COMBOBOX IDC_AA_COMBO,53,18,48,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_WIN_SIZE_COMBO,78,104,62,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
LTEXT "Default Window Size",IDC_STATIC,7,106,68,8
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 420
TOPMARGIN, 7
END
IDD_ABOUT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 175
TOPMARGIN, 7
BOTTOMMARGIN, 213
END
IDD_LOGGING, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 145
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
IDD_ADV_OPTIONS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 389
TOPMARGIN, 6
BOTTOMMARGIN, 301
END
IDD_CONFIG2, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 152
TOPMARGIN, 7
BOTTOMMARGIN, 152
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resrc1.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""resource.h""\r\n"
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -1,271 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|Win32">
<Configuration>Devel</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>ZZOgl</ProjectName>
<ProjectGuid>{2D4E85B2-F47F-4D65-B091-701E5C031DAC}</ProjectGuid>
<RootNamespace>ZZogl</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="..\..\..\..\common\vsprops\plugin_svnroot.props" />
<Import Project="..\..\..\..\common\vsprops\BaseProperties.props" />
<Import Project="..\..\..\..\common\vsprops\3rdpartyDeps.props" />
<Import Project="..\..\..\..\common\vsprops\CodeGen_Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="..\..\..\..\common\vsprops\plugin_svnroot.props" />
<Import Project="..\..\..\..\common\vsprops\BaseProperties.props" />
<Import Project="..\..\..\..\common\vsprops\3rdpartyDeps.props" />
<Import Project="..\..\..\..\common\vsprops\CodeGen_Debug.props" />
<Import Project="..\..\..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="PropertySheets">
<Import Project="..\..\..\..\common\vsprops\plugin_svnroot.props" />
<Import Project="..\..\..\..\common\vsprops\BaseProperties.props" />
<Import Project="..\..\..\..\common\vsprops\3rdpartyDeps.props" />
<Import Project="..\..\..\..\common\vsprops\CodeGen_Devel.props" />
<Import Project="..\..\..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">$(ProjectName)-dev</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)bin\$(PcsxSubsection)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>$(CG_INC_PATH);$(ProjectRootDir)\;$(ProjectRootDir)\ZeroGSShaders\;$(ProjectRootDir)\Win32;$(SvnRootDir)\3rdparty\libjpeg;$(SvnRootDir)\3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;_USRDLL;__i386__;ZEROGS_DEVBUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>winmm.lib;Vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;Comctl32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>$(CG_LIB_PATH);..\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>.\zerogs.def</ModuleDefinitionFile>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>$(CG_INC_PATH);$(ProjectRootDir)\;$(ProjectRootDir)\ZeroGSShaders\;$(ProjectRootDir)\Win32;$(SvnRootDir)\3rdparty\libjpeg;$(SvnRootDir)\3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_USRDLL;ZEROGS_DEVBUILD;_DEBUG;__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;Vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;Comctl32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>$(CG_LIB_PATH);..\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<ModuleDefinitionFile>.\zerogs.def</ModuleDefinitionFile>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>$(CG_INC_PATH);$(ProjectRootDir)\;$(ProjectRootDir)\ZeroGSShaders\;$(ProjectRootDir)\Win32;$(SvnRootDir)\3rdparty\libjpeg;$(SvnRootDir)\3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;_USRDLL;__i386__;ZEROGS_SSE2;RELEASE_TO_PUBLIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>winmm.lib;Vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;Comctl32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>$(CG_LIB_PATH);..\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>.\zerogs.def</ModuleDefinitionFile>
<ImportLibrary>
</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\GSDump.cpp" />
<ClCompile Include="..\ZZClut.cpp" />
<ClCompile Include="..\ZZDepthTargets.cpp" />
<ClCompile Include="..\ZZMemoryTargets.cpp" />
<ClCompile Include="..\ZZoglDrawing.cpp" />
<ClCompile Include="..\ZZoglFlushHack.cpp" />
<ClCompile Include="..\ZZoglMem.cpp" />
<ClCompile Include="..\ZZoglShadersGLSL.cpp" />
<ClCompile Include="..\ZZoglShadersGLSL4.cpp" />
<ClCompile Include="..\ZZRenderTargets.cpp" />
<ClCompile Include="Conf.cpp" />
<ClCompile Include="..\GifTransfer.cpp" />
<ClCompile Include="..\glprocs.c" />
<ClCompile Include="..\GLWin32.cpp" />
<ClCompile Include="..\GLWinX11.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\GSmain.cpp" />
<ClCompile Include="..\HostMemory.cpp" />
<ClCompile Include="..\Mem.cpp" />
<ClCompile Include="..\Mem_Swizzle.cpp" />
<ClCompile Include="..\Mem_Tables.cpp" />
<ClCompile Include="..\rasterfont.cpp" />
<ClCompile Include="..\Regs.cpp" />
<ClCompile Include="..\Profile.cpp" />
<ClCompile Include="..\targets.cpp" />
<ClCompile Include="Win32.cpp" />
<ClCompile Include="..\x86.cpp" />
<ClCompile Include="..\zerogs.cpp" />
<ClCompile Include="..\zpipe.cpp" />
<ClCompile Include="..\ZZHacks.cpp" />
<ClCompile Include="..\ZZKeyboard.cpp" />
<ClCompile Include="..\ZZLog.cpp" />
<ClCompile Include="..\ZZoglCreate.cpp" />
<ClCompile Include="..\ZZoglCRTC.cpp" />
<ClCompile Include="..\ZZoglFlush.cpp" />
<ClCompile Include="..\ZZoglSave.cpp" />
<ClCompile Include="..\ZZoglShaders.cpp" />
<ClCompile Include="..\ZZoglShoots.cpp" />
<ClCompile Include="..\ZZoglVB.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="GSsoftdx.def" />
<CustomBuild Include="..\x86-32.asm">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ml /nologo /c /Fo"$(IntDir)%(Filename).obj" "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">ml /nologo /c /Fo"$(IntDir)%(Filename).obj" "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ml /nologo /c /Fo"$(IntDir)%(Filename).obj" "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
</CustomBuild>
<None Include="Pcsx2.ico" />
<None Include="zerogs.bmp" />
<None Include="..\..\ReadMe.txt" />
<None Include="..\ps2hw.dat" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\GSDump.h" />
<ClInclude Include="..\ZZoglFlush.h" />
<ClInclude Include="..\ZZoglMem.h" />
<ClInclude Include="aviUtil.h" />
<ClInclude Include="..\GifTransfer.h" />
<ClInclude Include="..\CRC.h" />
<ClInclude Include="..\GS.h" />
<ClInclude Include="..\Util.h" />
<ClInclude Include="..\Mem.h" />
<ClInclude Include="..\Mem_Swizzle.h" />
<ClInclude Include="..\Mem_Transmit.h" />
<ClInclude Include="..\PS2Edefs.h" />
<ClInclude Include="..\PS2Etypes.h" />
<ClInclude Include="..\rasterfont.h" />
<ClInclude Include="..\Regs.h" />
<ClInclude Include="..\Profile.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="resrc1.h" />
<ClInclude Include="..\targets.h" />
<ClInclude Include="Win32.h" />
<ClInclude Include="..\x86.h" />
<ClInclude Include="..\ZZGl.h" />
<ClInclude Include="..\ZZHacks.h" />
<ClInclude Include="..\ZZLog.h" />
<ClInclude Include="..\zerogs.h" />
<ClInclude Include="..\zerogsmath.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="zerogs.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\3rdparty\libjpeg\libjpeg.vcxproj">
<Project>{bc236261-77e8-4567-8d09-45cd02965eb6}</Project>
<Private>true</Private>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
<ProjectReference Include="..\..\..\..\3rdparty\pthreads4w\build\pthreads4w.vcxproj">
<Project>{0fae817d-9a32-4830-857e-81da57246e16}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\..\..\3rdparty\wxwidgets3.0\build\msw\wx30_base.vcxproj">
<Project>{3fcc50c2-81e9-5db2-b8d8-2129427568b1}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\..\..\3rdparty\wxwidgets3.0\build\msw\wx30_core.vcxproj">
<Project>{6744dad8-9c70-574a-bff2-9f8dddb24a75}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\..\..\3rdparty\zlib\zlib.vcxproj">
<Project>{2f6c0388-20cb-4242-9f6c-a6ebb6a83f47}</Project>
<Private>true</Private>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
<ProjectReference Include="..\..\..\..\common\build\Utilities\utilities.vcxproj">
<Project>{4639972e-424e-4e13-8b07-ca403c481346}</Project>
<Private>true</Private>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,241 +0,0 @@
<?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>{db5b3cda-2af3-451d-95a6-1ecd6410acb3}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{609d2fdc-53bd-42af-90ff-793a1107f003}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{a2158e1c-a894-441e-ab9e-e2361e55f009}</UniqueIdentifier>
<Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
</Filter>
<Filter Include="Docs">
<UniqueIdentifier>{4755b02f-755a-491e-b851-acab63a59d75}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Conf.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\GifTransfer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\glprocs.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\GLWin32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\GLWinX11.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\GSmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Mem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Mem_Swizzle.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Mem_Tables.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\rasterfont.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Regs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\targets.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\x86.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\zerogs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\zpipe.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglCreate.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglCRTC.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglFlush.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglSave.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglShaders.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglShoots.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglVB.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\HostMemory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Profile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZHacks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZKeyboard.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZLog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZClut.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglDrawing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglFlushHack.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\GSDump.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZDepthTargets.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZMemoryTargets.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZRenderTargets.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglMem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglShadersGLSL.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ZZoglShadersGLSL4.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GSsoftdx.def">
<Filter>Source Files</Filter>
</None>
<None Include="Pcsx2.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="zerogs.bmp">
<Filter>Resource Files</Filter>
</None>
<None Include="..\..\ReadMe.txt">
<Filter>Docs</Filter>
</None>
<None Include="..\ps2hw.dat" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="aviUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\GifTransfer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\GS.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Mem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Mem_Swizzle.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Mem_Transmit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\PS2Edefs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\PS2Etypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\rasterfont.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Regs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resrc1.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\targets.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Win32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\x86.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\zerogs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\zerogsmath.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\CRC.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Profile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ZZGl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ZZHacks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ZZLog.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\GSDump.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ZZoglFlush.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ZZoglMem.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="zerogs.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\x86-32.asm">
<Filter>Source Files</Filter>
</CustomBuild>
</ItemGroup>
</Project>

View File

@ -1,42 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZZOgl", "zerogsogl_2008.vcproj", "{2D4E85B2-F47F-4D65-B091-701E5C031DAC}"
ProjectSection(ProjectDependencies) = postProject
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47} = {2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utilities", "..\..\..\..\common\build\Utilities\utilities.vcproj", "{4639972E-424E-4E13-8B07-CA403C481346}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\..\3rdparty\zlib\zlib.vcproj", "{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Devel|Win32 = Devel|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Debug|Win32.ActiveCfg = Debug|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Debug|Win32.Build.0 = Debug|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Devel|Win32.ActiveCfg = Devel|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Devel|Win32.Build.0 = Devel|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Release|Win32.ActiveCfg = Release|Win32
{2D4E85B2-F47F-4D65-B091-701E5C031DAC}.Release|Win32.Build.0 = Release|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.ActiveCfg = Debug|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.Build.0 = Debug|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.ActiveCfg = Devel|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.Build.0 = Devel|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.ActiveCfg = Release|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.Build.0 = Release|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|Win32.ActiveCfg = Debug|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|Win32.Build.0 = Debug|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|Win32.ActiveCfg = Devel|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|Win32.Build.0 = Devel|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|Win32.ActiveCfg = Release|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef CLUT_H_INCLUDED
#define CLUT_H_INCLUDED
extern void GSMem_to_ClutBuffer(tex0Info &tex0);
template <class T> extern void ClutBuffer_to_Array(T* dst, u32 csa, u32 clutsize);
template <class T> extern void Build_Clut_Texture(u32 psm, u32 height, T* pclut, u8* psrc, T* pdst);
template <class T> extern bool Cmp_ClutBuffer_GSMem(T* GSmem, u32 csa, u32 clutsize);
template <class T> extern bool Cmp_ClutBuffer_SavedClut(T* saved_clut, u32 csa, u32 clutsize);
#endif // CLUT_H_INCLUDED

View File

@ -1,315 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include <stdlib.h>
#include <math.h>
#include "GS.h"
#include "Mem.h"
#include "x86.h"
#include "targets.h"
#include "ZZoglShaders.h"
#include "ZZClut.h"
#include "ZZoglVB.h"
#include "Util.h"
extern bool g_bUpdateStencil;
void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, bool mode);
void SetWriteDepth();
bool IsWriteDepth();
bool IsWriteDestAlphaTest();
const float g_filog32 = 0.999f / (32.0f * logf(2.0f));
CDepthTarget::CDepthTarget() : CRenderTarget(), pdepth(0), pstencil(0), icount(0) {}
CDepthTarget::~CDepthTarget()
{
FUNCLOG
Destroy();
}
bool CDepthTarget::Create(const frameInfo& frame)
{
FUNCLOG
if (!CRenderTarget::Create(frame)) return false;
GL_REPORT_ERROR();
glGenRenderbuffersEXT(1, &pdepth);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, pdepth);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, RW(fbw), RH(fbh));
if (glGetError() != GL_NO_ERROR)
{
// try a separate depth and stencil buffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, pdepth);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, RW(fbw), RH(fbh));
if (g_bUpdateStencil)
{
glGenRenderbuffersEXT(1, &pstencil);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, pstencil);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, RW(fbw), RH(fbh));
if (glGetError() != GL_NO_ERROR)
{
ZZLog::Error_Log("Failed to create depth buffer %dx%d.", RW(fbw), RH(fbh));
return false;
}
}
else
{
pstencil = 0;
}
}
else
{
pstencil = pdepth;
}
status = TS_NeedUpdate;
return true;
}
void CDepthTarget::Destroy()
{
FUNCLOG
if (status) // In this case Framebuffer extension is off-use and lead to segfault
{
ResetRenderTarget(1);
FB::Attach(GL_DEPTH_ATTACHMENT_EXT);
FB::Attach(GL_STENCIL_ATTACHMENT_EXT);
GL_REPORT_ERRORD();
if (pstencil != 0)
{
if (pstencil != pdepth) glDeleteRenderbuffersEXT(1, &pstencil);
pstencil = 0;
}
if (pdepth != 0)
{
glDeleteRenderbuffersEXT(1, &pdepth);
pdepth = 0;
}
GL_REPORT_ERRORD();
}
CRenderTarget::Destroy();
}
extern int g_nDepthUsed; // > 0 if depth is used
void CDepthTarget::Resolve()
{
FUNCLOG
if (g_nDepthUsed > 0 && conf.mrtdepth && !(status & TS_Virtual) && IsWriteDepth() && !(conf.settings().no_depth_resolve))
CRenderTarget::Resolve();
else
{
// flush if necessary
FlushIfNecesary(this);
if (!(status & TS_Virtual)) status |= TS_Resolved;
}
if (!(status&TS_Virtual))
{
SetWriteDepth();
}
}
void CDepthTarget::Resolve(int startrange, int endrange)
{
FUNCLOG
if (g_nDepthUsed > 0 && conf.mrtdepth && !(status&TS_Virtual) && IsWriteDepth())
{
CRenderTarget::Resolve(startrange, endrange);
}
else
{
// flush if necessary
FlushIfNecesary(this) ;
if (!(status & TS_Virtual))
status |= TS_Resolved;
}
if (!(status&TS_Virtual))
{
SetWriteDepth();
}
}
void CDepthTarget::Update(int context, CRenderTarget* prndr)
{
FUNCLOG
assert(!(status & TS_Virtual));
// align the rect to the nearest page
// note that fbp is always aligned on page boundaries
tex0Info texframe;
texframe.tbp0 = fbp;
texframe.tbw = fbw;
texframe.tw = fbw;
texframe.th = fbh;
texframe.psm = psm;
// FIXME some field are not initialized...
// in particular the clut related one
assert(!PSMT_ISCLUT(psm));
DisableAllgl();
VB& curvb = vb[context];
if (curvb.test.zte == 0) return;
SetShaderCaller("CDepthTarget::Update");
glEnable(GL_DEPTH_TEST);
glDepthMask(!curvb.zbuf.zmsk);
static const u32 g_dwZCmp[] = { GL_NEVER, GL_ALWAYS, GL_GEQUAL, GL_GREATER };
glDepthFunc(g_dwZCmp[curvb.test.ztst]);
// write color and zero out stencil buf, always 0 context!
SetTexVariablesInt(0, 0, texframe, false, &ppsBitBltDepth, 1);
ZZshGLSetTextureParameter(ppsBitBltDepth.prog, ppsBitBltDepth.sMemory, vb[0].pmemtarg->ptex->tex, "BitBltDepth");
float4 v = DefaultBitBltPos();
v = DefaultBitBltTex();
v.x = 1;
v.y = 2;
v.z = PSMT_IS16Z(psm) ? 1.0f : 0.0f;
v.w = g_filog32;
ZZshSetParameter4fv(ppsBitBltDepth.prog, ppsBitBltDepth.sOneColor, v, "g_fOneColor");
float4 vdepth = g_vdepth;
if (psm == PSMT24Z)
{
vdepth.w = 0;
}
else if (psm != PSMT32Z)
{
vdepth.z = vdepth.w = 0;
}
#if defined(GLSL_API) || defined(GLSL4_API)
assert(ppsBitBltDepth.sBitBltZ != -1);
#else
assert(ppsBitBltDepth.sBitBltZ != 0);
#endif
ZZshSetParameter4fv(ppsBitBltDepth.prog, ppsBitBltDepth.sBitBltZ, (vdepth*(255.0f / 256.0f)), "g_fBitBltZ");
assert(pdepth != 0);
//GLint w1 = 0;
//GLint h1 = 0;
FB::Attach2D(0, ptex);
//glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &w1);
//glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &h1);
SetDepthStencilSurface();
FB::Attach2D(1);
GLenum buffer = GL_COLOR_ATTACHMENT0_EXT;
//ZZLog::Error_Log("CDepthTarget::Update: w1 = 0x%x; h1 = 0x%x", w1, h1);
DrawBuffers(&buffer);
SetViewport();
if (conf.wireframe()) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBindBuffer(GL_ARRAY_BUFFER, vboRect);
SET_STREAM();
ZZshSetVertexShader(pvsBitBlt.prog);
ZZshSetPixelShader(ppsBitBltDepth.prog);
DrawTriangleArray();
status = TS_Resolved;
if (!IsWriteDepth())
{
ResetRenderTarget(1);
}
if (conf.wireframe()) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glEnable(GL_SCISSOR_TEST);
#ifdef _DEBUG
if (g_bSaveZUpdate)
{
SaveTex(&texframe, 1);
SaveTexture("frame1.tga", GL_TEXTURE_RECTANGLE_NV, ptex, RW(fbw), RH(fbh));
}
#endif
}
void CDepthTarget::SetDepthStencilSurface()
{
FUNCLOG
FB::Attach(GL_DEPTH_ATTACHMENT_EXT, pdepth);
if (pstencil)
{
// there's a bug with attaching stencil and depth buffers
FB::Attach(GL_STENCIL_ATTACHMENT_EXT, pstencil);
if (icount++ < 8) // not going to fail if succeeded 4 times
{
GL_REPORT_ERRORD();
if (FB::State() != GL_FRAMEBUFFER_COMPLETE_EXT)
{
FB::Attach(GL_STENCIL_ATTACHMENT_EXT);
if (pstencil != pdepth) glDeleteRenderbuffersEXT(1, &pstencil);
pstencil = 0;
g_bUpdateStencil = 0;
}
}
}
else
{
FB::Attach(GL_STENCIL_ATTACHMENT_EXT);
}
}

View File

@ -1,354 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef ZZGL_H_INCLUDED
#define ZZGL_H_INCLUDED
#include "PS2Etypes.h"
#include "PS2Edefs.h"
// Need this before gl.h
#ifdef _WIN32
#include "Utilities/RedtapeWindows.h"
#include <GL/gl.h>
#include <GL/glext.h>
#include "glprocs.h"
#else
// adding glew support instead of glXGetProcAddress (thanks to scaught)
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glx.h>
#endif
#include "Mem.h"
extern u32 s_stencilfunc, s_stencilref, s_stencilmask;
extern GLenum s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha; // set by zgsBlendFuncSeparateEXT
extern GLenum s_rgbeq, s_alphaeq;
#ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils
# define GL_DEPTH_STENCIL_EXT 0x84F9
# define GL_UNSIGNED_INT_24_8_EXT 0x84FA
# define GL_DEPTH24_STENCIL8_EXT 0x88F0
# define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
#endif
#ifdef _WIN32
#define GL_LOADFN(name) { \
if( (*(void**)&name = (void*)wglGetProcAddress(#name)) == NULL ) { \
ZZLog::Error_Log("Failed to find %s, exiting.", #name); \
} \
}
#else
// let GLEW take care of it
#define GL_LOADFN(name)
#endif
static __forceinline void GL_STENCILFUNC(GLenum func, GLint ref, GLuint mask)
{
s_stencilfunc = func;
s_stencilref = ref;
s_stencilmask = mask;
glStencilFunc(func, ref, mask);
}
static __forceinline void GL_STENCILFUNC_SET()
{
glStencilFunc(s_stencilfunc, s_stencilref, s_stencilmask);
}
#ifdef GLSL4_API
#include "ZZoglShaders.h"
#endif
// sets the data stream
static __forceinline void SET_STREAM()
{
#ifndef GLSL4_API
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)8);
glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)12);
glTexCoordPointer(3, GL_FLOAT, sizeof(VertexGPU), (void*)16);
glVertexPointer(4, GL_SHORT, sizeof(VertexGPU), (void*)0);
#else
vertex_array->set_internal_format();
#endif
}
//static __forceinline void SAFE_RELEASE_TEX(u32& x)
//{
// if (x != 0)
// {
// glDeleteTextures(1, &x);
// x = 0;
// }
//}
#define SAFE_RELEASE_TEX(x) { if( (x) != 0 ) { glDeleteTextures(1, &(x)); x = 0; } }
// inline for an extremely often used sequence
// This is turning off all gl functions. Safe to do updates.
inline void DisableAllgl()
{
glDisable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);
glDepthMask(0);
glDisable(GL_STENCIL_TEST);
glColorMask(1, 1, 1, 1);
}
//--------------------- Dummies
#ifdef _WIN32
extern void (__stdcall *zgsBlendEquationSeparateEXT)(GLenum, GLenum);
extern void (__stdcall *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum);
#else
extern void (APIENTRY *zgsBlendEquationSeparateEXT)(GLenum, GLenum);
extern void (APIENTRY *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum);
#endif
// GL prototypes
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT;
extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT;
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT;
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
#ifdef GLSL4_API
#include "ZZoglShaders.h"
#endif
static __forceinline void DrawTriangleArray()
{
#ifdef GLSL4_API
ZZshSetupShader();
#endif
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
GL_REPORT_ERRORD();
}
static __forceinline void DrawBuffers(GLenum *buffer)
{
if (glDrawBuffers != NULL)
{
glDrawBuffers(1, buffer);
}
GL_REPORT_ERRORD();
}
namespace FB
{
extern u32 buf;
static __forceinline void Create()
{
assert(buf == 0);
glGenFramebuffersEXT(1, &buf);
if (buf == 0)
ZZLog::Error_Log("Failed to create the renderbuffer.");
}
static __forceinline void Delete()
{
if (buf != 0) {
glDeleteFramebuffersEXT(1, &buf);
buf = 0;
}
}
static __forceinline void Bind()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buf);
}
static __forceinline void Unbind()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
static __forceinline GLenum State()
{
return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
}
static __forceinline void Attach2D(int attach, int id = 0)
{
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + attach, GL_TEXTURE_RECTANGLE_NV, id, 0);
GL_REPORT_ERRORD();
}
static __forceinline void Attach(GLenum rend, GLuint id = 0)
{
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, rend, GL_RENDERBUFFER_EXT, id);
}
};
static __forceinline void ResetRenderTarget(int index)
{
FB::Attach2D(index);
}
static __forceinline void TextureImage(GLenum tex_type, GLint iFormat, GLint width, GLint height, GLenum format, GLenum type, const GLvoid* pixels)
{
glTexImage2D(tex_type, 0, iFormat, width, height, 0, format, type, pixels);
}
static __forceinline void Texture2D(GLint iFormat, GLint width, GLint height, GLenum format, GLenum type, const GLvoid* pixels)
{
TextureImage(GL_TEXTURE_2D, iFormat, width, height, format, type, pixels);
}
static __forceinline void Texture2D(GLint iFormat, GLenum format, GLenum type, const GLvoid* pixels)
{
TextureImage(GL_TEXTURE_2D, iFormat, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, format, type, pixels);
}
static __forceinline void TextureRect(GLint iFormat, GLint width, GLint height, GLenum format, GLenum type, const GLvoid* pixels)
{
TextureImage(GL_TEXTURE_RECTANGLE_NV, iFormat, width, height, format, type, pixels);
}
static __forceinline void TextureRect2(GLint iFormat, GLint width, GLint height, GLenum format, GLenum type, const GLvoid* pixels)
{
TextureImage(GL_TEXTURE_RECTANGLE, iFormat, width, height, format, type, pixels);
}
static __forceinline void Texture3D(GLint iFormat, GLint width, GLint height, GLint depth, GLenum format, GLenum type, const GLvoid* pixels)
{
glTexImage3D(GL_TEXTURE_3D, 0, iFormat, width, height, depth, 0, format, type, pixels);
}
static __forceinline void setTex2DFilters(GLint type)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, type);
}
static __forceinline void setTex2DWrap(GLint type)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, type);
}
static __forceinline void setTex3DFilters(GLint type)
{
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, type);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, type);
}
static __forceinline void setTex3DWrap(GLint type)
{
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, type);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, type);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, type);
}
static __forceinline void setRectFilters(GLint type)
{
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, type);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, type);
}
static __forceinline void setRectWrap(GLint type)
{
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, type);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, type);
}
static __forceinline void setRectWrap2(GLint type)
{
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, type);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, type);
}
static __forceinline void GL_BLEND_SET()
{
zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha);
}
static __forceinline void GL_BLEND_RGB(GLenum src, GLenum dst)
{
s_srcrgb = src;
s_dstrgb = dst;
GL_BLEND_SET();
}
static __forceinline void GL_BLEND_ALPHA(GLenum src, GLenum dst)
{
s_srcalpha = src;
s_dstalpha = dst;
GL_BLEND_SET();
}
static __forceinline void GL_BLEND_ALL(GLenum srcrgb, GLenum dstrgb, GLenum srcalpha, GLenum dstalpha)
{
s_srcrgb = srcrgb;
s_dstrgb = dstrgb;
s_srcalpha = srcalpha;
s_dstalpha = dstalpha;
GL_BLEND_SET();
}
static __forceinline void GL_ZTEST(bool enable)
{
if (enable)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
}
static __forceinline void GL_ALPHATEST(bool enable)
{
if (enable)
glEnable(GL_ALPHA_TEST);
else
glDisable(GL_ALPHA_TEST);
}
static __forceinline void GL_BLENDEQ_RGB(GLenum eq)
{
s_rgbeq = eq;
zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq);
}
static __forceinline void GL_BLENDEQ_ALPHA(GLenum eq)
{
s_alphaeq = eq;
zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq);
}
#endif // ZZGL_H_INCLUDED

View File

@ -1,186 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "Util.h"
#include "ZZHacks.h"
#include "ZZLog.h"
int CurrentHack = 0;
// A list of what bit controls each of the current hacks.
u32 hackList[HACK_NUMBER] =
{
0, // No hack
1, //GAME_TEXTURETARGS,
2, //GAME_AUTORESET,
3, //GAME_INTERLACE2X,
4, //GAME_TEXAHACK,
5, //GAME_NOTARGETRESOLVE,
6, //GAME_EXACTCOLOR,
//7 //GAME_NOCOLORCLAMP,
//8 //GAME_FFXHACK,
9, //GAME_NOALPHAFAIL,
10, //GAME_NODEPTHUPDATE,
11, //GAME_QUICKRESOLVE1,
12, //GAME_NOQUICKRESOLVE,
13, //GAME_NOTARGETCLUT,
14, //GAME_NOSTENCIL,
15, //GAME_NODEPTHRESOLVE,
16, //GAME_FULL16BITRES,
17, //GAME_RESOLVEPROMOTED,
18, //GAME_FASTUPDATE,
19, //GAME_NOALPHATEST,
20, //GAME_DISABLEMRTDEPTH,
//21 //GAME_32BITTARGS,
//22 //GAME_PATH3HACK,
//23 //GAME_DOPARALLELCTX,
24, //GAME_XENOSPECHACK,
//25 //GAME_PARTIALPOINTERS,
26, //GAME_PARTIALDEPTH,
27, //GAME_REGETHACK,
28, //GAME_GUSTHACK,
29, //GAME_NOLOGZ,
30, //GAME_AUTOSKIPDRAW
};
char hackDesc[32][64] =
{
"No hack",
"Texture targs",
"Auto reset",
"Interlace 2x",
"Texa",
"No target resolve",
"Exact color",
"No color clamp",
"Final Fantasy X",
"No alpha fail",
"No depth update",
"Quick resolve 1",
"No Quick resolve",
"No target clut",
"No stencil",
"VSS",
"No depth resolve",
"Full 16 bit resolution",
"Resolve promoted",
"Fast update",
"No alpha test",
"Disable mrt depth",
"Args 32 bit",
"",
"Parallel context",
"Xenosaga spec",
"Partial pointers",
"Partial depth",
"Reget",
"Gust",
"No logz",
"Automatic skip draw"
};
struct hacks
{
bool enabled;
char shortDesc[64];
char longDesc[256];
};
hacks hack_list[32] =
{
{ true, "No hack", "No hack" },
{ true, "Texture targs", "Tex Target checking - 00000001\nLego Racers" },
{ true, "Auto reset", "Auto reset targs - 00000002\nUse when game is slow and toggling AA fixes it. Samurai Warriors. (Automatically on for Shadow Hearts)" },
{ true, "Interlace 2x", "Interlace 2X - 00000004\nFixes 2x bigger screen. Gradius 3." },
{ false, "Texa", "" },
{ true, "No target resolve", "No target resolves - 00000010\nStops all resolving of targets. Try this first for really slow games. (Automatically on for Dark Cloud 1.)" },
{ true, "Exact color", "Exact color testing - 00000020\nFixes overbright or shadow/black artifacts. Crash 'n Burn." },
{ false, "No color clamp", "No color clamping - 00000040\nSpeeds up games, but might be too bright or too dim." },
{ false, "Final Fantasy X", "" },
{ false, "No alpha fail", "Alpha Fail hack - 00000100\nRemove vertical stripes or other coloring artifacts. Breaks Persona 4 and MGS3. (Automatically on for Sonic Unleashed, Shadow the Hedgehog, & Ghost in the Shell.)" },
{ true, "No depth update", "Disable depth updates - 00000200" },
{ true, "Quick resolve 1", "Resolve Hack #1 - 00000400\n Speeds some games. Kingdom Hearts."},
{ true, "No Quick resolve", "Resolve Hack #2 - 00000800\nShadow Hearts, Urbz. Destroys FFX."},
{ true, "No target clut", "No target CLUT - 00001000\nResident Evil 4, or foggy scenes." },
{ true, "No stencil", "Disable stencil buffer - 00002000\nUsually safe to do for simple scenes. Harvest Moon." },
{ false, "VSS", "" },
{ true, "No depth resolve", "No depth resolve - 00008000\nMight give z buffer artifacts." },
{ true, "Full 16 bit resolution", "Full 16 bit resolution - 00010000\nUse when half the screen is missing." },
{ true, "Resolve promoted", "Resolve Hack #3 - 00020000\nNeopets" },
{ true, "Fast update", "Fast Update - 00040000\n Speeds some games. Needed for Sonic Unleashed. Okami." },
{ true, "No alpha test", "Disable alpha testing - 00080000" },
{ true, "Disable mrt depth", "Enable Multiple RTs - 00100000" },
{ false, "Args 32 bit", "" },
{ false, "Path3", "" },
{ false, "Parallel context", "" },
{ true, "Xenosaga spec", "Specular Highlights - 01000000\nMakes graphics faster by removing highlights. (Automatically on for Xenosaga, Okami, & Okage.)" },
{ false, "Partial pointers", "Partial targets - 02000000" },
{ true, "Partial depth", "Partial depth - 04000000" },
{ false, "Reget", "" },
{ true, "Gust", "Gust fix - 10000000. Makes gust games cleaner and faster. (Automatically on for most Gust games)" },
{ true, "No logz", "No logarithmic Z - 20000000. Could decrease number of Z-artifacts." },
{ true, "Automatic skip draw", "Remove blur effect on some games\nSlow games." }
};
void ReportHacks(gameHacks hacks)
{
for(int i = 0; i < 32; i++)
{
if (hacks._u32 & (1 << i))
{
ZZLog::WriteLn("'%s' hack enabled.", hackDesc[i+1]);
}
}
}
void ListHacks()
{
if ((!conf.disableHacks) && (conf.def_hacks._u32 != 0))
{
ZZLog::WriteLn("Auto-enabling these hacks:");
ReportHacks(conf.def_hacks);
}
if (conf.hacks._u32 != 0)
{
ZZLog::WriteLn("You've manually enabled these hacks:");
ReportHacks(conf.hacks);
}
}
void DisplayHack(int hack)
{
ZZLog::WriteToScreen2("***%d %s", hack, hackDesc[hackList[hack]]);
}
void ChangeCurrentHack(int hack)
{
FUNCLOG
conf.hacks._u32 &= !(hackList[CurrentHack]);
conf.hacks._u32 |= hackList[hack];
DisplayHack(hack);
CurrentHack = hack;
SaveConfig();
}

View File

@ -1,118 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef ZZHACKS_H_INCLUDED
#define ZZHACKS_H_INCLUDED
#include "PS2Edefs.h"
// This is a list of the various hacks, and what bit controls them.
// Changing these is not advised unless you know what you are doing.
enum GAME_HACK_OPTIONS
{
GAME_TEXTURETARGS = 0x00000001,
GAME_AUTORESET = 0x00000002,
GAME_INTERLACE2X = 0x00000004,
GAME_TEXAHACK = 0x00000008, // apply texa to non textured polys
GAME_NOTARGETRESOLVE = 0x00000010,
GAME_EXACTCOLOR = 0x00000020,
GAME_NOCOLORCLAMP = 0x00000040,
GAME_FFXHACK = 0x00000080,
GAME_NOALPHAFAIL = 0x00000100,
GAME_NODEPTHUPDATE = 0x00000200,
GAME_QUICKRESOLVE1 = 0x00000400,
GAME_NOQUICKRESOLVE = 0x00000800,
GAME_NOTARGETCLUT = 0x00001000, // full 16 bit resolution
GAME_NOSTENCIL = 0x00002000,
GAME_VSSHACKOFF = 0x00004000, // vertical stripe syndrome
GAME_NODEPTHRESOLVE = 0x00008000,
GAME_FULL16BITRES = 0x00010000,
GAME_RESOLVEPROMOTED = 0x00020000,
GAME_FASTUPDATE = 0x00040000,
GAME_NOALPHATEST = 0x00080000,
GAME_DISABLEMRTDEPTH = 0x00100000,
GAME_32BITTARGS = 0x00200000,
GAME_PATH3HACK = 0x00400000,
GAME_DOPARALLELCTX = 0x00800000, // tries to parallelize both contexts so that render calls are reduced (xenosaga)
// makes the game faster, but can be buggy
GAME_XENOSPECHACK = 0x01000000, // xenosaga specularity hack (ignore any zmask=1 draws)
GAME_PARTIALPOINTERS = 0x02000000, // whenver the texture or render target are small, tries to look for bigger ones to read from
GAME_PARTIALDEPTH = 0x04000000, // tries to save depth targets as much as possible across height changes
GAME_REGETHACK = 0x08000000, // some sort of weirdness in ReGet() code
GAME_GUSTHACK = 0x10000000, // Needed for Gustgames fast update.
GAME_NOLOGZ = 0x20000000, // Intended for linux -- not logarithmic Z.
GAME_AUTOSKIPDRAW = 0x40000000, // Remove blur effect on some games
GAME_RESERVED_HACK = 0x80000000
};
#define USEALPHATESTING (!(conf.settings().no_alpha_test))
typedef union
{
struct
{
u32 texture_targs : 1;
u32 auto_reset : 1;
u32 interlace_2x : 1;
u32 texa : 1; // apply texa to non textured polys
u32 no_target_resolve : 1;
u32 exact_color : 1;
u32 no_color_clamp : 1;
u32 ffx : 1;
u32 no_alpha_fail : 1;
u32 no_depth_update : 1;
u32 quick_resolve_1 : 1;
u32 no_quick_resolve : 1;
u32 no_target_clut : 1; // full 16 bit resolution
u32 no_stencil : 1;
u32 vss_hack_off : 1; // vertical stripe syndrome
u32 no_depth_resolve : 1;
u32 full_16_bit_res : 1;
u32 resolve_promoted : 1;
u32 fast_update : 1;
u32 no_alpha_test : 1;
u32 disable_mrt_depth : 1;
u32 args_32_bit : 1;
u32 path3 : 1;
u32 parallel_context : 1; // tries to parallelize both contexts so that render calls are reduced (xenosaga)
// makes the game faster, but can be buggy
u32 xenosaga_spec : 1; // xenosaga specularity hack (ignore any zmask=1 draws)
u32 partial_pointers : 1; // whenver the texture or render target are small, tries to look for bigger ones to read from
u32 partial_depth : 1; // tries to save depth targets as much as possible across height changes
u32 reget : 1; // some sort of weirdness in ReGet() code
u32 gust : 1; // Needed for Gustgames fast update.
u32 no_logz : 1; // Intended for linux -- not logarithmic Z.
u32 automatic_skip_draw :1; // allow debug of the automatic skip draw option
u32 reserved2 :1;
};
u32 _u32;
} gameHacks;
#define HACK_NUMBER 25
extern u32 hackList[HACK_NUMBER];
extern char hackDesc[32][64];
extern int CurrentHack;
extern void ReportHacks(gameHacks hacks);
extern void ListHacks();
extern void DisplayHack(int hack);
extern void ChangeCurrentHack(int hack);
#endif // ZZHACKS_H_INCLUDED

View File

@ -1,247 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
// keyboard functions
#include "Util.h"
#include "GS.h"
#include "ZZoglShaders.h"
#include "Profile.h"
#include "GLWin.h"
extern int CurrentSavestate, g_GSMultiThreaded, g_nPixelShaderVer;
extern char *libraryName;
extern const unsigned char zgsversion;
extern unsigned char zgsrevision, zgsbuild, zgsminor;
extern bool SaveStateExists;
const char* s_aa[5] = { "AA none |", "AA 2x |", "AA 4x |", "AA 8x |", "AA 16x |" };
const char* pbilinear[] = { "off", "normal", "forced" };
extern void SetAA(int mode);
extern bool dump_enable;
void ProcessBilinear()
{
FUNCLOG
char strtitle[256];
if (g_nPixelShaderVer == SHADER_REDUCED)
{
conf.bilinear = 0;
sprintf(strtitle, "reduced shaders don't support bilinear filtering");
}
else
{
conf.bilinear = (conf.bilinear + 1) % 3;
sprintf(strtitle, "bilinear filtering - %s", pbilinear[conf.bilinear]);
}
ZZLog::WriteToScreen(strtitle);
SaveConfig();
}
void ProcessInterlace()
{
FUNCLOG
char strtitle[256];
conf.interlace++;
if (conf.interlace > 2) conf.interlace = 0;
if (conf.interlace < 2)
sprintf(strtitle, "interlace on - mode %d", conf.interlace);
else
sprintf(strtitle, "interlace off");
ZZLog::WriteToScreen(strtitle);
SaveConfig();
}
void ProcessAASetting(bool reverse)
{
FUNCLOG
char strtitle[256];
if (reverse)
conf.decAA();
else
conf.incAA();
sprintf(strtitle, "anti-aliasing - %s", s_aa[conf.aa]);
SetAA(conf.aa);
ZZLog::WriteToScreen(strtitle);
SaveConfig();
}
void ProcessFPS()
{
FUNCLOG
g_bDisplayFPS ^= 1;
ZZLog::Debug_Log("Toggled FPS.");
}
void ProcessWireFrame()
{
FUNCLOG
char strtitle[256];
conf.zz_options.wireframe = !conf.zz_options.wireframe;
glPolygonMode(GL_FRONT_AND_BACK, (conf.wireframe()) ? GL_LINE : GL_FILL);
sprintf(strtitle, "wireframe rendering - %s", (conf.wireframe()) ? "on" : "off");
ZZLog::WriteToScreen(strtitle);
}
void ProcessFrameDump()
{
FUNCLOG
conf.dump = 1;
char strtitle[256];
sprintf(strtitle, "GS dump-frame");
ZZLog::WriteToScreen(strtitle);
SaveConfig();
}
void ProcessVideoDump()
{
FUNCLOG
char strtitle[256];
if (conf.dump != 0) {
sprintf(strtitle, "Stop GS dump-video");
conf.dump = 0;
} else {
sprintf(strtitle, "Start GS dump-video");
conf.dump = 3;
}
ZZLog::WriteToScreen(strtitle);
SaveConfig();
}
void ProcessHackSetting(bool reverse)
{
FUNCLOG
int hack = CurrentHack;
if (reverse)
{
hack--;
if (hack < 0) hack = HACK_NUMBER - 1;
}
else
{
hack++;
if (hack >= HACK_NUMBER) hack = 0;
}
ChangeCurrentHack(hack);
SaveConfig();
}
void ProcessSaveState()
{
FUNCLOG
char strtitle[256];
sprintf(strtitle, "Saving in savestate %d", CurrentSavestate);
SaveStateExists = true;
if (CurrentHack != 0) DisplayHack(CurrentHack);
}
void OnFKey(int key, int shift)
{
switch(key)
{
//case 1:
// ProcessSaveState();
// break;
case 5:
if (shift)
ProcessBilinear();
else
ProcessInterlace();
break;
case 6:
if (shift)
ProcessAASetting(true);
else
ProcessAASetting(false);
break;
case 7:
if (!shift)
ProcessFPS();
else
ProcessWireFrame();
break;
case 9:
#ifdef _DEBUG
// Fn keys are a bit overload... I don't have a better idea --Gregory
if (shift)
ProcessVideoDump();
else
ProcessFrameDump();
#else
if (shift)
ProcessHackSetting(true);
else
ProcessHackSetting(false);
break;
#endif
default:
break;
}
}
void WriteAA()
{
if (conf.aa != 0)
{
char strtitle[64];
sprintf(strtitle, "anti-aliasing - %s", s_aa[conf.aa]);
ZZLog::WriteToScreen(strtitle, 1000);
}
}
void WriteBilinear()
{
switch (conf.bilinear)
{
case 2:
ZZLog::WriteToScreen("bilinear filtering - forced", 1000);
break;
case 1:
ZZLog::WriteToScreen("bilinear filtering - normal", 1000);
break;
default:
break;
}
}

View File

@ -1,439 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include <stdio.h>
#include "ZZLog.h"
#include <list>
#include <cstring>
extern GSconf conf;
using namespace std;
static list<MESSAGE> listMsgs;
const char* logging_prefix = "ZZOgl-PG";
void ProcessMessages()
{
FUNCLOG
if (listMsgs.size() > 0)
{
int left = 25, top = 15;
list<MESSAGE>::iterator it = listMsgs.begin();
while (it != listMsgs.end())
{
DrawText(it->str, left + 1, top + 1, 0xff000000);
DrawText(it->str, left, top, 0xffffff30);
top += 15;
if ((int)(it->dwTimeStamp - timeGetTime()) < 0)
it = listMsgs.erase(it);
else ++it;
}
}
}
void ZZAddMessage(const char* pstr, u32 ms)
{
FUNCLOG
listMsgs.push_back(MESSAGE(pstr, timeGetTime() + ms));
ZZLog::Log("%s\n", pstr);
}
namespace ZZLog
{
std::string s_strLogPath("logs");
FILE *gsLog;
FILE *gsLogGL; // I create a separate file because it could be very verbose
bool IsLogging()
{
// gsLog can be null if the config dialog is used prior to Pcsx2 starting an emulation session.
// (GSinit won't have been called then)
return (gsLog != NULL && conf.log);
}
void Open()
{
const std::string LogFile(s_strLogPath + "/GSzzogl.log");
const std::string LogFileGL(s_strLogPath + "/GSzzogl_GL.log");
gsLog = fopen(LogFile.c_str(), "w");
if (gsLog != NULL)
setvbuf(gsLog, NULL, _IONBF, 0);
else
SysMessage("Can't create log file %s\n", LogFile.c_str());
gsLogGL = fopen(LogFileGL.c_str(), "w");
if (gsLogGL != NULL)
setvbuf(gsLogGL, NULL, _IONBF, 0);
else
SysMessage("Can't create log file %s\n", LogFileGL.c_str());
}
void Close()
{
if (gsLog != NULL) {
fclose(gsLog);
gsLog = NULL;
}
if (gsLogGL != NULL) {
fclose(gsLogGL);
gsLogGL = NULL;
}
}
void SetDir(const char* dir)
{
// Get the path to the log directory.
s_strLogPath = (dir==NULL) ? "logs" : dir;
// Reload previously open log file
if (gsLog) {
Close();
Open();
}
}
void WriteToScreen(const char* pstr, u32 ms)
{
ZZAddMessage(pstr, ms);
}
void WriteToScreen2(const char* fmt, ...)
{
va_list list;
char tmp[512];
va_start(list, fmt);
vsprintf(tmp, fmt, list);
va_end(list);
ZZAddMessage(tmp, 5000);
}
void _Message(const char *str)
{
SysMessage(str);
}
void _WriteToConsole(const char *str)
{
fprintf(stderr,"%s: ", logging_prefix);
fprintf(stderr,"%s", str);
}
void Message(const char *fmt, ...)
{
va_list list;
char tmp[512];
va_start(list, fmt);
vsprintf(tmp, fmt, list);
va_end(list);
SysMessage(tmp);
}
void Log(const char *fmt, ...)
{
va_list list;
va_start(list, fmt);
if (IsLogging()) vfprintf(gsLog, fmt, list);
va_end(list);
}
void WriteToConsole(const char *fmt, ...)
{
va_list list;
va_start(list, fmt);
fprintf(stderr, "%s: ", logging_prefix);
vfprintf(stderr, fmt, list);
va_end(list);
}
void Print(const char *fmt, ...)
{
va_list list;
va_start(list, fmt);
if (IsLogging()) vfprintf(gsLog, fmt, list);
fprintf(stderr, "%s: ", logging_prefix);
vfprintf(stderr, fmt, list);
va_end(list);
}
void WriteLn(const char *fmt, ...)
{
va_list list;
va_start(list, fmt);
if (IsLogging()) vfprintf(gsLog, fmt, list);
fprintf(stderr, "%s: ", logging_prefix);
vfprintf(stderr, fmt, list);
va_end(list);
fprintf(stderr,"\n");
}
void Greg_Log(const char *fmt, ...)
{
#if defined(WRITE_GREG_LOGS)
va_list list;
char tmp[512];
va_start(list, fmt);
if (IsLogging()) {
fprintf(gsLog, "GRegs: ");
vfprintf(gsLog, fmt, list);
}
//fprintf(stderr,"GRegs: ");
//vfprintf(stderr, fmt, list);
va_end(list);
if (IsLogging()) fprintf(gsLog, "\n");
//fprintf(stderr,"\n");
#endif
}
void Prim_Log(const char *fmt, ...)
{
#if defined(ZEROGS_DEVBUILD) && defined(WRITE_PRIM_LOGS)
va_list list;
char tmp[512];
va_start(list, fmt);
if (conf.log /*& 0x00000010*/)
{
if (IsLogging()) vfprintf(gsLog, fmt, list);
fprintf(stderr, "%s(PRIM): ", logging_prefix);
vfprintf(stderr, fmt, list);
vprintf(fmt, list);
}
va_end(list);
fprintf(stderr,"\n");
#endif
}
void GS_Log(const char *fmt, ...)
{
#ifdef ZEROGS_DEVBUILD
va_list list;
va_start(list, fmt);
if (IsLogging())
{
vfprintf(gsLog, fmt, list);
fprintf(gsLog, "\n");
}
fprintf(stderr, "%s: ", logging_prefix);
vfprintf(stderr, fmt, list);
fprintf(stderr, "\n");
va_end(list);
#endif
}
void Warn_Log(const char *fmt, ...)
{
#ifdef ZEROGS_DEVBUILD
va_list list;
va_start(list, fmt);
if (IsLogging())
{
vfprintf(gsLog, fmt, list);
fprintf(gsLog, "\n");
}
fprintf(stderr, "%s(Warning): ", logging_prefix);
vfprintf(stderr, fmt, list);
fprintf(stderr, "\n");
va_end(list);
#endif
}
void Dev_Log(const char *fmt, ...)
{
#ifdef ZEROGS_DEVBUILD
va_list list;
va_start(list, fmt);
if (IsLogging())
{
vfprintf(gsLog, fmt, list);
fprintf(gsLog, "\n");
}
fprintf(stderr, "%s: ", logging_prefix);
vfprintf(stderr, fmt, list);
fprintf(stderr, "\n");
va_end(list);
#endif
}
void Debug_Log(const char *fmt, ...)
{
#ifdef _DEBUG
va_list list;
va_start(list, fmt);
if (IsLogging())
{
vfprintf(gsLog, fmt, list);
fprintf(gsLog, "\n");
}
fprintf(stderr, "%s: ", logging_prefix);
vfprintf(stderr, fmt, list);
fprintf(stderr, "\n");
va_end(list);
#endif
}
void Error_Log(const char *fmt, ...)
{
va_list list;
va_start(list, fmt);
if (IsLogging())
{
vfprintf(gsLog, fmt, list);
fprintf(gsLog, "\n");
}
fprintf(stderr, "%s: ", logging_prefix);
vfprintf(stderr, fmt, list);
fprintf(stderr, "\n");
va_end(list);
}
#ifdef _DEBUG
#define LOUD_DEBUGGING
#endif
#ifdef OGL4_LOG
void Check_GL_Error()
{
#if defined(ZEROGS_DEVBUILD) || defined(_DEBUG)
unsigned int count = 64; // max. num. of messages that will be read from the log
int bufsize = 2048;
unsigned int* sources = new unsigned int[count];
unsigned int* types = new unsigned int[count];
unsigned int* ids = new unsigned int[count];
unsigned int* severities = new unsigned int[count];
int* lengths = new int[count];
char* messageLog = new char[bufsize];
unsigned int retVal = glGetDebugMessageLogARB(count, bufsize, sources, types, ids, severities, lengths, messageLog);
if(retVal > 0)
{
unsigned int pos = 0;
for(unsigned int i=0; i<retVal; i++)
{
GL_Error_Log(sources[i], types[i], ids[i], severities[i],
&messageLog[pos]);
pos += lengths[i];
}
}
delete [] sources;
delete [] types;
delete [] ids;
delete [] severities;
delete [] lengths;
delete [] messageLog;
#endif
}
void GL_Error_Log(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message)
{
char debType[20], debSev[5];
static int sev_counter = 0;
if(type == GL_DEBUG_TYPE_ERROR_ARB)
strcpy(debType, "Error");
else if(type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB)
strcpy(debType, "Deprecated behavior");
else if(type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB)
strcpy(debType, "Undefined behavior");
else if(type == GL_DEBUG_TYPE_PORTABILITY_ARB)
strcpy(debType, "Portability");
else if(type == GL_DEBUG_TYPE_PERFORMANCE_ARB)
strcpy(debType, "Performance");
else if(type == GL_DEBUG_TYPE_OTHER_ARB)
strcpy(debType, "Other");
else
strcpy(debType, "UNKNOWN");
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) {
strcpy(debSev, "High");
sev_counter++;
}
else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB)
strcpy(debSev, "Med");
else if(severity == GL_DEBUG_SEVERITY_LOW_ARB)
strcpy(debSev, "Low");
#ifdef LOUD_DEBUGGING
fprintf(stderr,"Type:%s\tSeverity:%s\tMessage:%s\n", debType, debSev,message);
#endif
if(gsLogGL)
{
fprintf(gsLogGL,"Type:%s\tSeverity:%s\tMessage:%s\n", debType, debSev,message);
}
//if (sev_counter > 2) assert(0);
}
#else
void Check_GL_Error() {}
void GL_Error_Log(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message) {}
#endif
};

View File

@ -1,212 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef ZZLOG_H_INCLUDED
#define ZZLOG_H_INCLUDED
#include "Util.h"
#include <cstring>
extern void HandleGLError();
//Logging for errors that are called often should have a time counter.
#ifdef __linux__
static u32 __attribute__((unused)) lasttime = 0;
static u32 __attribute__((unused)) BigTime = 5000;
static bool __attribute__((unused)) SPAM_PASS;
#else
static u32 lasttime = 0;
static u32 BigTime = 5000;
static bool SPAM_PASS;
#endif
#define ERROR_LOG_SPAM(text) { \
if( timeGetTime() - lasttime > BigTime ) { \
ZZLog::Error_Log(text); \
lasttime = timeGetTime(); \
} \
}
// The same macro with one-argument substitution.
#define ERROR_LOG_SPAMA(fmt, value) { \
if( timeGetTime() - lasttime > BigTime ) { \
ZZLog::Error_Log(fmt, value); \
lasttime = timeGetTime(); \
} \
}
#define ERROR_LOG_SPAM_TEST(text) {\
if( timeGetTime() - lasttime > BigTime ) { \
ZZLog::Error_Log(text); \
lasttime = timeGetTime(); \
SPAM_PASS = true; \
} \
else \
SPAM_PASS = false; \
}
#if DEBUG_PROF
#define FILE_IS_IN_CHECK ((strcmp(__FILE__, "targets.cpp") == 0) || (strcmp(__FILE__, "ZZoglFlush.cpp") == 0))
#define FUNCLOG {\
static bool Was_Here = false; \
static unsigned long int waslasttime = 0; \
if (!Was_Here && FILE_IS_IN_CHECK) { \
Was_Here = true;\
ZZLog::Error_Log("%s:%d %s", __FILE__, __LINE__, __func__); \
waslasttime = timeGetTime(); \
} \
if (FILE_IS_IN_CHECK && (timeGetTime() - waslasttime > BigTime )) { \
Was_Here = false; \
} \
}
#else
#define FUNCLOG
#endif
//#define WRITE_GREG_LOGS
//#define WRITE_PRIM_LOGS
#if defined(_DEBUG) && !defined(ZEROGS_DEVBUILD)
#define ZEROGS_DEVBUILD
#endif
// sends a message to output window if assert fails
#define BMSG(x, str) { if( !(x) ) { ZZLog::Log(str); ZZLog::Log(str); } }
#define BMSG_RETURN(x, str) { if( !(x) ) { ZZLog::Log(str); ZZLog::Log(str); return; } }
#define BMSG_RETURNX(x, str, rtype) { if( !(x) ) { ZZLog::Log(str); ZZLog::Log(str); return (##rtype); } }
#define B(x) { if( !(x) ) { ZZLog::Log(_#x"\n"); ZZLog::Log(#x"\n"); } }
#define B_RETURN(x) { if( !(x) ) { ZZLog::Error_Log("%s:%d: %s", __FILE__, (u32)__LINE__, #x); return; } }
#define B_RETURNX(x, rtype) { if( !(x) ) { ZZLog::Error_Log("%s:%d: %s", __FILE__, (u32)__LINE__, #x); return (##rtype); } }
#define B_G(x, action) { if( !(x) ) { ZZLog::Error_Log("%s:%d: %s", __FILE__, (u32)__LINE__, #x); action; } }
#ifndef OGL4_LOG
#define GL_REPORT_ERROR() \
{ \
GLenum err = glGetError(); \
if( err != GL_NO_ERROR ) \
{ \
ZZLog::Error_Log("%s:%d: gl error %s(0x%x)", __FILE__, (int)__LINE__, error_name(err), err); \
HandleGLError(); \
} \
}
#ifdef _DEBUG
# define GL_REPORT_ERRORD() \
{ \
GLenum err = glGetError(); \
if( err != GL_NO_ERROR ) \
{ \
ZZLog::Error_Log("%s:%d: gl error %s (0x%x)", __FILE__, (int)__LINE__, error_name(err), err); \
/* HandleGLError();*/ \
} \
}
#else
# define GL_REPORT_ERRORD()
#endif
#else
#define GL_REPORT_ERROR()
#define GL_REPORT_ERRORD()
#endif
inline const char *error_name(int err)
{
switch (err)
{
case GL_NO_ERROR:
return "GL_NO_ERROR";
case GL_INVALID_ENUM:
return "GL_INVALID_ENUM";
case GL_INVALID_VALUE:
return "GL_INVALID_VALUE";
case GL_INVALID_OPERATION:
return "GL_INVALID_OPERATION";
case GL_STACK_OVERFLOW:
return "GL_STACK_OVERFLOW";
case GL_STACK_UNDERFLOW:
return "GL_STACK_UNDERFLOW";
case GL_OUT_OF_MEMORY:
return "GL_OUT_OF_MEMORY";
case GL_TABLE_TOO_LARGE:
return "GL_TABLE_TOO_LARGE";
case GL_INVALID_FRAMEBUFFER_OPERATION:
return "GL_INVALID_FRAMEBUFFER_OPERATION";
default:
return "Unknown GL error";
}
}
struct MESSAGE
{
MESSAGE() {}
MESSAGE(const char* p, u32 dw) { strcpy(str, p); dwTimeStamp = dw; }
char str[255];
u32 dwTimeStamp;
};
extern void DrawText(const char* pstr, int left, int top, u32 color);
extern void __LogToConsole(const char *fmt, ...);
extern void ZZAddMessage(const char* pstr, u32 ms = 5000);
extern void StartCapture();
extern void StopCapture();
namespace ZZLog
{
extern bool IsLogging();
void SetDir(const char* dir);
extern void Open();
extern void Close();
extern void Message(const char *fmt, ...);
extern void Log(const char *fmt, ...);
void WriteToScreen(const char* pstr, u32 ms = 5000);
void WriteToScreen2(const char* pstr, ...);
extern void WriteToConsole(const char *fmt, ...);
extern void Print(const char *fmt, ...);
extern void WriteLn(const char *fmt, ...);
extern void Greg_Log(const char *fmt, ...);
extern void Prim_Log(const char *fmt, ...);
extern void GS_Log(const char *fmt, ...);
extern void Debug_Log(const char *fmt, ...);
extern void Dev_Log(const char *fmt, ...);
extern void Warn_Log(const char *fmt, ...);
extern void Error_Log(const char *fmt, ...);
extern void Check_GL_Error();
extern void GL_Error_Log(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message);
};
#endif // ZZLOG_H_INCLUDED

View File

@ -1,617 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include <stdlib.h>
#include <math.h>
#include "GS.h"
#include "Mem.h"
#include "targets.h"
#include "ZZClut.h"
#include "Util.h"
extern int g_TransferredToGPU;
extern int VALIDATE_THRESH;
extern u32 TEXDESTROY_THRESH;
#define FORCE_TEXDESTROY_THRESH (3) // destroy texture after FORCE_TEXDESTROY_THRESH frames
void CMemoryTargetMngr::Destroy()
{
FUNCLOG
listTargets.clear();
listClearedTargets.clear();
}
bool CMemoryTarget::ValidateTex(const tex0Info& tex0, int starttex, int endtex, bool bDeleteBadTex)
{
FUNCLOG
if (clearmaxy == 0) return true;
int checkstarty = max(starttex, clearminy);
int checkendy = min(endtex, clearmaxy);
if (checkstarty >= checkendy) return true;
if (validatecount++ > VALIDATE_THRESH)
{
height = 0;
return false;
}
// lock and compare
assert(ptex != NULL && ptex->memptr != NULL);
int result = memcmp_mmx(ptex->memptr + MemorySize(checkstarty-realy), MemoryAddress(checkstarty), MemorySize(checkendy-checkstarty));
if (result == 0)
{
clearmaxy = 0;
return true;
}
if (!bDeleteBadTex) return false;
// delete clearminy, clearmaxy range (not the checkstarty, checkendy range)
//int newstarty = 0;
if (clearminy <= starty)
{
if (clearmaxy < starty + height)
{
// preserve end
height = starty + height - clearmaxy;
starty = clearmaxy;
assert(height > 0);
}
else
{
// destroy
height = 0;
}
}
else
{
// beginning can be preserved
height = clearminy - starty;
}
clearmaxy = 0;
assert((starty >= realy) && ((starty + height) <= (realy + realheight)));
return false;
}
#define TARGET_THRESH 0x500
extern int g_MaxTexWidth, g_MaxTexHeight; // Maximum height & width of supported texture.
//#define SORT_TARGETS
inline list<CMemoryTarget>::iterator CMemoryTargetMngr::DestroyTargetIter(list<CMemoryTarget>::iterator& it)
{
// find the target and destroy
list<CMemoryTarget>::iterator itprev = it;
++it;
listClearedTargets.splice(listClearedTargets.end(), listTargets, itprev);
if (listClearedTargets.size() > TEXDESTROY_THRESH)
{
listClearedTargets.pop_front();
}
return it;
}
// Compare target to current texture info
// Not same format -> 1
// Same format, not same data (clut only) -> 2
// identical -> 0
int CMemoryTargetMngr::CompareTarget(list<CMemoryTarget>::iterator& it, const tex0Info& tex0, int clutsize)
{
if (PSMT_ISCLUT(it->psm) != PSMT_ISCLUT(tex0.psm))
return 1;
if (PSMT_ISCLUT(tex0.psm)) {
if (it->psm != tex0.psm || it->cpsm != tex0.cpsm || it->clutsize != clutsize)
return 1;
if (PSMT_IS32BIT(tex0.cpsm)) {
if (Cmp_ClutBuffer_SavedClut<u32>((u32*)&it->clut[0], tex0.csa, clutsize))
return 2;
} else {
if (Cmp_ClutBuffer_SavedClut<u16>((u16*)&it->clut[0], tex0.csa, clutsize))
return 2;
}
} else {
if (PSMT_IS16BIT(tex0.psm) != PSMT_IS16BIT(it->psm))
return 1;
}
return 0;
}
void CMemoryTargetMngr::GetClutVariables(int& clutsize, const tex0Info& tex0)
{
clutsize = 0;
if (PSMT_ISCLUT(tex0.psm))
{
int entries = PSMT_IS8CLUT(tex0.psm) ? 256 : 16;
if (PSMT_IS32BIT(tex0.cpsm))
clutsize = min(entries, 256 - tex0.csa * 16) * 4;
else
clutsize = min(entries, 512 - tex0.csa * 16) * 2;
}
}
void CMemoryTargetMngr::GetMemAddress(int& start, int& end, const tex0Info& tex0)
{
int nbStart, nbEnd;
GetRectMemAddressZero(nbStart, nbEnd, tex0.psm, tex0.tw, tex0.th, tex0.tbp0, tex0.tbw);
assert(nbStart < nbEnd);
nbEnd = min(nbEnd, MEMORY_END);
start = nbStart / (4 * GPU_TEXWIDTH);
end = (nbEnd + GPU_TEXWIDTH * 4 - 1) / (4 * GPU_TEXWIDTH);
assert(start < end);
}
CMemoryTarget* CMemoryTargetMngr::SearchExistTarget(int start, int end, int clutsize, const tex0Info& tex0, int forcevalidate)
{
for (list<CMemoryTarget>::iterator it = listTargets.begin(); it != listTargets.end();)
{
if (it->starty <= start && it->starty + it->height >= end)
{
int res = CompareTarget(it, tex0, clutsize);
if (res == 1)
{
if (it->validatecount++ > VALIDATE_THRESH)
{
it = DestroyTargetIter(it);
if (listTargets.size() == 0) break;
}
else
++it;
continue;
}
else if (res == 2)
{
++it;
continue;
}
if (forcevalidate) //&& listTargets.size() < TARGET_THRESH ) {
{
// do more validation checking. delete if not been used for a while
if (!it->ValidateTex(tex0, start, end, curstamp > it->usedstamp + FORCE_TEXDESTROY_THRESH))
{
if (it->height <= 0)
{
it = DestroyTargetIter(it);
if (listTargets.size() == 0) break;
}
else
++it;
continue;
}
}
it->usedstamp = curstamp;
it->validatecount = 0;
return &(*it);
}
#ifdef SORT_TARGETS
else if (it->starty >= end) break;
#endif
++it;
}
return NULL;
}
CMemoryTarget* CMemoryTargetMngr::ClearedTargetsSearch(u32 fmt, int widthmult, int channels, int height)
{
CMemoryTarget* targ = NULL;
if (listClearedTargets.size() > 0)
{
list<CMemoryTarget>::iterator itbest = listClearedTargets.begin();
while (itbest != listClearedTargets.end())
{
if ((height == itbest->realheight) && (itbest->fmt == fmt) && (itbest->widthmult == widthmult) && (itbest->channels == channels))
{
// check channels
if (PIXELS_PER_WORD(itbest->psm) == channels) break;
}
++itbest;
}
if (itbest != listClearedTargets.end())
{
listTargets.splice(listTargets.end(), listClearedTargets, itbest);
targ = &listTargets.back();
targ->validatecount = 0;
}
else
{
// create a new
listTargets.push_back(CMemoryTarget());
targ = &listTargets.back();
}
}
else
{
listTargets.push_back(CMemoryTarget());
targ = &listTargets.back();
}
return targ;
}
CMemoryTarget* CMemoryTargetMngr::GetMemoryTarget(const tex0Info& tex0, int forcevalidate)
{
FUNCLOG
int start, end, clutsize;
GetClutVariables(clutsize, tex0);
GetMemAddress(start, end, tex0);
CMemoryTarget* it = SearchExistTarget(start, end, clutsize, tex0, forcevalidate);
if (it != NULL) return it;
// couldn't find so create
CMemoryTarget* targ;
u32 fmt;
u32 internal_fmt;
if (PSMT_ISHALF_STORAGE(tex0)) {
// RGBA_5551 storage format
fmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;
internal_fmt = GL_RGB5_A1;
} else {
// RGBA_8888 storage format
fmt = GL_UNSIGNED_BYTE;
internal_fmt = GL_RGBA;
}
int widthmult = 1, channels = 1;
// If our texture is too big and could not be placed in 1 GPU texture. Pretty rare in modern cards.
if ((g_MaxTexHeight < 4096) && (end - start > g_MaxTexHeight))
{
// In this rare case we made a texture of half height and place it on the screen.
ZZLog::Debug_Log("Making a half height texture (start - end == 0x%x)", (end-start));
widthmult = 2;
}
channels = PIXELS_PER_WORD(tex0.psm);
targ = ClearedTargetsSearch(fmt, widthmult, channels, end - start);
if (targ->ptex != NULL)
{
assert(end - start <= targ->realheight && targ->fmt == fmt && targ->widthmult == widthmult);
// good enough, so init
targ->realy = targ->starty = start;
targ->usedstamp = curstamp;
targ->psm = tex0.psm;
targ->cpsm = tex0.cpsm;
targ->height = end - start;
} else {
// not initialized yet
targ->fmt = fmt;
targ->realy = targ->starty = start;
targ->realheight = targ->height = end - start;
targ->usedstamp = curstamp;
targ->psm = tex0.psm;
targ->cpsm = tex0.cpsm;
targ->widthmult = widthmult;
targ->channels = channels;
targ->texH = (targ->realheight + widthmult - 1)/widthmult;
targ->texW = GPU_TEXWIDTH * widthmult * channels;
// alloc the mem
targ->ptex = new CMemoryTarget::TEXTURE();
targ->ptex->ref = 1;
}
#if defined(ZEROGS_DEVBUILD)
g_TransferredToGPU += MemorySize(channels * targ->height);
#endif
// fill with data
if (targ->ptex->memptr == NULL)
{
targ->ptex->memptr = (u8*)_aligned_malloc(MemorySize(targ->realheight), 16);
assert(targ->ptex->ref > 0);
}
memcpy(targ->ptex->memptr, MemoryAddress(targ->realy), MemorySize(targ->height));
__aligned16 u8* ptexdata = NULL;
bool has_data = false;
if (PSMT_ISCLUT(tex0.psm))
{
assert(clutsize > 0);
// Local clut parameter
targ->cpsm = tex0.cpsm;
// Allocate a local clut array
targ->clutsize = clutsize;
if(targ->clut == NULL)
targ->clut = (u8*)_aligned_malloc(clutsize, 16);
else {
// In case it could occured
// realloc would be better but you need to get it from libutilies first
// _aligned_realloc is brought in from ScopedAlloc.h now. --arcum42
_aligned_free(targ->clut);
targ->clut = (u8*)_aligned_malloc(clutsize, 16);
}
// texture parameter
ptexdata = (u8*)_aligned_malloc(CLUT_PIXEL_SIZE(tex0.cpsm) * targ->texH * targ->texW, 16);
has_data = true;
u8* psrc = (u8*)(MemoryAddress(targ->realy));
// Fill a local clut then build the real texture
if (PSMT_IS32BIT(tex0.cpsm))
{
ClutBuffer_to_Array<u32>((u32*)targ->clut, tex0.csa, clutsize);
Build_Clut_Texture<u32>(tex0.psm, targ->height, (u32*)targ->clut, psrc, (u32*)ptexdata);
}
else
{
ClutBuffer_to_Array<u16>((u16*)targ->clut, tex0.csa, clutsize);
Build_Clut_Texture<u16>(tex0.psm, targ->height, (u16*)targ->clut, psrc, (u16*)ptexdata);
}
assert(targ->clutsize > 0);
}
else if (tex0.psm == PSMT16Z || tex0.psm == PSMT16SZ)
{
ptexdata = (u8*)_aligned_malloc(4 * targ->texH * targ->texW, 16);
has_data = true;
// needs to be 8 bit, use xmm for unpacking
u16* dst = (u16*)ptexdata;
u16* src = (u16*)(MemoryAddress(targ->realy));
#ifdef ZEROGS_SSE2
assert(((u32)(uptr)dst) % 16 == 0);
__m128i zero_128 = _mm_setzero_si128();
// NOTE: future performance improvement
// SSE4.1 support uncacheable load 128bits. Maybe it can
// avoid some cache pollution
// NOTE2: I create multiple _n variable to mimic the previous ASM behavior
// but I'm not sure there are real gains.
for (int i = targ->height * GPU_TEXWIDTH/16 ; i > 0 ; --i)
{
// Convert 16 bits pixels to 32bits (zero extended)
// Batch 64 bytes (32 pixels) at once.
__m128i pixels_1 = _mm_load_si128((__m128i*)src);
__m128i pixels_2 = _mm_load_si128((__m128i*)(src+8));
__m128i pixels_3 = _mm_load_si128((__m128i*)(src+16));
__m128i pixels_4 = _mm_load_si128((__m128i*)(src+24));
__m128i pix_low_1 = _mm_unpacklo_epi16(pixels_1, zero_128);
__m128i pix_high_1 = _mm_unpackhi_epi16(pixels_1, zero_128);
__m128i pix_low_2 = _mm_unpacklo_epi16(pixels_2, zero_128);
__m128i pix_high_2 = _mm_unpackhi_epi16(pixels_2, zero_128);
// Note: bypass cache
_mm_stream_si128((__m128i*)dst, pix_low_1);
_mm_stream_si128((__m128i*)(dst+8), pix_high_1);
_mm_stream_si128((__m128i*)(dst+16), pix_low_2);
_mm_stream_si128((__m128i*)(dst+24), pix_high_2);
__m128i pix_low_3 = _mm_unpacklo_epi16(pixels_3, zero_128);
__m128i pix_high_3 = _mm_unpackhi_epi16(pixels_3, zero_128);
__m128i pix_low_4 = _mm_unpacklo_epi16(pixels_4, zero_128);
__m128i pix_high_4 = _mm_unpackhi_epi16(pixels_4, zero_128);
// Note: bypass cache
_mm_stream_si128((__m128i*)(dst+32), pix_low_3);
_mm_stream_si128((__m128i*)(dst+40), pix_high_3);
_mm_stream_si128((__m128i*)(dst+48), pix_low_4);
_mm_stream_si128((__m128i*)(dst+56), pix_high_4);
src += 32;
dst += 64;
}
// It is advise to use a fence instruction after non temporal move (mm_stream) instruction...
// store fence insures that previous store are finish before execute new one.
_mm_sfence();
#else // ZEROGS_SSE2
for (int i = 0; i < targ->height; ++i)
{
for (int j = 0; j < GPU_TEXWIDTH; ++j)
{
dst[0] = src[0];
dst[1] = 0;
dst[2] = src[1];
dst[3] = 0;
dst += 4;
src += 2;
}
}
#endif // ZEROGS_SSE2
}
else
{
ptexdata = targ->ptex->memptr;
// We really don't want to deallocate memptr. As a reminder...
has_data = false;
}
// create the texture
GL_REPORT_ERRORD();
assert(ptexdata != NULL);
if (targ->ptex->tex == 0) glGenTextures(1, &targ->ptex->tex);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, targ->ptex->tex);
TextureRect(internal_fmt, targ->texW, targ->texH, GL_RGBA, fmt, ptexdata);
while (glGetError() != GL_NO_ERROR)
{
// release resources until can create
if (listClearedTargets.size() > 0)
{
listClearedTargets.pop_front();
}
else
{
if (listTargets.size() == 0)
{
ZZLog::Error_Log("Failed to create %dx%x texture.", targ->texW, targ->texH);
channels = 1;
if (has_data) _aligned_free(ptexdata);
return NULL;
}
DestroyOldest();
}
TextureRect(internal_fmt, targ->texW, targ->texH, GL_RGBA, fmt, ptexdata);
}
setRectWrap(GL_CLAMP);
if (has_data) _aligned_free(ptexdata);
assert(tex0.psm != 0xd);
return targ;
}
void CMemoryTargetMngr::ClearRange(int nbStartY, int nbEndY)
{
FUNCLOG
int starty = nbStartY / (4 * GPU_TEXWIDTH);
int endy = (nbEndY + 4 * GPU_TEXWIDTH - 1) / (4 * GPU_TEXWIDTH);
for (list<CMemoryTarget>::iterator it = listTargets.begin(); it != listTargets.end();)
{
if (it->starty < endy && (it->starty + it->height) > starty)
{
// intersects, reduce valid texture mem (or totally delete texture)
// there are 4 cases
int miny = max(it->starty, starty);
int maxy = min(it->starty + it->height, endy);
assert(miny < maxy);
if (it->clearmaxy == 0)
{
it->clearminy = miny;
it->clearmaxy = maxy;
}
else
{
if (it->clearminy > miny) it->clearminy = miny;
if (it->clearmaxy < maxy) it->clearmaxy = maxy;
}
}
++it;
}
}
void CMemoryTargetMngr::DestroyCleared()
{
FUNCLOG
for (list<CMemoryTarget>::iterator it = listClearedTargets.begin(); it != listClearedTargets.end();)
{
if (it->usedstamp < curstamp - (FORCE_TEXDESTROY_THRESH -1))
{
it = listClearedTargets.erase(it);
continue;
}
++it;
}
if ((curstamp % FORCE_TEXDESTROY_THRESH) == 0)
{
// purge old targets every FORCE_TEXDESTROY_THRESH frames
for (list<CMemoryTarget>::iterator it = listTargets.begin(); it != listTargets.end();)
{
if (it->usedstamp < curstamp - FORCE_TEXDESTROY_THRESH)
{
it = listTargets.erase(it);
continue;
}
++it;
}
}
++curstamp;
}
void CMemoryTargetMngr::DestroyOldest()
{
FUNCLOG
if (listTargets.size() == 0)
return;
list<CMemoryTarget>::iterator it, itbest;
it = itbest = listTargets.begin();
while (it != listTargets.end())
{
if (it->usedstamp < itbest->usedstamp) itbest = it;
++it;
}
listTargets.erase(itbest);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,921 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
// Realisation of RenderCRTC function ONLY.
// It draw picture direct on screen, so here we have interlacing and frame skipping.
//------------------ Includes
#include "Util.h"
#include "ZZoglCRTC.h"
#include "GLWin.h"
#include "ZZoglShaders.h"
#include "ZZoglShoots.h"
#include "ZZoglDrawing.h"
#include "rasterfont.h" // simple font
#include <math.h>
#include "ZZoglVB.h"
//------------------ Defines
#if !defined(ZEROGS_DEVBUILD)
#define g_bSaveFrame 0
#define g_bSaveFinalFrame 0
#else
bool g_bSaveFrame = 0; // saves the current psurfTarget
bool g_bSaveFinalFrame = 0; // saves the input to the CRTC
#endif // !defined(ZEROGS_DEVBUILD)
extern int maxmin;
extern bool g_bCRTCBilinear;
bool g_bDisplayFPS = false;
int g_nFrameRender = 10, g_nFramesSkipped = 0, s_nResolved = 0; // s_nResolved == number of targets resolved this frame
// Helper for skip frames.
int TimeLastSkip = 0;
vector<u32> s_vecTempTextures; // temporary textures, released at the end of every frame
// Snapshot variables.
extern bool g_bMakeSnapshot;
extern string strSnapshot;
extern void ExtWrite();
extern void ZZDestroy();
extern void ChangeDeviceSize(int nNewWidth, int nNewHeight);
extern GLuint vboRect;
// I'm making this variable global for the moment in the course of fiddling with the interlace code
// to try and make it more straightforward.
int interlace_mode = 0; // 0 - not interlacing, 1 - interlacing.
bool bUsingStencil = false;
bool INTERLACE_COUNT()
{
return (interlace_mode && (gs.interlace == conf.interlace));
}
// Adjusts vertex shader BitBltPos vector v to preserve aspect ratio. It used to emulate 4:3 or 16:9.
void AdjustTransToAspect(float4& v)
{
double temp;
float f;
const float mult = 1 / 32767.0f;
if (conf.width * GLWin.backbuffer.h > conf.height * GLWin.backbuffer.w) // limited by width
{
// change in ratio
f = ((float)GLWin.backbuffer.w / (float)conf.width) / ((float)GLWin.backbuffer.h / (float)conf.height);
v.y *= f;
v.w *= f;
// scanlines mess up when not aligned right
v.y += (1 - (float)modf(v.y * (float)GLWin.backbuffer.h * 0.5f + 0.05f, &temp)) * 2.0f / (float)GLWin.backbuffer.h;
v.w += (1 - (float)modf(v.w * (float)GLWin.backbuffer.h * 0.5f + 0.05f, &temp)) * 2.0f / (float)GLWin.backbuffer.h;
}
else // limited by height
{
f = ((float)GLWin.backbuffer.h / (float)conf.height) / ((float)GLWin.backbuffer.w / (float)conf.width);
f -= (float)modf(f * GLWin.backbuffer.w, &temp) / (float)GLWin.backbuffer.w;
v.x *= f;
v.z *= f;
}
v *= mult;
}
inline bool FrameSkippingHelper()
{
bool ShouldSkip = false;
if (g_nFrameRender > 0)
{
if (g_nFrameRender < 8)
{
g_nFrameRender++;
if (g_nFrameRender <= 3)
{
g_nFramesSkipped++;
ShouldSkip = true;
}
}
}
else
{
if (g_nFrameRender < -1)
{
g_nFramesSkipped++;
ShouldSkip = true;
}
g_nFrameRender--;
}
#if defined _DEBUG
if (timeGetTime() - TimeLastSkip > 15000 && ShouldSkip)
{
ZZLog::Debug_Log("ZZogl Skipped frames.");
TimeLastSkip = timeGetTime();
}
#endif
return ShouldSkip;
}
// helper function for save frame in picture.
inline void FrameSavingHelper()
{
if (g_bSaveFrame)
{
if (vb[0].prndr != NULL)
{
SaveTexture("frame1.tga", GL_TEXTURE_RECTANGLE_NV, vb[0].prndr->ptex, RW(vb[0].prndr->fbw), RH(vb[0].prndr->fbh));
}
if (vb[1].prndr != NULL && vb[0].prndr != vb[1].prndr)
{
SaveTexture("frame2.tga", GL_TEXTURE_RECTANGLE_NV, vb[1].prndr->ptex, RW(vb[1].prndr->fbw), RH(vb[1].prndr->fbh));
}
#ifdef _WIN32
else
{
DeleteFile(L"frame2.tga");
}
#endif
}
}
// Function populated tex0Info[2] array
inline void FrameObtainDispinfo(tex0Info* dispinfo)
{
for (int i = 0; i < 2; ++i)
{
if (!Circuit_Enabled(i))
{
dispinfo[i].tw = 0;
dispinfo[i].th = 0;
continue;
}
GSRegDISPFB* pfb = Dispfb_Reg(i);
GSRegDISPLAY* pd = Display_Reg(i);
int magh = pd->MAGH + 1;
int magv = pd->MAGV + 1;
dispinfo[i].tbp0 = pfb->FBP << 5;
dispinfo[i].tbw = pfb->FBW << 6;
dispinfo[i].tw = (pd->DW + 1) / magh;
dispinfo[i].th = (pd->DH + 1) / magv;
dispinfo[i].psm = pfb->PSM;
// hack!!
// 2 * dispinfo[i].tw / dispinfo[i].th <= 1, metal slug 4
// Note: This is what causes the double image if interlace is off on the Final Fantasy X-2 opening.
if (interlace_mode && 2 * dispinfo[i].tw / dispinfo[i].th <= 1 && !(conf.settings().interlace_2x))
{
dispinfo[i].th >>= 1;
}
}
}
extern bool s_bWriteDepth;
// Something should be done before Renderering the picture.
inline void RenderStartHelper()
{
if (conf.mrtdepth && ZZshExistProgram(pvs[8]))
{
conf.mrtdepth = 0;
s_bWriteDepth = false;
ZZLog::Debug_Log("Disabling MRT depth writing\n");
}
FlushBoth();
FrameSavingHelper();
if (s_RangeMngr.ranges.size() > 0) FlushTransferRanges(NULL);
SetShaderCaller("RenderStartHelper");
// reset fba after every frame
vb[0].fba.fba = 0;
vb[1].fba.fba = 0;
FB::Unbind(); // switch to the backbuffer
glViewport(0, 0, GLWin.backbuffer.w, GLWin.backbuffer.h);
// if interlace, only clear every other vsync
if (!interlace_mode)
{
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
ZZshSetVertexShader(pvsBitBlt.prog);
glBindBuffer(GL_ARRAY_BUFFER, vboRect);
SET_STREAM();
GL_REPORT_ERRORD();
if (conf.wireframe()) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
DisableAllgl();
GL_REPORT_ERRORD();
if (interlace_mode) g_PrevBitwiseTexX = -1; // reset since will be using
}
// Settings for interlace texture multiplied vector;
// The idea is: (x, y) -- position on screen, then interlaced texture get F = 1 or 0 depending
// on image y coords. So if we write valpha.z * F + valpha.w + 0.5, it would be switching odd
// and even strings at each frame.
// valpha.x and y are used for image blending.
inline void RenderGetForClip(int psm, CRTC_TYPE render_type)
{
SetShaderCaller("RenderGetForClip");
FRAGMENTSHADER* prog = curr_pps(render_type);
float4 valpha;
// first render the current render targets, then from ptexMem
if (psm == PSMCT24)
{
valpha.x = 1;
valpha.y = 0;
}
else
{
valpha.x = 0;
valpha.y = 1;
}
if (interlace_mode)
{
if (gs.interlace == (conf.interlace & 1))
{
// pass if odd
valpha.z = 1.0f;
valpha.w = -0.4999f;
}
else
{
// pass if even
valpha.z = -1.0f;
valpha.w = 0.5001f;
}
}
else
{
// always pass interlace test
valpha.z = 0;
valpha.w = 1;
}
ZZshSetParameter4fv(prog->prog, prog->sOneColor, valpha, "g_fOneColor");
}
// Put interlaced texture in use for shader prog.
// Note: if the frame is interlaced, its th is halved, so we should multiply it by 2.
inline void RenderCreateInterlaceTex(int th, CRTC_TYPE render_type)
{
FRAGMENTSHADER* prog;
int interlacetex;
if (!interlace_mode) return;
prog = curr_pps(render_type);
interlacetex = CreateInterlaceTex(2 * th);
ZZshGLSetTextureParameter(prog->prog, prog->sInterlace, interlacetex, "Interlace");
}
// Do blending setup prior to second pass of half-frame drawing.
inline void RenderSetupBlending()
{
// setup right blending
glEnable(GL_BLEND);
zgsBlendEquationSeparateEXT(GL_FUNC_ADD, GL_FUNC_ADD);
if (PMODE->MMOD)
{
// Use the ALP register for alpha blending.
glBlendColorEXT(PMODE->ALP*(1 / 255.0f), PMODE->ALP*(1 / 255.0f), PMODE->ALP*(1 / 255.0f), 0.5f);
s_srcrgb = GL_CONSTANT_COLOR_EXT;
s_dstrgb = GL_ONE_MINUS_CONSTANT_COLOR_EXT;
}
else
{
// Use the alpha value of circuit 1 for alpha blending.
s_srcrgb = GL_SRC_ALPHA;
s_dstrgb = GL_ONE_MINUS_SRC_ALPHA;
}
if (PMODE->AMOD)
{
s_srcalpha = GL_ZERO;
s_dstalpha = GL_ONE;
}
else
{
s_srcalpha = GL_ONE;
s_dstalpha = GL_ZERO;
}
zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha);
}
// each frame could be drawn in two stages, so blending should be different for them
inline void RenderSetupStencil(int i)
{
s_stencilmask = 1 << i;
glStencilMask(s_stencilmask);
GL_STENCILFUNC_SET();
}
// do stencil check for each found target i -- texturing stage
inline void RenderUpdateStencil(int i)
{
if (!bUsingStencil)
{
glClear(GL_STENCIL_BUFFER_BIT);
bUsingStencil = true;
}
glEnable(GL_STENCIL_TEST);
GL_STENCILFUNC(GL_NOTEQUAL, 3, 1 << i);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilMask(1 << i);
}
// CRTC24 could not be rendered
/*inline void RenderCRTC24helper(int psm)
{
ZZLog::Debug_Log("ZZogl: CRTC24!!! I'm trying to show something.");
SetShaderCaller("RenderCRTC24helper");
// assume that data is already in ptexMem (do Resolve?)
RenderGetForClip(psm, CRTC_RENDER_24);
ZZshSetPixelShader(curr_ppsCRTC24()->prog);
DrawTriangleArray();
}*/
// Maybe I do this function global-defined. Calculate bits per pixel for
// each psm. It's the only place with PSMCT16 which have a different bpp.
// FIXME: check PSMCT16S
inline int RenderGetBpp(int psm)
{
if (psm == PSMCT16S)
{
//ZZLog::Debug_Log("ZZogl: 16S target.");
return 3;
}
if (PSMT_ISHALF(psm)) return 2;
return 4;
}
// We want to draw ptarg on screen, that could be disaligned to viewport.
// So we do aligning it by height.
inline int RenderGetOffsets(int* dby, int* movy, tex0Info& texframe, CRenderTarget* ptarg, int bpp)
{
*dby += (256 / bpp) * (texframe.tbp0 - ptarg->fbp) / texframe.tbw;
if (*dby < 0)
{
*movy = -*dby;
*dby = 0;
}
return min(ptarg->fbh - *dby, texframe.th - *movy);
}
// BltBit shader calculate vertex (4 coord's pixel) position at the viewport.
inline float4 RenderSetTargetBitPos(int dh, int th, int movy)
{
SetShaderCaller("RenderSetTargetBitPos");
float4 v;
// dest rect
v.x = 1;
v.y = dh / (float)th;
v.z = 0;
v.w = 1 - v.y;
if (movy > 0) v.w -= movy / (float)th;
AdjustTransToAspect(v);
if (INTERLACE_COUNT())
{
// move down by 1 pixel
v.w += 1.0f / (float)dh ;
}
ZZshSetParameter4fv(pvsBitBlt.prog, pvsBitBlt.sBitBltPos, v, "g_fBitBltPos");
return v;
}
// Important stuff. We could use these coordinates to change viewport position on the frame.
// For example, use tw / X and tw / X magnify the viewport.
// Interlaced output is little out of VB, it could be seen as an evil blinking line on top
// and bottom, so we try to remove it.
inline float4 RenderSetTargetBitTex(float th, float tw, float dh, float dw)
{
SetShaderCaller("RenderSetTargetBitTex");
float4 v;
v = float4(th, tw, dh, dw);
// Incorrect Aspect ratio on interlaced frames
if (INTERLACE_COUNT())
{
v.y -= 1.0f / conf.height;
v.w += 1.0f / conf.height;
}
ZZshSetParameter4fv(pvsBitBlt.prog, pvsBitBlt.sBitBltTex, v, "g_fBitBltTex");
return v;
}
// Translator for POSITION coordinates (-1.0:+1.0f at x axis, +1.0f:-1.0y at y) into target frame ones.
// We don't need x coordinate, because interlacing is y-axis only.
inline float4 RenderSetTargetBitTrans(int th)
{
SetShaderCaller("RenderSetTargetBitTrans");
float4 v = float4(float(th), -float(th), float(th), float(th));
ZZshSetParameter4fv(pvsBitBlt.prog, pvsBitBlt.fBitBltTrans, v, "g_fBitBltTrans");
return v;
}
// use g_fInvTexDims to store inverse texture dims
// Seems, that Targ shader does not use it
inline float4 RenderSetTargetInvTex(int tw, int th, CRTC_TYPE render_type)
{
SetShaderCaller("RenderSetTargetInvTex");
FRAGMENTSHADER* prog = curr_pps(render_type);
float4 v = float4(0, 0, 0, 0);
if (prog->sInvTexDims)
{
v.x = 1.0f / (float)tw;
v.y = 1.0f / (float)th;
v.z = (float)0.0;
v.w = -0.5f / (float)th;
ZZshSetParameter4fv(prog->prog, prog->sInvTexDims, v, "g_fInvTexDims");
}
return v;
}
// Metal Slug 5 hack (as was written). If target tbp not equal to framed fbp, than we look for a better possibility,
// Note, than after true result iterator it could not be used.
inline bool RenderLookForABetterTarget(int fbp, int tbp, list<CRenderTarget*>& listTargs, list<CRenderTarget*>::iterator& it)
{
if (fbp == tbp) return false;
// look for a better target (metal slug 5)
list<CRenderTarget*>::iterator itbetter;
for (itbetter = listTargs.begin(); itbetter != listTargs.end(); ++itbetter)
{
if ((*itbetter)->fbp == tbp) break;
}
if (itbetter != listTargs.end())
{
it = listTargs.erase(it);
return true;
}
return false;
}
inline void RenderCheckForMemory(tex0Info& texframe, list<CRenderTarget*>& listTargs, int circuit);
// First try to draw frame from targets.
inline void RenderCheckForTargets(tex0Info& texframe, list<CRenderTarget*>& listTargs, int circuit)
{
// get the start and end addresses of the buffer
int bpp = RenderGetBpp(texframe.psm);
GSRegDISPFB* pfb = Dispfb_Reg(circuit);
int start, end;
int tex_th = (interlace_mode) ? texframe.th * 2 : texframe.th;
//ZZLog::WriteLn("Render checking for targets, circuit %d", circuit);
GetRectMemAddressZero(start, end, texframe.psm, texframe.tw, tex_th, texframe.tbp0, texframe.tbw);
// We need share list of targets between functions
s_RTs.GetTargs(start, end, listTargs);
for (list<CRenderTarget*>::iterator it = listTargs.begin(); it != listTargs.end();)
{
CRenderTarget* ptarg = *it;
if (ptarg->fbw == texframe.tbw && !(ptarg->status&CRenderTarget::TS_NeedUpdate) && ((256 / bpp)*(texframe.tbp0 - ptarg->fbp)) % texframe.tbw == 0)
{
FRAGMENTSHADER* pps;
int dby = pfb->DBY;
int movy = 0;
if (RenderLookForABetterTarget(ptarg->fbp, texframe.tbp0, listTargs, it))
{
continue;
}
if (g_bSaveFinalFrame) SaveTexture("frame1.tga", GL_TEXTURE_RECTANGLE_NV, ptarg->ptex, RW(ptarg->fbw), RH(ptarg->fbh));
// determine the rectangle to render
int dh = RenderGetOffsets(&dby, &movy, texframe, ptarg, bpp);
if (dh >= 64)
{
if (ptarg->fbh - dby < tex_th - movy && !bUsingStencil)
{
RenderUpdateStencil(circuit);
}
else if (ptarg->fbh - dby > 2 * ( tex_th - movy )) // I'm not sure this is needed any more.
{
// Sometimes calculated position onscreen is misaligned, ie in FFX-2 intro. In such case some part of image are out of
// border's and we should move it manually.
dby -= ((ptarg->fbh - dby) >> 2) - ((tex_th + movy) >> 1);
}
SetShaderCaller("RenderCheckForTargets");
// Texture
float4 v = RenderSetTargetBitTex((float)RW(texframe.tw), (float)RH(dh), (float)RW(pfb->DBX), (float)RH(dby));
// dest rect
v = RenderSetTargetBitPos(dh, texframe.th, movy);
v = RenderSetTargetBitTrans(ptarg->fbh);
v = RenderSetTargetInvTex(texframe.tbw, ptarg->fbh, CRTC_RENDER_TARG); // FIXME. This is no use
RenderGetForClip(texframe.psm, CRTC_RENDER_TARG);
pps = curr_ppsCRTCTarg();
// inside vb[0]'s target area, so render that region only
ZZshGLSetTextureParameter(pps->prog, pps->sFinal, ptarg->ptex, "CRTC target");
RenderCreateInterlaceTex(texframe.th, CRTC_RENDER_TARG);
ZZshSetPixelShader(pps->prog);
DrawTriangleArray();
if (abs(dh - (int)texframe.th) <= 1)
{
return;
}
if (abs(dh - (int)ptarg->fbh) <= 1)
{
it = listTargs.erase(it);
continue;
}
}
}
++it;
}
RenderCheckForMemory(texframe, listTargs, circuit);
}
// The same as the previous, but from memory.
// If you ever wondered why a picture from a minute ago suddenly flashes on the screen (say, in Mana Khemia),
// this is the function that does it.
inline void RenderCheckForMemory(tex0Info& texframe, list<CRenderTarget*>& listTargs, int circuit)
{
float4 v;
for (list<CRenderTarget*>::iterator it = listTargs.begin(); it != listTargs.end(); ++it)
{
(*it)->Resolve();
}
// context has to be 0
if (interlace_mode >= 2) ZZLog::Error_Log("CRCR Check for memory shader fault.");
//if (!bUsingStencil) RenderUpdateStencil(i);
SetShaderCaller("RenderCheckForMemory");
float w1, h1, w2, h2;
if (g_bCRTCBilinear)
{
w1 = texframe.tw;
h1 = texframe.th;
w2 = -0.5f;
h2 = -0.5f;
SetTexVariablesInt(0, 2, texframe, false, curr_ppsCRTC(), 1);
}
else
{
w1 = 1;
h1 = 1;
w2 = -0.5f / (float)texframe.tw;
h2 = -0.5f / (float)texframe.th;
SetTexVariablesInt(0, 0, texframe, false, curr_ppsCRTC(), 1);
}
if (g_bSaveFinalFrame) SaveTex(&texframe, g_bSaveFinalFrame - 1 > 0);
// Fixme: Why is this here?
// We should probably call RenderSetTargetBitTex instead.
v = RenderSetTargetBitTex(w1, h1, w2, h2);
// finally render from the memory (note that the stencil buffer will keep previous regions)
v = RenderSetTargetBitPos(1, 1, 0);
v = RenderSetTargetBitTrans(texframe.th);
v = RenderSetTargetInvTex(texframe.tw, texframe.th, CRTC_RENDER);
RenderGetForClip(texframe.psm, CRTC_RENDER);
ZZshGLSetTextureParameter(curr_ppsCRTC()->prog, curr_ppsCRTC()->sMemory, vb[0].pmemtarg->ptex->tex, "CRTC memory");
RenderCreateInterlaceTex(texframe.th, CRTC_RENDER);
ZZshSetPixelShader(curr_ppsCRTC()->prog);
DrawTriangleArray();
}
extern RasterFont* font_p;
void DrawText(const char* pstr, int left, int top, u32 color)
{
FUNCLOG
ZZshGLDisableProfile();
float4 v;
v.SetColor(color);
glColor3f(v.z, v.y, v.x);
font_p->printString(pstr, left * 2.0f / (float)GLWin.backbuffer.w - 1, 1 - top * 2.0f / (float)GLWin.backbuffer.h, 0);
ZZshGLEnableProfile();
}
// Put FPS counter on screen (not in window title)
inline void DisplayFPS()
{
char str[64];
int left = 10, top = 15;
sprintf(str, "%.1f fps", fFPS);
DrawText(str, left + 1, top + 1, 0xff000000);
DrawText(str, left, top, 0xffc0ffff);
}
// Snapshot helper
inline void MakeSnapshot()
{
if (!g_bMakeSnapshot) return;
char str[64];
int left = 200, top = 15;
sprintf(str, "ZeroGS %d.%d.%d - %.1f fps %s", zgsrevision, zgsbuild, zgsminor, fFPS, s_frameskipping ? " - frameskipping" : "");
DrawText(str, left + 1, top + 1, 0xff000000);
DrawText(str, left, top, 0xffc0ffff);
if (SaveRenderTarget(strSnapshot != "" ? strSnapshot.c_str() : "temp.jpg", GLWin.backbuffer.w, -GLWin.backbuffer.h, 0)) //(conf.options.tga_snap)?0:1) ) {
{
char str[255];
sprintf(str, "saved %s\n", strSnapshot.c_str());
ZZAddMessage(str, 500);
}
g_bMakeSnapshot = false;
}
// call to destroy video resources
void ZZReset()
{
FUNCLOG
s_RTs.ResolveAll();
s_DepthRTs.ResolveAll();
vb[0].nCount = 0;
vb[1].nCount = 0;
memset(s_nResolveCounts, 0, sizeof(s_nResolveCounts));
s_nLastResolveReset = 0;
icurctx = -1;
g_vsprog = g_psprog = sZero;
ZZGSStateReset();
ZZDestroy();
//clear_drawfn();
if (ZZKick != NULL) delete ZZKick;
}
// Put new values on statistic variable
inline void CountStatistics()
{
if (s_nWriteDepthCount > 0)
{
assert(conf.mrtdepth);
if (--s_nWriteDepthCount <= 0)
{
s_bWriteDepth = false;
}
}
if (s_nWriteDestAlphaTest > 0)
{
if (--s_nWriteDestAlphaTest <= 0)
{
s_bDestAlphaTest = false;
}
}
if (g_nDepthUsed > 0) --g_nDepthUsed;
s_ClutResolve = 0;
g_nDepthUpdateCount = 0;
}
// This all could be easily forefeit
inline void AfterRendererUnimportantJob()
{
ProcessMessages();
if (g_bDisplayFPS) DisplayFPS();
// Swapping buffers, so we could use another window
GLWin.SwapGLBuffers();
// clear all targets
if (conf.wireframe()) s_nWireframeCount = 1;
if (g_bMakeSnapshot) MakeSnapshot();
CaptureFrame();
CountStatistics();
if (s_nNewWidth >= 0 && s_nNewHeight >= 0)
{
// If needed reset
ZZReset();
ChangeDeviceSize(s_nNewWidth, s_nNewHeight);
s_nNewWidth = s_nNewHeight = -1;
}
maxmin = 608;
}
// Swich Framebuffers
inline void AfterRendererSwitchBackToTextures()
{
FB::Bind();
g_MemTargs.DestroyCleared();
if (s_vecTempTextures.size() > 0)
glDeleteTextures((GLsizei)s_vecTempTextures.size(), &s_vecTempTextures[0]);
s_vecTempTextures.clear();
if (EXTWRITE->WRITE & 1)
{
ZZLog::Warn_Log("EXTWRITE!");
ExtWrite();
EXTWRITE->WRITE = 0;
}
if (conf.wireframe()) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glEnable(GL_SCISSOR_TEST);
if (icurctx >= 0)
{
vb[icurctx].bVarsSetTarg = false;
vb[icurctx].bVarsTexSync = false;
vb[0].bVarsTexSync = false;
}
}
// Reset Targets Helper, for hack.
inline void AfterRendererAutoresetTargets()
{
if (conf.settings().auto_reset)
{
s_nResolveCounts[s_nCurResolveIndex] = s_nResolved;
s_nCurResolveIndex = (s_nCurResolveIndex + 1) % ArraySize(s_nResolveCounts);
int total = 0;
for (u32 i = 0; i < ArraySize(s_nResolveCounts); ++i) total += s_nResolveCounts[i];
if (total / ArraySize(s_nResolveCounts) > 3)
{
if (s_nLastResolveReset > (int)(fFPS * 8))
{
// reset
ZZLog::Error_Log("Video memory reset.");
s_nLastResolveReset = 0;
memset(s_nResolveCounts, 0, sizeof(s_nResolveCounts));
s_RTs.ResolveAll();
return;
}
}
s_nLastResolveReset++;
}
if (s_nResolved > 8)
s_nResolved = 2;
else if (s_nResolved > 0)
--s_nResolved;
}
int count = 0;
// The main renderer function
void RenderCRTC()
{
tex0Info dispinfo[2];
if (FrameSkippingHelper()) return;
// If we are in frame mode and interlacing, and we haven't forced interlacing off, interlace_mode is 1.
interlace_mode = SMODE2->INT && SMODE2->FFMD && (conf.interlace < 2);
bUsingStencil = false;
RenderStartHelper();
FrameObtainDispinfo(dispinfo);
// start from the last circuit
for (int i = !PMODE->SLBG; i >= 0; --i)
{
if (!Circuit_Enabled(i)) continue;
tex0Info& texframe = dispinfo[i];
// I don't think this is neccessary, now that we make sure the ciruit we are working with is enabled.
//
// Actually it seems there are still empty frame in some games (persona 4 and tales of abyss). I'm not sure it
// is normal, for the moment keep the check to avoid some undefined behavior. -- Gregory
if (texframe.th <= 1) continue;
if (SMODE2->INT && SMODE2->FFMD)
{
texframe.th >>= 1;
// Final Fantasy X-2 issue here.
/*if (conf.interlace == 2 && texframe.th >= 512)
{
texframe.th >>= 1;
}*/
}
if (i == 0) RenderSetupBlending();
if (bUsingStencil) RenderSetupStencil(i);
/*if (texframe.psm == 0x12) // Probably broken - 0x12 isn't a valid psm. 24 bit is 1.
{
RenderCRTC24helper(texframe.psm);
continue;
}*/
// We shader targets between two functions, so declare it here;
list<CRenderTarget*> listTargs;
// if we could not draw image from target's, do it from memory
RenderCheckForTargets(texframe, listTargs, i);
}
GL_REPORT_ERRORD();
glDisable(GL_BLEND);
AfterRendererUnimportantJob();
AfterRendererSwitchBackToTextures();
AfterRendererAutoresetTargets();
}

View File

@ -1,89 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef ZZOGLCRTC_H_INCLUDED
#define ZZOGLCRTC_H_INCLUDED
#include <stdlib.h>
#include "targets.h"
extern int s_frameskipping;
extern float fFPS;
extern unsigned char zgsrevision, zgsbuild, zgsminor;
extern int s_nWriteDepthCount;
extern int s_nWireframeCount;
extern int s_nWriteDestAlphaTest;
extern int g_PrevBitwiseTexX, g_PrevBitwiseTexY; // textures stored in SAMP_BITWISEANDX and SAMP_BITWISEANDY
extern bool s_bDestAlphaTest;
extern int s_ClutResolve;
extern int s_nLastResolveReset;
extern int g_nDepthUpdateCount;
extern int s_nResolveCounts[30]; // resolve counts for last 30 frames
static int s_nCurResolveIndex = 0;
extern int g_nDepthUsed; // ffx2 pal movies
//------------------ Namespace
extern u32 s_ptexInterlace; // holds interlace fields
extern int s_nNewWidth, s_nNewHeight;
extern CRangeManager s_RangeMngr; // manages overwritten memory
extern void FlushTransferRanges(const tex0Info* ptex);
extern void ProcessMessages();
void AdjustTransToAspect(float4& v);
void ZZGSStateReset();
// Interlace texture is lazy 1*(height) array of 1 and 0.
// If its height (named s_nInterlaceTexWidth here) is hanging we must redo
// the texture.
// FIXME: If this function were spammed too often, we could use
// width < s_nInterlaceTexWidth as correct for old texture
static int s_nInterlaceTexWidth = 0; // width of texture
inline u32 CreateInterlaceTex(int width)
{
if (width == s_nInterlaceTexWidth && s_ptexInterlace != 0) return s_ptexInterlace;
SAFE_RELEASE_TEX(s_ptexInterlace);
s_nInterlaceTexWidth = width;
vector<u32> data(width);
for (int i = 0; i < width; ++i)
{
data[i] = (i & 1) ? 0xffffffff : 0;
}
glGenTextures(1, &s_ptexInterlace);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, s_ptexInterlace);
TextureRect(GL_RGBA, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
setRectFilters(GL_NEAREST);
GL_REPORT_ERRORD();
return s_ptexInterlace;
}
#endif // ZZOGLCRTC_H_INCLUDED

View File

@ -1,846 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
// Create and Destroy function. They would be called once per session.
//------------------ Includes
#include "GS.h"
#include "Mem.h"
#include "GLWin.h"
#include "ZZoglShaders.h"
#include "targets.h"
#include "rasterfont.h" // simple font
#include "ZZoglDrawing.h"
#include "ZZoglVB.h"
// This include for windows resource file with Shaders
#ifdef _WIN32
# include "Win32.h"
#endif
// ----------------- Types
map<string, GLbyte> mapGLExtensions;
extern bool ZZshLoadExtraEffects();
GLuint vboRect = 0;
GLuint g_vboBuffers[VB_NUMBUFFERS]; // VBOs for all drawing commands
u32 g_nCurVBOIndex = 0;
inline bool CreateImportantCheck();
inline void CreateOtherCheck();
inline bool CreateOpenShadersFile();
void ZZGSStateReset();
//------------------ Dummies
#ifdef _WIN32
void __stdcall glBlendFuncSeparateDummy(GLenum e1, GLenum e2, GLenum e3, GLenum e4)
#else
void APIENTRY glBlendFuncSeparateDummy(GLenum e1, GLenum e2, GLenum e3, GLenum e4)
#endif
{
glBlendFunc(e1, e2);
}
#ifdef _WIN32
void __stdcall glBlendEquationSeparateDummy(GLenum e1, GLenum e2)
#else
void APIENTRY glBlendEquationSeparateDummy(GLenum e1, GLenum e2)
#endif
{
glBlendEquation(e1);
}
#ifdef _WIN32
extern HINSTANCE hInst;
void (__stdcall *zgsBlendEquationSeparateEXT)(GLenum, GLenum) = NULL;
void (__stdcall *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum) = NULL;
#else
void (APIENTRY *zgsBlendEquationSeparateEXT)(GLenum, GLenum) = NULL;
void (APIENTRY *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum) = NULL;
#endif
//------------------ variables
////////////////////////////
// State parameters
extern u8* s_lpShaderResources;
// String's for shader file in developer mode
//#ifdef ZEROGS_DEVBUILD
char EFFECT_NAME[256];
char EFFECT_DIR[256];
//#endif
/////////////////////
// graphics resources
GLenum s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha; // set by zgsBlendFuncSeparateEXT
u32 s_stencilfunc, s_stencilref, s_stencilmask;
GLenum s_drawbuffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
u32 ptexLogo = 0;
int nLogoWidth, nLogoHeight;
u32 s_ptexInterlace = 0; // holds interlace fields
static bool vb_buffer_allocated = false;
//------------------ Global Variables
int GPU_TEXWIDTH = 512;
float g_fiGPU_TEXWIDTH = 1/512.0f;
int g_MaxTexWidth = 4096, g_MaxTexHeight = 4096;
namespace FB
{
u32 buf = 0;
};
RasterFont* font_p = NULL;
float g_fBlockMult = 1;
//int s_nFullscreen = 0;
u32 ptexBlocks = 0, ptexConv16to32 = 0; // holds information on block tiling
u32 ptexBilinearBlocks = 0;
u32 ptexConv32to16 = 0;
// int g_nDepthBias = 0;
extern void Delete_Avi_Capture();
extern void ZZDestroy();
extern void SetAA(int mode);
//------------------ Code
///< returns true if the the opengl extension is supported
bool IsGLExt(const char* szTargetExtension)
{
return mapGLExtensions.find(string(szTargetExtension)) != mapGLExtensions.end();
}
inline bool check_gl_version(uint32 major, uint32 minor) {
const GLubyte* s;
s = glGetString(GL_VERSION);
if (s == NULL) return false;
ZZLog::Error_Log("Supported Opengl version: %s on GPU: %s. Vendor: %s\n", s, glGetString(GL_RENDERER), glGetString(GL_VENDOR));
// Could be useful to detect the GPU vendor:
// if ( strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc.") == 0 )
GLuint dot = 0;
while (s[dot] != '\0' && s[dot] != '.') dot++;
if (dot == 0) return false;
GLuint major_gl = s[dot-1]-'0';
GLuint minor_gl = s[dot+1]-'0';
if ( (major_gl < major) || ( major_gl == major && minor_gl < minor ) ) {
ZZLog::Error_Log("OPENGL %d.%d is not supported\n", major, minor);
return false;
}
return true;
}
// Function asks about different OGL extensions, that are required to setup accordingly. Return false if checks failed
inline bool CreateImportantCheck()
{
bool bSuccess = true;
#ifndef _WIN32
int const glew_ok = glewInit();
if (glew_ok != GLEW_OK) {
ZZLog::Error_Log("glewInit() is not ok!");
// Better exit now, any openGL call will segfault.
return false;
}
#endif
// Require a minimum of openGL2.0 (first version that support hardware shader)
bSuccess &= check_gl_version(2, 0);
// GL_EXT_framebuffer_object -> GL3.0
// Opensource driver -> Intel OK. Radeon need EXT_packed_depth_stencil
if (!IsGLExt("GL_EXT_framebuffer_object"))
{
ZZLog::Error_Log("*********\nZZogl: ERROR: Need GL_EXT_framebuffer_object for multiple render targets\nZZogl: *********");
bSuccess = false;
}
bSuccess &= ZZshCheckProfilesSupport();
return bSuccess;
}
// This is a check for less important open gl extensions.
inline void CreateOtherCheck()
{
// GL_EXT_blend_equation_separate -> GL2.0
// Opensource driver -> Intel OK. Radeon OK.
zgsBlendEquationSeparateEXT = glBlendEquationSeparateEXT;
// GL_EXT_blend_func_separate -> GL1.4
// Opensource driver -> Intel OK. Radeon OK.
zgsBlendFuncSeparateEXT = glBlendFuncSeparateEXT;
// GL_ARB_draw_buffers -> GL2.0
// Opensource driver -> Intel (need gen4). Radeon OK.
if (glDrawBuffers == NULL) {
ZZLog::Error_Log("*********\nZZogl: OGL ERROR: multiple render targets not supported, some effects might look bad\nZZogl: *********");
conf.mrtdepth = 0;
}
GLint Max_Texture_Size_NV = 0;
GLint Max_Texture_Size_2d = 0;
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_NV, &Max_Texture_Size_NV);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &Max_Texture_Size_2d);
g_MaxTexHeight = min(Max_Texture_Size_2d, Max_Texture_Size_NV);
ZZLog::Error_Log("Maximum texture size is %d for Tex_2d and %d for Tex_NV.", Max_Texture_Size_2d, Max_Texture_Size_NV);
if (Max_Texture_Size_NV < 1024)
ZZLog::Error_Log("Could not properly make bitmasks, so some textures will be missed.");
#ifdef _WIN32
GLWin.InitVsync(IsGLExt("WGL_EXT_swap_control") || IsGLExt("EXT_swap_control"));
#else
GLWin.InitVsync(IsGLExt("GLX_SGI_swap_control"));
#endif
GLWin.SetVsync(false);
}
#ifdef _WIN32
__forceinline bool LoadShadersFromRes()
{
HRSRC hShaderSrc = FindResource(hInst, MAKEINTRESOURCE(IDR_SHADERS), RT_RCDATA);
assert(hShaderSrc != NULL);
HGLOBAL hShaderGlob = LoadResource(hInst, hShaderSrc);
assert(hShaderGlob != NULL);
s_lpShaderResources = (u8*)LockResource(hShaderGlob);
return true;
}
#else
__forceinline bool LoadShadersFromDat()
{
FILE* fres = fopen("ps2hw.dat", "rb");
if (fres == NULL)
{
fres = fopen("plugins/ps2hw.dat", "rb");
if (fres == NULL)
{
// Each linux distributions have his rules for path so we give them the possibility to
// change it with compilation flags. -- Gregory
#ifdef PLUGIN_DIR_COMPILATION
#define xPLUGIN_DIR_str(s) PLUGIN_DIR_str(s)
#define PLUGIN_DIR_str(s) #s
const std::string shader_file = string(xPLUGIN_DIR_str(PLUGIN_DIR_COMPILATION)) + "/ps2hw.dat";
fres = fopen(shader_file.c_str(), "rb");
#endif
if (fres == NULL)
{
ZZLog::Error_Log("Cannot find ps2hw.dat in working directory. Exiting.");
return false;
}
}
}
fseek(fres, 0, SEEK_END);
size_t s = ftell(fres);
s_lpShaderResources = new u8[s+1];
fseek(fres, 0, SEEK_SET);
if (fread(s_lpShaderResources, s, 1, fres) == 0)
fprintf(stderr, "Failed to read ps2hw.dat. Corrupted file?\n");
s_lpShaderResources[s] = 0;
fclose(fres);
return true;
}
#ifdef DEVBUILD
__forceinline bool LoadShadersFromFX()
{
// test if ps2hw.fx exists
char tempstr[255];
char curwd[255];
getcwd(curwd, ArraySize(curwd));
strcpy(tempstr, "/plugins/");
sprintf(EFFECT_NAME, "%sps2hw.fx", tempstr);
FILE* f = fopen(EFFECT_NAME, "r");
if (f == NULL)
{
strcpy(tempstr, "../../plugins/zzogl-pg/opengl/");
sprintf(EFFECT_NAME, "%sps2hw.fx", tempstr);
f = fopen(EFFECT_NAME, "r");
if (f == NULL)
{
ZZLog::Error_Log("Failed to find %s, try compiling a non-devbuild.", EFFECT_NAME);
return false;
}
}
fclose(f);
sprintf(EFFECT_DIR, "%s/%s", curwd, tempstr);
sprintf(EFFECT_NAME, "%sps2hw.fx", EFFECT_DIR);
return true;
}
#endif
#endif
// open shader file according to build target
inline bool CreateOpenShadersFile()
{
#ifndef DEVBUILD
# ifdef _WIN32
return LoadShadersFromRes();
# else // not _WIN32
return LoadShadersFromDat();
# endif // _WIN32
#else // defined(ZEROGS_DEVBUILD)
# ifndef _WIN32 // NOT WINDOWS
return LoadShadersFromFX();
// No else clause?
#endif
#endif // !defined(ZEROGS_DEVBUILD)
}
// Read all extensions name and fill mapGLExtensions
inline bool CreateFillExtensionsMap()
{
int max_ext = 0;
string all_ext("");
PFNGLGETSTRINGIPROC glGetStringi = 0;
glGetStringi = (PFNGLGETSTRINGIPROC)GLWin.GetProcAddress("glGetStringi");
glGetIntegerv(GL_NUM_EXTENSIONS, &max_ext);
if (glGetStringi && max_ext) {
// Get opengl extension (opengl3)
for (GLint i = 0; i < max_ext; i++)
{
string extension((const char*)glGetStringi(GL_EXTENSIONS, i));
mapGLExtensions[extension];
all_ext += extension;
if (i != (max_ext - 1)) all_ext += ", ";
}
} else {
// fallback to old method (pre opengl3, intel gma, geforce 7 ...)
ZZLog::Error_Log("glGetStringi opengl 3 interface not supported, fallback to opengl 2");
const char* ptoken = (const char*)glGetString(GL_EXTENSIONS);
if (ptoken == NULL) return false;
all_ext = string(ptoken); // save the string to print a nice debug message
const char* pend = NULL;
while (ptoken != NULL)
{
pend = strchr(ptoken, ' ');
if (pend != NULL)
{
max_ext++;
mapGLExtensions[string(ptoken, pend-ptoken)];
}
else
{
max_ext++;
mapGLExtensions[string(ptoken)];
break;
}
ptoken = pend;
while (*ptoken == ' ') ++ptoken;
}
}
#ifndef _DEBUG
ZZLog::Log("%d supported OpenGL Extensions: %s\n", max_ext, all_ext.c_str());
#endif
ZZLog::Debug_Log("%d supported OpenGL Extensions: %s\n", max_ext, all_ext.c_str());
return true;
}
void LoadglFunctions()
{
// GL_EXT_framebuffer_object
// CORE -> 3.0 and replaced by GL_ARB_framebuffer_object
GL_LOADFN(glIsRenderbufferEXT);
GL_LOADFN(glBindRenderbufferEXT);
GL_LOADFN(glDeleteRenderbuffersEXT);
GL_LOADFN(glGenRenderbuffersEXT);
GL_LOADFN(glRenderbufferStorageEXT);
GL_LOADFN(glGetRenderbufferParameterivEXT);
GL_LOADFN(glIsFramebufferEXT);
GL_LOADFN(glBindFramebufferEXT);
GL_LOADFN(glDeleteFramebuffersEXT);
GL_LOADFN(glGenFramebuffersEXT);
GL_LOADFN(glCheckFramebufferStatusEXT);
GL_LOADFN(glFramebufferTexture1DEXT);
GL_LOADFN(glFramebufferTexture2DEXT);
GL_LOADFN(glFramebufferTexture3DEXT);
GL_LOADFN(glFramebufferRenderbufferEXT);
GL_LOADFN(glGetFramebufferAttachmentParameterivEXT);
// CORE -> 2.0
GL_LOADFN(glDrawBuffers);
}
inline bool TryBlockFormat(GLint fmt, const GLvoid* vBlockData) {
glTexImage2D(GL_TEXTURE_2D, 0, fmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_ALPHA, GL_FLOAT, vBlockData);
return (glGetError() == GL_NO_ERROR);
}
inline bool TryBlinearFormat(GLint fmt32, const GLvoid* vBilinearData) {
glTexImage2D(GL_TEXTURE_2D, 0, fmt32, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_RGBA, GL_FLOAT, vBilinearData);
return (glGetError() == GL_NO_ERROR);
}
bool ZZCreate(int _width, int _height)
{
GLenum err = GL_NO_ERROR;
bool bSuccess = true;
ZZDestroy();
ZZGSStateReset();
if (!GLWin.DisplayWindow(_width, _height)) return false;
conf.mrtdepth = 0; // for now
if (!CreateFillExtensionsMap()) return false;
if (!CreateImportantCheck()) return false;
CreateOtherCheck();
// Incorrect must check rectangle texture too. Now done directly on CreateOtherCheck()
//
// check the max texture width and height
///glGetIntegerv(GL_MAX_TEXTURE_SIZE, &g_MaxTexWidth);
// Limit the texture size supported to 8192. We do not need bigger texture.
// Besides the following assertion is false when texture are too big.
// ZZoglFlush.cpp:2349: assert(fblockstride >= 1.0f)
//g_MaxTexWidth = min(8192, g_MaxTexWidth);
g_MaxTexHeight = g_MaxTexWidth / 4;
GPU_TEXWIDTH = min (g_MaxTexWidth/8, 1024);
g_fiGPU_TEXWIDTH = 1.0f / GPU_TEXWIDTH;
#if !(defined(GLSL_API) || defined(GLSL4_API))
if (!CreateOpenShadersFile()) return false;
#endif
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
s_srcrgb = s_dstrgb = s_srcalpha = s_dstalpha = GL_ONE;
LoadglFunctions();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
FB::Create();
GL_REPORT_ERRORD();
FB::Bind();
DrawBuffers(s_drawbuffers);
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
font_p = new RasterFont();
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
// init draw fns
//init_drawfn();
if (ZZKick != NULL) delete ZZKick;
ZZKick = new Kick;
SetAA(conf.aa);
GSsetGameCRC(g_LastCRC, conf.settings()._u32);
GL_STENCILFUNC(GL_ALWAYS, 0, 0);
//s_bWriteDepth = true;
GL_BLEND_ALL(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
glViewport(0, 0, GLWin.backbuffer.w, GLWin.backbuffer.h); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glGenTextures(1, &ptexLogo);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptexLogo);
#ifdef _WIN32
HRSRC hBitmapSrc = FindResource(hInst, MAKEINTRESOURCE(IDB_ZEROGSLOGO), RT_BITMAP);
assert(hBitmapSrc != NULL);
HGLOBAL hBitmapGlob = LoadResource(hInst, hBitmapSrc);
assert(hBitmapGlob != NULL);
PBITMAPINFO pinfo = (PBITMAPINFO)LockResource(hBitmapGlob);
GLenum tempFmt = (pinfo->bmiHeader.biBitCount == 32) ? GL_RGBA : GL_RGB;
TextureRect(GL_RGBA, pinfo->bmiHeader.biWidth, pinfo->bmiHeader.biHeight, tempFmt, GL_UNSIGNED_BYTE, (u8*)pinfo + pinfo->bmiHeader.biSize);
nLogoWidth = pinfo->bmiHeader.biWidth;
nLogoHeight = pinfo->bmiHeader.biHeight;
setRectFilters(GL_LINEAR);
#else
#endif
GL_REPORT_ERROR();
#ifdef GLSL4_API
GSInputLayoutOGL vert_format[] =
{
{0 , 4 , GL_SHORT , GL_FALSE , sizeof(VertexGPU) , (const GLvoid*)(0) } , // vertex
{1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(VertexGPU) , (const GLvoid*)(8) } , // color
{2 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(VertexGPU) , (const GLvoid*)(12) } , // z value. FIXME WTF 4 unsigned byte, why not a full integer
{3 , 3 , GL_FLOAT , GL_FALSE , sizeof(VertexGPU) , (const GLvoid*)(16) } , // tex coord
};
vertex_array = new GSVertexBufferStateOGL(sizeof(VertexGPU), vert_format, 4);
#endif
g_nCurVBOIndex = 0;
if (!vb_buffer_allocated) {
glGenBuffers((GLsizei)ArraySize(g_vboBuffers), g_vboBuffers);
for (u32 i = 0; i < ArraySize(g_vboBuffers); ++i)
{
glBindBuffer(GL_ARRAY_BUFFER, g_vboBuffers[i]);
glBufferData(GL_ARRAY_BUFFER, 0x100*sizeof(VertexGPU), NULL, GL_STREAM_DRAW);
#ifdef GLSL4_API
vertex_array->set_internal_format();
#endif
}
vb_buffer_allocated = true; // mark the buffer allocated
}
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
// create the blocks texture
g_fBlockMult = 1;
#ifndef ZZNORMAL_MEMORY
FillAlowedPsnTable();
FillBlockTables();
#endif
vector<char> vBlockData, vBilinearData;
BLOCK::FillBlocks(vBlockData, vBilinearData);
glGenTextures(1, &ptexBlocks);
glBindTexture(GL_TEXTURE_2D, ptexBlocks);
// Opensource driver -> Intel (need gen4) (enabled by default on mesa 9). Radeon depends on the HW capability
#ifdef GLSL4_API
// texture float -> GL3.0
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_RED, GL_FLOAT, &vBlockData[0]);
if (glGetError() != GL_NO_ERROR) {
ZZLog::Error_Log("ZZogl ERROR: could not fill blocks");
return false;
}
#else
if (TryBlockFormat(GL_RGBA32F, &vBlockData[0]))
ZZLog::Error_Log("Use GL_RGBA32F for blockdata.");
else if (TryBlockFormat(GL_ALPHA_FLOAT32_ATI, &vBlockData[0]))
ZZLog::Error_Log("Use ATI_texture_float for blockdata.");
else {
ZZLog::Error_Log("ZZogl ERROR: float texture not supported. If you use opensource driver (aka Mesa), you probably need to compile it with texture float support.");
ZZLog::Error_Log("ZZogl ERROR: Otherwise you probably have a very very old GPU, either use an older version of the plugin or upgrade your computer");
return false;
}
#endif
setTex2DFilters(GL_NEAREST);
setTex2DWrap(GL_REPEAT);
// fill in the bilinear blocks (main variant).
glGenTextures(1, &ptexBilinearBlocks);
glBindTexture(GL_TEXTURE_2D, ptexBilinearBlocks);
#ifdef GLSL4_API
if (!TryBlinearFormat(GL_RGBA32F, &vBilinearData[0]))
ZZLog::Error_Log("Fill bilinear blocks failed.");
#else
if (TryBlinearFormat(GL_RGBA32F, &vBilinearData[0]))
ZZLog::Error_Log("Fill bilinear blocks OK.!");
else if (TryBlinearFormat(GL_RGBA_FLOAT32_ATI, &vBilinearData[0]))
ZZLog::Error_Log("Fill bilinear blocks with ATI_texture_float.");
else if (TryBlinearFormat(GL_FLOAT_RGBA32_NV, &vBilinearData[0]))
ZZLog::Error_Log("ZZogl Fill bilinear blocks with NVidia_float.");
else
ZZLog::Error_Log("Fill bilinear blocks failed.");
#endif
setTex2DFilters(GL_NEAREST);
setTex2DWrap(GL_REPEAT);
float fpri = 1;
glPrioritizeTextures(1, &ptexBlocks, &fpri);
if (ptexBilinearBlocks != 0) glPrioritizeTextures(1, &ptexBilinearBlocks, &fpri);
GL_REPORT_ERROR();
// fill a simple rect
glGenBuffers(1, &vboRect);
glBindBuffer(GL_ARRAY_BUFFER, vboRect);
#ifdef GLSL4_API
vertex_array->set_internal_format();
#endif
vector<VertexGPU> verts(4);
VertexGPU* pvert = &verts[0];
pvert->set_xyzst(-0x7fff, 0x7fff, 0, 0, 0);
pvert++;
pvert->set_xyzst(0x7fff, 0x7fff, 0, 1, 0);
pvert++;
pvert->set_xyzst(-0x7fff, -0x7fff, 0, 0, 1);
pvert++;
pvert->set_xyzst(0x7fff, -0x7fff, 0, 1, 1);
pvert++;
glBufferDataARB(GL_ARRAY_BUFFER, 4*sizeof(VertexGPU), &verts[0], GL_STATIC_DRAW);
#ifndef GLSL4_API
// setup the default vertex declaration
glEnableClientState(GL_VERTEX_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
GL_REPORT_ERROR();
#endif
// create the conversion textures
glGenTextures(1, &ptexConv16to32);
glBindTexture(GL_TEXTURE_2D, ptexConv16to32);
vector<u32> conv16to32data(256*256);
for (int i = 0; i < 256*256; ++i)
{
u32 tempcol = RGBA16to32(i);
// have to flip r and b
conv16to32data[i] = (tempcol & 0xff00ff00) | ((tempcol & 0xff) << 16) | ((tempcol & 0xff0000) >> 16);
}
Texture2D(4, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, &conv16to32data[0]);
setTex2DFilters(GL_NEAREST);
setTex2DWrap(GL_CLAMP);
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
vector<u32> conv32to16data(32*32*32);
glGenTextures(1, &ptexConv32to16);
glBindTexture(GL_TEXTURE_3D, ptexConv32to16);
u32* dst = &conv32to16data[0];
for (int i = 0; i < 32; ++i)
{
for (int j = 0; j < 32; ++j)
{
for (int k = 0; k < 32; ++k)
{
u32 col = (i << 10) | (j << 5) | k;
*dst++ = ((col & 0xff) << 16) | (col & 0xff00);
}
}
}
Texture3D(4, 32, 32, 32, GL_RGBA, GL_UNSIGNED_BYTE, &conv32to16data[0]);
setTex3DFilters(GL_NEAREST);
setTex3DWrap(GL_CLAMP);
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
if (!ZZshStartUsingShaders()) bSuccess = false;
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
glDisable(GL_STENCIL_TEST);
glEnable(GL_SCISSOR_TEST);
GL_BLEND_ALPHA(GL_ONE, GL_ZERO);
glBlendColorEXT(0, 0, 0, 0.5f);
glDisable(GL_CULL_FACE);
// points
// This was changed in SetAA - should we be changing it back?
glPointSize(1.0f);
// g_nDepthBias = 0;
glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_POLYGON_OFFSET_LINE);
glPolygonOffset(0, 1);
vb[0].Init(VB_BUFFERSIZE);
vb[1].Init(VB_BUFFERSIZE);
g_vsprog = g_psprog = sZero;
if (glGetError() == GL_NO_ERROR)
{
return bSuccess;
}
else
{
ZZLog::Debug_Log("Error In final init!");
return false;
}
}
void ZZDestroy()
{
Delete_Avi_Capture();
g_MemTargs.Destroy();
s_RTs.Destroy();
s_DepthRTs.Destroy();
s_BitwiseTextures.Destroy();
SAFE_RELEASE_TEX(s_ptexInterlace);
SAFE_RELEASE_TEX(ptexBlocks);
SAFE_RELEASE_TEX(ptexBilinearBlocks);
SAFE_RELEASE_TEX(ptexConv16to32);
SAFE_RELEASE_TEX(ptexConv32to16);
vb[0].Destroy();
vb[1].Destroy();
if (vb_buffer_allocated)
{
glDeleteBuffers((GLsizei)ArraySize(g_vboBuffers), g_vboBuffers);
vb_buffer_allocated = false; // mark the buffer unallocated
}
#ifdef GLSL4_API
if (vertex_array != NULL) {
delete vertex_array;
vertex_array = NULL;
}
#endif
g_nCurVBOIndex = 0;
for (u32 i = 0; i < ArraySize(pvs); ++i)
{
SAFE_RELEASE_PROG(pvs[i]);
}
for (u32 i = 0; i < ArraySize(ppsRegular); ++i)
{
SAFE_RELEASE_PROG(ppsRegular[i].prog);
}
for (u32 i = 0; i < ArraySize(ppsTexture); ++i)
{
SAFE_RELEASE_PROG(ppsTexture[i].prog);
}
SAFE_RELEASE_PROG(pvsBitBlt.prog);
SAFE_RELEASE_PROG(ppsBitBlt[0].prog);
SAFE_RELEASE_PROG(ppsBitBlt[1].prog);
SAFE_RELEASE_PROG(ppsBitBltDepth.prog);
SAFE_RELEASE_PROG(ppsCRTCTarg[0].prog);
SAFE_RELEASE_PROG(ppsCRTCTarg[1].prog);
SAFE_RELEASE_PROG(ppsCRTC[0].prog);
SAFE_RELEASE_PROG(ppsCRTC[1].prog);
// SAFE_RELEASE_PROG(ppsCRTC24[0].prog);
// SAFE_RELEASE_PROG(ppsCRTC24[1].prog);
SAFE_RELEASE_PROG(ppsOne.prog);
safe_delete(font_p);
FB::Delete();
GLWin.ReleaseContext();
mapGLExtensions.clear();
}

View File

@ -1,255 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#include "ZZoglDrawing.h"
#include "ZZoglVB.h"
Kick* ZZKick;
const u32 g_primmult[8] = { 1, 2, 2, 3, 3, 3, 2, 0xff };
const u32 g_primsub[8] = { 1, 2, 1, 3, 1, 1, 2, 0 };
const GLenum primtype[8] = { GL_POINTS, GL_LINES, GL_LINES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES, 0xffffffff };
extern float fiTexWidth[2], fiTexHeight[2]; // current tex width and height
// Still thinking about the best place to put this.
// called on a primitive switch
void Prim()
{
FUNCLOG
VB& curvb = vb[prim->ctxt];
if (curvb.CheckPrim()) Flush(prim->ctxt);
curvb.SetCurrentPrim();
}
// Replaced by a macro -> see ZZoglDrawing.h
// return true if triangle SHOULD be painted.
// Hackish and should be replaced.
// bool __forceinline NoHighlights(int i)
// {
// //Old code
// return (!(conf.settings().xenosaga_spec) || !vb[i].zbuf.zmsk || prim->iip) ;
// }
// Not inlining for the moment to avoid getting 'unresolved external symbol' errors in Windows.
// This could also be resolved by moving the function into the header...
void Kick::KickVertex(bool adc)
{
FUNCLOG
if (++gs.primC >= (int)g_primmult[prim->prim])
{
if (!adc && NoHighlights(prim->ctxt)) DrawPrim(prim->prim);
else DirtyValidPrevPrim();
gs.primC -= g_primsub[prim->prim];
}
gs.primIndex = gs.primNext();
}
template<bool DO_Z_FOG>
void Kick::Set_Vertex(VertexGPU *p, Vertex & gsvertex)
{
VB& curvb = vb[prim->ctxt];
p->move_x(gsvertex, curvb.offset.x);
p->move_y(gsvertex, curvb.offset.y);
if(DO_Z_FOG) {
p->move_z(gsvertex, curvb.zprimmask);
p->move_fog(gsvertex);
}
p->rgba = prim->iip ? gsvertex.rgba : gs.rgba;
if (conf.settings().texa)
{
u32 B = ((p->rgba & 0xfe000000) >> 1) + (0x01000000 * vb[prim->ctxt].fba.fba);
p->rgba = (p->rgba & 0xffffff) + B;
}
if (prim->tme)
{
if (prim->fst)
{
p->s = (float)gsvertex.u * fiTexWidth[prim->ctxt];
p->t = (float)gsvertex.v * fiTexHeight[prim->ctxt];
p->q = 1;
}
else
{
p->s = gsvertex.s;
p->t = gsvertex.t;
p->q = gsvertex.q;
}
}
}
__forceinline void Kick::Output_Vertex(VertexGPU vert, u32 id)
{
#ifdef WRITE_PRIM_LOGS
ZZLog::Prim_Log("%c%d(%d): xyzf=(%4d,%4d,0x%x,%3d), rgba=0x%8.8x, stq = (%2.5f,%2.5f,%2.5f)",
id == 0 ? '*' : ' ', id, prim->prim, vert.x / 8, vert.y / 8, vert.z, vert.f / 128,
vert.rgba, Clamp(vert.s, -10, 10), Clamp(vert.t, -10, 10), Clamp(vert.q, -10, 10));
#endif
}
void Kick::DrawPrim(u32 prim_type)
{
VB& curvb = vb[prim->ctxt];
curvb.FlushTexData();
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp))
{
assert(vb[prim->ctxt].nCount == 0);
Flush(!prim->ctxt);
}
// check enough place is left for the biggest primitive (sprite)
// This function is unlikely to be called so do not inline it.
if (unlikely(curvb.nCount + 6 > curvb.nNumVertices))
curvb.IncreaseVertexBuffer();
VertexGPU* p = curvb.pBufferData + curvb.nCount;
u32 prev;
u32 last;
switch(prim_type) {
case PRIM_POINT:
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primIndex]);
curvb.nCount ++;
break;
case PRIM_LINE:
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev()]);
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primIndex]);
curvb.nCount += 2;
break;
case PRIM_LINE_STRIP:
if (likely(ValidPrevPrim) && curvb.nCount != 0) {
assert(curvb.nCount >= 1);
p[0] = p[-1];
} else {
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev()]);
ValidPrevPrim = true;
}
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primIndex]);
curvb.nCount += 2;
break;
case PRIM_TRIANGLE:
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev(2)]);
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primPrev()]);
Set_Vertex<true>(&p[2], gs.gsvertex[gs.primIndex]);
curvb.nCount += 3;
break;
case PRIM_TRIANGLE_STRIP:
if (likely(ValidPrevPrim) && curvb.nCount != 0) {
assert(curvb.nCount >= 2);
p[0] = p[-2];
p[1] = p[-1];
} else {
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev(2)]);
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primPrev()]);
ValidPrevPrim = true;
}
Set_Vertex<true>(&p[2], gs.gsvertex[gs.primIndex]);
curvb.nCount += 3;
break;
case PRIM_TRIANGLE_FAN:
if (likely(ValidPrevPrim) && curvb.nCount != 0) {
assert(curvb.nCount >= 2);
VertexGPU* TriFanVert = curvb.pBufferData + gs.nTriFanVert;
p[0] = TriFanVert[0];
p[1] = p[-1];
} else {
Set_Vertex<true>(&p[0], gs.gsTriFanVertex);
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primPrev(1)]);
ValidPrevPrim = true;
// Remenber the base for future processing
gs.nTriFanVert = curvb.nCount;
}
Set_Vertex<true>(&p[2], gs.gsvertex[gs.primIndex]);
curvb.nCount += 3;
break;
case PRIM_SPRITE:
prev = gs.primPrev();
last = gs.primIndex;
// sprite is too small and AA shows lines (tek4, Mana Khemia)
gs.gsvertex[last].x += (4 * AA.x);
gs.gsvertex[last].y += (4 * AA.y);
// might be bad sprite (KH dialog text)
//if( gs.gsvertex[prev].x == gs.gsvertex[last].x || gs.gsvertex[prev].y == gs.gsvertex[last].y )
//return;
// process sprite as 2 triangles. The common diagonal is 0,1 and 3,4
Set_Vertex<false>(&p[0], gs.gsvertex[prev]);
Set_Vertex<true>(&p[1], gs.gsvertex[last]);
// Only fog and Z of last vertex is valid
p[0].z = p[1].z;
p[0].f = p[1].f;
// Duplicate the vertex
p[3] = p[0];
p[2] = p[0];
p[4] = p[1];
p[5] = p[1];
// Move some vertex x coord to create the others corners of the sprite
p[2].s = p[1].s;
p[2].x = p[1].x;
p[5].s = p[0].s;
p[5].x = p[0].x;
curvb.nCount += 6;
break;
default: break;
}
// Print DEBUG info and code assertion
switch(prim_type) {
case PRIM_TRIANGLE:
case PRIM_TRIANGLE_STRIP:
case PRIM_TRIANGLE_FAN:
assert(gs.primC >= 3);
Output_Vertex(p[2],2);
case PRIM_LINE:
case PRIM_LINE_STRIP:
case PRIM_SPRITE:
assert(gs.primC >= 2);
Output_Vertex(p[1],1);
case PRIM_POINT:
assert(gs.primC >= 1);
Output_Vertex(p[0],0);
default: break;
}
}

View File

@ -1,67 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef ZZOGLDRAWING_H_INCLUDED
#define ZZOGLDRAWING_H_INCLUDED
#include "Util.h"
#include "GS.h"
// extern bool __forceinline NoHighlights(int i);
// return true if triangle SHOULD be painted.
// Hackish and should be replaced.
// Previous version was an inlined function but gcc-4.6 does not want to inline it.
// Because the code is in the middle of vertex which are very often call,
// a basic macro is more effective -- Gregory
#define NoHighlights(I) (!(conf.settings().xenosaga_spec) || !vb[(I)].zbuf.zmsk || prim->iip)
enum PRIM_TYPE {
PRIM_POINT = 0,
PRIM_LINE,
PRIM_LINE_STRIP,
PRIM_TRIANGLE,
PRIM_TRIANGLE_STRIP,
PRIM_TRIANGLE_FAN,
PRIM_SPRITE,
PRIM_DUMMY
};
class Kick
{
private:
// template<bool DO_Z_FOG> void Set_Vertex(VertexGPU *p, int i);
template<bool DO_Z_FOG> void Set_Vertex(VertexGPU *p, Vertex &gsvertex);
void Output_Vertex(VertexGPU vert, u32 id);
bool ValidPrevPrim;
public:
Kick() : ValidPrevPrim(false) { }
~Kick() { }
void KickVertex(bool adc);
void DrawPrim(u32 i);
inline void DirtyValidPrevPrim() {
ValidPrevPrim = 0;
}
};
extern Kick* ZZKick;
#endif // ZZOGLDRAWING_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,123 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef ZZOGLFLUSH_H_INCLUDED
#define ZZOGLFLUSH_H_INCLUDED
#ifndef ZEROGS_DEVBUILD
#define INC_GENVARS()
#define INC_TEXVARS()
#define INC_ALPHAVARS()
#define INC_RESOLVE()
#define g_bUpdateEffect 0
#define g_bSaveTex 0
#define g_bSaveResolved 0
#else // defined(ZEROGS_DEVBUILD)
#define INC_GENVARS() ++g_nGenVars
#define INC_TEXVARS() ++g_nTexVars
#define INC_ALPHAVARS() ++g_nAlphaVars
#define INC_RESOLVE() ++g_nResolve
extern bool g_bUpdateEffect;
extern bool g_bSaveTex; // saves the current texture
extern bool g_bSaveResolved;
#endif // !defined(ZEROGS_DEVBUILD)
enum StencilBits
{
STENCIL_ALPHABIT = 1, // if set, dest alpha >= 0x80
STENCIL_PIXELWRITE = 2, // if set, pixel just written (reset after every Flush)
STENCIL_FBA = 4, // if set, just written pixel's alpha >= 0 (reset after every Flush)
STENCIL_SPECIAL = 8 // if set, indicates that pixel passed its alpha test (reset after every Flush)
//STENCIL_PBE = 16
};
#define STENCIL_CLEAR (2|4|8|16)
enum ColorMask
{
COLORMASK_RED = 1,
COLORMASK_GREEN = 2,
COLORMASK_BLUE = 4,
COLORMASK_ALPHA = 8
};
#define GL_COLORMASK(mask) glColorMask(!!((mask)&COLORMASK_RED), !!((mask)&COLORMASK_GREEN), !!((mask)&COLORMASK_BLUE), !!((mask)&COLORMASK_ALPHA))
// extern int g_nDepthBias;
extern float g_fBlockMult; // used for old cards, that do not support Alpha-32float textures. We store block data in u16 and use it.
extern u32 g_nCurVBOIndex;
extern u8* g_pbyGSClut;
extern int ppf;
extern bool s_bTexFlush;
extern vector<u32> s_vecTempTextures; // temporary textures, released at the end of every frame
extern GLuint g_vboBuffers[VB_NUMBUFFERS]; // VBOs for all drawing commands
extern CRangeManager s_RangeMngr; // manages overwritten memory // zz
#if 0
typedef union
{
struct
{
u8 _bNeedAlphaColor; // set if vAlphaBlendColor needs to be set
u8 _b2XAlphaTest; // Only valid when bNeedAlphaColor is set. if 1st bit set set, double all alpha testing values
// otherwise alpha testing needs to be done separately.
u8 _bDestAlphaColor; // set to 1 if blending with dest color (process only one tri at a time). If 2, dest alpha is always 1.
u8 _bAlphaClamping; // if first bit is set, do min; if second bit, do max
};
u32 _bAlphaState;
} g_flag_vars;
extern g_flag_vars g_vars;
#endif
//#define bNeedAlphaColor g_vars._bNeedAlphaColor
//#define b2XAlphaTest g_vars._b2XAlphaTest
//#define bDestAlphaColor g_vars._bDestAlphaColor
//#define bAlphaClamping g_vars._bAlphaClamping
void FlushTransferRanges(const tex0Info* ptex); //zz
// use to update the state
void SetTexVariables(int context, FRAGMENTSHADER* pfragment); // zz
void SetTexInt(int context, FRAGMENTSHADER* pfragment, int settexint); // zz
void SetAlphaVariables(const alphaInfo& ainfo); // zzz
//void ResetAlphaVariables();
inline void SetAlphaTestInt(pixTest curtest);
inline void RenderAlphaTest(const VB& curvb, FRAGMENTSHADER* pfragment);
inline void RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting);
inline void ProcessStencil(const VB& curvb);
inline void RenderFBA(const VB& curvb, FRAGMENTSHADER* pfragment);
inline void ProcessFBA(const VB& curvb, FRAGMENTSHADER* pfragment); // zz
void SetContextTarget(int context);
void SetWriteDepth();
bool IsWriteDepth();
void SetDestAlphaTest();
#endif // ZZOGLFLUSH_H_INCLUDED

View File

@ -1,531 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2010 gregory.hainaut@gmail.com, zeydlitz@gmail.com
* Based on GSdx Copyright (C) 2007-2009 Gabest
*
* 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 file is a collection of hack for removing the blur effect on some games
* The blur renders very badly on high screen flat panel.
*
* To avoid severals combo-box, the hack detects the game based on crc
*/
#include "ZZoglFlushHack.h"
inline bool GABEST_HAS_SHARED_BITS (int fbp, int fpsm, int tbp, int tpsm)
{
if ( !PSMT_HAS_SHARED_BITS (fpsm, tpsm) )
return ((fbp ^ tbp) == 0);
else
return false;
}
// GSC_... function has been imported from GSdx
void GSC_Okami(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32)
skip = 1000;
}
else
{
if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSMT4)
skip = 0;
}
}
void GSC_MetalGearSolid3(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSMCT24)
skip = 1000; // 76, 79
else if(fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSMCT24 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSMCT32)
skip = 1000; // 69
}
else
{
if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && fi.FPSM == PSMCT32)
skip = 0;
}
}
void GSC_DBZBT2(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && /*fi.FBP == 0x00000 && fi.FPSM == PSMCT16 &&*/ fi.TBP0 == 0x02000 && fi.TPSM == PSMT16Z)
skip = 27;
else if(!fi.TME && fi.FBP == 0x03000 && fi.FPSM == PSMCT16)
skip = 10;
}
}
void GSC_DBZBT3(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x01c00 && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00) && fi.TPSM == PSMT8H)
skip = 24; // blur
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && fi.FPSM == PSMCT32 && fi.TPSM == PSMT8H)
skip = 28; // outline
}
}
void GSC_SFEX3(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x00500 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00f00 && fi.TPSM == PSMCT16)
skip = 2; // blur
}
}
void GSC_Bully(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
// Test is useless !
// if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.FPSM == fi.TPSM)
// return; // allowed
if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSMCT16S && fi.TBP0 == 0x02300 && fi.TPSM == PSMT16SZ)
skip = 6;
}
else
{
if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSMCT32)
skip = 0;
}
}
void GSC_BullyCC(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
// Test is useless !
// if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.FPSM == fi.TPSM)
// return; // allowed
if(!fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSMCT24)
skip = 9;
}
}
void GSC_SoTC(const GSFrameInfo& fi, int& skip)
{
// Not needed anymore? What did it fix anyway? (rama)
/*if(skip == 0)
{
if(fi.TME && fi.FBP == 0x02b80 && fi.FPSM == PSMCT24 && fi.TBP0 == 0x01e80 && fi.TPSM == PSMCT24)
skip = 9;
else if(fi.TME && fi.FBP == 0x01c00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSMCT32)
skip = 8;
else if(fi.TME && fi.FBP == 0x01e80 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03880 && fi.TPSM == PSMCT32)
skip = 8;
}*/
}
void GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x00f00) && fi.TPSM == PSMCT16)
skip = 4;
}
}
void GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00f00) && fi.TPSM == PSMCT16)
skip = 4;
}
}
void GSC_ICO(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03d00 && fi.TPSM == PSMCT32)
skip = 3;
else if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02800 && fi.TPSM == PSMT8H)
skip = 1;
}
else
{
if(fi.TME && fi.TBP0 == 0x00800 && fi.TPSM == PSMCT32)
skip = 0;
}
}
void GSC_GT4(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && (fi.FBP == 0x03440 || fi.FBP >= 0x03e00) && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01400) && fi.TPSM == PSMT8)
skip = 880;
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01400) && fi.FPSM == PSMCT24 && fi.TBP0 >= 0x03420 && fi.TPSM == PSMT8)
{
// TODO: removes gfx from where it is not supposed to (garage)
// skip = 58;
}
}
}
void GSC_WildArms4(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMT32Z && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT32Z)
skip = 100;
}
else
{
if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02a00 && fi.TPSM == PSMCT32)
skip = 1;
}
}
void GSC_WildArms5(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMT32Z && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT32Z)
skip = 100;
}
else
{
if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02a00 && fi.TPSM == PSMCT32)
skip = 1;
}
}
void GSC_Manhunt2(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x03c20 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x01400 && fi.TPSM == PSMT8)
skip = 640;
}
}
void GSC_CrashBandicootWoC(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
// Test is useless !
// if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00a00) && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.FPSM == fi.TPSM)
// return false; // allowed
if(fi.TME && fi.FBP == 0x02200 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01400 && fi.TPSM == PSMT24Z)
skip = 41;
}
else
{
if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00) && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03c00 && fi.TPSM == PSMCT32)
skip = 0;
else if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00))
skip = 0;
}
}
void GSC_ResidentEvil4(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT24Z)
skip = 176;
}
}
void GSC_Spartan(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32)
skip = 107;
}
}
void GSC_AceCombat4(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x02a00 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01600 && fi.TPSM == PSMT24Z)
skip = 71; // clouds (z, 16-bit)
else if(fi.TME && fi.FBP == 0x02900 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT24)
skip = 28; // blur
}
}
void GSC_Drakengard2(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x026c0 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00a00 && fi.TPSM == PSMCT32)
skip = 64;
}
}
void GSC_Tekken5(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x02ea0 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32)
skip = 95;
}
}
void GSC_IkkiTousen(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x00a80 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01180 && fi.TPSM == PSMT24Z)
skip = 1000; // shadow (result is broken without depth copy, also includes 16 bit)
else if(fi.TME && fi.FBP == 0x00700 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01180 && fi.TPSM == PSMT24Z)
skip = 11; // blur
}
else if(skip > 7)
{
if(fi.TME && fi.FBP == 0x00700 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00700 && fi.TPSM == PSMCT16)
skip = 7; // the last steps of shadow drawing
}
}
void GSC_GodOfWar(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT16)
{
// skip = 30; //GSdx
skip = 4; // 23 or 4 need more testing
}
else if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32 && fi.FBMSK == 0xff000000)
skip = 1; // blur
else if(fi.FBP == 0x00000 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT8
&& ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000)))
skip = 1; // wall of fog
}
}
void GSC_GodOfWar2(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME)
{
if((fi.FBP == 0x00100 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00100 && fi.TPSM == PSMCT16) // ntsc
|| (fi.FBP == 0x02100 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02100 && fi.TPSM == PSMCT16)) // pal
skip = 29; // shadows
if(fi.FBP == 0x00100 && fi.FPSM == PSMCT32 && (fi.TBP0 & 0x03000) == 0x03000
&& (fi.TPSM == PSMT8 || fi.TPSM == PSMT4)
&& ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000)))
skip = 1; // wall of fog
}
}
}
void GSC_GiTS(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x01400 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02e40 && fi.TPSM == PSMCT16)
skip = 1315;
}
}
void GSC_Onimusha3(const GSFrameInfo& fi, int& skip)
{
if(fi.TME /*&& (fi.FBP == 0x00000 || fi.FBP == 0x00700)*/ && (fi.TBP0 == 0x01180 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x01000 || fi.TBP0 == 0x01200) && (fi.TPSM == PSMCT32 || fi.TPSM == PSMCT24))
skip = 1;
}
void GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT8) // copies the z buffer to the alpha channel of the fb
skip = 1000;
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && (fi.TBP0 == 0x03560 || fi.TBP0 == 0x038e0) && fi.TPSM == PSMCT32)
skip = 1;
}
else
{
if(fi.TME && fi.TPSM != PSMT8)
skip = 0;
}
}
void GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x02200 && fi.FPSM == PSMCT16S && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT16)
skip = 1000; // shadow
}
else
{
if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02200 && fi.TPSM == PSMCT16S)
skip = 2;
}
}
void GSC_Genji(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == 0x01500 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00e00 && fi.TPSM == PSMT16Z)
skip = 6; //
}
}
void GSC_StarOcean3(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)
skip = 1000; //
}
else
{
if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH))
skip = 0;
}
}
void GSC_ValkyrieProfile2(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)
skip = 1000; //
}
else
{
if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH))
skip = 0;
}
}
void GSC_RadiataStories(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)
skip = 1000; // Shadows
else if (fi.TME && fi.FBP == fi.TBP0 && (fi.TBP0 == 0x3700 || fi.TBP0 == 0x3400) && fi.TZTST == 1)
skip = 1; // Start manu issue;
}
else
{
if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH))
skip = 0;
}
}
bool GSC_HauntingGround(const GSFrameInfo& fi, int& skip)
{
// Note GSdx seems to use invert somewhere FBMSK. So values were inverted
if(skip == 0)
{
if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSMCT16S && ~fi.FBMSK == 0x03FFF)
skip = 1;
else if(fi.TME && fi.FBP == 0x3000 && fi.TBP0 == 0x3380)
skip = 1; // bloom
else if(fi.TME && fi.FBP == fi.TBP0 && fi.TBP0 == 0x3000 && ~fi.FBMSK == 0xFFFFFF &&
GABEST_HAS_SHARED_BITS(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM))
skip = 1;
}
return true;
}
// Record skipped frame to allow better analysis
// #define FRAME_RECORDING_ON 1
#ifdef FRAME_RECORDING_ON
static const u32 MAX_FRAMES = 500;
static GSFrameInfo FrameAppear[MAX_FRAMES];
static u32 Rec_Numbers = 0;
void RecordNewFrames(VB& curvb, GSFrameInfo fi) {
if (Rec_Numbers >= MAX_FRAMES)
return;
u32 i;
bool was_recorded = false;
for (i = 0; i < Rec_Numbers; i++ ) {
if (FrameAppear[i].FBP == fi.FBP && FrameAppear[i].FPSM == fi.FPSM
&& FrameAppear[i].TBP0 == fi.TBP0 && FrameAppear[i].TPSM == fi.TPSM) {
was_recorded = true;
break;
}
}
if (!was_recorded) {
FrameAppear[Rec_Numbers] = fi;
Rec_Numbers++;
ZZLog::Print( "New frame %d, skip %d | fpb: %x fpsm: %d fpmsk: %x tme: %x tbp0: %x tpsm: %d tztst: %x | bits %d\n", \
Rec_Numbers, g_SkipFlushFrame, fi.FBP, fi.FPSM, fi.FBMSK, fi.TME, fi.TBP0, fi.TPSM, fi.TZTST, GABEST_HAS_SHARED_BITS(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM) );
// Dump a nice picture of the frame
char filename[255];
sprintf(filename, "SkipFlushFrame_%d__%d.tga", g_SkipFlushFrame, Rec_Numbers);
SaveRenderTarget(filename, curvb.prndr->fbw, curvb.prndr->fbh, 0);
}
}
#endif
__forceinline bool IsBadFrame(VB& curvb)
{
GSFrameInfo fi;
// Keep GSdx naming convention to ease sharing code
fi.FBP = curvb.frame.fbp;
fi.FPSM = curvb.frame.psm;
fi.FBMSK = ~curvb.frame.fbm;
fi.TME = curvb.curprim.tme;
fi.TBP0 = curvb.tex0.tbp0;
fi.TPSM = curvb.tex0.psm;
fi.TZTST = curvb.test.ztst;
if (GetSkipCount_Handler && conf.settings().automatic_skip_draw)
GetSkipCount_Handler(fi, g_SkipFlushFrame);
if(g_SkipFlushFrame == 0 && (conf.SkipDraw > 0))
{
if(fi.TME)
{
// depth textures (bully, mgs3s1 intro, Front Mission 5)
// Or General, often problematic post processing
if (PSMT_ISZTEX(fi.TPSM) || (GABEST_HAS_SHARED_BITS(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)))
g_SkipFlushFrame = conf.SkipDraw;
}
}
if(g_SkipFlushFrame > 0)
{
#ifdef FRAME_RECORDING_ON
RecordNewFrames(curvb, fi);
#endif
g_SkipFlushFrame--;
return true;
}
return false;
}

View File

@ -1,84 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2010 gregory.hainaut@gmail.com
* Based on GSdx Copyright (C) 2007-2009 Gabest
*
* 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 file is a collection of hack for removing the blur effect on some games
* The blur renders very badly on high screen flat panel.
*
* To avoid severals combo-box, the hack detects the game based on crc
*/
#ifndef ZZOGL_FLUSH_HACK_H_INCLUDED
#define ZZOGL_FLUSH_HACK_H_INCLUDED
#include "GS.h"
#include "targets.h"
#include "ZZoglVB.h"
extern int g_SkipFlushFrame;
struct GSFrameInfo
{
u32 FBP;
u32 FPSM;
u32 FBMSK;
u32 TBP0;
u32 TPSM;
u32 TZTST;
bool TME;
};
typedef void (*GetSkipCount)(const GSFrameInfo& fi, int& skip);
extern GetSkipCount GetSkipCount_Handler;
void GSC_Okami(const GSFrameInfo& fi, int& skip);
void GSC_MetalGearSolid3(const GSFrameInfo& fi, int& skip);
void GSC_DBZBT2(const GSFrameInfo& fi, int& skip);
void GSC_DBZBT3(const GSFrameInfo& fi, int& skip);
void GSC_SFEX3(const GSFrameInfo& fi, int& skip);
void GSC_Bully(const GSFrameInfo& fi, int& skip);
void GSC_BullyCC(const GSFrameInfo& fi, int& skip);
void GSC_SoTC(const GSFrameInfo& fi, int& skip);
void GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip);
void GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip);
void GSC_ICO(const GSFrameInfo& fi, int& skip);
void GSC_GT4(const GSFrameInfo& fi, int& skip);
void GSC_WildArms4(const GSFrameInfo& fi, int& skip);
void GSC_WildArms5(const GSFrameInfo& fi, int& skip);
void GSC_Manhunt2(const GSFrameInfo& fi, int& skip);
void GSC_CrashBandicootWoC(const GSFrameInfo& fi, int& skip);
void GSC_ResidentEvil4(const GSFrameInfo& fi, int& skip);
void GSC_Spartan(const GSFrameInfo& fi, int& skip);
void GSC_AceCombat4(const GSFrameInfo& fi, int& skip);
void GSC_Drakengard2(const GSFrameInfo& fi, int& skip);
void GSC_Tekken5(const GSFrameInfo& fi, int& skip);
void GSC_IkkiTousen(const GSFrameInfo& fi, int& skip);
void GSC_GodOfWar(const GSFrameInfo& fi, int& skip);
void GSC_GodOfWar2(const GSFrameInfo& fi, int& skip);
void GSC_GiTS(const GSFrameInfo& fi, int& skip);
void GSC_Onimusha3(const GSFrameInfo& fi, int& skip);
void GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip);
void GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip);
void GSC_Genji(const GSFrameInfo& fi, int& skip);
void GSC_StarOcean3(const GSFrameInfo& fi, int& skip);
void GSC_ValkyrieProfile2(const GSFrameInfo& fi, int& skip);
void GSC_RadiataStories(const GSFrameInfo& fi, int& skip);
extern bool IsBadFrame(VB& curvb);
#endif

View File

@ -1,511 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef ZZOGLMATH_H_INCLUDED
#define ZZOGLMATH_H_INCLUDED
//Remind me to check and see if this is necessary, and what uses it. --arcum42
#ifndef _WIN32
#include <alloca.h>
#endif
#include <assert.h>
#include "Pcsx2Defs.h"
//#define ZZ_MMATH
#ifndef ZZ_MMATH
template <class T>
class Vector4
{
public:
T x, y, z, w;
Vector4(T x1 = 0, T y1 = 0, T z1 = 0, T w1 = 0)
{
x = x1;
y = y1;
z = z1;
w = w1;
}
Vector4(Vector4<T> &f)
{
x = f.x;
y = f.y;
z = f.z;
w = f.w;
}
Vector4(T* f)
{
x = f[0];
y = f[1];
z = f[2];
w = f[3]; // For some reason, the old code set this to 0.
}
T& operator[](int i)
{
switch(i)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: assert(0);
}
}
operator T*()
{
return (T*) this;
}
operator const T*() const
{
return (const T*) this;
}
Vector4<T>& operator =(const Vector4<T>& v)
{
x = v.x;
y = v.y;
z = v.z;
w = v.w;
return *this;
}
bool operator ==(const Vector4<T>& v)
{
return !!( x == v.x &&
y == v.y &&
z == v.z &&
w == v.w );
}
Vector4<T> operator +(const Vector4<T>& v) const
{
return Vector4<T>(x + v.x, y + v.y, z + v.z, w + v.w);
}
Vector4<T> operator -(const Vector4<T>& v) const
{
return Vector4<T>(x - v.x, y - v.y, z - v.z, w - v.w);
}
Vector4<T> operator *(const Vector4<T>& v) const
{
return Vector4<T>(x * v.x, y * v.y, z * v.z, w * v.w);
}
Vector4<T> operator /(const Vector4<T>& v) const
{
return Vector4<T>(x / v.x, y / v.y, z / v.z, w / v.w);
}
Vector4<T> operator +(T val) const
{
return Vector4<T>(x + val, y + val, z + val, w + val);
}
Vector4<T> operator -(T val) const
{
return Vector4<T>(x - val, y - val, z - val, w - val);
}
Vector4<T> operator *(T val) const
{
return Vector4<T>(x * val, y * val, z * val, w * val);
}
Vector4<T> operator /(T val) const
{
return Vector4<T>(x / val, y / val, z / val, w / val);
}
Vector4<T>& operator +=(const Vector4<T>& v)
{
*this = *this + v;
return *this;
}
Vector4<T>& operator -=(const Vector4<T>& v)
{
*this = *this - v;
return *this;
}
Vector4<T>& operator *=(const Vector4<T>& v)
{
*this = *this * v;
return *this;
}
Vector4<T>& operator /=(const Vector4<T>& v)
{
*this = *this - v;
return *this;
}
Vector4<T>& operator +=(T val)
{
*this = *this + (T)val;
return *this;
}
Vector4<T>& operator -=(T val)
{
*this = *this - (T)val;
return *this;
}
Vector4<T>& operator *=(T val)
{
*this = *this * (T)val;
return *this;
}
Vector4<T>& operator /=(T val)
{
*this = *this / (T)val;
return *this;
}
// Probably doesn't belong here, but I'll leave it in for the moment.
void SetColor(u32 color)
{
x = (color & 0xff) / 255.0f;
y = ((color >> 8) & 0xff) / 255.0f;
z = ((color >> 16) & 0xff) / 255.0f;
}
bool equal_vectors(const Vector4<T>& v)
{
if (abs(x - v.x) + abs(y - v.y) + abs(z - v.z) + abs(w - v.w) < 0.01)
return true;
else
return false;
}
};
typedef Vector4<float> float4;
#else
// Reimplement, swiping a bunch of code from GSdx and adapting it. (specifically GSVector.h)
// This doesn't include more then half of the functions in there, as well as some of the structs...
#include "Util.h"
#include "Pcsx2Types.h"
class float4
{
public:
union
{
struct {float x, y, z, w;};
struct {float r, g, b, a;};
struct {float left, top, right, bottom;};
float v[4];
float f32[4];
s8 _s8[16];
s16 _s16[8];
s32 _s32[4];
s64 _s64[2];
u8 _u8[16];
u16 _u16[8];
u32 _u32[4];
u64 _u64[2];
__m128 m;
};
float4()
{
m = _mm_setzero_ps();
}
float4(float x, float y, float z, float w = 0)
{
m = _mm_set_ps(w, z, y, x);
}
float4(float4 &f)
{
m = f.m;
}
float4(float x, float y)
{
m = _mm_unpacklo_ps(_mm_load_ss(&x), _mm_load_ss(&y));
}
float4(int x, int y)
{
m = _mm_cvtepi32_ps(_mm_unpacklo_epi32(_mm_cvtsi32_si128(x), _mm_cvtsi32_si128(y)));
}
explicit float4(float f)
{
m = _mm_set1_ps(f);
}
explicit float4(__m128 m)
{
this->m = m;
}
float4(float* f)
{
x = f[0];
y = f[1];
z = f[2];
w = f[3]; // For some reason, the old code set this to 0.
}
float& operator[](int i)
{
switch(i)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: assert(0);
}
}
operator float*()
{
return (float*) this;
}
operator const float*() const
{
return (const float*) this;
}
void operator = (float f)
{
m = _mm_set1_ps(f);
}
void operator = (__m128 m)
{
this->m = m;
}
void operator += (const float4& v)
{
m = _mm_add_ps(m, v.m);
}
void operator -= (const float4& v)
{
m = _mm_sub_ps(m, v.m);
}
void operator *= (const float4& v)
{
m = _mm_mul_ps(m, v.m);
}
void operator /= (const float4& v)
{
m = _mm_div_ps(m, v.m);
}
void operator += (float f)
{
*this += float4(f);
}
void operator -= (float f)
{
*this -= float4(f);
}
void operator *= (float f)
{
*this *= float4(f);
}
void operator /= (float f)
{
*this /= float4(f);
}
void operator &= (const float4& v)
{
m = _mm_and_ps(m, v.m);
}
void operator |= (const float4& v)
{
m = _mm_or_ps(m, v.m);
}
void operator ^= (const float4& v)
{
m = _mm_xor_ps(m, v.m);
}
friend float4 operator + (const float4& v1, const float4& v2)
{
return float4(_mm_add_ps(v1.m, v2.m));
}
friend float4 operator - (const float4& v1, const float4& v2)
{
return float4(_mm_sub_ps(v1.m, v2.m));
}
friend float4 operator * (const float4& v1, const float4& v2)
{
return float4(_mm_mul_ps(v1.m, v2.m));
}
friend float4 operator / (const float4& v1, const float4& v2)
{
return float4(_mm_div_ps(v1.m, v2.m));
}
friend float4 operator + (const float4& v, float f)
{
return v + float4(f);
}
friend float4 operator - (const float4& v, float f)
{
return v - float4(f);
}
friend float4 operator * (const float4& v, float f)
{
return v * float4(f);
}
friend float4 operator / (const float4& v, float f)
{
return v / float4(f);
}
friend float4 operator & (const float4& v1, const float4& v2)
{
return float4(_mm_and_ps(v1.m, v2.m));
}
friend float4 operator | (const float4& v1, const float4& v2)
{
return float4(_mm_or_ps(v1.m, v2.m));
}
friend float4 operator ^ (const float4& v1, const float4& v2)
{
return float4(_mm_xor_ps(v1.m, v2.m));
}
friend float4 operator == (const float4& v1, const float4& v2)
{
return float4(_mm_cmpeq_ps(v1.m, v2.m));
}
friend float4 operator != (const float4& v1, const float4& v2)
{
return float4(_mm_cmpneq_ps(v1.m, v2.m));
}
friend float4 operator > (const float4& v1, const float4& v2)
{
return float4(_mm_cmpgt_ps(v1.m, v2.m));
}
friend float4 operator < (const float4& v1, const float4& v2)
{
return float4(_mm_cmplt_ps(v1.m, v2.m));
}
friend float4 operator >= (const float4& v1, const float4& v2)
{
return float4(_mm_cmpge_ps(v1.m, v2.m));
}
friend float4 operator <= (const float4& v1, const float4& v2)
{
return float4(_mm_cmple_ps(v1.m, v2.m));
}
bool equal_vectors(const float4& v)
{
if (abs(x - v.x) + abs(y - v.y) + abs(z - v.z) + abs(w - v.w) < 0.01)
return true;
else
return false;
}
// This looked interesting, so I thought I'd include it...
template<int i> float4 shuffle() const
{
return float4(_mm_shuffle_ps(m, m, _MM_SHUFFLE(i, i, i, i)));
}
#define VECTOR4_SHUFFLE_4(xs, xn, ys, yn, zs, zn, ws, wn) \
float4 xs##ys##zs##ws() const {return float4(_mm_shuffle_ps(m, m, _MM_SHUFFLE(wn, zn, yn, xn)));} \
float4 xs##ys##zs##ws(const float4& v) const {return float4(_mm_shuffle_ps(m, v.m, _MM_SHUFFLE(wn, zn, yn, xn)));} \
#define VECTOR4_SHUFFLE_3(xs, xn, ys, yn, zs, zn) \
VECTOR4_SHUFFLE_4(xs, xn, ys, yn, zs, zn, x, 0) \
VECTOR4_SHUFFLE_4(xs, xn, ys, yn, zs, zn, y, 1) \
VECTOR4_SHUFFLE_4(xs, xn, ys, yn, zs, zn, z, 2) \
VECTOR4_SHUFFLE_4(xs, xn, ys, yn, zs, zn, w, 3) \
#define VECTOR4_SHUFFLE_2(xs, xn, ys, yn) \
VECTOR4_SHUFFLE_3(xs, xn, ys, yn, x, 0) \
VECTOR4_SHUFFLE_3(xs, xn, ys, yn, y, 1) \
VECTOR4_SHUFFLE_3(xs, xn, ys, yn, z, 2) \
VECTOR4_SHUFFLE_3(xs, xn, ys, yn, w, 3) \
#define VECTOR4_SHUFFLE_1(xs, xn) \
float4 xs##4() const {return float4(_mm_shuffle_ps(m, m, _MM_SHUFFLE(xn, xn, xn, xn)));} \
float4 xs##4(const float4& v) const {return float4(_mm_shuffle_ps(m, v.m, _MM_SHUFFLE(xn, xn, xn, xn)));} \
VECTOR4_SHUFFLE_2(xs, xn, x, 0) \
VECTOR4_SHUFFLE_2(xs, xn, y, 1) \
VECTOR4_SHUFFLE_2(xs, xn, z, 2) \
VECTOR4_SHUFFLE_2(xs, xn, w, 3) \
VECTOR4_SHUFFLE_1(x, 0)
VECTOR4_SHUFFLE_1(y, 1)
VECTOR4_SHUFFLE_1(z, 2)
VECTOR4_SHUFFLE_1(w, 3)
// Probably doesn't belong here, but I'll leave it in for the moment.
void SetColor(u32 color)
{
x = (color & 0xff) / 255.0f;
y = ((color >> 8) & 0xff) / 255.0f;
z = ((color >> 16) & 0xff) / 255.0f;
}
};
#endif
#endif

View File

@ -1,556 +0,0 @@
/* ZeroGS KOSMOS
* Copyright (C) 2005-2006 zerofrog@gmail.com
*
* 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
*/
#include "GS.h"
#include "Util.h"
#include "ZZoglMem.h"
#include "targets.h"
#include "x86.h"
#include "Mem_Swizzle.h"
#ifndef ZZNORMAL_MEMORY
bool allowed_psm[256] = {false, }; // Sometimes we got strange unknown psm
PSM_value PSM_value_Table[64] = {PSMT_BAD_PSM, }; // for int -> PSM_value
// return array of pointer of array string,
// We SHOULD do memory allocation for u32** -- otherwize we have a lot of trouble!
// if bw and bh are set correctly, as dimensions of table, than array have pointers
// to table rows, so array[i][j] = table[i][j];
inline u32** InitTable(int bh, int bw, u32* table) {
u32** array = (u32**)malloc(bh * sizeof(u32*));
for (int i = 0; i < bh; i++) {
array[i] = &table[i * bw];
}
return array;
}
// initialize dynamic arrays (u32**) for each regular psm.
inline void SetTable(int psm) {
switch (psm) {
case PSMCT32:
g_pageTable[psm] = InitTable( 32, 64, &g_pageTable32[0][0]);
g_blockTable[psm] = InitTable( 4, 8, &g_blockTable32[0][0]);
g_columnTable[psm] = InitTable( 8, 8, &g_columnTable32[0][0]);
break;
case PSMCT24:
g_pageTable[psm] = g_pageTable[PSMCT32];;
g_blockTable[psm] = InitTable( 4, 8, &g_blockTable32[0][0]);
g_columnTable[psm] = InitTable( 8, 8, &g_columnTable32[0][0]);
break;
case PSMCT16:
g_pageTable[psm] = InitTable( 64, 64, &g_pageTable16[0][0]);
g_blockTable[psm] = InitTable( 8, 4, &g_blockTable16[0][0]);
g_columnTable[psm] = InitTable( 8, 16, &g_columnTable16[0][0]);
break;
case PSMCT16S:
g_pageTable[psm] = InitTable( 64, 64, &g_pageTable16S[0][0]);
g_blockTable[psm] = InitTable( 8, 4, &g_blockTable16S[0][0]);
g_columnTable[psm] = InitTable( 8, 16, &g_columnTable16[0][0]);
break;
case PSMT8:
g_pageTable[psm] = InitTable( 64, 128, &g_pageTable8[0][0]);
g_blockTable[psm] = InitTable( 4, 8, &g_blockTable8[0][0]);
g_columnTable[psm] = InitTable( 16, 16, &g_columnTable8[0][0]);
break;
case PSMT8H:
g_pageTable[psm] = g_pageTable[PSMCT32];
g_blockTable[psm] = InitTable( 4, 8, &g_blockTable8[0][0]);
g_columnTable[psm] = InitTable( 16, 16, &g_columnTable8[0][0]);
break;
case PSMT4:
g_pageTable[psm] = InitTable(128, 128, &g_pageTable4[0][0]);
g_blockTable[psm] = InitTable( 8, 4, &g_blockTable4[0][0]);
g_columnTable[psm] = InitTable( 16, 32, &g_columnTable4[0][0]);
break;
case PSMT4HL:
case PSMT4HH:
g_pageTable[psm] = g_pageTable[PSMCT32];
g_blockTable[psm] = InitTable( 8, 4, &g_blockTable4[0][0]);
g_columnTable[psm] = InitTable( 16, 32, &g_columnTable4[0][0]);
break;
case PSMT32Z:
g_pageTable[psm] = InitTable( 32, 64, &g_pageTable32Z[0][0]);
g_blockTable[psm] = InitTable( 4, 8, &g_blockTable32Z[0][0]);
g_columnTable[psm] = InitTable( 8, 8, &g_columnTable32[0][0]);
break;
case PSMT24Z:
g_pageTable[psm] = g_pageTable[PSMT32Z];
g_blockTable[psm] = InitTable( 4, 8, &g_blockTable32Z[0][0]);
g_columnTable[psm] = InitTable( 8, 8, &g_columnTable32[0][0]);
break;
case PSMT16Z:
g_pageTable[psm] = InitTable( 64, 64, &g_pageTable16Z[0][0]);
g_blockTable[psm] = InitTable( 8, 4, &g_blockTable16Z[0][0]);
g_columnTable[psm] = InitTable( 8, 16, &g_columnTable16[0][0]);
break;
case PSMT16SZ:
g_pageTable[psm] = InitTable( 64, 64, &g_pageTable16SZ[0][0]);
g_blockTable[psm] = InitTable( 8, 4, &g_blockTable16SZ[0][0]);
g_columnTable[psm] = InitTable( 8, 16, &g_columnTable16[0][0]);
break;
}
}
// After this, the function arrays with u32** have memory set and filled.
void FillBlockTables() {
for (int i = 0; i < MAX_PSM; i++)
SetTable(i);
}
// Deallocate memory for u32** arrays.
void DestroyBlockTables() {
for (int i = 0; i < MAX_PSM; i++) {
if (g_pageTable[i] != NULL && (i != PSMT8H && i != PSMT4HL && i != PSMT4HH && i != PSMCT24 && i != PSMT24Z))
free(g_pageTable[i]);
if (g_blockTable[i] != NULL)
free(g_blockTable[i]);
if (g_columnTable[i] != NULL)
free(g_columnTable[i]);
}
}
void FillNewPageTable() {
int k = 0;
for (int psm = 0; psm < MAX_PSM; psm ++)
if (allowed_psm[psm]) {
for (u32 i = 0; i < 127; i++)
for(u32 j = 0; j < 127; j++) {
u32 address;
u32 shift;
address = g_pageTable[psm][i & ZZ_DT[psm][3]][j & ZZ_DT[psm][4]];
shift = (((address << ZZ_DT[psm][5]) & 0x7 ) << 3)+ ZZ_DT[psm][7]; // last part is for 8H, 4HL and 4HH -- they have data from 24 and 28 byte
g_pageTable2[k][i][j] = (address >> ZZ_DT[psm][0]) + (shift << 16); // now lower 16 byte of page table is 32-bit aligned address, and upper --
// shift.
}
g_pageTableNew[psm] = InitTable( 128, 128, &g_pageTable2[k][0][0]);
k++;;
}
}
BLOCK m_Blocks[MAX_PSM]; // Do so that blocks are indexable.
// At the begining and the end of each string we should made unaligned writes, with nSize checks. We should be sure that all
// these pixels are inside one widthlimit space.
template <int psm>
inline bool DoOneTransmitStep(void* pstart, int& nSize, int endj, const void* pbuf, int& k, int& i, int& j, int widthlimit) {
for (; j < endj && nSize > 0; j++, k++, nSize -= 1) {
writePixelMem<psm, false>((u32*)pstart, j%2048, i%2048, (u32*)(pbuf), k, gs.dstbuf.bw);
}
return (nSize == 0);
}
// FFX has PSMT8 transmit (starting intro -- sword and hairs).
// Persona 4 texts at start are PSMCT32 (and there is also PSMCT16 transmit somwhere after that).
// Tekken V has PSMCT24 and PSMT4 transfers
// This function transfers "Y" block pixels. I use little another code than Zerofrog. My code often uses widthmult != 1 addition (Zerofrog's code
// have an strict condition for fast path: width of transferred data should be widthlimit multiplied by j; EndY also should be multiplied. But
// the usual data block of 255 pixels becomes transfered by 1.
// I should check, maybe Unaligned_Start and Unaligned_End often == 0, and I could try a fastpath -- with this block off.
template <int psm, int widthlimit>
inline bool TRANSMIT_HOSTLOCAL_Y(u32* pbuf, int& nSize, u8* pstart, int endY, int& i, int& j, int& k) {
// if (psm != PSMT8 && psm != 0 && psm != PSMT4 && psm != PSMCT24)
// ERROR_LOG("This is usable function TRANSMIT_HOSTLOCAL_Y at ZZoglMem.cpp %d %d %d %d %d\n", psm, widthlimit, i, j, nSize);
int q = (gs.trxpos.dx - j) % widthlimit;
if (DoOneTransmitStep<psm>(pstart, nSize, q, pbuf, k, i, j, widthlimit)) return true; // After this j and dx are compatible by modyle of widthlimit
int Unaligned_Start = (gs.trxpos.dx % widthlimit == 0) ? 0 : widthlimit - gs.trxpos.dx % widthlimit; // gs.trpos.dx + Unaligned_Start is multiple of widthlimit
for (; i < endY; ++i) {
if (DoOneTransmitStep<psm>(pstart, nSize, j + Unaligned_Start, pbuf, k, i, j, widthlimit)) return true; // This operation made j % widthlimit == 0.
//assert (j % widthlimit != 0);
for (; j < gs.imageEnd.x - widthlimit + 1 && nSize >= widthlimit; j += widthlimit, nSize -= widthlimit) {
writePixelsFromMemory<psm, true, widthlimit>(pstart, pbuf, k, j % 2048, i % 2048, gs.dstbuf.bw);
}
assert ( gs.imageEnd.x - j < widthlimit || nSize < widthlimit);
if (DoOneTransmitStep<psm>(pstart, nSize, gs.imageEnd.x, pbuf, k, i, j, widthlimit)) return true; // There are 2 reasons for finish of previous for: 1) nSize < widthlimit
// 2) j > gs.imageEnd.x - widthlimit + 1. We would try to write pixels up do
// EndX, it's no more widthlimit pixels
j = gs.trxpos.dx;
}
return false;
}
// PSMT4 -- Tekken V
template <int psm, int widthlimit>
inline void TRANSMIT_HOSTLOCAL_X(u32* pbuf, int& nSize, u8* pstart, int& i, int& j, int& k, int blockheight, int startX, int pitch, int fracX) {
if (psm != PSMT8 && psm != PSMT4)
ZZLog::Error_Log("This is usable function TRANSMIT_HOSTLOCAL_X at ZZoglMem.cpp %d %d %d %d %d\n", psm, widthlimit, i, j, nSize);
for(int tempi = 0; tempi < blockheight; ++tempi) {
for(j = startX; j < gs.imageEnd.x; j++, k++) {
writePixelMem<psm, false>((u32*)pstart, j%2048, (i + tempi)%2048, (u32*)(pbuf), k, gs.dstbuf.bw);
}
k += ( pitch - fracX );
}
}
template <int psm>
inline int TRANSMIT_PITCH(int pitch) {
return (PSM_BITS_PER_PIXEL<psm>() * pitch) >> 3;
}
// ------------------------
// | Y |
// ------------------------
// | block | |
// | aligned area | X |
// | | |
// ------------------------
// | Y |
// ------------------------
template <int psmX>
int FinishTransfer(int i, int j, int nSize, int nLeftOver)
{
if( i >= gs.imageEnd.y )
{
assert( gs.transferring == false || i == gs.imageEnd.y );
gs.transferring = false;
}
else {
/* update new params */
gs.image.y = i;
gs.image.x = j;
}
return (nSize * TRANSMIT_PITCH<psmX>(2) + nLeftOver)/2;
}
template<int psmX, int widthlimit, int blockbits, int blockwidth, int blockheight>
int TransferHostLocal(const void* pbyMem, u32 nQWordSize)
{
assert( gs.imageTransfer == XFER_HOST_TO_LOCAL );
u8* pstart = g_pbyGSMemory + gs.dstbuf.bp*256;
int i = gs.image.y, j = gs.image.x;
const u8* pbuf = (const u8*)pbyMem;
int nLeftOver = (nQWordSize*4*2)%(TRANSMIT_PITCH<psmX>(2));
int nSize = nQWordSize*4*2/TRANSMIT_PITCH<psmX>(2);
nSize = min(nSize, gs.imageNew.w * gs.imageNew.h);
int pitch, area, fracX;
int endY = ROUND_UPPOW2(i, blockheight);
Point alignedPt;
alignedPt.x = ROUND_DOWNPOW2(gs.imageEnd.x, blockwidth);
alignedPt.y = ROUND_DOWNPOW2(gs.imageEnd.y, blockheight);
bool bAligned;
bool bCanAlign = MOD_POW2(gs.trxpos.dx, blockwidth) == 0 && (j == gs.trxpos.dx) && (alignedPt.y > endY) && alignedPt.x > gs.trxpos.dx;
if( (gs.imageEnd.x - gs.trxpos.dx) % widthlimit ) {
/* hack */
int testwidth = (int)nSize - (gs.imageEnd.y - i) * (gs.imageEnd.x - gs.trxpos.dx) + (j - gs.trxpos.dx);
if((testwidth <= widthlimit) && (testwidth >= -widthlimit)) {
/* don't transfer */
/*ZZLog::Debug_Log("bad texture %s: %d %d %d\n", #psm, gs.trxpos.dx, gs.imageEnd.x, nQWordSize);*/
gs.transferring = false;
}
bCanAlign = false;
}
/* first align on block boundary */
if( MOD_POW2(i, blockheight) || !bCanAlign ) {
if( !bCanAlign )
endY = gs.imageEnd.y; /* transfer the whole image */
else
assert( endY < gs.imageEnd.y); /* part of alignment condition */
int limit = widthlimit;
if (((gs.imageEnd.x - gs.trxpos.dx) % widthlimit) || ((gs.imageEnd.x - j) % widthlimit))
/* transmit with a width of 1 */
limit = 1 + (gs.dstbuf.psm == PSMT4);
/*TRANSMIT_HOSTLOCAL_Y##TransSfx(psm, T, limit, endY)*/
int k = 0;
if (TRANSMIT_HOSTLOCAL_Y<psmX, widthlimit>((u32*)pbuf, nSize, pstart, endY, i, j, k))
return FinishTransfer<psmX>(i, j, nSize, nLeftOver);
pbuf += TRANSMIT_PITCH<psmX>(k);
if (nSize == 0 || i == gs.imageEnd.y) return FinishTransfer<psmX>(i, j, nSize, nLeftOver);
}
assert( MOD_POW2(i, blockheight) == 0 && j == gs.trxpos.dx);
/* can align! */
pitch = gs.imageEnd.x - gs.trxpos.dx;
area = pitch * blockheight;
fracX = gs.imageEnd.x - alignedPt.x;
/* on top of checking whether pbuf is aligned, make sure that the width is at least aligned to its limits (due to bugs in pcsx2) */
bAligned = !((uptr)pbuf & 0xf) && ((TRANSMIT_PITCH<psmX>(pitch)&0xf) == 0);
/* transfer aligning to blocks */
for(; i < alignedPt.y && nSize >= area; i += blockheight, nSize -= area) {
for(int tempj = gs.trxpos.dx; tempj < alignedPt.x; tempj += blockwidth, pbuf += TRANSMIT_PITCH<psmX>(blockwidth)) {
SwizzleBlock<psmX>((u32*)(pstart + getPixelAddress<psmX>(tempj, i, gs.dstbuf.bw)*blockbits/8),
(u32*)pbuf, TRANSMIT_PITCH<psmX>(pitch));
}
/* transfer the rest */
if( alignedPt.x < gs.imageEnd.x ) {
int k = 0;
TRANSMIT_HOSTLOCAL_X<psmX, widthlimit>((u32*)pbuf, nSize, pstart, i, j, k, blockheight, alignedPt.x, pitch, fracX);
pbuf += TRANSMIT_PITCH<psmX>(k - alignedPt.x + gs.trxpos.dx);
}
else pbuf += (blockheight-1)*TRANSMIT_PITCH<psmX>(pitch);
j = gs.trxpos.dx;
}
if( TRANSMIT_PITCH<psmX>(nSize)/4 > 0 ) {
int k = 0;
TRANSMIT_HOSTLOCAL_Y<psmX, widthlimit>((u32*)pbuf, nSize, pstart, gs.imageEnd.y, i, j, k);
pbuf += TRANSMIT_PITCH<psmX>(k);
/* sometimes wrong sizes are sent (tekken tag) */
assert( gs.transferring == false || TRANSMIT_PITCH<psmX>(nSize)/4 <= 2 );
}
return FinishTransfer<psmX>(i, j, nSize, nLeftOver);
}
inline int TransferHostLocal32(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMCT32, 2, 32, 8, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal32Z(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT32Z, 2, 32, 8, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal24(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMCT24, 8, 32, 8, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal24Z(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT24Z, 8, 32, 8, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal16(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMCT16, 4, 16, 16, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal16S(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMCT16S, 4, 16, 16, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal16Z(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT16Z, 4, 16, 16, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal16SZ(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT16SZ, 4, 16, 16, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal8(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT8, 4, 8, 16, 16>( pbyMem, nQWordSize);
}
inline int TransferHostLocal4(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT4, 8, 4, 32, 16>( pbyMem, nQWordSize);
}
inline int TransferHostLocal8H(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT8H, 4, 32, 8, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal4HL(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT4HL, 8, 32, 8, 8>( pbyMem, nQWordSize);
}
inline int TransferHostLocal4HH(const void* pbyMem, u32 nQWordSize)
{
return TransferHostLocal<PSMT4HH, 8, 32, 8, 8>( pbyMem, nQWordSize);
}
void TransferLocalHost32(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost24(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost16(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost16S(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost8(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost4(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost8H(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost4HL(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost4HH(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost32Z(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost24Z(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost16Z(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost16SZ(void* pbyMem, u32 nQWordSize) { FUNCLOG }
inline void FILL_BLOCK(BLOCK& b, vector<char>& vBlockData, vector<char>& vBilinearData, int ox, int oy, int psmX) {
int bw = ZZ_DT[psmX][4] + 1;
int bh = ZZ_DT[psmX][3] + 1;
int mult = 1 << ZZ_DT[psmX][0];
b.vTexDims = float4 (BLOCK_TEXWIDTH/(float)(bw), BLOCK_TEXHEIGHT/(float)(bh), 0, 0);
b.vTexBlock = float4( (float)bw/BLOCK_TEXWIDTH, (float)bh/BLOCK_TEXHEIGHT, ((float)ox+0.2f)/BLOCK_TEXWIDTH, ((float)oy+0.05f)/BLOCK_TEXHEIGHT);
b.width = bw;
b.height = bh;
b.colwidth = bh / 4;
b.colheight = bw / 8;
b.bpp = 32/mult;
b.pageTable = g_pageTable[psmX];
b.blockTable = g_blockTable[psmX];
b.columnTable = g_columnTable[psmX];
// This is never true.
//assert( sizeof(g_pageTable[psmX]) == bw*bh*sizeof(g_pageTable[psmX][0][0]) );
float* psrcf = (float*)&vBlockData[0] + ox + oy * BLOCK_TEXWIDTH;
for(int i = 0; i < bh; ++i) {
for(int j = 0; j < bw; ++j) {
/* fill the table */
u32 u = g_blockTable[psmX][(i / b.colheight)][(j / b.colwidth)] * 64 * mult + g_columnTable[psmX][i%b.colheight][j%b.colwidth];
b.pageTable[i][j] = u;
psrcf[i*BLOCK_TEXWIDTH+j] = (float)(u) / (float)(GPU_TEXWIDTH*mult);
}
}
float4* psrcv = (float4*)&vBilinearData[0] + ox + oy * BLOCK_TEXWIDTH;
for(int i = 0; i < bh; ++i) {
for(int j = 0; j < bw; ++j) {
float4* pv = &psrcv[i*BLOCK_TEXWIDTH+j];
pv->x = psrcf[i*BLOCK_TEXWIDTH+j];
pv->y = psrcf[i*BLOCK_TEXWIDTH+((j+1)%bw)];
pv->z = psrcf[((i+1)%bh)*BLOCK_TEXWIDTH+j];
pv->w = psrcf[((i+1)%bh)*BLOCK_TEXWIDTH+((j+1)%bw)];
}
}
}
void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData)
{
FUNCLOG
vBlockData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * (floatfmt ? 4 : 2));
if (floatfmt)
vBilinearData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * sizeof(float4));
BLOCK b;
memset(m_Blocks, 0, sizeof(m_Blocks));
// 32
FILL_BLOCK(b, vBlockData, vBilinearData, 0, 0, PSMCT32);
b.TransferHostLocal = TransferHostLocal32;
b.TransferLocalHost = TransferLocalHost32;
m_Blocks[PSMCT32] = b;
// 24 (same as 32 except write/readPixel are different)
b.TransferHostLocal = TransferHostLocal24;
b.TransferLocalHost = TransferLocalHost24;
m_Blocks[PSMCT24] = b;
// 8H (same as 32 except write/readPixel are different)
b.TransferHostLocal = TransferHostLocal8H;
b.TransferLocalHost = TransferLocalHost8H;
m_Blocks[PSMT8H] = b;
b.TransferHostLocal = TransferHostLocal4HL;
b.TransferLocalHost = TransferLocalHost4HL;
m_Blocks[PSMT4HL] = b;
b.TransferHostLocal = TransferHostLocal4HH;
b.TransferLocalHost = TransferLocalHost4HH;
m_Blocks[PSMT4HH] = b;
// 32z
FILL_BLOCK(b, vBlockData, vBilinearData, 64, 0, PSMT32Z);
b.TransferHostLocal = TransferHostLocal32Z;
b.TransferLocalHost = TransferLocalHost32Z;
m_Blocks[PSMT32Z] = b;
// 24Z (same as 32Z except write/readPixel are different)
b.TransferHostLocal = TransferHostLocal24Z;
b.TransferLocalHost = TransferLocalHost24Z;
m_Blocks[PSMT24Z] = b;
// 16
FILL_BLOCK(b, vBlockData, vBilinearData, 0, 32, PSMCT16);
b.TransferHostLocal = TransferHostLocal16;
b.TransferLocalHost = TransferLocalHost16;
m_Blocks[PSMCT16] = b;
// 16s
FILL_BLOCK(b, vBlockData, vBilinearData, 64, 32, PSMCT16S);
b.TransferHostLocal = TransferHostLocal16S;
b.TransferLocalHost = TransferLocalHost16S;
m_Blocks[PSMCT16S] = b;
// 16z
FILL_BLOCK(b, vBlockData, vBilinearData, 0, 96, PSMT16Z);
b.TransferHostLocal = TransferHostLocal16Z;
b.TransferLocalHost = TransferLocalHost16Z;
m_Blocks[PSMT16Z] = b;
// 16sz
FILL_BLOCK(b, vBlockData, vBilinearData, 64, 96, PSMT16SZ);
b.TransferHostLocal = TransferHostLocal16SZ;
b.TransferLocalHost = TransferLocalHost16SZ;
m_Blocks[PSMT16SZ] = b;
// 8
FILL_BLOCK(b, vBlockData, vBilinearData, 0, 160, PSMT8);
b.TransferHostLocal = TransferHostLocal8;
b.TransferLocalHost = TransferLocalHost8;
m_Blocks[PSMT8] = b;
// 4
FILL_BLOCK(b, vBlockData, vBilinearData, 0, 224, PSMT4);
b.TransferHostLocal = TransferHostLocal4;
b.TransferLocalHost = TransferLocalHost4;
m_Blocks[PSMT4] = b;
}
#endif

View File

@ -1,790 +0,0 @@
/* ZeroGS KOSMOS
* Copyright (C) 2005-2006 zerofrog@gmail.com
*
* 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
*/
#ifndef __ZZOGL_MEM_H__
#define __ZZOGL_MEM_H__
#include <assert.h>
#include <vector>
#include "GS.h"
#include "Util.h"
#include "Mem.h"
#ifndef ZZNORMAL_MEMORY
extern u32 g_blockTable32[4][8];
extern u32 g_blockTable32Z[4][8];
extern u32 g_blockTable16[8][4];
extern u32 g_blockTable16S[8][4];
extern u32 g_blockTable16Z[8][4];
extern u32 g_blockTable16SZ[8][4];
extern u32 g_blockTable8[4][8];
extern u32 g_blockTable4[8][4];
extern u32 g_columnTable32[8][8];
extern u32 g_columnTable16[8][16];
extern u32 g_columnTable8[16][16];
extern u32 g_columnTable4[16][32];
//--
extern u32 g_pageTable32[32][64];
extern u32 g_pageTable32Z[32][64];
extern u32 g_pageTable16[64][64];
extern u32 g_pageTable16S[64][64];
extern u32 g_pageTable16Z[64][64];
extern u32 g_pageTable16SZ[64][64];
extern u32 g_pageTable8[64][128];
extern u32 g_pageTable4[128][128];
//maximum PSM is 58, so our arrays have 58 + 1 = 59 elements
// This table is used for fast access to memory storage data.
extern u32 ZZ_DT[MAX_PSM][TABLE_WIDTH];
//maxium PSM is 58, so our arrays have 58 + 1 = 59 elements
extern u32** g_pageTable[MAX_PSM];
extern u32** g_blockTable[MAX_PSM];
extern u32** g_columnTable[MAX_PSM];
extern u32 g_pageTable2[MAX_PSM][127][127];
extern u32** g_pageTableNew[MAX_PSM];
// rest not visible externally
struct BLOCK
{
BLOCK() { memset(this, 0, sizeof(BLOCK)); }
// shader constants for this block
float4 vTexBlock;
float4 vTexDims;
int width, height; // dims of one page in pixels
int bpp;
int colwidth, colheight;
u32** pageTable; // offset inside each page
u32** blockTable;
u32** columnTable;
// Nobody use this, so we better remove it.
// u32 (*getPixelAddress)(int x, int y, u32 bp, u32 bw);
// u32 (*getPixelAddress_0)(int x, int y, u32 bw);
// void (*writePixel)(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw);
// void (*writePixel_0)(void* pmem, int x, int y, u32 pixel, u32 bw);
// u32 (*readPixel)(const void* pmem, int x, int y, u32 bp, u32 bw);
// u32 (*readPixel_0)(const void* pmem, int x, int y, u32 bw);
int (*TransferHostLocal)(const void* pbyMem, u32 nQWordSize);
void (*TransferLocalHost)(void* pbyMem, u32 nQWordSize);
// texture must be of dims BLOCK_TEXWIDTH and BLOCK_TEXHEIGHT
static void FillBlocks(std::vector<char>& vBlockData, std::vector<char>& vBilinearData);
};
void FillBlockTables();
void DestroyBlockTables();
void FillNewPageTable();
extern BLOCK m_Blocks[];
extern u32 g_blockTable32[4][8];
extern u32 g_blockTable32Z[4][8];
extern u32 g_blockTable16[8][4];
extern u32 g_blockTable16S[8][4];
extern u32 g_blockTable16Z[8][4];
extern u32 g_blockTable16SZ[8][4];
extern u32 g_blockTable8[4][8];
extern u32 g_blockTable4[8][4];
extern u32 g_columnTable32[8][8];
extern u32 g_columnTable16[8][16];
extern u32 g_columnTable8[16][16];
extern u32 g_columnTable4[16][32];
extern u32 g_pageTable32[32][64];
extern u32 g_pageTable32Z[32][64];
extern u32 g_pageTable16[64][64];
extern u32 g_pageTable16S[64][64];
extern u32 g_pageTable16Z[64][64];
extern u32 g_pageTable16SZ[64][64];
extern u32 g_pageTable8[64][128];
extern u32 g_pageTable4[128][128];
extern u32** g_pageTable[MAX_PSM];
extern u32** g_blockTable[MAX_PSM];
extern u32** g_columnTable[MAX_PSM];
extern u32 ZZ_DT[MAX_PSM][TABLE_WIDTH];
extern u32** g_pageTableNew[MAX_PSM];
static __forceinline void MaskedOR(u32* dst, u32 pixel, u32 mask = 0xffffffff) {
if (mask == 0xffffffff)
*dst = pixel;
else
*dst = (*dst & (~mask)) | (pixel & mask);
}
// This two defines seems like idiotic code, but in reality it have one, but big importance -- this code
// made psm variable (and psm2 in second case) -- constant, so optimiser could properly pass proper function
#define PSM_SWITCHCASE(X) { \
switch (psm) { \
case PSMCT32: { \
const int psmC = PSMCT32; \
X; } \
break; \
case PSMT32Z: { \
const int psmC = PSMT32Z; \
X; } \
break; \
case PSMCT24: { \
const int psmC = PSMCT24; \
X; } \
break; \
case PSMT24Z: { \
const int psmC = PSMT24Z; \
X; } \
break; \
case PSMCT16: { \
const int psmC = PSMCT16; \
X; } \
break; \
case PSMCT16S: { \
const int psmC = PSMCT16S; \
X; } \
break; \
case PSMT16Z: { \
const int psmC = PSMT16Z; \
X; } \
break; \
case PSMT16SZ: { \
const int psmC = PSMT16SZ; \
X; } \
break; \
case PSMT8: { \
const int psmC = PSMT8; \
X; } \
break; \
case PSMT8H: { \
const int psmC = PSMT8H; \
X; } \
break; \
case PSMT4HH: { \
const int psmC = PSMT4HH; \
X; } \
break; \
case PSMT4HL: { \
const int psmC = PSMT4HL; \
X; } \
break; \
case PSMT4: { \
const int psmC = PSMT4; \
X; } \
break; \
}\
}
#define PSM_SWITCHCASE_2(X) { \
switch (psm) { \
case PSMCT32: \
if( psm2 == PSMCT32 ) { const int psmC = PSMCT32, psmC1 = PSMCT32; X; } \
else { const int psmC = PSMCT32, psmC1 = PSMT32Z; X; } \
break; \
case PSMCT24: \
if( psm2 == PSMCT24 ) { const int psmC = PSMCT24, psmC1 = PSMCT24; X; } \
else { const int psmC = PSMCT24, psmC1 = PSMT24Z; X; } \
break; \
case PSMT32Z: \
if( psm2 == PSMT32Z ) { const int psmC = PSMT32Z, psmC1 = PSMCT32; X; } \
else { const int psmC = PSMT32Z, psmC1 = PSMT32Z; X; } \
break; \
case PSMT24Z: \
if( psm2 == PSMCT24 ) { const int psmC = PSMT24Z, psmC1 = PSMCT24; X; } \
else { const int psmC = PSMT24Z, psmC1 = PSMT24Z; X; } \
break; \
case PSMCT16: \
switch(psm2) { \
case PSMCT16: { const int psmC = PSMCT16, psmC1 = PSMCT16; X; } break; \
case PSMCT16S: { const int psmC = PSMCT16, psmC1 = PSMCT16S; X; } break; \
case PSMT16Z: { const int psmC = PSMCT16, psmC1 = PSMT16Z; X; } break; \
case PSMT16SZ: { const int psmC = PSMCT16, psmC1 = PSMT16SZ; X; } break; \
} \
break; \
case PSMCT16S: \
switch(psm2) { \
case PSMCT16: { const int psmC = PSMCT16S, psmC1 = PSMCT16; X; } break; \
case PSMCT16S: { const int psmC = PSMCT16S, psmC1 = PSMCT16S; X; } break; \
case PSMT16Z: { const int psmC = PSMCT16S, psmC1 = PSMT16Z; X; } break; \
case PSMT16SZ: { const int psmC = PSMCT16S, psmC1 = PSMT16SZ; X; } break; \
} \
break; \
case PSMT16Z: \
switch(psm2) { \
case PSMCT16: { const int psmC = PSMT16Z, psmC1 = PSMCT16; X; } break; \
case PSMCT16S: { const int psmC = PSMT16Z, psmC1 = PSMCT16S; X; } break; \
case PSMT16Z: { const int psmC = PSMT16Z, psmC1 = PSMT16Z; X; } break; \
case PSMT16SZ: { const int psmC = PSMT16Z, psmC1 = PSMT16SZ; X; } break; \
} \
break; \
case PSMT16SZ: \
switch(psm2) { \
case PSMCT16: { const int psmC = PSMT16SZ, psmC1 = PSMCT16; X; } break; \
case PSMCT16S: { const int psmC = PSMT16SZ, psmC1 = PSMCT16S; X; } break; \
case PSMT16Z: { const int psmC = PSMT16SZ, psmC1 = PSMT16Z; X; } break; \
case PSMT16SZ: { const int psmC = PSMT16SZ, psmC1 = PSMT16SZ; X; } break; \
} \
break; \
case PSMT8: \
if( psm2 == PSMT8 ) { const int psmC = PSMT8, psmC1 = PSMT8; X; } \
else { const int psmC = PSMT8, psmC1 = PSMT8H; X; } \
break; \
case PSMT8H: \
if( psm2 == PSMT8H ) { const int psmC = PSMT8H, psmC1 = PSMT8; X; } \
else { const int psmC = PSMT8H, psmC1 = PSMT8H; X; } \
break; \
case PSMT4: \
switch(psm2) { \
case PSMT4: { const int psmC = PSMT4, psmC1 = PSMT4; X; } break; \
case PSMT4HL: { const int psmC = PSMT4, psmC1 = PSMT4HL; X; } break; \
case PSMT4HH: { const int psmC = PSMT4, psmC1 = PSMT4HH; X; } break; \
} \
break; \
case PSMT4HL: \
switch(psm2) { \
case PSMT4: { const int psmC = PSMT4HL, psmC1 = PSMT4; X; } break; \
case PSMT4HL: { const int psmC = PSMT4HL, psmC1 = PSMT4HL; X; } break; \
case PSMT4HH: { const int psmC = PSMT4HL, psmC1 = PSMT4HH; X; } break; \
} \
break; \
case PSMT4HH: \
switch(psm2) { \
case PSMT4: { const int psmC = PSMT4HH, psmC1 = PSMT4; X; } break; \
case PSMT4HL: { const int psmC = PSMT4HH, psmC1 = PSMT4HL; X; } break; \
case PSMT4HH: { const int psmC = PSMT4HH, psmC1 = PSMT4HH; X; } break; \
} \
break; \
} \
}
template <int psm>
static __forceinline void setPsmtConstantsX(u8& A, u8& B, u8& C, u8& D, u8& E, u8& F, u32& G, u8& H) {
switch (psm) {
case PSMCT32:
case PSMT32Z:
A = 5; B = 6; C = 0; D = 31; E = 63; F = 0; H = 1; G = 0xffffffff;
break;
case PSMCT24:
case PSMT24Z:
A = 5; B = 6; C = 0; D = 31; E = 63; F = 0; H = 1; G = 0xffffff;
break;
case PSMT8H:
A = 5; B = 6; C = 0; D = 31; E = 63; F = 24; H = 4; G = 0xff;
break;
case PSMT4HH:
A = 5; B = 6; C = 0; D = 31; E = 63; F = 28; H = 8; G = 0xf;
break;
case PSMT4HL:
A = 5; B = 6; C = 0; D = 31; E = 63; F = 24; H = 8; G = 0xf;
break;
case PSMCT16:
case PSMT16Z:
case PSMCT16S:
case PSMT16SZ:
A = 6; B = 6; C = 1; D = 63; E = 63; F = 0; H = 2; G = 0xffff;
break;
case PSMT8:
A = 6; B = 7; C = 2; D = 63; E = 127; F = 0; H = 4; G = 0xff;
break;
case PSMT4:
A = 7; B = 7; C = 3; D = 127; E = 127; F = 0; H = 8; G = 0xf;
break;
}
}
// This is where the NEW_CODE define used to be.
// ------------------------------------------ get Address functions ------------------------------------
// Yes, only 1 function to all cases of life!
// Warning! We switch bp and bw for usage of default value, so be warned! It's
// not C, it's C++, so not it.
template <int psm>
static __forceinline u32 getPixelAddress(int x, int y, u32 bw, u32 bp = 0) {
u32 basepage;
u32 word;
u8 A = 0, B = 0, C = 0, D = 0, E = 0, F = 0; u32 G = 0; u8 H= 0;
setPsmtConstantsX<psm>(A, B, C, D, E, F, G, H);
basepage = ((y>>A) * (bw>>B)) + (x>>B);
word = ((bp * 64 + basepage * 2048) << C) + g_pageTable[psm][y&D][x&E];
return word;
}
// It's Zerofrog's function. I need to eliminate them all! All access should be 32-bit aligned.
static __forceinline u32 getPixelAddress(int psm, int x, int y, u32 bw, u32 bp = 0) {
PSM_SWITCHCASE(return getPixelAddress<psmC>(x, y, bw, bp) ;)
return 0;
}
// This is compatibility code, for reference,
#define Def_getPixelAddress(psmT, psmX) \
static __forceinline u32 getPixelAddress##psmT(int x, int y, u32 bp, u32 bw) { \
return getPixelAddress<psmX>(x, y, bw, bp); } \
static __forceinline u32 getPixelAddress##psmT##_0(int x, int y, u32 bw) { \
return getPixelAddress<psmX>(x, y, bw); } \
Def_getPixelAddress(32, PSMCT32)
Def_getPixelAddress(16, PSMCT16)
Def_getPixelAddress(16S, PSMCT16S)
Def_getPixelAddress(8, PSMT8)
Def_getPixelAddress(4, PSMT4)
Def_getPixelAddress(32Z, PSMT32Z)
Def_getPixelAddress(16Z, PSMT16Z)
Def_getPixelAddress(16SZ, PSMT16SZ)
#define getPixelAddress24 getPixelAddress32
#define getPixelAddress24_0 getPixelAddress32_0
#define getPixelAddress8H getPixelAddress32
#define getPixelAddress8H_0 getPixelAddress32_0
#define getPixelAddress4HL getPixelAddress32
#define getPixelAddress4HL_0 getPixelAddress32_0
#define getPixelAddress4HH getPixelAddress32
#define getPixelAddress4HH_0 getPixelAddress32_0
#define getPixelAddress24Z getPixelAddress32Z
#define getPixelAddress24Z_0 getPixelAddress32Z_0
// Check FFX-1 (very begining) for PSMT8
// Check Tekken menu for PSMT4
// ZZ_DT[7] is needed only for PSMT8H, PSMT4HL and PSMT4HH -- at this case word contain data not from a begining.
// This function return shift from 32-bit aligned address and shift -- number of byte in u32 order.
// so if ((u32*)mem + getPixelAddress_Aligned32) is exact location of u32, where our pixel data stored.
// Just for remember:
// PMSCT32, 24, 32Z, 24Z, 8HH, 4HL and 4HH have ZZ_DT[psm] == 3, so shift is always 0.
// PSMCT16, 16S, 16SZ, 16Z have ZZ_DT[psm] == 2, so shift is 0 or 16.
// PSMT8 ZZ_DT[psm] == 1, shift is 0, 8, 16, 24
// PSMT4 ZZ_DT[psm] == 0, shift is 0, 4, 8, 12, 16, 20, 24, 28.
// It allow us to made a fast access to pixels in the same basepage: if x % N == 0 (N = 1, 2, 4, 8, .. 64)
// than we could guarantee that all pixels form x to x + N - 1 are in the same basepage.
template <int psm>
static __forceinline u32* getPixelBasepage(const void* pmem, int x, int y, u32 bw, u32 bp = 0) {
u32 basepage;
u8 A = 0, B = 0, C = 0 , D = 0, E = 0, F = 0; u32 G = 0; u8 H = 0;
setPsmtConstantsX<psm> (A, B, C, D, E, F, G, H);
basepage = ((y>>A) * (bw>>B)) + (x>>B);
return ((u32*)pmem + (bp * 64 + basepage * 2048));
}
// And this is offset for this pixels.
template <int psm>
static __forceinline u32* getPixelOffset(u32& mask, u32& shift, const void* pmem, int x, int y) {
u32 word;
u8 A = 0, B = 0, C = 0 , D = 0, E = 0, F = 0; u32 G = 0; u8 H = 0;
setPsmtConstantsX<psm> (A, B, C, D, E, F, G, H);
word = (g_pageTable[psm][y&D][x&E] << (3 - C));
shift = ((word & 0x7) << 2) + F;
mask &= G << shift;
return ((u32*)pmem + ((word & ~0x7) >> 3));
}
template <int psm>
static __forceinline u32* getPixelAddress_A32(u32& mask, u32& shift, const void* pmem, int x, int y, u32 bw, u32 bp = 0) {
return getPixelOffset<psm>(mask, shift, getPixelBasepage<psm>(pmem, x, y, bw, bp), x, y);
}
template <int psm>
static __forceinline u32* getPixelBaseAddress_A32(const void* pmem, int x, int y, u32 bw, u32 bp = 0) {
u32 word;
u8 A = 0, B = 0, C = 0 , D = 0, E = 0, F = 0; u32 G = 0; u8 H = 0;
setPsmtConstantsX<psm> (A, B, C, D, E, F, G, H);
word = (g_pageTable[psm][y&D][x&E] << (3 - C));
return ((u32*)getPixelBasepage<psm>(pmem, x, y, bw, bp) + ((word & ~0x7) >> 3));
}
// Wrapper for cases, where psm is not constant, should be avoided inside cycles
static __forceinline u32* getPixelAddress_A32(u32& mask, u32& shift, int psm, const void* pmem, int x, int y, u32 bw, u32 bp = 0) {
PSM_SWITCHCASE( return getPixelAddress_A32<psmC>(mask, shift, pmem, x, y, bw, bp) );
return 0;
}
static __forceinline u32* getClutAddress(u8* pmem, const tex0Info& tex0) {
if (PSMT_ISHALF(tex0.cpsm))
return (u32*)(pmem + 64 * (tex0.csa & 15) + (tex0.csa >= 16 ? 2 : 0) );
else
return (u32*)(pmem + 64 * (tex0.csa & 15));
}
//--------------------------------------------- Write Pixel -----------------------------------------------------------
// Set proper mask for transfering multiple bytes per word.
template <int psm>
inline u32 HandleWritemask(u32 Writemask) {
u8 G = PSM_BITS_PER_PIXEL<psm>();
u32 dmask = Writemask & ((1 << G) - 1); // drop all bits in writemask, that could not be used
u32 mask;
switch (psm) {
case PSMT8H: // modes with non-zero start bit should be handled differently
return 0xff000000;
case PSMT4HL:
return 0x0f000000;
case PSMT4HH:
return 0xf0000000;
default:
mask = dmask; // 32 targets and lower
if (G < 24) {
mask |= dmask << G; // 16 targets and lower
if (G < 16) {
mask |= dmask << (2 * G); // 8 targets and lower
mask |= dmask << (3 * G);
if (G < 8) {
mask |= dmask << (4 * G); // 4 targets
mask |= dmask << (5 * G);
mask |= dmask << (6 * G);
mask |= dmask << (7 * G);
}}}
return mask;
}
}
//push pixel data at position x,y, according psm storage format. pixel do not need to be properly masked, wrong bit's would not be used
//mask should be made according PSM.
template <int psm>
static __forceinline void writePixel(void* pmem, int x, int y, u32 pixel, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
u32 shift;
u32* p = getPixelAddress_A32<psm>(mask, shift, pmem, x, y, bw, bp);
MaskedOR (p, pixel << shift, mask);
}
static __forceinline void writePixel(int psm, void* pmem, int x, int y, u32 pixel, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
PSM_SWITCHCASE(writePixel<psmC>(pmem, x, y, pixel, bw, bp, mask));
}
// Put pixel data from memory. Pixel is p, memory start from pixel, and we should count pmove words and shift resulting word to shift
// 24 targets could be outside of 32-bit borders.
template <int psm>
static __forceinline void pushPixelMem(u32* p, u32* pixel, int pmove, int shift, u32 mask = 0xffffffff) {
if (psm != PSMCT24 || psm != PSMT24Z) {
if (shift > 0)
MaskedOR (p, (*(pixel + pmove)) << (shift), mask);
else
MaskedOR (p, (*(pixel + pmove)) >> (-shift), mask);
}
else { // for 24 and 24Z psm data could be not-aligned by 32. Merde!
u64 pixel64 = (*(u64*)(pixel + pmove) ) >> (-shift); // we read more data, but for 24 targets shift always negative and resulting data is u32
MaskedOR(p, (u32)pixel64, mask); // drop upper part, we don't need it. all data is stored in lower part of u64 after shift
// MaskedOR(p, (u32)((u8*)pixel + count * 3), mask);
}
}
// use it if pixel already shifted by needed number of bytes.
// offseted mean that we should skip basepage calculation, pmem is link to basepage'ed memory. Just a little quicker.
template <int psm, int offseted>
static __forceinline void writePixelMem(const void* pmem, int x, int y, u32* pixel, int count, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
u32 shift;
u32* p;
if (offseted)
p = getPixelOffset<psm>(mask, shift, pmem, x, y);
else
p = getPixelAddress_A32<psm>(mask, shift, pmem, x, y, bw, bp);
int A = PSM_BITS_PER_PIXEL<psm>();
int pmove = (count * A) >> 5;
int pshift = (count * A) & 31; // we assume, that if shift outside word, than user want next pixel data
pushPixelMem<psm>(p, pixel, pmove, (int)shift - pshift, mask);
}
// This function push several pixels. Note, that for 32, 24, 8HH, 4HL, 4HH it's simply write (and pixel should not be properly masked), 16 do push 2 pixels (and x should be even).
// 8 push 4 pixels: 0,0; 0,1; 1,0 and 1,1. 4 push 8: 0,0; 0,1; 1,0; 1,1; 2,0, 2,1; 3,0; 3,1.
template <int psm>
static __forceinline void writePixelWord(const void* pmem, int x, int y, u32 pixel, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
u32 maskA = mask, shift;
u32* p = getPixelAddress_A32<psm>(maskA, shift, pmem, x, y, bw, bp);
/* if (PSM_NON_FULL_WORD<psm>())
maskA = maskA & mask;
else
maskA = mask;*/
MaskedOR (p, pixel, mask);
}
// ------------------------------------- Read Pixel ---------------------------------------
template <int psm>
static __forceinline u32 readPixel(const void* pmem, int x, int y, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
u32 shift;
u32* p = getPixelAddress_A32<psm>(mask, shift, pmem, x, y, bw, bp);
return ((*p & mask) >> shift);
}
static __forceinline u32 readPixel(int psm, const void* pmem, int x, int y, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
PSM_SWITCHCASE(return readPixel<psmC>(pmem, x, y, bw, bp, mask););
return 0;
}
template <int psm>
static __forceinline u32 readPixelWord(const void* pmem, int x, int y, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
u32 maskA = 0xffffffff, shift;
if (PSM_NON_FULL_WORD<psm>())
return *getPixelAddress_A32<psm>(mask, shift, pmem, x, y, bw, bp) & mask;
else
return *getPixelAddress_A32<psm>(maskA, shift, pmem, x, y, bw, bp) & mask;
}
template <int psm>
static __forceinline void fillMemoryFromPixels(u32* dst, const void* pmem, int& count, int x, int y, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
u32 pixel;
u8 I = PSM_BITS_PER_PIXEL<psm>();
int K = count / PSM_PIXELS_STORED_PER_WORD<psm>(); // offset for pmem, count for 32, count / 2 for 16, etc.
pixel = readPixel<psm>(pmem, x, y, bw, bp, mask); // I prefer not to use for here. It's slow
if (I < 32) {
pixel += readPixel<psm>(pmem, x + 1, y, bw, bp, mask) << I;
if (I < 16) { // 8 and 4 targets
pixel += readPixel<psm>(pmem, x + 2, y, bw, bp, mask) << (2 * I);
pixel += readPixel<psm>(pmem, x + 3, y, bw, bp, mask) << (3 * I);
if (I < 8) { // This is for 4, 4HH and 4HL
pixel += readPixel<psm>(pmem, x + 4, y, bw, bp, mask) << (4 * I);
pixel += readPixel<psm>(pmem, x + 5, y, bw, bp, mask) << (5 * I);
pixel += readPixel<psm>(pmem, x + 6, y, bw, bp, mask) << (6 * I);
pixel += readPixel<psm>(pmem, x + 7, y, bw, bp, mask) << (7 * I);
}}}
if (I != 24) {
*(dst + K) = pixel;
}
else { // 24. should have special care.
// ERROR_LOG("special care %d\n", count);
MaskedOR((u32*)((u8*)dst + 3 * count), pixel, 0xffffff);
}
count += PSM_PIXELS_STORED_PER_WORD<psm>();
}
// Fill count pixels form continues memory region, starting from pmem, First pixel to read have number shift in this region.
// Read no more than count pixels. We could assert, that all this pixels would be place in the same basepage
// Shift is automaticaly increased by count (or decreased if count < 0)
template <int psm, bool offseted, int count>
static __forceinline void writePixelsFromMemory(void* dst, const void* pmem, int& shift, int x, int y, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
const void* base;
if (offseted)
base = getPixelBasepage<psm>(dst, x, y, bw, bp);
else
base = (const void*)dst;
shift += count;
writePixelMem<psm, offseted>(base, x, y, (u32*)pmem, shift - count, bw, bp, mask); // I prefer not to use for here. It's slow
if (count < 2) return;
writePixelMem<psm, offseted>(base, x + 1, y, (u32*)pmem, shift - count + 1, bw, bp, mask);
if (count < 3) return;
writePixelMem<psm, offseted>(base, x + 2, y, (u32*)pmem, shift - count + 2, bw, bp, mask);
if (count < 4) return;
writePixelMem<psm, offseted>(base, x + 3, y, (u32*)pmem, shift - count + 3, bw, bp, mask);
if (count < 5) return;
writePixelMem<psm, offseted>(base, x + 4, y, (u32*)pmem, shift - count + 4, bw, bp, mask);
if (count < 6) return;
writePixelMem<psm, offseted>(base, x + 5, y, (u32*)pmem, shift - count + 5, bw, bp, mask);
if (count < 7) return;
writePixelMem<psm, offseted>(base, x + 6, y, (u32*)pmem, shift - count + 6, bw, bp, mask);
if (count < 8) return;
writePixelMem<psm, offseted>(base, x + 7, y, (u32*)pmem, shift - count + 7, bw, bp, mask);
}
// Use it if we don't know that starting pixel is aligned for multiple-pixel write
template <int psm, bool offseted>
static __forceinline void writeUnalignedPixelsFromMemory(void* dst, int div, const void* pmem, int& shift, int x, int y, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
switch (div){
case 0: return; // Pixels are aligned, so we could move on
case 1: writePixelsFromMemory<psm, offseted, 1>(dst, pmem, shift, x, y, bw, bp, mask);
return;
case 2: writePixelsFromMemory<psm, offseted, 2>(dst, pmem, shift, x, y, bw, bp, mask);
return;
case 3: writePixelsFromMemory<psm, offseted, 3>(dst, pmem, shift, x, y, bw, bp, mask);
return;
case 4: writePixelsFromMemory<psm, offseted, 4>(dst, pmem, shift, x, y, bw, bp, mask);
return;
case 5: writePixelsFromMemory<psm, offseted, 5>(dst, pmem, shift, x, y, bw, bp, mask);
return;
case 6: writePixelsFromMemory<psm, offseted, 6>(dst, pmem, shift, x, y, bw, bp, mask);
return;
case 7: writePixelsFromMemory<psm, offseted, 7>(dst, pmem, shift, x, y, bw, bp, mask);
return;
}
}
// This little swizzle function used to convert data form memory. z is first byte in destination block, and y is number of word, in which we look look for data.
// s is shift by number of pixels, that should be used in masking
template <int psm, int y, int z>
static __forceinline u32 BitmaskinPSM(u32* pmem, u8 x) {
u8 H = PSM_BITCOUNT<psm>();
u8 I = PSM_BITS_PER_PIXEL<psm>() ; // length of bitmask in bits.
if (PSM_BITMODE<psm>() != 1) { // PSMCT24 and 24Z should be handle separated, as it could pass 32-bit storage.
u8 k = (x & (H - 1)) * I; // shift of PC data -- in PC we use pixels from constant position: x / H word and k is shift: x = ( x % H ) * H + k / I
// in PS2 we use all bit position from 0 by I pixels.
u32 J = ((1 << I) - 1) << k; // bitmask (of length ) & mask, moved by position k
// gcc complains repeatedly about this always being false. I'll investigate later.
if (z > k)
return ((*(pmem + x/H + y)) & J) << (z - k); // we use PX data from *mem + and properly shift
else // This formula loo little swizzled.
return ((*(pmem + x/H + y)) & J) >> (k - z);
}
else { // only 24 targets
u8* mem = ((u8*)pmem + (x * 3) + 4 * y); // Our pixel's is disaligned on 32-bit. So just use u8*.
return *(u32*)mem; // Mask would be handled later
}
}
// We use this function to limit number of memory R/W. This function fill all pixels for data with coordindates x, y. inside block data.
// Only rule is x, y should be < 8 (it automatically fill all needed pixels, that lie in blockdata, but have coords more than 8).
template <int psm>
static __forceinline void fillPixelsFromMemory(u32* dst, u32* pmem, int x, int y, int pitch, u32 bw, u32 bp = 0, u32 mask = 0xffffffff) {
u32 pixel = 0;
const u8 H = PSM_PIXELS_PER_WORD<psm>();
if (PSM_PIXEL_SHIFT<psm>() == 0) // We could not use calculated constants as templated parameters.
pixel = BitmaskinPSM<psm, 0, 0>(pmem, x); // First pixel x,y is the common part of all psmt path's
else {
if (PSM_PIXEL_SHIFT<psm>() == 24) // 8H and 4HL have 1 pixel, but shifted to 24 bits. 4HH -- 28 bits.
pixel = BitmaskinPSM<psm, 0, 24>(pmem, x);
else
pixel = BitmaskinPSM<psm, 0, 28>(pmem, x);
}
if (H > 1) {
const u8 G = psm & 0x7; // Bitmode, we use it for better chance of switch optimization
int div = ( x < 4 ) ? 4 : -4; // secondary row have shift by +4 or -4 pixels
switch (G) {
case 2:
pixel |= BitmaskinPSM<psm, 4, 16>(pmem, x);
break;
case 3:
pixel |= BitmaskinPSM<psm, 2, 16>(pmem, x);
pixel |= BitmaskinPSM<psm, 0, 8>(pmem + 2 * pitch, x + div);
pixel |= BitmaskinPSM<psm, 2, 24>(pmem + 2 * pitch, x + div);
break;
case 4:
pixel |= BitmaskinPSM<psm, 1, 8>(pmem, x);
pixel |= BitmaskinPSM<psm, 2, 16>(pmem, x);
pixel |= BitmaskinPSM<psm, 3, 24>(pmem, x);
pixel |= BitmaskinPSM<psm, 0, 4>(pmem + 2 * pitch, x + div);
pixel |= BitmaskinPSM<psm, 1, 12>(pmem + 2 * pitch, x + div);
pixel |= BitmaskinPSM<psm, 2, 20>(pmem + 2 * pitch, x + div);
pixel |= BitmaskinPSM<psm, 3, 28>(pmem + 2 * pitch, x + div);
break;
}
}
writePixelWord<psm>(dst, x, y, pixel, bw, bp, HandleWritemask<psm>(mask)); // use it for 32, 24, 8H, 4HL and 4HH
}
template <int psm>
void writeWordPixel(u32* pmem, u32 pixel, u32 mask) {
if (psm == PSMT4HH || psm == PSMT8H || psm == PSMT4HL || psm == PSMCT24 || psm == PSMT24Z)
MaskedOR(pmem, pixel, mask);
else
*pmem = pixel;
}
// Get pixel from src and put in in src. We assume, that psm of both buffers are the same and (sx-dx) & E == (sy - dy) & D == 0;
// Also in this case we could transfer the whole word
template <int psm>
void transferPixelFast(void* dst, void* src, int dx, int dy, int sx, int sy, u32 dbw, u32 sbw ) {
u32 Dbasepage, Sbasepage;
u32 word, mask = 0xffffffff;
u8 A = 0, B = 0, C = 0 , D = 0, E = 0, F = 0; u32 G = 0; u8 H = 0;
setPsmtConstantsX<psm> (A, B, C, D, E, F, G, H);
assert ( ((sx-dx) & E == (sy - dy) & D) && ((sy - dy) & D == 0) );
Dbasepage = ((dy>>A) * (dbw>>B)) + (dx>>B);
Sbasepage = ((sy>>A) * (sbw>>B)) + (sx>>B);
word = (g_pageTable[psm][sy&D][sx&E] >> C);
u32* dstp = (u32*)dst + Dbasepage * 2048 + word;
u32* srcp = (u32*)src + Sbasepage * 2048 + word;
writeWordPixel<psm>(dstp, *srcp, G << F);
}
// if we could not guarantee, that buffer suize shared same page Table address
template <int psm>
void transferPixel(void* dst, void* src, int dx, int dy, int sx, int sy, u32 dbw, u32 sbw ) {
u32 mask = 0xffffffff, shift;
u32* dstp = getPixelAddress_A32<psm>(mask, shift, dst, dx, dy, dbw);
u32* srcp = getPixelAddress_A32<psm>(mask, shift, src, sx, sy, sbw);
writeWordPixel<psm>(dstp, *srcp, mask); // write whole word
}
#define Def_getReadWrite(psmT, psmX) \
static __forceinline void writePixel##psmT(void* pmem, int x, int y, u32 pixel, u32 bp, u32 bw) { \
writePixel<psmX>(pmem, x, y, pixel, bw, bp); } \
static __forceinline u32 readPixel##psmT(const void* pmem, int x, int y, u32 bp, u32 bw) { \
return readPixel<psmX>(pmem, x, y, bw, bp); } \
static __forceinline void writePixel##psmT##_0(void* pmem, int x, int y, u32 pixel, u32 bw) { \
writePixel<psmX>(pmem, x, y, pixel, bw); } \
static __forceinline u32 readPixel##psmT##_0(const void* pmem, int x, int y, u32 bw) { \
return readPixel<psmX>(pmem, x, y, bw); }
Def_getReadWrite(32, PSMCT32);
Def_getReadWrite(24, PSMCT24);
Def_getReadWrite(16, PSMCT16);
Def_getReadWrite(16S, PSMCT16);
Def_getReadWrite(8, PSMT8);
Def_getReadWrite(8H, PSMT8H);
Def_getReadWrite(4, PSMT4);
Def_getReadWrite(4HH, PSMT4HH);
Def_getReadWrite(4HL, PSMT4HL);
Def_getReadWrite(32Z, PSMCT32);
Def_getReadWrite(24Z, PSMCT24);
Def_getReadWrite(16Z, PSMCT16);
Def_getReadWrite(16SZ, PSMCT16);
#endif // Zeydlitz's code
#endif /* __ZZOGL_MEM_H__ */

View File

@ -1,174 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
// Save and Load.
//------------------ Includes
#include "Util.h"
#include "ZZoglVB.h"
extern void ZZGSStateReset();
//----------------------- Defines
#define VBSAVELIMIT ((u32)((u8*)&vb[0].nNextFrameHeight-(u8*)&vb[0]))
#define ZEROGS_SAVEVER 0xaa000005
//------------------ Variables
// Hack for save game compatible!
#ifdef _DEBUG
const char *libraryNameX = "ZeroGS-Pg OpenGL (Debug) ";
#elif defined(ZEROGS_DEVBUILD)
const char *libraryNameX = "ZeroGS-Pg OpenGL (Dev) ";
#else
const char *libraryNameX = "ZeroGS Playground OpenGL ";
#endif
//------------------ Code
extern char *libraryName;
extern u32 s_uTex1Data[2][2], s_uClampData[2];
void SetFogColor(u32 fog);
void SetFogColor(GIFRegFOGCOL* fog);
int ZZSave(s8* pbydata)
{
if (pbydata == NULL)
return 40 + MEMORY_END + sizeof(gs) + 2*VBSAVELIMIT + 2*sizeof(frameInfo) + 4 + 256*4;
s_RTs.ResolveAll();
s_DepthRTs.ResolveAll();
strcpy((char*)pbydata, libraryNameX);
*(u32*)(pbydata + 16) = ZEROGS_SAVEVER;
pbydata += 32;
*(int*)pbydata = icurctx;
pbydata += 4;
*(int*)pbydata = VBSAVELIMIT;
pbydata += 4;
memcpy(pbydata, g_pbyGSMemory, MEMORY_END);
pbydata += MEMORY_END;
memcpy(pbydata, g_pbyGSClut, 256*4);
pbydata += 256 * 4;
*(int*)pbydata = sizeof(gs);
pbydata += 4;
memcpy(pbydata, &gs, sizeof(gs));
pbydata += sizeof(gs);
for (int i = 0; i < 2; ++i)
{
memcpy(pbydata, &vb[i], VBSAVELIMIT);
pbydata += VBSAVELIMIT;
}
return 0;
}
extern u32 g_nCurVBOIndex;
bool ZZLoad(s8* pbydata)
{
memset(s_uTex1Data, 0, sizeof(s_uTex1Data));
memset(s_uClampData, 0, sizeof(s_uClampData));
g_nCurVBOIndex = 0;
// first 32 bytes are the id
u32 savever = *(u32*)(pbydata + 16);
if (strncmp((char*)pbydata, libraryNameX, 6) == 0 && (savever == ZEROGS_SAVEVER || savever == 0xaa000004))
{
g_MemTargs.Destroy();
ZZGSStateReset();
pbydata += 32;
//int context = *(int*)pbydata;
pbydata += 4;
u32 savelimit = VBSAVELIMIT;
savelimit = *(u32*)pbydata;
pbydata += 4;
memcpy(g_pbyGSMemory, pbydata, MEMORY_END);
pbydata += MEMORY_END;
memcpy(g_pbyGSClut, pbydata, 256*4);
pbydata += 256 * 4;
memset(&gs, 0, sizeof(gs));
int savedgssize;
if (savever == 0xaa000004)
{
savedgssize = 0x1d0;
}
else
{
savedgssize = *(int*)pbydata;
pbydata += 4;
}
memcpy(&gs, pbydata, savedgssize);
pbydata += savedgssize;
prim = &gs._prim[gs.prac];
vb[0].Destroy();
memcpy(&vb[0], pbydata, min(savelimit, VBSAVELIMIT));
pbydata += savelimit;
vb[0].pBufferData = NULL;
vb[1].Destroy();
memcpy(&vb[1], pbydata, min(savelimit, VBSAVELIMIT));
pbydata += savelimit;
vb[1].pBufferData = NULL;
for (int i = 0; i < 2; ++i)
{
vb[i].Init(VB_BUFFERSIZE);
vb[i].bNeedZCheck = vb[i].bNeedFrameCheck = 1;
vb[i].bSyncVars = 0;
vb[i].bNeedTexCheck = 1;
memset(vb[i].uCurTex0Data, 0, sizeof(vb[i].uCurTex0Data));
}
icurctx = -1;
FB::Bind(); // switch to the backbuffer
SetFogColor(gs.fogcol);
GL_REPORT_ERRORD();
return true;
}
return false;
}

View File

@ -1,935 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009 zeydlitz@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2006
*
* 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
*/
// By default enable nvidia cg api
#if !defined(GLSL_API) && !defined(NVIDIA_CG_API) && !defined(GLSL4_API)
#define NVIDIA_CG_API
#endif
#ifdef NVIDIA_CG_API // This code is only for NVIDIA cg-toolkit API
// ZZogl Shader manipulation functions.
//------------------- Includes
#include "Util.h"
#include "ZZoglShaders.h"
#include "zpipe.h"
#include <math.h>
#include <map>
#ifdef _WIN32
# include "Win32.h"
extern HINSTANCE hInst;
#endif
// ----------------- Defines
#define TEXWRAP_REPEAT 0
#define TEXWRAP_CLAMP 1
#define TEXWRAP_REGION_REPEAT 2
#define TEXWRAP_REPEAT_CLAMP 3
#define SH_WRITEDEPTH 0x2000 // depth is written
#define SH_CONTEXT1 0x1000 // context1 is used
#define SH_REGULARVS 0x8000
#define SH_TEXTUREVS 0x8001
#define SH_REGULARFOGVS 0x8002
#define SH_TEXTUREFOGVS 0x8003
#define SH_REGULARPS 0x8004
#define SH_REGULARFOGPS 0x8005
#define SH_BITBLTVS 0x8006
#define SH_BITBLTPS 0x8007
#define SH_BITBLTDEPTHPS 0x8009
#define SH_CRTCTARGPS 0x800a
#define SH_CRTCPS 0x800b
#define SH_CRTC24PS 0x800c
#define SH_ZEROPS 0x800e
#define SH_BASETEXTUREPS 0x800f
#define SH_BITBLTAAPS 0x8010
#define SH_CRTCTARGINTERPS 0x8012
#define SH_CRTCINTERPS 0x8013
#define SH_CRTC24INTERPS 0x8014
#define SH_BITBLTDEPTHMRTPS 0x8016
#define SH_CONVERT16TO32PS 0x8020
#define SH_CONVERT32TO16PS 0x8021
#define SH_CRTC_NEARESTPS 0x8022
#define SH_CRTCINTER_NEARESTPS 0x8023
//------------------ Constants
// Used in a logarithmic Z-test, as (1-o(1))/log(MAX_U32).
const float g_filog32 = 0.999f / (32.0f * logf(2.0f));
const char* g_pShaders[4] = { "full", "reduced", "accurate", "accurate-reduced" };
// ----------------- Global Variables
ZZshContext g_cgcontext;
ZZshProfile cgvProf, cgfProf;
int g_nPixelShaderVer = 0; // default
u8* s_lpShaderResources = NULL;
ZZshProgram pvs[16] = {NULL};
ZZshProgram g_vsprog = 0, g_psprog = 0; // 2 -- ZZ
ZZshParameter g_vparamPosXY[2] = {0}, g_fparamFogColor = 0;
//#ifdef DEVBUILD
extern char EFFECT_NAME[256]; // All this variables used for testing and set manually
extern char EFFECT_DIR[256];
//#endif
bool g_bCRTCBilinear = true;
float4 g_vdepth, vlogz;
FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne;
FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16;
FRAGMENTSHADER ppsRegular[4], ppsTexture[NUM_SHADERS];
FRAGMENTSHADER ppsCRTC[2], /*ppsCRTC24[2],*/ ppsCRTCTarg[2];
VERTEXSHADER pvsBitBlt;
inline bool LoadEffects();
extern bool s_bWriteDepth;
struct SHADERHEADER
{
unsigned int index, offset, size; // if highest bit of index is set, pixel shader
};
map<int, SHADERHEADER*> mapShaderResources;
// Debug variable, store name of the function that call the shader.
const char* ShaderCallerName = "";
const char* ShaderHandleName = "";
//------------------ Code
inline int GET_SHADER_INDEX(int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int context, int ps) {
return type + texfilter*NUM_TYPES + NUM_FILTERS*NUM_TYPES*texwrap + NUM_TEXWRAPS*NUM_FILTERS*NUM_TYPES*(fog+2*writedepth+4*testaem+8*exactcolor+16*context+32*ps) ;
}
bool ZZshCheckProfilesSupport() {
// load the effect, find the best profiles (if any)
if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) {
ZZLog::Error_Log("arbvp1 not supported.");
return false;
}
if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1) != CG_TRUE) {
ZZLog::Error_Log("arbfp1 not supported.");
return false;
}
return true;
}
// Error handler. Setup in ZZogl_Create once.
void HandleCgError(ZZshContext ctx, ZZshError err, void* appdata)
{
ZZLog::Error_Log("%s->%s: %s\n", ShaderCallerName, ShaderHandleName, cgGetErrorString(err));
const char* listing = cgGetLastListing(g_cgcontext);
if (listing != NULL)
ZZLog::Debug_Log(" last listing: %s\n", listing);
}
bool ZZshStartUsingShaders() {
cgSetErrorHandler(HandleCgError, NULL);
g_cgcontext = cgCreateContext();
cgvProf = CG_PROFILE_ARBVP1;
cgfProf = CG_PROFILE_ARBFP1;
cgGLEnableProfile(cgvProf);
cgGLEnableProfile(cgfProf);
cgGLSetOptimalOptions(cgvProf);
cgGLSetOptimalOptions(cgfProf);
cgGLSetManageTextureParameters(g_cgcontext, CG_FALSE);
//cgSetAutoCompile(g_cgcontext, CG_COMPILE_IMMEDIATE);
g_fparamFogColor = cgCreateParameter(g_cgcontext, CG_FLOAT4);
g_vparamPosXY[0] = cgCreateParameter(g_cgcontext, CG_FLOAT4);
g_vparamPosXY[1] = cgCreateParameter(g_cgcontext, CG_FLOAT4);
ZZLog::GS_Log("Creating effects.");
B_G(LoadEffects(), return false);
// create a sample shader
clampInfo temp;
memset(&temp, 0, sizeof(temp));
temp.wms = 3; temp.wmt = 3;
g_nPixelShaderVer = 0;//SHADER_ACCURATE;
// test
bool bFailed;
FRAGMENTSHADER* pfrag = ZZshLoadShadeEffect(0, 1, 1, 1, 1, temp, 0, &bFailed);
if( bFailed || pfrag == NULL ) {
g_nPixelShaderVer = SHADER_ACCURATE|SHADER_REDUCED;
pfrag = ZZshLoadShadeEffect(0, 0, 1, 1, 0, temp, 0, &bFailed);
if( pfrag != NULL )
cgGLLoadProgram(pfrag->prog);
if( bFailed || pfrag == NULL || cgGetError() != CG_NO_ERROR ) {
g_nPixelShaderVer = SHADER_REDUCED;
ZZLog::Error_Log("Basic shader test failed.");
}
}
if (g_nPixelShaderVer & SHADER_REDUCED)
conf.bilinear = 0;
ZZLog::GS_Log("Creating extra effects.");
B_G(ZZshLoadExtraEffects(), return false);
ZZLog::GS_Log("using %s shaders\n", g_pShaders[g_nPixelShaderVer]);
return true;
}
void ZZshExitCleaning() {
// nothing to do with cg
}
// open shader file according to build target
bool ZZshCreateOpenShadersFile() {
#ifndef DEVBUILD
# ifdef _WIN32
HRSRC hShaderSrc = FindResource(hInst, MAKEINTRESOURCE(IDR_SHADERS), RT_RCDATA);
assert( hShaderSrc != NULL );
HGLOBAL hShaderGlob = LoadResource(hInst, hShaderSrc);
assert( hShaderGlob != NULL );
s_lpShaderResources = (u8*)LockResource(hShaderGlob);
# else // not _WIN32
FILE* fres = fopen("ps2hw.dat", "rb");
if( fres == NULL ) {
fres = fopen("plugins/ps2hw.dat", "rb");
if( fres == NULL ) {
ZZLog::Error_Log("Cannot find ps2hw.dat in working directory. Exiting.");
return false;
}
}
fseek(fres, 0, SEEK_END);
size_t s = ftell(fres);
s_lpShaderResources = new u8[s+1];
fseek(fres, 0, SEEK_SET);
if (fread(s_lpShaderResources, s, 1, fres) == 0)
ZZLog::Error_Log("Cannot read ps2hw.dat in working directory.");
s_lpShaderResources[s] = 0;
fclose(fres);
# endif // _WIN32
#else // NOT RELEASE_TO_PUBLIC
# ifndef _WIN32 // NOT WINDOWS
// test if ps2hw.fx exists
char tempstr[255];
char curwd[255];
getcwd(curwd, ArraySize(curwd));
strcpy(tempstr, "/plugins/");
sprintf(EFFECT_NAME, "%sps2hw.fx", tempstr);
FILE* f = fopen(EFFECT_NAME, "r");
if( f == NULL ) {
strcpy(tempstr, "../../plugins/zzogl-pg/opengl/");
sprintf(EFFECT_NAME, "%sps2hw.fx", tempstr);
f = fopen(EFFECT_NAME, "r");
if( f == NULL ) {
ZZLog::Error_Log("Failed to find %s, try compiling a non-devbuild\n", EFFECT_NAME);
return false;
}
}
fclose(f);
sprintf(EFFECT_DIR, "%s/%s", curwd, tempstr);
sprintf(EFFECT_NAME, "%sps2hw.fx", EFFECT_DIR);
#endif
#endif // RELEASE_TO_PUBLIC
return true;
}
// Disable CG
void ZZshGLDisableProfile() {
cgGLDisableProfile(cgvProf);
cgGLDisableProfile(cgfProf);
}
//Enable CG
void ZZshGLEnableProfile() {
cgGLEnableProfile(cgvProf);
cgGLEnableProfile(cgfProf);
}
// This is helper of cgGLSetParameter4fv, made for debug purpose.
// Name could be any string. We must use it on compilation time, because erroneus handler does not
// return name
void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name) {
ShaderHandleName = name;
cgGLSetParameter4fv(param, v);
}
void ZZshSetParameter4fv(ZZshProgram& prog, ZZshParameter param, const float* v, const char* name) {
ShaderHandleName = name;
cgGLSetParameter4fv(param, v);
}
// The same stuff, but also with retry of param, name should be USED name of param for prog.
void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshProgram& prog, const float* v, const char* name) {
if (param != NULL)
ZZshSetParameter4fv(prog, param[0], v, name);
else
ZZshSetParameter4fv(prog, cgGetNamedParameter(prog, name), v, name);
}
void ZZshGLSetTextureParameter(ZZshParameter param, GLuint texobj, const char* name) {
ShaderHandleName = name;
cgGLSetTextureParameter(param, texobj);
cgGLEnableTextureParameter(param);
}
// The same function for texture, also to cgGLEnable
void ZZshGLSetTextureParameter(ZZshProgram prog, ZZshParameter param, GLuint texobj, const char* name) {
ShaderHandleName = name;
cgGLSetTextureParameter(param, texobj);
cgGLEnableTextureParameter(param);
}
// Used sometimes for color 1.
void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) {
ShaderHandleName = "Set Default One color";
float4 v = float4 ( 1, 1, 1, 1 );
ZZshSetParameter4fv( ptr.prog, ptr.sOneColor, v, "DefaultOne");
}
#define SET_UNIFORMPARAM(var, name) { \
p = cgGetNamedParameter(pf->prog, name); \
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) \
pf->var = p; \
} \
void ZZshSetVertexShader(ZZshProgram prog) {
if ((prog) != g_vsprog) {
cgGLBindProgram(prog);
g_vsprog = prog;
}
}
void ZZshSetPixelShader(ZZshProgram prog) {
if ((prog) != g_psprog) {
cgGLBindProgram(prog);
g_psprog = prog;
}
}
void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type)
{
// uniform parameters
ZZshParameter p;
p = cgGetNamedParameter(pf->prog, "g_fFogColor");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
cgConnectParameter(g_fparamFogColor, p);
}
SET_UNIFORMPARAM(sOneColor, "g_fOneColor");
SET_UNIFORMPARAM(sBitBltZ, "g_fBitBltZ");
SET_UNIFORMPARAM(sInvTexDims, "g_fInvTexDims");
SET_UNIFORMPARAM(fTexAlpha2, "fTexAlpha2");
SET_UNIFORMPARAM(fTexOffset, "g_fTexOffset");
SET_UNIFORMPARAM(fTexDims, "g_fTexDims");
SET_UNIFORMPARAM(fTexBlock, "g_fTexBlock");
SET_UNIFORMPARAM(fClampExts, "g_fClampExts");
SET_UNIFORMPARAM(fTexWrapMode, "TexWrapMode");
SET_UNIFORMPARAM(fRealTexDims, "g_fRealTexDims");
SET_UNIFORMPARAM(fTestBlack, "g_fTestBlack");
SET_UNIFORMPARAM(fPageOffset, "g_fPageOffset");
SET_UNIFORMPARAM(fTexAlpha, "fTexAlpha");
// textures
p = cgGetNamedParameter(pf->prog, "g_sBlocks");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
cgGLSetTextureParameter(p, ptexBlocks);
cgGLEnableTextureParameter(p);
}
// cg parameter usage is wrong, so do it manually
if( type == 3 ) {
p = cgGetNamedParameter(pf->prog, "g_sConv16to32");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
cgGLSetTextureParameter(p, ptexConv16to32);
cgGLEnableTextureParameter(p);
}
}
else if( type == 4 ) {
p = cgGetNamedParameter(pf->prog, "g_sConv32to16");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
cgGLSetTextureParameter(p, ptexConv32to16);
cgGLEnableTextureParameter(p);
}
}
else {
p = cgGetNamedParameter(pf->prog, "g_sBilinearBlocks");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
cgGLSetTextureParameter(p, ptexBilinearBlocks);
cgGLEnableTextureParameter(p);
}
}
p = cgGetNamedParameter(pf->prog, "g_sMemory");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
//cgGLEnableTextureParameter(p);
pf->sMemory = p;
}
p = cgGetNamedParameter(pf->prog, "g_sSrcFinal");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
//cgGLEnableTextureParameter(p);
pf->sFinal = p;
}
p = cgGetNamedParameter(pf->prog, "g_sBitwiseANDX");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
//cgGLEnableTextureParameter(p);
pf->sBitwiseANDX = p;
}
p = cgGetNamedParameter(pf->prog, "g_sBitwiseANDY");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
//cgGLEnableTextureParameter(p);
pf->sBitwiseANDY = p;
}
p = cgGetNamedParameter(pf->prog, "g_sCLUT");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
//cgGLEnableTextureParameter(p);
pf->sCLUT = p;
}
p = cgGetNamedParameter(pf->prog, "g_sInterlace");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
//cgGLEnableTextureParameter(p);
pf->sInterlace = p;
}
// set global shader constants
p = cgGetNamedParameter(pf->prog, "g_fExactColor");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) {
cgGLSetParameter4fv(p, float4(0.5f, (conf.settings().exact_color)?0.9f/256.0f:0.5f/256.0f, 0,1/255.0f));
}
p = cgGetNamedParameter(pf->prog, "g_fBilinear");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE )
cgGLSetParameter4fv(p, float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ));
p = cgGetNamedParameter(pf->prog, "g_fZBias");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE )
cgGLSetParameter4fv(p, float4(1.0f/256.0f, 1.0004f, 1, 0.5f));
p = cgGetNamedParameter(pf->prog, "g_fc0");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE )
cgGLSetParameter4fv(p, float4(0,1, 0.001f, 0.5f));
p = cgGetNamedParameter(pf->prog, "g_fMult");
if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE )
cgGLSetParameter4fv(p, float4(1/1024.0f, 0.2f/1024.0f, 1/128.0f, 1/512.0f));
}
void SetupVertexProgramParameters(ZZshProgram prog, int context)
{
ZZshParameter p;
p = cgGetNamedParameter(prog, "g_fPosXY");
if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE )
cgConnectParameter(g_vparamPosXY[context], p);
// Set Z-test, log or no log;
if (conf.settings().no_logz) {
g_vdepth = float4( 255.0 /256.0f, 255.0/65536.0f, 255.0f/(65535.0f*256.0f), 1.0f/(65536.0f*65536.0f));
vlogz = float4( 1.0f, 0.0f, 0.0f, 0.0f);
}
else {
g_vdepth = float4( 256.0f*65536.0f, 65536.0f, 256.0f, 65536.0f*65536.0f);
vlogz = float4( 0.0f, 1.0f, 0.0f, 0.0f);
}
p = cgGetNamedParameter(prog, "g_fZ");
if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) {
cgGLSetParameter4fv(p, g_vdepth);
p = cgGetNamedParameter(prog, "g_fZMin"); // Switch to flat-z when needed
if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) {
//ZZLog::Error_Log("Use flat-z\n");
cgGLSetParameter4fv(p, vlogz);
}
else
ZZLog::Error_Log("Shader file version is outdated! Only log-Z is possible.");
}
float4 vnorm = float4(g_filog32, 0, 0,0);
p = cgGetNamedParameter(prog, "g_fZNorm");
if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE )
cgGLSetParameter4fv(p, vnorm);
p = cgGetNamedParameter(prog, "g_fBilinear");
if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE )
cgGLSetParameter4fv(p, float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ));
p = cgGetNamedParameter(prog, "g_fZBias");
if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE )
cgGLSetParameter4fv(p, float4(1.0f/256.0f, 1.0004f, 1, 0.5f));
p = cgGetNamedParameter(prog, "g_fc0");
if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE )
cgGLSetParameter4fv(p, float4(0,1, 0.001f, 0.5f));
}
#ifndef DEVBUILD
#if 0
static __forceinline void LOAD_VS(int Index, ZZshProgram prog)
{
assert(mapShaderResources.find(Index) != mapShaderResources.end());
header = mapShaderResources[Index];
assert((header) != NULL && (header)->index == (Index));
prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgvProf, NULL, NULL);
if (!cgIsProgram(prog))
{
ZZLog::Error_Log("Failed to load vs %d: \n%s", Index, cgGetLastListing(g_cgcontext));
return false;
}
cgGLLoadProgram(prog);
if (cgGetError() != CG_NO_ERROR) ZZLog::Error_Log("Failed to load program %d.", Index);
SetupVertexProgramParameters(prog, !!(Index&SH_CONTEXT1));
}
static __forceinline void LOAD_VS(int Index, FRAGMENTSHADER fragment)
{
bLoadSuccess = true;
assert(mapShaderResources.find(Index) != mapShaderResources.end());
header = mapShaderResources[Index];
fragment.prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgfProf, NULL, NULL);
if (!cgIsProgram(fragment.prog))
{
ZZLog::Error_Log("Failed to load ps %d: \n%s", Index, cgGetLastListing(g_cgcontext));
return false;
}
cgGLLoadProgram(fragment.prog);
if (cgGetError() != CG_NO_ERROR)
{
ZZLog::Error_Log("failed to load program %d.", Index);
bLoadSuccess = false;
}
SetupFragmentProgramParameters(&fragment, !!(Index&SH_CONTEXT1), 0);
}
#endif
#define LOAD_VS(Index, prog) { \
assert( mapShaderResources.find(Index) != mapShaderResources.end() ); \
header = mapShaderResources[Index]; \
assert( (header) != NULL && (header)->index == (Index) ); \
prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgvProf, NULL, NULL); \
if( !cgIsProgram(prog) ) { \
ZZLog::Error_Log("Failed to load vs %d: \n%s", Index, cgGetLastListing(g_cgcontext)); \
return false; \
} \
cgGLLoadProgram(prog); \
if( cgGetError() != CG_NO_ERROR ) ZZLog::Error_Log("Failed to load program %d.", Index); \
SetupVertexProgramParameters(prog, !!(Index&SH_CONTEXT1)); \
} \
#define LOAD_PS(Index, fragment) { \
bLoadSuccess = true; \
assert( mapShaderResources.find(Index) != mapShaderResources.end() ); \
header = mapShaderResources[Index]; \
fragment.prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgfProf, NULL, NULL); \
if( !cgIsProgram(fragment.prog) ) { \
ZZLog::Error_Log("Failed to load ps %d: \n%s", Index, cgGetLastListing(g_cgcontext)); \
return false; \
} \
cgGLLoadProgram(fragment.prog); \
if( cgGetError() != CG_NO_ERROR ) { \
ZZLog::Error_Log("failed to load program %d.", Index); \
bLoadSuccess = false; \
} \
SetupFragmentProgramParameters(&fragment, !!(Index&SH_CONTEXT1), 0); \
} \
inline bool LoadEffects()
{
assert( s_lpShaderResources != NULL );
// process the header
u32 num = *(u32*)s_lpShaderResources;
int compressed_size = *(int*)(s_lpShaderResources+4);
int real_size = *(int*)(s_lpShaderResources+8);
int out;
char* pbuffer = (char*)malloc(real_size);
inf((char*)s_lpShaderResources+12, &pbuffer[0], compressed_size, real_size, &out);
assert(out == real_size);
s_lpShaderResources = (u8*)pbuffer;
SHADERHEADER* header = (SHADERHEADER*)s_lpShaderResources;
mapShaderResources.clear();
while(num-- > 0 ) {
mapShaderResources[header->index] = header;
++header;
}
// clear the textures
for(u16 i = 0; i < ArraySize(ppsTexture); ++i) {
SAFE_RELEASE_PROG(ppsTexture[i].prog);
ppsTexture[i].prog = NULL;
}
#ifndef _DEBUG
memset(ppsTexture, 0, sizeof(ppsTexture));
#endif
return true;
}
// called
bool ZZshLoadExtraEffects()
{
SHADERHEADER* header;
bool bLoadSuccess = true;
const u32 vsshaders[4] = { SH_REGULARVS, SH_TEXTUREVS, SH_REGULARFOGVS, SH_TEXTUREFOGVS };
for(int i = 0; i < 4; ++i) {
LOAD_VS(vsshaders[i], pvs[2*i]);
LOAD_VS((vsshaders[i] | SH_CONTEXT1), pvs[2*i+1]);
//if( conf.mrtdepth ) {
LOAD_VS((vsshaders[i] | SH_WRITEDEPTH), pvs[2*i+8]);
LOAD_VS((vsshaders[i] | SH_WRITEDEPTH | SH_CONTEXT1), pvs[2*i+8+1]);
// }
// else {
// pvs[2*i+8] = pvs[2*i+8+1] = NULL;
// }
}
LOAD_VS(SH_BITBLTVS, pvsBitBlt.prog);
pvsBitBlt.sBitBltPos = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltPos");
pvsBitBlt.sBitBltTex = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltTex");
pvsBitBlt.fBitBltTrans = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltTrans");
LOAD_PS(SH_REGULARPS, ppsRegular[0]);
LOAD_PS(SH_REGULARFOGPS, ppsRegular[1]);
if( conf.mrtdepth ) {
LOAD_PS(SH_REGULARPS, ppsRegular[2]);
if( !bLoadSuccess )
conf.mrtdepth = 0;
LOAD_PS(SH_REGULARFOGPS, ppsRegular[3]);
if( !bLoadSuccess )
conf.mrtdepth = 0;
}
LOAD_PS(SH_BITBLTPS, ppsBitBlt[0]);
LOAD_PS(SH_BITBLTAAPS, ppsBitBlt[1]);
if( !bLoadSuccess ) {
ZZLog::Error_Log("Failed to load BitBltAAPS, using BitBltPS.");
LOAD_PS(SH_BITBLTPS, ppsBitBlt[1]);
}
LOAD_PS(SH_BITBLTDEPTHPS, ppsBitBltDepth);
LOAD_PS(SH_CRTCTARGPS, ppsCRTCTarg[0]);
LOAD_PS(SH_CRTCTARGINTERPS, ppsCRTCTarg[1]);
g_bCRTCBilinear = true;
LOAD_PS(SH_CRTCPS, ppsCRTC[0]);
if( !bLoadSuccess ) {
// switch to simpler
g_bCRTCBilinear = false;
LOAD_PS(SH_CRTC_NEARESTPS, ppsCRTC[0]);
LOAD_PS(SH_CRTCINTER_NEARESTPS, ppsCRTC[0]);
}
else {
LOAD_PS(SH_CRTCINTERPS, ppsCRTC[1]);
}
if( !bLoadSuccess )
ZZLog::Error_Log("Failed to create CRTC shaders.");
// LOAD_PS(SH_CRTC24PS, ppsCRTC24[0]);
// LOAD_PS(SH_CRTC24INTERPS, ppsCRTC24[1]);
LOAD_PS(SH_ZEROPS, ppsOne);
LOAD_PS(SH_BASETEXTUREPS, ppsBaseTexture);
LOAD_PS(SH_CONVERT16TO32PS, ppsConvert16to32);
LOAD_PS(SH_CONVERT32TO16PS, ppsConvert32to16);
return true;
}
FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed)
{
int texwrap;
assert( texfilter < NUM_FILTERS );
if(g_nPixelShaderVer&SHADER_REDUCED)
texfilter = 0;
assert(!(g_nPixelShaderVer&SHADER_REDUCED) || !exactcolor);
if( clamp.wms == clamp.wmt ) {
switch( clamp.wms ) {
case 0: texwrap = TEXWRAP_REPEAT; break;
case 1: texwrap = TEXWRAP_CLAMP; break;
case 2: texwrap = TEXWRAP_CLAMP; break;
default: texwrap = TEXWRAP_REGION_REPEAT; break;
}
}
else if( clamp.wms==3||clamp.wmt==3)
texwrap = TEXWRAP_REGION_REPEAT;
else
texwrap = TEXWRAP_REPEAT_CLAMP;
u32 index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0);
assert( index < ArraySize(ppsTexture) );
FRAGMENTSHADER* pf = ppsTexture+index;
if( pbFailed != NULL ) *pbFailed = false;
if( pf->prog != NULL )
return pf;
if( (g_nPixelShaderVer & SHADER_ACCURATE) && mapShaderResources.find(index+NUM_SHADERS*SHADER_ACCURATE) != mapShaderResources.end() )
index += NUM_SHADERS*SHADER_ACCURATE;
assert( mapShaderResources.find(index) != mapShaderResources.end() );
SHADERHEADER* header = mapShaderResources[index];
if( header == NULL )
ZZLog::Error_Log("%d %d", index, g_nPixelShaderVer);
assert( header != NULL );
//DEBUG_LOG("shader:\n%s\n", (char*)(s_lpShaderResources + (header)->offset));
pf->prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgfProf, NULL, NULL);
if( pf->prog != NULL && cgIsProgram(pf->prog) && cgGetError() == CG_NO_ERROR ) {
SetupFragmentProgramParameters(pf, context, type);
cgGLLoadProgram(pf->prog);
if( cgGetError() != CG_NO_ERROR ) {
// cgGLLoadProgram(pf->prog);
// if( cgGetError() != CG_NO_ERROR ) {
ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
if( pbFailed != NULL ) *pbFailed = true;
return pf;
// }
}
return pf;
}
ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
if( pbFailed != NULL ) *pbFailed = true;
return NULL;
}
#else // not RELEASE_TO_PUBLIC
#define LOAD_VS(name, prog, shaderver) { \
prog = cgCreateProgramFromFile(g_cgcontext, CG_SOURCE, EFFECT_NAME, shaderver, name, args); \
if( !cgIsProgram(prog) ) { \
ZZLog::Error_Log("Failed to load vs %s: \n%s", name, cgGetLastListing(g_cgcontext)); \
return false; \
} \
cgGLLoadProgram(prog); \
if( cgGetError() != CG_NO_ERROR ) ZZLog::Error_Log("failed to load program %s", name); \
SetupVertexProgramParameters(prog, args[0]==context1); \
} \
#ifdef _DEBUG
#define SET_PSFILENAME(frag, name) frag.filename = name
#else
#define SET_PSFILENAME(frag, name)
#endif
#define LOAD_PS(name, fragment, shaderver) { \
bLoadSuccess = true; \
fragment.prog = cgCreateProgramFromFile(g_cgcontext, CG_SOURCE, EFFECT_NAME, shaderver, name, args); \
if( !cgIsProgram(fragment.prog) ) { \
ZZLog::Error_Log("Failed to load ps %s: \n%s", name, cgGetLastListing(g_cgcontext)); \
return false; \
} \
cgGLLoadProgram(fragment.prog); \
if( cgGetError() != CG_NO_ERROR ) { \
ZZLog::Error_Log("failed to load program %s", name); \
bLoadSuccess = false; \
} \
SetupFragmentProgramParameters(&fragment, args[0]==context1, 0); \
SET_PSFILENAME(fragment, name); \
} \
inline bool LoadEffects()
{
// clear the textures
for(int i = 0; i < ArraySize(ppsTexture); ++i) {
SAFE_RELEASE_PROG(ppsTexture[i].prog);
}
#ifndef _DEBUG
memset(ppsTexture, 0, sizeof(ppsTexture));
#endif
return true;
}
bool ZZshLoadExtraEffects()
{
const char* args[] = { NULL , NULL, NULL, NULL };
char context0[255], context1[255];
sprintf(context0, "-I%sctx0", EFFECT_DIR);
sprintf(context1, "-I%sctx1", EFFECT_DIR);
char* write_depth = "-DWRITE_DEPTH";
bool bLoadSuccess = true;
const char* pvsshaders[4] = { "RegularVS", "TextureVS", "RegularFogVS", "TextureFogVS" };
for(int i = 0; i < 4; ++i) {
args[0] = context0;
args[1] = NULL;
LOAD_VS(pvsshaders[i], pvs[2*i], cgvProf);
args[0] = context1;
LOAD_VS(pvsshaders[i], pvs[2*i+1], cgvProf);
//if( conf.mrtdepth ) {
args[0] = context0;
args[1] = write_depth;
LOAD_VS(pvsshaders[i], pvs[2*i+8], cgvProf);
args[0] = context1;
LOAD_VS(pvsshaders[i], pvs[2*i+8+1], cgvProf);
// }
// else {
// pvs[2*i+8] = pvs[2*i+8+1] = NULL;
// }
}
args[0] = context0;
args[1] = NULL;
LOAD_VS("BitBltVS", pvsBitBlt.prog, cgvProf);
pvsBitBlt.sBitBltPos = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltPos");
pvsBitBlt.sBitBltTex = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltTex");
pvsBitBlt.fBitBltTrans = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltTrans");
LOAD_PS("RegularPS", ppsRegular[0], cgfProf);
LOAD_PS("RegularFogPS", ppsRegular[1], cgfProf);
if( conf.mrtdepth ) {
args[0] = context0;
args[1] = write_depth;
LOAD_PS("RegularPS", ppsRegular[2], cgfProf);
if( !bLoadSuccess )
conf.mrtdepth = 0;
LOAD_PS("RegularFogPS", ppsRegular[3], cgfProf);
if( !bLoadSuccess )
conf.mrtdepth = 0;
}
LOAD_PS("BitBltPS", ppsBitBlt[0], cgfProf);
LOAD_PS("BitBltAAPS", ppsBitBlt[1], cgfProf);
if( !bLoadSuccess ) {
ZZLog::Error_Log("Failed to load BitBltAAPS, using BitBltPS.");
LOAD_PS("BitBltPS", ppsBitBlt[1], cgfProf);
}
LOAD_PS("BitBltDepthPS", ppsBitBltDepth, cgfProf);
LOAD_PS("CRTCTargPS", ppsCRTCTarg[0], cgfProf);
LOAD_PS("CRTCTargInterPS", ppsCRTCTarg[1], cgfProf);
g_bCRTCBilinear = true;
LOAD_PS("CRTCPS", ppsCRTC[0], cgfProf);
if( !bLoadSuccess ) {
// switch to simpler
g_bCRTCBilinear = false;
LOAD_PS("CRTCPS_Nearest", ppsCRTC[0], cgfProf);
LOAD_PS("CRTCInterPS_Nearest", ppsCRTC[0], cgfProf);
}
else {
LOAD_PS("CRTCInterPS", ppsCRTC[1], cgfProf);
}
if( !bLoadSuccess )
ZZLog::Error_Log("Failed to create CRTC shaders.");
// LOAD_PS("CRTC24PS", ppsCRTC24[0], cgfProf); LOAD_PS("CRTC24InterPS", ppsCRTC24[1], cgfProf);
LOAD_PS("ZeroPS", ppsOne, cgfProf);
LOAD_PS("BaseTexturePS", ppsBaseTexture, cgfProf);
LOAD_PS("Convert16to32PS", ppsConvert16to32, cgfProf);
LOAD_PS("Convert32to16PS", ppsConvert32to16, cgfProf);
// if( !conf.mrtdepth ) {
// ZZLog::Error_Log("Disabling MRT depth writing,");
// s_bWriteDepth = FALSE;
// }
return true;
}
FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed)
{
int texwrap;
assert( texfilter < NUM_FILTERS );
//assert( g_nPixelShaderVer == SHADER_30 );
if( clamp.wms == clamp.wmt ) {
switch( clamp.wms ) {
case 0: texwrap = TEXWRAP_REPEAT; break;
case 1: texwrap = TEXWRAP_CLAMP; break;
case 2: texwrap = TEXWRAP_CLAMP; break;
default:
texwrap = TEXWRAP_REGION_REPEAT; break;
}
}
else if( clamp.wms==3||clamp.wmt==3)
texwrap = TEXWRAP_REGION_REPEAT;
else
texwrap = TEXWRAP_REPEAT_CLAMP;
int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0);
if( pbFailed != NULL ) *pbFailed = false;
FRAGMENTSHADER* pf = ppsTexture+index;
if( pf->prog != NULL )
return pf;
pf->prog = LoadShaderFromType(EFFECT_DIR, EFFECT_NAME, type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, g_nPixelShaderVer, context);
if( pf->prog != NULL ) {
#ifdef _DEBUG
char str[255];
const static char* g_pTexTypes[] = { "32", "tex32", "clut32", "tex32to16", "tex16to8h" };
sprintf(str, "Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]);
pf->filename = str;
#endif
SetupFragmentProgramParameters(pf, context, type);
cgGLLoadProgram(pf->prog);
if( cgGetError() != CG_NO_ERROR ) {
// try again
// cgGLLoadProgram(pf->prog);
// if( cgGetError() != CG_NO_ERROR ) {
ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
if( pbFailed != NULL ) *pbFailed = true;
//assert(0);
// NULL makes things crash
return pf;
// }
}
return pf;
}
ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
if( pbFailed != NULL ) *pbFailed = true;
return NULL;
}
#endif // RELEASE_TO_PUBLIC
#endif // NVIDIA_CG_API

View File

@ -1,782 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef __ZEROGS_SHADERS_H__
#define __ZEROGS_SHADERS_H__
// -- Not very important things, but we keep it to enumerate shader
#define NUM_FILTERS 2 // texture filtering
#define NUM_TYPES 5 // types of texture read modes
#define NUM_TEXWRAPS 4 // texture wrapping
#define NUM_SHADERS (NUM_FILTERS*NUM_TYPES*NUM_TEXWRAPS*32) // # shaders for a given ps
// Just bitmask for different type of shaders
#define SHADER_REDUCED 1 // equivalent to ps2.0
#define SHADER_ACCURATE 2 // for older cards with less accurate math (ps2.x+)
#include <math.h>
#include "ZZoglMath.h"
#include "GS.h"
// By default enable nvidia cg api
#if !defined(GLSL_API) && !defined(NVIDIA_CG_API) && !defined(GLSL4_API)
#define NVIDIA_CG_API
#endif
// --------------------------- API abstraction level --------------------------------
#ifdef NVIDIA_CG_API // Code for NVIDIA cg-toolkit API
#include <Cg/cg.h>
#include <Cg/cgGL.h>
#define ZZshProgram CGprogram
#define ZZshShader CGprogram
#define ZZshShaderLink CGprogram
#define ZZshParameter CGparameter
#define ZZshContext CGcontext
#define ZZshProfile CGprofile
#define ZZshError CGerror
#define pZero 0 // Zero parameter
#define sZero 0 // Zero program
#define SAFE_RELEASE_PROG(x) { if( (x) != NULL ) { cgDestroyProgram(x); x = NULL; } }
#endif // end NVIDIA cg-toolkit API
#ifdef GLSL4_API
#include "GSUniformBufferOGL.h"
#include "GSVertexArrayOGL.h"
#endif
// GLSL only
// Set it to 0 to diable context usage, 1 -- to enable. FFX-1 have a strange issue with ClampExt.
#define NOCONTEXT 0
#if defined(GLSL_API)
#define MAX_ACTIVE_UNIFORMS 600
#define MAX_ACTIVE_SHADERS 400
enum ZZshPARAMTYPE {
ZZ_UNDEFINED,
ZZ_TEXTURE_2D,
ZZ_TEXTURE_RECT,
ZZ_TEXTURE_3D,
ZZ_FLOAT4,
};
typedef struct {
const char* ShName; // Name of uniform
ZZshPARAMTYPE type; // Choose between parameter type
float fvalue[4];
GLuint sampler; // Number of texture unit in array
GLint texid; // Number of texture - texid.
bool Constant; // Uniform could be constants, does not change at program flow
bool Settled; // Check if Uniform value was set.
} ZZshParamInfo;
const ZZshParamInfo qZero = {ShName:"", type:ZZ_UNDEFINED, fvalue:{0}, sampler: -1, texid: 0, Constant: false, Settled: false};
#define SAFE_RELEASE_PROG(x) { /*don't know what to do*/ }
#endif
#if defined(GLSL_API) || defined(GLSL4_API)
typedef struct {
void* link;
bool isFragment;
} ZZshShaderLink;
#define ZZshProgram GLuint
#define ZZshShader GLuint
#define ZZshParameter GLint
#define ZZshContext int
#define ZZshProfile int
#define ZZshError int
#define ZZshIndex GLuint
#define pZero 0
const ZZshShaderLink sZero = {link: NULL, isFragment: false};
#endif
// ---------------------------
extern float4 g_vdepth;
extern float4 vlogz;
#ifdef GLSL4_API
enum {
ZZSH_CTX_0 = 0,
ZZSH_CTX_1 = 1,
ZZSH_CTX_ALL = 2
};
// Note A nice template could be better
// Warning order is important for buffer (see GLSL)
// Note must be keep POD (so you can map it to GLSL)
struct GlobalUniform {
union {
struct {
// VS
float g_fPosXY[4]; // dual context
// PS
float g_fFogColor[4];
};
float linear[2*4];
};
void SettleFloat(uint indice, const float* v) {
assert(indice + 3 < 2*4);
linear[indice+0] = v[0];
linear[indice+1] = v[1];
linear[indice+2] = v[2];
linear[indice+3] = v[3];
}
};
struct ConstantUniform {
union {
struct {
// Both VS/PS
float g_fBilinear[4];
float g_fZbias[4];
float g_fc0[4];
float g_fMult[4];
// VS
float g_fZ[4];
// PS
float g_fExactColor[4];
};
float linear[6*4];
};
void SettleFloat(uint indice, const float* v) {
assert(indice + 3 < 6*4);
linear[indice+0] = v[0];
linear[indice+1] = v[1];
linear[indice+2] = v[2];
linear[indice+3] = v[3];
}
};
struct FragmentUniform {
union {
struct {
float g_fTexAlpha2[4]; // dual context
float g_fTexOffset[4]; // dual context
float g_fTexDims[4]; // dual context
float g_fTexBlock[4]; // dual context
float g_fClampExts[4]; // dual context
float g_fTexWrapMode[4]; // dual context
float g_fRealTexDims[4]; // dual context
float g_fTestBlack[4]; // dual context
float g_fPageOffset[4]; // dual context
float g_fTexAlpha[4]; // dual context
float g_fInvTexDims[4];
float g_fBitBltZ[4];
float g_fOneColor[4];
};
float linear[13*4];
};
void SettleFloat(uint indice, const float* v) {
assert(indice + 3 < 13*4);
linear[indice+0] = v[0];
linear[indice+1] = v[1];
linear[indice+2] = v[2];
linear[indice+3] = v[3];
}
};
struct VertexUniform {
union {
struct {
float g_fBitBltPos[4];
float g_fBitBltTex[4];
float g_fBitBltTrans[4];
};
float linear[3*4];
};
void SettleFloat(uint indice, const float* v) {
assert(indice + 3 < 3*4);
linear[indice+0] = v[0];
linear[indice+1] = v[1];
linear[indice+2] = v[2];
linear[indice+3] = v[3];
}
};
#endif
enum ZZshShaderType {ZZ_SH_ZERO, ZZ_SH_REGULAR, ZZ_SH_REGULAR_FOG, ZZ_SH_TEXTURE, ZZ_SH_TEXTURE_FOG, ZZ_SH_CRTC, ZZ_SH_NONE};
// We have "compatible" shaders, as RegularFogVS and RegularFogPS. if don't need to wory about incompatible shaders
// It used only in GLSL mode.
// ------------------------- Variables -------------------------------
extern int g_nPixelShaderVer;
extern ZZshShaderLink pvs[16], g_vsprog, g_psprog;
extern ZZshParameter g_vparamPosXY[2], g_fparamFogColor;
#ifndef GLSL4_API
struct FRAGMENTSHADER
{
FRAGMENTSHADER() : prog(sZero), Shader(0), sMemory(pZero), sFinal(pZero), sBitwiseANDX(pZero), sBitwiseANDY(pZero), sInterlace(pZero), sCLUT(pZero), sOneColor(pZero), sBitBltZ(pZero),
fTexAlpha2(pZero), fTexOffset(pZero), fTexDims(pZero), fTexBlock(pZero), fClampExts(pZero), fTexWrapMode(pZero),
fRealTexDims(pZero), fTestBlack(pZero), fPageOffset(pZero), fTexAlpha(pZero) {}
ZZshShaderLink prog; // it link to FRAGMENTSHADER structure, for compability between GLSL and CG
ZZshShader Shader; // GLSL store shader's not as ready programs, but as shaders compilated object. VS and PS should be linked together to
// made a program.
ZZshShaderType ShaderType; // Not every PS and VS are used together, only compatible ones.
ZZshParameter sMemory, sFinal, sBitwiseANDX, sBitwiseANDY, sInterlace, sCLUT;
ZZshParameter sOneColor, sBitBltZ, sInvTexDims;
ZZshParameter fTexAlpha2, fTexOffset, fTexDims, fTexBlock, fClampExts, fTexWrapMode, fRealTexDims, fTestBlack, fPageOffset, fTexAlpha;
int ParametersStart, ParametersFinish; // this is part of UniformsIndex array in which parameters of this shader stored. Last one is ParametersFinish-1
#ifdef _DEBUG
string filename;
#endif
#ifdef NVIDIA_CG_API
void set_uniform_param(ZZshParameter &var, const char *name)
{
ZZshParameter p;
p = cgGetNamedParameter(prog, name);
if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE) var = p;
}
bool set_texture(GLuint texobj, const char *name)
{
ZZshParameter p;
p = cgGetNamedParameter(prog, name);
if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE)
{
cgGLSetTextureParameter(p, texobj);
cgGLEnableTextureParameter(p);
return true;
}
return false;
}
bool connect(ZZshParameter &tex, const char *name)
{
ZZshParameter p;
p = cgGetNamedParameter(prog, name);
if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE)
{
cgConnectParameter(tex, p);
return true;
}
return false;
}
bool set_texture(ZZshParameter &tex, const char *name)
{
ZZshParameter p;
p = cgGetNamedParameter(prog, name);
if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE)
{
//cgGLEnableTextureParameter(p);
tex = p;
return true;
}
return false;
}
bool set_shader_const(float4 v, const char *name)
{
ZZshParameter p;
p = cgGetNamedParameter(prog, name);
if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE)
{
cgGLSetParameter4fv(p, v);
return true;
}
return false;
}
#endif
};
#else
const GLenum g_texture_target[11] = {GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE};
extern uint g_current_texture_bind[11];
struct SamplerParam {
int unit;
GLuint texid;
GLenum target;
SamplerParam() : unit(-1), texid(0), target(0) {}
void set_unit(int new_unit) {
assert(new_unit < 11);
unit = new_unit;
target = g_texture_target[new_unit];
}
void enable_texture() {
assert(unit >= 0);
assert(unit < 11);
if (texid) {
// Unfortunately there is a nastly corner case
// 1/ Attach a texture to the unit
// 2/ delete the texture
// 3/ recreate a texture (with same id)
// 4/ => texture need to be reattached again...
#if 0
if (g_current_texture_bind[unit] != texid) {
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(target, texid);
g_current_texture_bind[unit] = texid;
}
#else
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(target, texid);
#endif
}
}
void set_texture(GLuint new_texid) {
texid = new_texid;
}
void release_texture() {
texid = 0;
}
};
struct FRAGMENTSHADER
{
FRAGMENTSHADER() : prog(sZero)
, program(0)
, context(0)
, sMemory(0) // dual context need 2 slots
, sFinal(2)
, sBitwiseANDX(3)
, sBitwiseANDY(4)
, sInterlace(5)
, sCLUT(6)
{
// Uniform
sOneColor = (ZZshParameter)offsetof(struct FragmentUniform, g_fOneColor) /4;
sBitBltZ = (ZZshParameter)offsetof(struct FragmentUniform, g_fBitBltZ) /4;
sInvTexDims = (ZZshParameter)offsetof(struct FragmentUniform, g_fInvTexDims) /4;
fTexAlpha = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexAlpha) /4;
fTexAlpha2 = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexAlpha2) /4;
fTexOffset = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexOffset) /4;
fTexDims = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexDims) /4;
fTexBlock = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexBlock) /4;
fClampExts = (ZZshParameter)offsetof(struct FragmentUniform, g_fClampExts) /4; // FIXME: There is a bug, that lead FFX-1 to incorrect CLAMP if this uniform have context.
fTexWrapMode = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexWrapMode) /4;
fRealTexDims = (ZZshParameter)offsetof(struct FragmentUniform, g_fRealTexDims) /4;
fTestBlack = (ZZshParameter)offsetof(struct FragmentUniform, g_fTestBlack) /4;
fPageOffset = (ZZshParameter)offsetof(struct FragmentUniform, g_fPageOffset) /4;
//sFinal = 2;
//sBitwiseANDX = 3;
//sBitwiseANDY = 4;
//sInterlace = 5;
//sCLUT = 6;
samplers[sMemory].set_unit(10);
samplers[sMemory+1].set_unit(10); // Dual context. Use same unit
samplers[sFinal].set_unit(1);
samplers[sBitwiseANDX].set_unit(6);
samplers[sBitwiseANDY].set_unit(7);
samplers[sInterlace].set_unit(8);
samplers[sCLUT].set_unit(9);
prog.isFragment = true;
prog.link = (void*)this;
}
ZZshShaderLink prog; // it link to FRAGMENTSHADER structure, for compability between GLSL and CG
ZZshProgram program;
uint context;
FragmentUniform uniform_buffer[ZZSH_CTX_ALL];
// sampler
const ZZshParameter sMemory;
const ZZshParameter sFinal, sBitwiseANDX, sBitwiseANDY, sInterlace, sCLUT;
SamplerParam samplers[7];
// uniform
ZZshParameter sOneColor, sBitBltZ, sInvTexDims;
ZZshParameter fTexAlpha2, fTexOffset, fTexDims, fTexBlock, fClampExts, fTexWrapMode, fRealTexDims, fTestBlack, fPageOffset, fTexAlpha;
#ifdef _DEBUG
string filename;
#endif
void ZZshSetParameter4fv(ZZshParameter param, const float* v) {
if (IsDualContext(param))
uniform_buffer[context].SettleFloat((int) param, v);
else
for ( int i = 0; i < ZZSH_CTX_ALL ; i++)
uniform_buffer[i].SettleFloat((int) param, v);
}
bool IsDualContext(ZZshParameter param) {
if (param == sInvTexDims || param == sBitBltZ || param == sOneColor)
return false;
else
return true;
}
void enable_texture() {
samplers[sMemory+context].enable_texture(); // sMemory is dual context
for (int i = 2; i < 7; i++)
samplers[i].enable_texture();
}
void set_texture(ZZshParameter param, GLuint texid) {
if (param == sMemory) // sMemory is dual context
samplers[sMemory+context].set_texture(texid);
else
samplers[param].set_texture(texid);
}
void release_prog() {
if(program) {
glDeleteProgram(program);
program = 0;
}
for (uint i = 0; i < 7 ; i++)
samplers[i].release_texture();
}
void set_context(uint new_context) { context = new_context * NOCONTEXT;}
};
#endif
#ifdef GLSL4_API
struct COMMONSHADER
{
COMMONSHADER() : context(0)
, sBlocks(0)
, sBilinearBlocks(1)
, sConv16to32(2)
, sConv32to16(3)
{
// sBlocks = 0;
// sBilinearBlocks = 1;
// sConv16to32 = 2;
// sConv32to16 = 3;
samplers[sBlocks].set_unit(2);
samplers[sBilinearBlocks].set_unit(3);
samplers[sConv16to32].set_unit(4);
samplers[sConv32to16].set_unit(5);
g_fparamFogColor = (ZZshParameter)offsetof(struct GlobalUniform, g_fFogColor) /4;
g_vparamPosXY = (ZZshParameter)offsetof(struct GlobalUniform, g_fPosXY) /4;
g_fBilinear = (ZZshParameter)offsetof(struct ConstantUniform, g_fBilinear) /4;
g_fZBias = (ZZshParameter)offsetof(struct ConstantUniform, g_fZbias) /4;
g_fc0 = (ZZshParameter)offsetof(struct ConstantUniform, g_fc0) /4;
g_fMult = (ZZshParameter)offsetof(struct ConstantUniform, g_fMult) /4;
g_fZ = (ZZshParameter)offsetof(struct ConstantUniform, g_fZ) /4;
g_fExactColor = (ZZshParameter)offsetof(struct ConstantUniform, g_fExactColor) /4;
// Setup the constant buffer
// Set Z-test, log or no log;
if (conf.settings().no_logz) {
g_vdepth = float4( 255.0 /256.0f, 255.0/65536.0f, 255.0f/(65535.0f*256.0f), 1.0f/(65536.0f*65536.0f));
}
else {
g_vdepth = float4( 256.0f*65536.0f, 65536.0f, 256.0f, 65536.0f*65536.0f);
}
uniform_buffer_constant.SettleFloat(g_fZ, g_vdepth );
uniform_buffer_constant.SettleFloat(g_fBilinear, float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ) );
uniform_buffer_constant.SettleFloat(g_fZBias, float4(1.0f/256.0f, 1.0004f, 1, 0.5f) );
uniform_buffer_constant.SettleFloat(g_fc0, float4(0,1, 0.001f, 0.5f) );
uniform_buffer_constant.SettleFloat(g_fExactColor, float4(0.5f, (conf.settings().exact_color)?0.9f/256.0f:0.5f/256.0f, 0,1/255.0f) );
uniform_buffer_constant.SettleFloat(g_fMult, float4(1/1024.0f, 0.2f/1024.0f, 1/128.0f, 1/512.0f));
}
ZZshParameter g_fparamFogColor, g_vparamPosXY;
ZZshParameter g_fBilinear, g_fZBias, g_fc0, g_fMult, g_fZ, g_fExactColor;
uint context;
GlobalUniform uniform_buffer[ZZSH_CTX_ALL];
ConstantUniform uniform_buffer_constant;
// Sampler
const ZZshParameter sBlocks, sBilinearBlocks, sConv16to32, sConv32to16;
SamplerParam samplers[4];
void ZZshSetParameter4fv(ZZshParameter param, const float* v) {
if (IsDualContext(param))
uniform_buffer[context].SettleFloat((int) param, v);
else
for ( int i = 0; i < ZZSH_CTX_ALL ; i++)
uniform_buffer[i].SettleFloat((int) param, v);
}
bool IsDualContext(ZZshParameter param) {
if (param == g_vparamPosXY) return true;
else return false;
}
void set_texture(ZZshParameter param, GLuint texid) {
samplers[param].set_texture(texid);
}
void enable_texture() {
for (int i = 0; i < 4; i++)
samplers[i].enable_texture();
}
void set_context(uint new_context) { context = new_context * NOCONTEXT;}
};
#endif
#ifndef GLSL4_API
struct VERTEXSHADER
{
VERTEXSHADER() : prog(sZero), Shader(0), sBitBltPos(pZero), sBitBltTex(pZero) {}
ZZshShaderLink prog;
ZZshShader Shader;
ZZshShaderType ShaderType;
ZZshParameter sBitBltPos, sBitBltTex, fBitBltTrans; // vertex shader constants
int ParametersStart, ParametersFinish;
};
#else
struct VERTEXSHADER
{
VERTEXSHADER() : prog(sZero), program(0), context(0)
{
sBitBltPos = (ZZshParameter)offsetof(struct VertexUniform, g_fBitBltPos) /4;
sBitBltTex = (ZZshParameter)offsetof(struct VertexUniform, g_fBitBltTex) /4;
fBitBltTrans = (ZZshParameter)offsetof(struct VertexUniform, g_fBitBltTrans) /4;
// Default value not sure it is needed
uniform_buffer[0].SettleFloat(fBitBltTrans, float4(0.5f, -0.5f, 0.5, 0.5 + 0.4/416.0f ) );
uniform_buffer[1].SettleFloat(fBitBltTrans, float4(0.5f, -0.5f, 0.5, 0.5 + 0.4/416.0f ) );
prog.isFragment = false;
prog.link = (void*)this;
}
VertexUniform uniform_buffer[ZZSH_CTX_ALL];
ZZshShaderLink prog;
ZZshProgram program;
uint context;
ZZshParameter sBitBltPos, sBitBltTex, fBitBltTrans; // vertex shader constants
void ZZshSetParameter4fv(ZZshParameter param, const float* v) {
if (IsDualContext(param))
uniform_buffer[context].SettleFloat((int) param, v);
else
for ( int i = 0; i < ZZSH_CTX_ALL ; i++)
uniform_buffer[i].SettleFloat((int) param, v);
}
bool IsDualContext(ZZshParameter param) { return false;}
void set_context(uint new_context) { context = new_context * NOCONTEXT;}
void release_prog() {
if(program) {
glDeleteProgram(program);
program = 0;
}
}
};
#endif
#ifdef GLSL4_API
#define SAFE_RELEASE_PROG(x) { \
if ((x.link) != NULL) { \
if (x.isFragment) { \
FRAGMENTSHADER* shader = (FRAGMENTSHADER*)x.link; \
shader->release_prog(); \
} else { \
VERTEXSHADER* shader = (VERTEXSHADER*)x.link; \
shader->release_prog(); \
} \
} \
}
#endif
extern VERTEXSHADER pvsBitBlt;
extern FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne; // ppsOne used to stop using shaders for draw
extern FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16;
extern FRAGMENTSHADER ppsRegular[4], ppsTexture[NUM_SHADERS];
extern FRAGMENTSHADER ppsCRTC[2], /*ppsCRTC24[2],*/ ppsCRTCTarg[2];
#ifdef GLSL4_API
extern COMMONSHADER g_cs;
#endif
extern int interlace_mode;
enum CRTC_TYPE
{
CRTC_RENDER,
//CRTC_RENDER_24,
CRTC_RENDER_TARG
};
static __forceinline FRAGMENTSHADER* curr_ppsCRTC() { return &ppsCRTC[interlace_mode]; }
//static __forceinline FRAGMENTSHADER* curr_ppsCRTC24() { return &ppsCRTC24[interlace_mode]; }
static __forceinline FRAGMENTSHADER* curr_ppsCRTCTarg() { return &ppsCRTCTarg[interlace_mode]; }
static __forceinline FRAGMENTSHADER* curr_pps(CRTC_TYPE render_type)
{
switch (render_type)
{
case CRTC_RENDER: return curr_ppsCRTC();
//case CRTC_RENDER_24: return curr_ppsCRTC24();
case CRTC_RENDER_TARG: return curr_ppsCRTCTarg();
default: return NULL;
}
}
// ------------------------- Functions -------------------------------
#ifdef NVIDIA_CG_API
inline bool ZZshExistProgram(FRAGMENTSHADER* pf) {return (pf->prog != NULL); }; // We don't check ps != NULL, so be warned,
inline bool ZZshExistProgram(VERTEXSHADER* pf) {return (pf->prog != NULL); };
inline bool ZZshExistProgram(ZZshShaderLink prog) {return (prog != NULL); };
#endif
#if defined(GLSL_API) && !defined(GLSL4_API)
inline bool ZZshExistProgram(FRAGMENTSHADER* pf) {return (pf->Shader != 0); };
inline bool ZZshExistProgram(VERTEXSHADER* pf) {return (pf->Shader != 0); };
inline bool ZZshExistProgram(ZZshShaderLink prog) {return (prog.link != NULL); } // This is used for pvs mainly. No NULL means that we do LOAD_VS
#endif
#if defined(GLSL4_API)
inline bool ZZshExistProgram(FRAGMENTSHADER* pf) {return (pf->program != 0); };
inline bool ZZshExistProgram(VERTEXSHADER* pf) {return (pf->program != 0); };
inline bool ZZshExistProgram(ZZshShaderLink prog) {return (prog.link != NULL); } // This is used for pvs mainly. No NULL means that we do LOAD_VS
#endif
extern const char* ShaderCallerName;
extern const char* ShaderHandleName;
inline void SetShaderCaller(const char* Name) {
ShaderCallerName = Name;
}
inline void SetHandleName(const char* Name) {
ShaderHandleName = Name;
}
inline void ResetShaderCounters() {
// g_vsprog = g_psprog = sZero;
}
/////////////////////////////////////////////////////////////////
// Improvement:
// * store the location of uniform. Avoid to call glGetUniformLocation a lots of time
// * Use separate shader build pipeline: current code emulate this behavior but with the recent opengl4
// it would be much more easier to code it.
/////////////////////////////////////////////////////////////////
// GLSL: Stub
extern bool ZZshCheckProfilesSupport();
// Try various Shader to choose supported configuration
// g_nPixelShaderVer -> SHADER_ACCURATE and SHADER_REDUCED
// Honestly we can probably stop supporting those cards.
extern bool ZZshStartUsingShaders();
// Open the shader file into an source array
extern bool ZZshCreateOpenShadersFile();
// Those 2 functions are used to stop/start shader. The idea is to draw the HUD text.
// Enable is not implemented and it is likely to stop everythings
extern void ZZshGLDisableProfile();
extern void ZZshGLEnableProfile();
// Set the Uniform parameter in host (NOT GL)
// Param seem to be an absolute index inside a table of uniform
extern void ZZshSetParameter4fv(ZZshShaderLink& prog, ZZshParameter param, const float* v, const char* name);
extern void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name);
extern void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink& prog, const float* v, const char* name);
// Set the Texture parameter in host (NOT GL)
extern void ZZshGLSetTextureParameter(ZZshShaderLink prog, ZZshParameter param, GLuint texobj, const char* name);
extern void ZZshGLSetTextureParameter(ZZshParameter param, GLuint texobj, const char* name);
// Set a default value for 1 uniform in host (NOT GL)
extern void ZZshDefaultOneColor( FRAGMENTSHADER& ptr );
// Link then run with the new Vertex/Fragment Shader
extern void ZZshSetVertexShader(ZZshShaderLink prog);
extern void ZZshSetPixelShader(ZZshShaderLink prog);
// Compile standalone Fragment/Vertex shader program
// Note It also init all the Uniform parameter in host (NOT GL)
extern bool ZZshLoadExtraEffects();
// Clean some stuff on exit
extern void ZZshExitCleaning();
extern FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed);
// only sets a limited amount of state (for Update)
void SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, bool CheckVB, FRAGMENTSHADER* pfragment, int force);
extern u32 ptexBlocks; // holds information on block tiling. It's texture number in OpenGL -- if 0 than such texture
extern u32 ptexConv16to32; // does not exists. This textures should be created on start and released on finish.
extern u32 ptexBilinearBlocks;
extern u32 ptexConv32to16;
#ifdef GLSL4_API
extern GSUniformBufferOGL *constant_buffer;
extern GSUniformBufferOGL *common_buffer;
extern GSUniformBufferOGL *vertex_buffer;
extern GSUniformBufferOGL *fragment_buffer;
extern GSVertexBufferStateOGL *vertex_array;
extern GLenum g_current_vs;
extern GLenum g_current_ps;
extern void init_shader();
extern void PutParametersInProgram(VERTEXSHADER* vs, FRAGMENTSHADER* ps);
extern void init_shader();
extern void ZZshSetupShader();
#endif
#endif

View File

@ -1,980 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009 zeydlitz@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2006
*
* 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(GLSL_API) && !defined(GLSL4_API) // This code is only for GLSL API
// ZZogl Shader manipulation functions.
/*
* used cg calls:
* cgGLIsProfileSupported -- don't needed
* cgGetErrorString -- later
* cgGetLastListing -- later
* cgSetErrorHandler -- later
* cgCreateContext -- think that don't need
* cgGLEnableProfile -- don't need
* cgGLSetOptimalOptions -- don't need?
* cgGLSetManageTextureParameters -- what's this?
* cgCreateParameter -- don't need
* cgGLLoadProgram void LinkProgram(uint program)
* cgGetError -- later
* cgGLDisableProfile -- don't need
* cgGLSetParameter4fv
* cgGetNamedParameter
* cgGLEnableTextureParameter
* cgIsParameterUsed
* cgGLBindProgram void UseProgram(uint program)
* cgConnectParameter
* cgIsProgram bool IsProgram(uint program)
* cgCreateProgramFromFile
*/
//------------------- Includes
#include "Util.h"
#include "ZZoglShaders.h"
#include "zpipe.h"
#include <math.h>
#include <map>
#include <fcntl.h> // this for open(). Maybe linux-specific
#include <sys/mman.h> // and this for mmap
// ----------------- Defines
#define TEXWRAP_REPEAT 0
#define TEXWRAP_CLAMP 1
#define TEXWRAP_REGION_REPEAT 2
#define TEXWRAP_REPEAT_CLAMP 3
#ifdef DEVBUILD
# define UNIFORM_ERROR_LOG ZZLog::Error_Log
#else
# define UNIFORM_ERROR_LOG
#endif
// Set it to 0 to diable context usage, 1 -- to enable. FFX-1 have a strange issue with ClampExt.
#define NOCONTEXT 0
#define NUMBER_OF_SAMPLERS 11
#define MAX_SHADER_NAME_SIZE 25
#define MAX_UNIFORM_NAME_SIZE 20
#define DEFINE_STRING_SIZE 256
//------------------ Constants
// Used in a logarithmic Z-test, as (1-o(1))/log(MAX_U32).
const float g_filog32 = 0.999f / (32.0f * logf(2.0f));
const static char* g_pTexTypes[] = { "32", "tex32", "clut32", "tex32to16", "tex16to8h" };
const static char* g_pShaders[4] = { "full", "reduced", "accurate", "accurate-reduced" };
// ----------------- Global Variables
ZZshContext g_cgcontext;
ZZshProfile cgvProf, cgfProf;
int g_nPixelShaderVer = 0; // default
u8* s_lpShaderResources = NULL;
ZZshShaderLink pvs[16] = {sZero}, g_vsprog = sZero, g_psprog = sZero; // 2 -- ZZ
ZZshParameter g_vparamPosXY[2] = {pZero}, g_fparamFogColor = pZero;
ZZshProgram ZZshMainProgram;
char* ZZshSource; // Shader's source data.
off_t ZZshSourceSize;
extern char EFFECT_NAME[256]; // All this variables used for testing and set manually
extern char EFFECT_DIR[256];
bool g_bCRTCBilinear = true;
float4 g_vdepth, vlogz;
FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne;
FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16;
FRAGMENTSHADER ppsRegular[4], ppsTexture[NUM_SHADERS];
FRAGMENTSHADER ppsCRTC[2], /*ppsCRTC24[2],*/ ppsCRTCTarg[2];
VERTEXSHADER pvsStore[16];
VERTEXSHADER pvsBitBlt;
inline bool LoadEffects();
extern bool s_bWriteDepth;
struct SHADERHEADER
{
unsigned int index, offset, size; // if highest bit of index is set, pixel shader
};
map<int, SHADERHEADER*> mapShaderResources;
// Debug variable, store name of the function that call the shader.
const char* ShaderCallerName = "";
const char* ShaderHandleName = "";
int NumActiveUniforms, NumGlobalUniforms;
ZZshParamInfo UniformsIndex[MAX_ACTIVE_UNIFORMS] = {qZero};
const char* ShaderNames[MAX_ACTIVE_SHADERS] = {""};
ZZshShaderType ShaderTypes[MAX_ACTIVE_SHADERS] = {ZZ_SH_NONE};
ZZshProgram CompiledPrograms[MAX_ACTIVE_SHADERS][MAX_ACTIVE_SHADERS] = {{0}};
const char* TextureUnits[NUMBER_OF_SAMPLERS] =
{"g_sMemory[0]", "g_sMemory[1]", "g_sSrcFinal", "g_sBitwiseANDX", "g_sBitwiseANDY", "g_sInterlace", \
"g_sCLUT", "g_sBlocks", "g_sBilinearBlocks", "g_sConv16to32", "g_sConv32to16"};
ZZshPARAMTYPE TextureTypes[NUMBER_OF_SAMPLERS] =
{ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, \
ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_3D} ;
//------------------ Code
inline int GET_SHADER_INDEX(int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int context, int ps) {
return type + texfilter*NUM_TYPES + NUM_FILTERS*NUM_TYPES*texwrap + NUM_TEXWRAPS*NUM_FILTERS*NUM_TYPES*(fog+2*writedepth+4*testaem+8*exactcolor+16*context+32*ps) ;
}
// Nothing need to be done.
bool ZZshCheckProfilesSupport() {
return true;
}
// Error handler. Setup in ZZogl_Create once.
void HandleCgError(ZZshContext ctx, ZZshError err, void* appdata)
{/*
ZZLog::Error_Log("%s->%s: %s", ShaderCallerName, ShaderHandleName, cgGetErrorString(err));
const char* listing = cgGetLastListing(g_cgcontext);
if (listing != NULL)
ZZLog::Debug_Log(" last listing: %s", listing);
*/
}
float ZeroFloat4[4] = {0};
inline void SettleFloat(float* f, const float* v) {
f[0] = v[0];
f[1] = v[1];
f[2] = v[2];
f[3] = v[3];
}
inline ZZshParamInfo ParamInfo(const char* ShName, ZZshPARAMTYPE type, const float fvalue[], GLuint sampler, GLint texid, bool Constant, bool Settled) {
ZZshParamInfo x;
x.ShName = new char[MAX_UNIFORM_NAME_SIZE];
x.ShName = ShName;
x.type = type;
SettleFloat(x.fvalue, fvalue);
x.sampler = sampler;
x.texid = texid;
x.Constant = Constant;
x.Settled = Settled;
return x;
}
inline void SetGlobalUniform(ZZshParameter* param, const char* name) {
*param = NumActiveUniforms;
UniformsIndex[NumActiveUniforms] = ParamInfo(name, ZZ_FLOAT4, ZeroFloat4, -1, 0, false, false);
NumActiveUniforms++;
}
bool ZZshStartUsingShaders() {
ZZLog::Error_Log("Creating effects.");
B_G(LoadEffects(), return false);
if (!glCreateShader)
{
ZZLog::Error_Log("GLSL shaders is not supported, stop.");
return false;
}
// create a sample shader
clampInfo temp;
memset(&temp, 0, sizeof(temp));
temp.wms = 3; temp.wmt = 3;
g_nPixelShaderVer = 0;//SHADER_ACCURATE;
// test
bool bFailed;
FRAGMENTSHADER* pfrag = ZZshLoadShadeEffect(0, 1, 1, 1, 1, temp, 0, &bFailed);
if( bFailed || pfrag == NULL ) {
g_nPixelShaderVer = SHADER_ACCURATE|SHADER_REDUCED;
pfrag = ZZshLoadShadeEffect(0, 0, 1, 1, 0, temp, 0, &bFailed);
if( pfrag != NULL )
glLinkProgram(pfrag->Shader);
if( bFailed || pfrag == NULL || glGetError() != GL_NO_ERROR) {
g_nPixelShaderVer = SHADER_REDUCED;
ZZLog::Error_Log("Basic shader test failed.");
}
}
ZZshMainProgram = glCreateProgram();
NumActiveUniforms = 0;
SetGlobalUniform(&g_fparamFogColor, "g_fFogColor");
SetGlobalUniform(&g_vparamPosXY[0], "g_fPosXY[0]");
SetGlobalUniform(&g_vparamPosXY[1], NOCONTEXT?"g_fPosXY[1]":"g_fPosXY[0]");
NumGlobalUniforms = NumActiveUniforms;
if (g_nPixelShaderVer & SHADER_REDUCED)
conf.bilinear = 0;
ZZLog::Error_Log("Creating extra effects.");
B_G(ZZshLoadExtraEffects(), return false);
ZZLog::Error_Log("Using %s shaders.", g_pShaders[g_nPixelShaderVer]);
return true;
}
// open shader file according to build target
bool ZZshCreateOpenShadersFile() {
std::string ShaderFileName("plugins/ps2hw.glsl");
int ShaderFD = open(ShaderFileName.c_str(), O_RDONLY);
struct stat sb;
if ((ShaderFD == -1) || (fstat(ShaderFD, &sb) == -1)) {
// Each linux distributions have his rules for path so we give them the possibility to
// change it with compilation flags. -- Gregory
#ifdef GLSL_SHADER_DIR_COMPILATION
#define xGLSL_SHADER_DIR_str(s) GLSL_SHADER_DIR_str(s)
#define GLSL_SHADER_DIR_str(s) #s
ShaderFileName = string(xGLSL_SHADER_DIR_str(GLSL_SHADER_DIR_COMPILATION)) + "/ps2hw.glsl";
ShaderFD = open(ShaderFileName.c_str(), O_RDONLY);
#endif
if ((ShaderFD == -1) || (fstat(ShaderFD, &sb) == -1)) {
ZZLog::Error_Log("No source for %s: \n", ShaderFileName.c_str());
return false;
}
}
ZZshSourceSize = sb.st_size;
ZZshSource = (char*)mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, ShaderFD, 0); // This function directly maped file into memory.
ZZshSource[ ZZshSourceSize - 1] = 0; // Made source null-terminated.
close(ShaderFD);
return true;
}
void ZZshExitCleaning() {
munmap(ZZshSource, ZZshSourceSize);
}
// Disable CG
void ZZshGLDisableProfile() { // This stop all other shader programs from running;
glUseProgram(0);
}
//Enable CG
void ZZshGLEnableProfile() {
}
//-------------------------------------------------------------------------------------
// The same function for texture, also to cgGLEnable
void ZZshGLSetTextureParameter(ZZshParameter param, GLuint texobj, const char* name) {
if (param > -1) {
// ZZLog::Error_Log("Set texture parameter %s %d... Ok", name, texobj);
UniformsIndex[param].texid = texobj;
UniformsIndex[param].Settled = true;
}
}
void ZZshGLSetTextureParameter(ZZshShaderLink prog, ZZshParameter param, GLuint texobj, const char* name) {
if (param > -1) {
// ZZLog::Error_Log("Set texture parameter %s %d... Ok", name, texobj);
UniformsIndex[param].texid = texobj;
UniformsIndex[param].Settled = true;
}
}
// This is helper of cgGLSetParameter4fv, made for debug purpose.
// Name could be any string. We must use it on compilation time, because erroneus handler does not
// return name
void ZZshSetParameter4fv(ZZshShaderLink& prog, ZZshParameter param, const float* v, const char* name) {
if (param > -1) {
// ZZLog::Error_Log("Set float parameter %s %f, %f, %f, %f... Ok", name, v[0], v[1], v[2], v[3]);
SettleFloat(UniformsIndex[param].fvalue, v);
UniformsIndex[param].Settled = true;
}
}
void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name) {
if (param > -1) {
// ZZLog::Error_Log("Set float parameter %s %f, %f, %f, %f... Ok", name, v[0], v[1], v[2], v[3]);
SettleFloat(UniformsIndex[param].fvalue, v);
UniformsIndex[param].Settled = true;
}
}
// The same stuff, but also with retry of param, name should be USED name of param for prog.
void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink& prog, const float* v, const char* name) {
if (param != NULL)
ZZshSetParameter4fv(prog, *param, v, name);
}
// Used sometimes for color 1.
void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) {
// return;
ShaderHandleName = "Set Default One colot";
float4 v = float4 ( 1, 1, 1, 1 );
ZZshSetParameter4fv(ptr.prog, ptr.sOneColor, v, "DegaultOne");
}
//-------------------------------------------------------------------------------------
const GLchar * EmptyVertex = "void main(void) {gl_Position = ftransform();}";
const GLchar * EmptyFragment = "void main(void) {gl_FragColor = gl_Color;}";
inline ZZshProgram UseEmptyProgram(const char* name, GLenum shaderType) {
GLuint shader = glCreateShader(shaderType);
if (shaderType == GL_VERTEX_SHADER)
glShaderSource(shader, 1, &EmptyVertex, NULL);
else
glShaderSource(shader, 1, &EmptyFragment, NULL);
glCompileShader(shader);
ZZshProgram prog = glCreateProgram();
glAttachShader(prog, shader);
glLinkProgram(prog);
if( !glIsProgram(prog) || glGetError() != GL_NO_ERROR ) {
ZZLog::Error_Log("Failed to load empty shader for %s:", name);
return -1;
}
ZZLog::Error_Log("Used Empty program for %s... Ok.",name);
return prog;
}
ZZshShaderType ZZshGetShaderType(const char* name) {
if (strncmp(name, "TextureFog", 10) == 0) return ZZ_SH_TEXTURE_FOG;
if (strncmp(name, "Texture", 7) == 0) return ZZ_SH_TEXTURE;
if (strncmp(name, "RegularFog", 10) == 0) return ZZ_SH_REGULAR_FOG;
if (strncmp(name, "Regular", 7) == 0) return ZZ_SH_REGULAR;
if (strncmp(name, "Zero", 4) == 0) return ZZ_SH_ZERO;
return ZZ_SH_CRTC;
}
inline ZZshShader UseEmptyShader(const char* name, GLenum shaderType) {
GLuint shader = glCreateShader(shaderType);
if (shaderType == GL_VERTEX_SHADER)
glShaderSource(shader, 1, &EmptyVertex, NULL);
else
glShaderSource(shader, 1, &EmptyFragment, NULL);
glCompileShader(shader);
ShaderNames[shader] = name;
ShaderTypes[shader] = ZZshGetShaderType(name);
ZZLog::Error_Log("Used Empty shader for %s... Ok.",name);
return shader;
}
inline bool GetCompilationLog(GLuint shader) {
GLint CompileStatus;
glGetShaderiv(shader, GL_COMPILE_STATUS, &CompileStatus);
if (CompileStatus == GL_TRUE)
return true;
int* lenght, infologlength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologlength);
char* InfoLog = new char[infologlength];
glGetShaderInfoLog(shader, infologlength, lenght, InfoLog);
ZZLog::Error_Log("Compiling... %d:\t %s", shader, InfoLog);
return false;
}
inline bool CompileShader(ZZshProgram& shader, const char* DefineString, const char* name, GLenum shaderType) {
const GLchar* ShaderSource[2];
ShaderSource[0] = (const GLchar*)DefineString;
ShaderSource[1] = (const GLchar*)ZZshSource;
shader = glCreateShader(shaderType);
glShaderSource(shader, 2, &ShaderSource[0], NULL);
glCompileShader(shader);
ZZLog::Debug_Log("Creating shader %d for %s", shader, name);
if (!GetCompilationLog(shader)) {
ZZLog::Error_Log("Failed to compile shader for %s:", name);
return false;
}
ShaderTypes[shader] = ZZshGetShaderType(name);
ShaderNames[shader] = name;
GL_REPORT_ERRORD();
return true;
}
inline bool LoadShaderFromFile(ZZshShader& shader, const char* DefineString, const char* name, GLenum ShaderType) { // Linux specific, as I presume
if (!CompileShader(shader, DefineString, name, ShaderType)) {
ZZLog::Error_Log("Failed to compile shader for %s: ", name);
return false;
}
ZZLog::Error_Log("Used shader for %s... Ok",name);
return true;
}
inline bool GetLinkLog(ZZshProgram prog) {
GLint LinkStatus;
glGetProgramiv(prog, GL_LINK_STATUS, &LinkStatus);
int unif, atrib;
glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &unif);
glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &atrib);
UNIFORM_ERROR_LOG("Uniforms %d, attributes %d", unif, atrib);
if (LinkStatus == GL_TRUE && glIsProgram(prog)) return true;
#if defined(DEVBUILD) || defined(_DEBUG)
int* lenght, infologlength;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &infologlength);
char* InfoLog = new char[infologlength];
glGetProgramInfoLog(prog, infologlength, lenght, InfoLog);
if (!infologlength == 0)
ZZLog::Error_Log("Linking %d... %d:\t %s", prog, infologlength, InfoLog);
#endif
return false;
}
//-------------------------------------------------------------------------------------
inline ZZshProgram madeProgram(ZZshShader shader, ZZshShader shader2, char* name) {
ZZshProgram prog = glCreateProgram();
glAttachShader(prog, shader);
if (shader2 != 0)
glAttachShader(prog, shader2);
glLinkProgram(prog);
if (!GetLinkLog(prog)) {
ZZLog::Error_Log("Failed to link shader for %s: ", name);
prog = UseEmptyProgram(name, GL_FRAGMENT_SHADER);
}
glDetachShader(prog, shader);
ZZLog::Error_Log("Made shader program for %s... Ok",name);
return prog;
}
static void PutParametersInProgam(int start, int finish) {
for (int i = start; i < finish; i++) {
ZZshParamInfo param = UniformsIndex[i];
GLint location = glGetUniformLocation(ZZshMainProgram, param.ShName);
if (location != -1 && param.type != ZZ_UNDEFINED) {
UNIFORM_ERROR_LOG("\tTry uniform %d %d %d %s...\t\t", i, location, param.type, param.ShName);
if (!param.Settled && !param.Constant) {
UNIFORM_ERROR_LOG("\tUnsettled, non-constant uniform, could be bug: %d %s", param.type, param.ShName);
continue;
}
if (param.type == ZZ_FLOAT4) {
glUniform4fv(location, 1, param.fvalue);
}
else
{
// assert(param.texid != 0);
// ZZLog::Error_Log("Set texture (%s) : %d with sampler %d\n", param.ShName, param.texid, param.sampler);
// assert(param.sampler >= 0);
glActiveTexture(GL_TEXTURE0 + param.sampler);
if (param.type == ZZ_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, param.texid);
else if (param.type == ZZ_TEXTURE_3D)
glBindTexture(GL_TEXTURE_3D, param.texid);
else
glBindTexture(GL_TEXTURE_RECTANGLE, param.texid);
GL_REPORT_ERRORD();
}
if (glGetError() == GL_NO_ERROR)
UNIFORM_ERROR_LOG("Ok. Param name %s, location %d, type %d", param.ShName, location, param.type);
else
ZZLog::Error_Log("error in PutParametersInProgam param name %s, location %d, type %d", param.ShName, location, param.type);
if (!param.Constant) // Unset used parameters
UniformsIndex[i].Settled == false;
}
else if (start != 0 && location == -1 && param.Settled) // No global variable
ZZLog::Error_Log("Warning! Unused, but set uniform %d, %s", location, param.ShName);
}
GL_REPORT_ERRORD();
}
void PutSInProgam(int start, int finish) {
for (int i = start; i < finish; i++) {
ZZshParamInfo param = UniformsIndex[i];
GLint location = glGetUniformLocation(ZZshMainProgram, param.ShName);
if (location != -1 && param.type != ZZ_UNDEFINED) {
if (param.type != ZZ_FLOAT4) {
UNIFORM_ERROR_LOG("\tTry sampler %d %d %d %s %d...\t\t", i, location, param.type, param.ShName, param.sampler);
if (glGetError() == GL_NO_ERROR)
UNIFORM_ERROR_LOG("Ok");
else
UNIFORM_ERROR_LOG("error!");
glUniform1i(location, param.sampler);
}
}
}
GL_REPORT_ERRORD();
}
static bool ValidateProgram(ZZshProgram Prog) {
GLint isValid;
glGetProgramiv(Prog, GL_VALIDATE_STATUS, &isValid);
if (!isValid) {
glValidateProgram(Prog);
int* lenght, infologlength;
glGetProgramiv(Prog, GL_INFO_LOG_LENGTH, &infologlength);
char* InfoLog = new char[infologlength];
glGetProgramInfoLog(Prog, infologlength, lenght, InfoLog);
ZZLog::Error_Log("Validation %d... %d:\t %s", Prog, infologlength, InfoLog);
}
return (isValid != 0);
}
static void PutParametersAndRun(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
UNIFORM_ERROR_LOG("Run program %s(%d) \t+\t%s(%d)", ShaderNames[vs->Shader], vs->Shader, ShaderNames[ps->Shader], ps->Shader);
glUseProgram(ZZshMainProgram);
if (glGetError() != GL_NO_ERROR) {
ZZLog::Error_Log("Something weird happened on Linking stage.");
glUseProgram(0);
return;
}
PutSInProgam(vs->ParametersStart, vs->ParametersFinish);
PutSInProgam(ps->ParametersStart, ps->ParametersFinish);
PutParametersInProgam(0, NumGlobalUniforms);
PutParametersInProgam(vs->ParametersStart, vs->ParametersFinish);
PutParametersInProgam(ps->ParametersStart, ps->ParametersFinish);
ValidateProgram(ZZshMainProgram);
GL_REPORT_ERRORD();
}
static void CreateNewProgram(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
ZZLog::Error_Log("\n---> New shader program %d, %s(%d) \t+\t%s(%d).", ZZshMainProgram, ShaderNames[vs->Shader], vs->Shader, ShaderNames[ps->Shader], ps->Shader);
if (vs->Shader != 0)
glAttachShader(ZZshMainProgram, vs->Shader);
if (ps->Shader != 0)
glAttachShader(ZZshMainProgram, ps->Shader);
glLinkProgram(ZZshMainProgram);
if (!GetLinkLog(ZZshMainProgram)) {
ZZLog::Error_Log("Main program linkage error, don't use any shader for this stage.");
return;
}
GL_REPORT_ERRORD();
}
inline bool ZZshCheckShaderCompatibility(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
if (vs == NULL) return false;
if (vs->ShaderType == ZZ_SH_ZERO) return true; // ZeroPS is compatible with everything
if (ps == NULL) return false;
return (vs->ShaderType == ps->ShaderType);
}
static void ZZshSetShader(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
if (!ZZshCheckShaderCompatibility(vs, ps)) // We don't need to link uncompatible shaders
return;
int vss = (vs!=NULL)?vs->Shader:0;
int pss = (ps!=NULL)?ps->Shader:0;
if (vss !=0 && pss != 0) {
if (CompiledPrograms[vss][pss] != 0 && glIsProgram(CompiledPrograms[vss][pss])) {
ZZshMainProgram = CompiledPrograms[vs->Shader][ps->Shader];
}
else {
ZZshProgram NewProgram = glCreateProgram();
ZZshMainProgram = NewProgram;
CompiledPrograms[vss][pss] = NewProgram;
CreateNewProgram(vs, ps) ;
}
PutParametersAndRun(vs, ps);
GL_REPORT_ERRORD();
}
}
void ZZshSetVertexShader(ZZshShaderLink prog) {
g_vsprog = prog;
ZZshSetShader((VERTEXSHADER*)(g_vsprog.link), (FRAGMENTSHADER*)(g_psprog.link)) ;
}
void ZZshSetPixelShader(ZZshShaderLink prog) {
g_psprog = prog;
ZZshSetShader((VERTEXSHADER*)(g_vsprog.link), (FRAGMENTSHADER*)(g_psprog.link)) ;
}
//------------------------------------------------------------------------------------------------------------------
// For several reason texobj could not be put in sampler directly, only though GL_TEXTUREi interface. So we need to check correct sampler for each one.
inline void SettleTextureUnit(ZZshParamInfo* param, const char* name) {
for (int i = 0; i < NUMBER_OF_SAMPLERS; i++) {
if (strcmp(TextureUnits[i], name) == 0) {
param->sampler = i;
param->type = TextureTypes[i];
return;
}
}
}
inline int SetUniformParam(ZZshProgram prog, ZZshParameter* param, const char* name) {
GLint p = glGetUniformLocation(prog, name);
if (p > -1) {
*param = NumActiveUniforms;
UniformsIndex[NumActiveUniforms] = ParamInfo(name, ZZ_FLOAT4, ZeroFloat4, -1, 0, false, false); // By define Uniform is FLOAT4
SettleTextureUnit(&(UniformsIndex[NumActiveUniforms]), name);
UNIFORM_ERROR_LOG("uniform %s \t\t%d %d", name, p, UniformsIndex[NumActiveUniforms].type);
NumActiveUniforms++;
}
else *param = -1;
return p;
}
#define SET_UNIFORMPARAM(var, name) { \
p = SetUniformParam(prog, &(pf->var), name); \
}
#define INIT_SAMPLERPARAM(tex, name) { \
ZZshParameter x; \
p = SetUniformParam(prog, &x, name); \
(UniformsIndex[x]).Constant = true; \
ZZshGLSetTextureParameter(pf->prog, x, tex, name); \
}
#define INIT_UNIFORMPARAM(var, name) { \
ZZshParameter x; \
p = SetUniformParam(prog, &x, name); \
(UniformsIndex[x]).Constant = true; \
ZZshSetParameter4fv(pf->prog, x, var, name); \
}
char* AddContextToName(const char* name, int context) {
char* newname = new char[MAX_UNIFORM_NAME_SIZE];
sprintf(newname, "%s[%d]", name, context * NOCONTEXT);
return newname;
}
static void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type)
{
// uniform parameters
GLint p;
pf->prog.link = (void*)pf; // Setting autolink
pf->prog.isFragment = true; // Setting autolink
pf->ShaderType = ShaderTypes[pf->Shader];
pf->ParametersStart = NumActiveUniforms;
ZZshProgram prog = madeProgram(pf->Shader, 0, "");
glUseProgram(prog);
GL_REPORT_ERRORD();
SET_UNIFORMPARAM(sOneColor, "g_fOneColor");
SET_UNIFORMPARAM(sBitBltZ, "g_fBitBltZ");
SET_UNIFORMPARAM(sInvTexDims, "g_fInvTexDims");
SET_UNIFORMPARAM(fTexAlpha2, AddContextToName("fTexAlpha2", context));
SET_UNIFORMPARAM(fTexOffset, AddContextToName("g_fTexOffset", context));
SET_UNIFORMPARAM(fTexDims, AddContextToName("g_fTexDims", context));
SET_UNIFORMPARAM(fTexBlock, AddContextToName("g_fTexBlock", context));
SET_UNIFORMPARAM(fClampExts, AddContextToName("g_fClampExts", context)); // FIXME: There is a bug, that lead FFX-1 to incorrect CLAMP if this uniform have context.
SET_UNIFORMPARAM(fTexWrapMode, AddContextToName("TexWrapMode", context));
SET_UNIFORMPARAM(fRealTexDims, AddContextToName("g_fRealTexDims", context));
SET_UNIFORMPARAM(fTestBlack, AddContextToName("g_fTestBlack", context));
SET_UNIFORMPARAM(fPageOffset, AddContextToName("g_fPageOffset", context));
SET_UNIFORMPARAM(fTexAlpha, AddContextToName("fTexAlpha", context));
GL_REPORT_ERRORD();
// textures
INIT_SAMPLERPARAM(ptexBlocks, "g_sBlocks");
if (type == 3)
{INIT_SAMPLERPARAM(ptexConv16to32, "g_sConv16to32");}
else if (type == 4)
{INIT_SAMPLERPARAM(ptexConv32to16, "g_sConv32to16");}
else
{INIT_SAMPLERPARAM(ptexBilinearBlocks, "g_sBilinearBlocks");}
GL_REPORT_ERRORD();
SET_UNIFORMPARAM(sMemory, AddContextToName("g_sMemory", context));
SET_UNIFORMPARAM(sFinal, "g_sSrcFinal");
SET_UNIFORMPARAM(sBitwiseANDX, "g_sBitwiseANDX");
SET_UNIFORMPARAM(sBitwiseANDY, "g_sBitwiseANDY");
SET_UNIFORMPARAM(sCLUT, "g_sCLUT");
SET_UNIFORMPARAM(sInterlace, "g_sInterlace");
GL_REPORT_ERRORD();
// set global shader constants
INIT_UNIFORMPARAM(float4(0.5f, (conf.settings().exact_color)?0.9f/256.0f:0.5f/256.0f, 0,1/255.0f), "g_fExactColor");
INIT_UNIFORMPARAM(float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ), "g_fBilinear");
INIT_UNIFORMPARAM(float4(1.0f/256.0f, 1.0004f, 1, 0.5f), "g_fZBias");
INIT_UNIFORMPARAM(float4(0,1, 0.001f, 0.5f), "g_fc0");
INIT_UNIFORMPARAM(float4(1/1024.0f, 0.2f/1024.0f, 1/128.0f, 1/512.0f), "g_fMult");
pf->ParametersFinish = NumActiveUniforms;
if (NumActiveUniforms > MAX_ACTIVE_UNIFORMS)
ZZLog::Error_Log("Too many shader variables. You may increase the limit in source %d.", NumActiveUniforms);
glUseProgram(0);
GL_REPORT_ERRORD();
}
void SetupVertexProgramParameters(VERTEXSHADER* pf, int context)
{
GLint p;
pf->prog.link = (void*)pf; // Setting autolink
pf->prog.isFragment = false; // Setting autolink
pf->ShaderType = ShaderTypes[pf->Shader];
pf->ParametersStart = NumActiveUniforms;
ZZshProgram prog = madeProgram(pf->Shader, 0, "");
glUseProgram(prog);
GL_REPORT_ERRORD();
// Set Z-test, log or no log;
if (conf.settings().no_logz) {
g_vdepth = float4( 255.0 /256.0f, 255.0/65536.0f, 255.0f/(65535.0f*256.0f), 1.0f/(65536.0f*65536.0f));
vlogz = float4( 1.0f, 0.0f, 0.0f, 0.0f);
}
else {
g_vdepth = float4( 256.0f*65536.0f, 65536.0f, 256.0f, 65536.0f*65536.0f);
vlogz = float4( 0.0f, 1.0f, 0.0f, 0.0f);
}
INIT_UNIFORMPARAM(g_vdepth, "g_fZ");
if (p > -1) {
INIT_UNIFORMPARAM(vlogz, "g_fZMin");
if (p == -1) ZZLog::Error_Log ("Shader file version is outdated! Only log-Z is possible.");
}
GL_REPORT_ERRORD();
float4 vnorm = float4(g_filog32, 0, 0,0);
INIT_UNIFORMPARAM(vnorm, "g_fZNorm");
INIT_UNIFORMPARAM(float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ), "g_fBilinear");
INIT_UNIFORMPARAM(float4(1.0f/256.0f, 1.0004f, 1, 0.5f), "g_fZBias") ;
INIT_UNIFORMPARAM(float4(0,1, 0.001f, 0.5f), "g_fc0");
SET_UNIFORMPARAM(sBitBltPos, "g_fBitBltPos");
SET_UNIFORMPARAM(sBitBltTex, "g_fBitBltTex");
SET_UNIFORMPARAM(fBitBltTrans, "g_fBitBltTrans");
pf->ParametersFinish = NumActiveUniforms;
if (NumActiveUniforms > MAX_ACTIVE_UNIFORMS)
ZZLog::Error_Log("Too many shader variables. You may increase the limit in the source.");
glUseProgram(0);
GL_REPORT_ERRORD();
}
const int GLSL_VERSION = 130; // Sampler2DRect appear in 1.3
// We use strictly compilation from source for GSLS
static __forceinline void GlslHeaderString(char* header_string, const char* name, const char* depth)
{
sprintf(header_string, "#version %d\n#define %s main\n%s\n", GLSL_VERSION, name, depth);
}
static __forceinline bool LOAD_VS(char* DefineString, const char* name, VERTEXSHADER& vertex, int shaderver, ZZshProfile context, const char* depth)
{
bool flag;
char temp[200];
GlslHeaderString(temp, name, depth);
sprintf(DefineString, "%s#define VERTEX_SHADER 1\n#define CTX %d\n", temp, context * NOCONTEXT);
//ZZLog::WriteLn("Define for VS == '%s'", DefineString);
flag = LoadShaderFromFile(vertex.Shader, DefineString, name, GL_VERTEX_SHADER);
SetupVertexProgramParameters(&vertex, context);
return flag;
}
static __forceinline bool LOAD_PS(char* DefineString, const char* name, FRAGMENTSHADER& fragment, int shaderver, ZZshProfile context, const char* depth)
{
bool flag;
char temp[200];
GlslHeaderString(temp, name, depth);
sprintf(DefineString, "%s#define FRAGMENT_SHADER 1\n#define CTX %d\n", temp, context * NOCONTEXT);
//ZZLog::WriteLn("Define for PS == '%s'", DefineString);
flag = LoadShaderFromFile(fragment.Shader, DefineString, name, GL_FRAGMENT_SHADER);
SetupFragmentProgramParameters(&fragment, context, 0);
return flag;
}
inline bool LoadEffects()
{
// clear the textures
for(u32 i = 0; i < ArraySize(ppsTexture); ++i) {
SAFE_RELEASE_PROG(ppsTexture[i].prog);
}
#ifndef _DEBUG
memset(ppsTexture, 0, sizeof(ppsTexture));
#endif
return true;
}
bool ZZshLoadExtraEffects() {
bool bLoadSuccess = true;
char DefineString[DEFINE_STRING_SIZE] = "";
const char* writedepth = "#define WRITE_DEPTH 1\n"; // should we write depth field
const char* pvsshaders[4] = { "RegularVS", "TextureVS", "RegularFogVS", "TextureFogVS" };
for (int i = 0; i < 4; ++i) {
if (!LOAD_VS(DefineString, pvsshaders[i], pvsStore[2 * i], cgvProf, 0, "")) bLoadSuccess = false;
if (!LOAD_VS(DefineString, pvsshaders[i], pvsStore[2 *i + 1 ], cgvProf, 1, "")) bLoadSuccess = false;
if (!LOAD_VS(DefineString, pvsshaders[i], pvsStore[2 *i + 8 ], cgvProf, 0, writedepth)) bLoadSuccess = false;
if (!LOAD_VS(DefineString, pvsshaders[i], pvsStore[2 *i + 8 + 1], cgvProf, 1, writedepth)) bLoadSuccess = false;
}
for (int i = 0; i < 16; ++i)
pvs[i] = pvsStore[i].prog;
if (!LOAD_VS(DefineString, "BitBltVS", pvsBitBlt, cgvProf, 0, "")) bLoadSuccess = false;
GLint p;
GL_REPORT_ERRORD();
if (!LOAD_PS(DefineString, "RegularPS", ppsRegular[0], cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "RegularFogPS", ppsRegular[1], cgfProf, 0, "")) bLoadSuccess = false;
if( conf.mrtdepth ) {
if (!LOAD_PS(DefineString, "RegularPS", ppsRegular[2], cgfProf, 0, writedepth)) bLoadSuccess = false;
if (!bLoadSuccess) conf.mrtdepth = 0;
if (!LOAD_PS(DefineString, "RegularFogPS", ppsRegular[3], cgfProf, 0, writedepth)) bLoadSuccess = false;
if (!bLoadSuccess) conf.mrtdepth = 0;
}
if (!LOAD_PS(DefineString, "BitBltPS", ppsBitBlt[0], cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "BitBltAAPS", ppsBitBlt[1], cgfProf, 0, "")) bLoadSuccess = false;
if (!bLoadSuccess) {
ZZLog::Error_Log("Failed to load BitBltAAPS, using BitBltPS.");
if (!LOAD_PS(DefineString, "BitBltPS", ppsBitBlt[1], cgfProf, 0, "")) bLoadSuccess = false;
}
if (!LOAD_PS(DefineString, "BitBltDepthPS", ppsBitBltDepth, cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "CRTCTargPS", ppsCRTCTarg[0], cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "CRTCTargInterPS", ppsCRTCTarg[1], cgfProf, 0, "")) bLoadSuccess = false;
g_bCRTCBilinear = true;
if (!LOAD_PS(DefineString, "CRTCPS", ppsCRTC[0], cgfProf, 0, "")) bLoadSuccess = false;
if( !bLoadSuccess ) {
// switch to simpler
g_bCRTCBilinear = false;
if (!LOAD_PS(DefineString, "CRTCPS_Nearest", ppsCRTC[0], cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "CRTCInterPS_Nearest", ppsCRTC[0], cgfProf, 0, "")) bLoadSuccess = false;
}
else {
if (!LOAD_PS(DefineString, "CRTCInterPS", ppsCRTC[1], cgfProf, 0, "")) bLoadSuccess = false;
}
if( !bLoadSuccess )
ZZLog::Error_Log("Failed to create CRTC shaders.");
// if (!LOAD_PS(DefineString, "CRTC24PS", ppsCRTC24[0], cgfProf, 0, "")) bLoadSuccess = false;
// if (!LOAD_PS(DefineString, "CRTC24InterPS", ppsCRTC24[1], cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "ZeroPS", ppsOne, cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "BaseTexturePS", ppsBaseTexture, cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "Convert16to32PS", ppsConvert16to32, cgfProf, 0, "")) bLoadSuccess = false;
if (!LOAD_PS(DefineString, "Convert32to16PS", ppsConvert32to16, cgfProf, 0, "")) bLoadSuccess = false;
GL_REPORT_ERRORD();
return true;
}
const static char* g_pPsTexWrap[] = { "#define REPEAT 1\n", "#define CLAMP 1\n", "#define REGION_REPEAT 1\n", "" };
static ZZshShader LoadShaderFromType(const char* srcdir, const char* srcfile, int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int ps, int context) {
assert( texwrap < NUM_TEXWRAPS);
assert( type < NUM_TYPES );
//ZZLog::Error_Log("\n");
ZZshProgram prog;
char* name = new char[MAX_SHADER_NAME_SIZE];
sprintf(name, "Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]);
ZZLog::Debug_Log("Starting shader for %s", name);
const char* AddWrap = g_pPsTexWrap[texwrap];
const char* AddDepth = writedepth?"#define WRITE_DEPTH 1\n":"";
const char* AddAEM = testaem?"#define TEST_AEM 1\n":"";
const char* AddExcolor = exactcolor?"#define EXACT_COLOR 1\n":"";
const char* AddAccurate = (ps & SHADER_ACCURATE)?"#define ACCURATE_DECOMPRESSION 1\n":"";
char DefineString[DEFINE_STRING_SIZE] = "";
char temp[200];
GlslHeaderString(temp, name, AddWrap);
sprintf(DefineString, "%s#define FRAGMENT_SHADER 1\n%s%s%s%s\n#define CTX %d\n", temp, AddDepth, AddAEM, AddExcolor, AddAccurate, context * NOCONTEXT);
ZZshShader shader;
if (!CompileShader(shader, DefineString, name, GL_FRAGMENT_SHADER))
return UseEmptyShader(name, GL_FRAGMENT_SHADER);
ZZLog::Debug_Log("Used shader for type:%d filter:%d wrap:%d for:%d depth:%d aem:%d color:%d decompression:%d ctx:%d... Ok \n", type, texfilter, texwrap, fog, writedepth, testaem, exactcolor, ps, context);
GL_REPORT_ERRORD();
return shader;
}
FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed)
{
int texwrap;
assert( texfilter < NUM_FILTERS );
//assert( g_nPixelShaderVer == SHADER_30 );
if( clamp.wms == clamp.wmt ) {
switch( clamp.wms ) {
case 0: texwrap = TEXWRAP_REPEAT; break;
case 1: texwrap = TEXWRAP_CLAMP; break;
case 2: texwrap = TEXWRAP_CLAMP; break;
default:
texwrap = TEXWRAP_REGION_REPEAT; break;
}
}
else if( clamp.wms==3||clamp.wmt==3)
texwrap = TEXWRAP_REGION_REPEAT;
else
texwrap = TEXWRAP_REPEAT_CLAMP;
int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0);
if( pbFailed != NULL ) *pbFailed = false;
FRAGMENTSHADER* pf = ppsTexture+index;
if (ZZshExistProgram(pf))
{
return pf;
}
pf->Shader = LoadShaderFromType(EFFECT_DIR, EFFECT_NAME, type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, g_nPixelShaderVer, context);
if (ZZshExistProgram(pf)) {
SetupFragmentProgramParameters(pf, context, type);
GL_REPORT_ERRORD();
if( glGetError() != GL_NO_ERROR ) {
ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
if (pbFailed != NULL ) *pbFailed = true;
return pf;
}
return pf;
}
ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
if( pbFailed != NULL ) *pbFailed = true;
GL_REPORT_ERRORD();
return NULL;
}
#endif

View File

@ -1,594 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009 zeydlitz@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2006
*
* 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
*/
#ifdef GLSL4_API // This code is only for GLSL API
// ZZogl Shader manipulation functions.
/*
* used cg calls:
* cgGLIsProfileSupported -- don't needed
* cgGetErrorString -- later
* cgGetLastListing -- later
* cgSetErrorHandler -- later
* cgCreateContext -- think that don't need
* cgGLEnableProfile -- don't need
* cgGLSetOptimalOptions -- don't need?
* cgGLSetManageTextureParameters -- what's this?
* cgCreateParameter -- don't need
* cgGLLoadProgram void LinkProgram(uint program)
* cgGetError -- later
* cgGLDisableProfile -- don't need
* cgGLSetParameter4fv
* cgGetNamedParameter
* cgGLEnableTextureParameter
* cgIsParameterUsed
* cgGLBindProgram void UseProgram(uint program)
* cgConnectParameter
* cgIsProgram bool IsProgram(uint program)
* cgCreateProgramFromFile
*/
//------------------- Includes
#include "Util.h"
#include "ZZoglShaders.h"
#include "zpipe.h"
#include <map>
#include <fcntl.h> // this for open(). Maybe linux-specific
#include "ps2hw_gl4.h"
// ----------------- Defines
#define TEXWRAP_REPEAT 0
#define TEXWRAP_CLAMP 1
#define TEXWRAP_REGION_REPEAT 2
#define TEXWRAP_REPEAT_CLAMP 3
#ifdef DEVBUILD
# define UNIFORM_ERROR_LOG ZZLog::Error_Log
#else
# define UNIFORM_ERROR_LOG
#endif
// Set it to 0 to diable context usage, 1 -- to enable. FFX-1 have a strange issue with ClampExt.
#define NOCONTEXT 0
#define NUMBER_OF_SAMPLERS 11
#define MAX_SHADER_NAME_SIZE 25
#define DEFINE_STRING_SIZE 256
// #define ENABLE_MARKER // Fire some marker for opengl Debugger (apitrace, gdebugger)
//------------------ Constants
const static char* g_pTexTypes[] = { "32", "tex32", "clut32", "tex32to16", "tex16to8h" };
const static char* g_pPsTexWrap[] = { "#define REPEAT 1\n", "#define CLAMP 1\n", "#define REGION_REPEAT 1\n", "\n" };
const int GLSL_VERSION = 330;
// ----------------- Global Variables
ZZshContext g_cgcontext;
ZZshProfile cgvProf, cgfProf;
int g_nPixelShaderVer = 0; // default
u8* s_lpShaderResources = NULL;
ZZshShaderLink pvs[16] = {sZero}, g_vsprog = sZero, g_psprog = sZero; // 2 -- ZZ
ZZshParameter g_vparamPosXY[2] = {pZero}, g_fparamFogColor = pZero;
bool g_bCRTCBilinear = true;
float4 g_vdepth, vlogz;
FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne;
FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16;
FRAGMENTSHADER ppsRegular[4], ppsTexture[NUM_SHADERS];
FRAGMENTSHADER ppsCRTC[2], /*ppsCRTC24[2],*/ ppsCRTCTarg[2];
VERTEXSHADER pvsStore[16];
VERTEXSHADER pvsBitBlt;
inline bool LoadEffects();
extern bool s_bWriteDepth;
// Debug variable, store name of the function that call the shader.
const char* ShaderCallerName = "";
const char* ShaderHandleName = "";
// new for GLSL4
GSUniformBufferOGL *constant_buffer;
GSUniformBufferOGL *common_buffer;
GSUniformBufferOGL *vertex_buffer;
GSUniformBufferOGL *fragment_buffer;
static bool dirty_common_buffer = true;
static bool dirty_vertex_buffer = true;
static bool dirty_fragment_buffer = true;
GSVertexBufferStateOGL *vertex_array = NULL;
COMMONSHADER g_cs;
static GLuint s_pipeline = 0;
uint g_current_texture_bind[11] = {0};
GLenum g_current_vs = 0;
GLenum g_current_ps = 0;
FRAGMENTSHADER ppsDebug;
FRAGMENTSHADER ppsDebug2;
FRAGMENTSHADER ppsDebug3;
//------------------ Code
inline int GET_SHADER_INDEX(int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int context, int ps) {
return type + texfilter*NUM_TYPES + NUM_FILTERS*NUM_TYPES*texwrap + NUM_TEXWRAPS*NUM_FILTERS*NUM_TYPES*(fog+2*writedepth+4*testaem+8*exactcolor+16*context+32*ps) ;
}
// Nothing need to be done.
bool ZZshCheckProfilesSupport() {
return true;
}
bool ZZshStartUsingShaders() {
ZZLog::Error_Log("Creating effects.");
B_G(LoadEffects(), return false);
if (!glCreateShader)
{
ZZLog::Error_Log("GLSL shaders is not supported, stop.");
return false;
}
init_shader();
// create a sample shader
clampInfo temp;
memset(&temp, 0, sizeof(temp));
temp.wms = 3; temp.wmt = 3;
// test
bool bFailed;
FRAGMENTSHADER* pfrag = ZZshLoadShadeEffect(0, 1, 1, 1, 1, temp, 0, &bFailed);
if( bFailed || pfrag == NULL ) {
ZZLog::Error_Log("Shader test failed.");
return false;
}
ZZLog::Error_Log("Creating extra effects.");
B_G(ZZshLoadExtraEffects(), return false);
return true;
}
// open shader file according to build target
bool ZZshCreateOpenShadersFile() {
return true;
}
void ZZshExitCleaning() {
delete constant_buffer;
delete common_buffer;
delete vertex_buffer;
delete fragment_buffer;
dirty_fragment_buffer = true;
dirty_vertex_buffer = true;
dirty_common_buffer = true;
g_current_ps = 0;
g_current_vs = 0;
for (uint i = 0; i < 11; i++)
g_current_texture_bind[i] = 0;
glDeleteProgramPipelines(1, &s_pipeline);
}
// Disable CG
void ZZshGLDisableProfile() { // This stop all other shader programs from running;
glBindProgramPipeline(0);
}
//Enable CG
void ZZshGLEnableProfile() {
glBindProgramPipeline(s_pipeline);
}
//-------------------------------------------------------------------------------------
// The same function for texture, also to cgGLEnable
void ZZshGLSetTextureParameter(ZZshParameter param, GLuint texobj, const char* name) {
#ifdef ENABLE_MARKER
if (GLEW_GREMEDY_string_marker) glStringMarkerGREMEDY(0, format("CS: texture %d, param %d", texobj, param).c_str() );
#endif
g_cs.set_texture(param, texobj);
}
void ZZshGLSetTextureParameter(ZZshShaderLink prog, ZZshParameter param, GLuint texobj, const char* name) {
FRAGMENTSHADER* shader = (FRAGMENTSHADER*)prog.link;
#ifdef ENABLE_MARKER
if (GLEW_GREMEDY_string_marker) glStringMarkerGREMEDY(0, format("FS(%d):texture %d, param %d", shader->program, texobj, param).c_str() );
#endif
shader->set_texture(param, texobj);
}
// This is helper of cgGLSetParameter4fv, made for debug purpose.
// Name could be any string. We must use it on compilation time, because erroneus handler does not
// return name
void ZZshSetParameter4fv(ZZshShaderLink& prog, ZZshParameter param, const float* v, const char* name) {
if (prog.isFragment) {
FRAGMENTSHADER* shader = (FRAGMENTSHADER*)prog.link;
shader->ZZshSetParameter4fv(param, v);
dirty_fragment_buffer = true;
} else {
VERTEXSHADER* shader = (VERTEXSHADER*)prog.link;
shader->ZZshSetParameter4fv(param, v);
dirty_vertex_buffer = true;
}
#ifdef ENABLE_MARKER
if (GLEW_GREMEDY_string_marker) glStringMarkerGREMEDY(0, format("prog: uniform (%s) (%f)", name, *v).c_str() );
#endif
}
void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name) {
g_cs.ZZshSetParameter4fv(param, v);
dirty_common_buffer = true;
#ifdef ENABLE_MARKER
if (GLEW_GREMEDY_string_marker) glStringMarkerGREMEDY(0, format("CS: uniform (%s) (%f)", name, *v).c_str() );
#endif
}
// The same stuff, but also with retry of param, name should be USED name of param for prog.
void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink& prog, const float* v, const char* name) {
ZZshSetParameter4fv(prog, *param, v, name);
}
// Used sometimes for color 1.
void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) {
ShaderHandleName = "Set Default One colot";
float4 v = float4 ( 1, 1, 1, 1 );
ptr.ZZshSetParameter4fv(ptr.sOneColor, v);
dirty_fragment_buffer = true;
}
//-------------------------------------------------------------------------------------
static bool ValidateProgram(ZZshProgram Prog) {
GLint isValid;
glValidateProgram(Prog);
glGetProgramiv(Prog, GL_VALIDATE_STATUS, &isValid);
if (!isValid) {
int lenght, infologlength;
glGetProgramiv(Prog, GL_INFO_LOG_LENGTH, &infologlength);
char* InfoLog = new char[infologlength];
glGetProgramInfoLog(Prog, infologlength, &lenght, InfoLog);
ZZLog::Error_Log("Validation %d... %d:\t %s", Prog, infologlength, InfoLog);
delete[] InfoLog;
}
return (isValid != 0);
}
static void ValidatePipeline(GLuint pipeline) {
glValidateProgramPipeline(pipeline);
GLint isValid;
glGetProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, &isValid);
if (!isValid) {
int lenght, infologlength;
glGetProgramPipelineiv(pipeline, GL_INFO_LOG_LENGTH, &infologlength);
char* InfoLog = new char[infologlength];
glGetProgramPipelineInfoLog(pipeline, infologlength, &lenght, InfoLog);
ZZLog::Error_Log("Validation %d... %d:\t %s", pipeline, infologlength, InfoLog);
delete[] InfoLog;
}
}
inline bool CompileShaderFromFile(ZZshProgram& program, const std::string& DefineString, std::string main_entry, GLenum ShaderType)
{
std::string header("");
header += format("#version %d\n", GLSL_VERSION);
header += format("#define %s main\n", main_entry.c_str());
if (ShaderType == GL_VERTEX_SHADER) header += "#define VERTEX_SHADER 1\n";
else if (ShaderType == GL_FRAGMENT_SHADER) header += "#define FRAGMENT_SHADER 1\n";
header += DefineString;
const GLchar* ShaderSource[2];
#if 0
// It sucks because it doesn't report the good line for error/warnings!
// But at least this stupid AMD drivers doesn't crash...
ShaderSource[0] = header.append(ps2hw_gl4_glsl).c_str();
program = glCreateShaderProgramv(ShaderType, 1, &ShaderSource[0]);
#else
ShaderSource[0] = header.c_str();
ShaderSource[1] = ps2hw_gl4_glsl;
program = glCreateShaderProgramv(ShaderType, 2, &ShaderSource[0]);
#endif
ZZLog::Debug_Log("Creating program %d for %s", program, main_entry.c_str());
#if defined(DEVBUILD) || defined(_DEBUG)
if (!ValidateProgram(program)) return false;
#endif
return true;
}
//-------------------------------------------------------------------------------------
void ZZshSetupShader() {
VERTEXSHADER* vs = (VERTEXSHADER*)g_vsprog.link;
FRAGMENTSHADER* ps = (FRAGMENTSHADER*)g_psprog.link;
if (vs == NULL || ps == NULL) return;
// From the glValidateProgram docs: "The implementation may use this as an opportunity to perform any internal
// shader modifications that may be required to ensure correct operation of the installed
// shaders given the current GL state"
// It might be a good idea to validate the pipeline also in release mode???
#if defined(DEVBUILD) || defined(_DEBUG)
ValidatePipeline(s_pipeline);
#endif
PutParametersInProgram(vs, ps);
GL_REPORT_ERRORD();
}
void ZZshSetVertexShader(ZZshShaderLink prog) {
g_vsprog = prog;
VERTEXSHADER* vs = (VERTEXSHADER*)g_vsprog.link;
if (!vs) return;
if (vs->program != g_current_vs) {
glUseProgramStages(s_pipeline, GL_VERTEX_SHADER_BIT, vs->program);
g_current_vs = vs->program;
}
}
void ZZshSetPixelShader(ZZshShaderLink prog) {
g_psprog = prog;
FRAGMENTSHADER* ps = (FRAGMENTSHADER*)g_psprog.link;
if (!ps) return;
if (ps->program != g_current_ps) {
glUseProgramStages(s_pipeline, GL_FRAGMENT_SHADER_BIT, ps->program);
g_current_ps = ps->program;
}
}
//------------------------------------------------------------------------------------------------------------------
void init_shader() {
// TODO:
// Note it would be more clever to allocate buffer inside SHADER class
// Add a dirty flags to avoid to upload twice same data...
// You need to attach() properly the uniform buffer;
// Note: don't put GSUniformBuffer creation inside constructor of static object (context won't
// be set to call gl command)
// Warning put same order than GLSL
constant_buffer = new GSUniformBufferOGL(0, sizeof(ConstantUniform));
common_buffer = new GSUniformBufferOGL(1, sizeof(GlobalUniform));
vertex_buffer = new GSUniformBufferOGL(2, sizeof(VertexUniform));
fragment_buffer = new GSUniformBufferOGL(3, sizeof(FragmentUniform));
constant_buffer->bind();
constant_buffer->upload((void*)&g_cs.uniform_buffer_constant);
g_cs.set_texture(g_cs.sBlocks, ptexBlocks);
g_cs.set_texture(g_cs.sConv16to32, ptexConv16to32);
g_cs.set_texture(g_cs.sConv32to16, ptexConv32to16);
g_cs.set_texture(g_cs.sBilinearBlocks, ptexBilinearBlocks);
glGenProgramPipelines(1, &s_pipeline);
glBindProgramPipeline(s_pipeline);
// FIXME
// In the future it would be better to use directly the common shader
g_vparamPosXY[0] = g_cs.g_vparamPosXY;
g_vparamPosXY[1] = g_cs.g_vparamPosXY;
g_fparamFogColor = g_cs.g_fparamFogColor;
}
void PutParametersInProgram(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
if (dirty_common_buffer) {
common_buffer->bind();
common_buffer->upload((void*)&g_cs.uniform_buffer[g_cs.context]);
dirty_common_buffer = false;
}
if (dirty_vertex_buffer) {
vertex_buffer->bind();
vertex_buffer->upload((void*)&vs->uniform_buffer[vs->context]);
dirty_vertex_buffer = false;
}
if (dirty_fragment_buffer) {
fragment_buffer->bind();
fragment_buffer->upload((void*)&ps->uniform_buffer[ps->context]);
dirty_fragment_buffer = false;
}
#ifdef ENABLE_MARKER
if (GLEW_GREMEDY_string_marker) glStringMarkerGREMEDY(0, format("FS(%d): enable texture", ps->program).c_str() );
#endif
g_cs.enable_texture();
ps->enable_texture();
// By default enable the unit 0, so I have the guarantee that any
// texture command won't change current binding of others unit
glActiveTexture(GL_TEXTURE0);
}
std::string BuildGlslMacro(bool writedepth, int texwrap = 3, bool testaem = false, bool exactcolor = false)
{
std::string header("");
if (writedepth) header += "#define WRITE_DEPTH 1\n";
if (testaem) header += "#define TEST_AEM 1\n";
if (exactcolor) header += "#define EXACT_COLOR 1\n";
header += format("%s", g_pPsTexWrap[texwrap]);
//const char* AddAccurate = (ps & SHADER_ACCURATE)?"#define ACCURATE_DECOMPRESSION 1\n":"";
if (conf.settings().no_logz) {
header += "#define NO_LOGZ 1\n";
}
return header;
}
static __forceinline bool LOAD_VS(const std::string& DefineString, const char* name, VERTEXSHADER& vertex, ZZshProfile context)
{
bool flag = CompileShaderFromFile(vertex.program, DefineString, name, GL_VERTEX_SHADER);
vertex.set_context(context);
return flag;
}
static __forceinline bool LOAD_PS(const std::string& DefineString, const char* name, FRAGMENTSHADER& fragment, ZZshProfile context)
{
bool flag = CompileShaderFromFile(fragment.program, DefineString, name, GL_FRAGMENT_SHADER);
fragment.set_context(context);
return flag;
}
inline bool LoadEffects()
{
// clear the textures
for(u32 i = 0; i < ArraySize(ppsTexture); ++i)
ppsTexture[i].release_prog();
return true;
}
bool ZZshLoadExtraEffects() {
bool bLoadSuccess = true;
std::string depth_macro = BuildGlslMacro(true);
std::string empty_macro = BuildGlslMacro(false);
// DEBUG
// Put them first so it is easier to get their program index in apitrace. Namely 3,4,5
if (!LOAD_PS(empty_macro, "ZeroDebugPS", ppsDebug, 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "ZeroDebug2PS", ppsDebug2, 0)) bLoadSuccess = false;
//if (!LOAD_PS(empty_macro, "ZeroDebug3PS", ppsDebug3, 0)) bLoadSuccess = false;
const char* pvsshaders[4] = { "RegularVS", "TextureVS", "RegularFogVS", "TextureFogVS" };
for (int i = 0; i < 4; ++i) {
if (!LOAD_VS(empty_macro, pvsshaders[i], pvsStore[2 * i], 0)) bLoadSuccess = false;
if (!LOAD_VS(empty_macro, pvsshaders[i], pvsStore[2 *i + 1 ], 1)) bLoadSuccess = false;
if (!LOAD_VS(depth_macro, pvsshaders[i], pvsStore[2 *i + 8 ], 0)) bLoadSuccess = false;
if (!LOAD_VS(depth_macro, pvsshaders[i], pvsStore[2 *i + 8 + 1], 1)) bLoadSuccess = false;
}
for (int i = 0; i < 16; ++i)
pvs[i] = pvsStore[i].prog;
if (!LOAD_VS(empty_macro, "BitBltVS", pvsBitBlt, 0)) bLoadSuccess = false;
GL_REPORT_ERRORD();
if (!LOAD_PS(empty_macro, "RegularPS", ppsRegular[0], 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "RegularFogPS", ppsRegular[1], 0)) bLoadSuccess = false;
if( conf.mrtdepth ) {
if (!LOAD_PS(depth_macro, "RegularPS", ppsRegular[2], 0)) bLoadSuccess = false;
if (!bLoadSuccess) conf.mrtdepth = 0;
if (!LOAD_PS(depth_macro, "RegularFogPS", ppsRegular[3], 0)) bLoadSuccess = false;
if (!bLoadSuccess) conf.mrtdepth = 0;
}
if (!LOAD_PS(empty_macro, "BitBltPS", ppsBitBlt[0], 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "BitBltAAPS", ppsBitBlt[1], 0)) bLoadSuccess = false;
if (!bLoadSuccess) {
ZZLog::Error_Log("Failed to load BitBltAAPS, using BitBltPS.");
if (!LOAD_PS(empty_macro, "BitBltPS", ppsBitBlt[1], 0)) bLoadSuccess = false;
}
if (!LOAD_PS(empty_macro, "BitBltDepthPS", ppsBitBltDepth, 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "CRTCTargPS", ppsCRTCTarg[0], 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "CRTCTargInterPS", ppsCRTCTarg[1], 0)) bLoadSuccess = false;
g_bCRTCBilinear = true;
if (!LOAD_PS(empty_macro, "CRTCPS", ppsCRTC[0], 0)) bLoadSuccess = false;
if( !bLoadSuccess ) {
// switch to simpler
g_bCRTCBilinear = false;
if (!LOAD_PS(empty_macro, "CRTCPS_Nearest", ppsCRTC[0], 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "CRTCInterPS_Nearest", ppsCRTC[0], 0)) bLoadSuccess = false;
}
else {
if (!LOAD_PS(empty_macro, "CRTCInterPS", ppsCRTC[1], 0)) bLoadSuccess = false;
}
if( !bLoadSuccess )
ZZLog::Error_Log("Failed to create CRTC shaders.");
// if (!LOAD_PS(empty_macro, "CRTC24PS", ppsCRTC24[0], 0)) bLoadSuccess = false;
// if (!LOAD_PS(empty_macro, "CRTC24InterPS", ppsCRTC24[1], 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "ZeroPS", ppsOne, 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "BaseTexturePS", ppsBaseTexture, 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "Convert16to32PS", ppsConvert16to32, 0)) bLoadSuccess = false;
if (!LOAD_PS(empty_macro, "Convert32to16PS", ppsConvert32to16, 0)) bLoadSuccess = false;
GL_REPORT_ERRORD();
return true;
}
FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed)
{
int texwrap;
assert( texfilter < NUM_FILTERS );
if( clamp.wms == clamp.wmt ) {
switch( clamp.wms ) {
case 0: texwrap = TEXWRAP_REPEAT; break;
case 1: texwrap = TEXWRAP_CLAMP; break;
case 2: texwrap = TEXWRAP_CLAMP; break;
default:
texwrap = TEXWRAP_REGION_REPEAT; break;
}
}
else if( clamp.wms==3||clamp.wmt==3)
texwrap = TEXWRAP_REGION_REPEAT;
else
texwrap = TEXWRAP_REPEAT_CLAMP;
int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, 0, 0);
if( pbFailed != NULL ) *pbFailed = false;
FRAGMENTSHADER* pf = ppsTexture+index;
if (ZZshExistProgram(pf))
{
return pf;
}
std::string macro = BuildGlslMacro(s_bWriteDepth, texwrap, testaem, exactcolor);
std::string main_entry = format("Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]);
pf->set_context(context);
if (!CompileShaderFromFile(pf->program, macro, main_entry, GL_FRAGMENT_SHADER)) {
ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
if( pbFailed != NULL ) *pbFailed = false;
return NULL;
}
return pf;
}
#endif // GLSL4_API

View File

@ -1,667 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
// Texture and avi saving to file functions
//------------------ Includes
#include "Util.h"
#if defined(_WIN32)
# include "Utilities/RedtapeWindows.h"
# include <aviUtil.h>
# include "resource.h"
#endif
#include <stdlib.h>
#include "targets.h"
#include "Mem.h"
#include "ZZoglShoots.h"
// AVI Capture
int s_avicapturing = 0;
bool g_bMakeSnapshot = false;
extern "C"
{
#ifdef _WIN32
# define XMD_H
# undef FAR
#define HAVE_BOOLEAN
#endif
#include "jpeglib.h"
}
//------------------ Defines
#define TGA_FILE_NAME_MAX_LENGTH 20
#define MAX_NUMBER_SAVED_TGA 200
//Windows have no snprintf
#if defined(_WIN32)
# define snprintf sprintf_s
#endif
//------------------ Constants
//------------------ Global Variables
int TexNumber = 0;
int s_aviinit = 0;
string strSnapshot;
//------------------ Code
// Set variables need to made a snapshoot when it's possible
void SaveSnapshot(const char* filename)
{
g_bMakeSnapshot = true;
strSnapshot = filename;
}
// Save curent renderer in jpeg or TGA format
bool SaveRenderTarget(const char* filename, int width, int height, int jpeg)
{
bool bflip = height < 0;
height = abs(height);
vector<u32> data(width*height);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
if (glGetError() != GL_NO_ERROR) return false;
if (bflip)
{
// swap scanlines
vector<u32> scanline(width);
for (int i = 0; i < height / 2; ++i)
{
memcpy(&scanline[0], &data[i * width], width * 4);
memcpy(&data[i * width], &data[(height - i - 1) * width], width * 4);
memcpy(&data[(height - i - 1) * width], &scanline[0], width * 4);
}
}
if (jpeg) return SaveJPEG(filename, width, height, &data[0], 70);
return SaveTGA(filename, width, height, &data[0]);
}
// Save selected texture as TGA
bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height, int ext_format)
{
vector<u32> data(width*height);
glBindTexture(textarget, tex);
glGetTexImage(textarget, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
if (glGetError() != GL_NO_ERROR) return false;
if (ext_format == EXT_BMP)
return SaveBMP(filename, width, height, &data[0]);
else if (ext_format == EXT_TGA)
return SaveTGA(filename, width, height, &data[0]);
else
return false;
}
// Save image as BMP
bool SaveBMP(const char* filename, int width, int height, void* pdata)
{
// FIXME
assert(0);
return false;
}
// save image as JPEG
bool SaveJPEG(const char* filename, int image_width, int image_height, const void* pdata, int quality)
{
u8* image_buffer = new u8[image_width * image_height * 3];
u8* psrc = (u8*)pdata;
// input data is rgba format, so convert to rgb
u8* p = image_buffer;
for (int i = 0; i < image_height; ++i)
{
for (int j = 0; j < image_width; ++j)
{
p[0] = psrc[0];
p[1] = psrc[1];
p[2] = psrc[2];
p += 3;
psrc += 4;
}
}
/* This struct contains the JPEG compression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
* It is possible to have several such structures, representing multiple
* compression/decompression processes, in existence at once. We refer
* to any one struct (and its associated working data) as a "JPEG object".
*/
struct jpeg_compress_struct cinfo;
/* This struct represents a JPEG error handler. It is declared separately
* because applications often want to supply a specialized error handler
* (see the second half of this file for an example). But here we just
* take the easy way out and use the standard error handler, which will
* print a message on stderr and call exit() if compression fails.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct jpeg_error_mgr jerr;
/* More stuff */
FILE * outfile; /* target file */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
/* Step 1: allocate and initialize JPEG compression object */
/* We have to set up the error handler first, in case the initialization
* step fails. (Unlikely, but it could happen if you are out of memory.)
* This routine fills in the contents of struct jerr, and returns jerr's
* address which we place into the link field in cinfo.
*/
cinfo.err = jpeg_std_error(&jerr);
/* Now we can initialize the JPEG compression object. */
jpeg_create_compress(&cinfo);
/* Step 2: specify data destination (eg, a file) */
/* Note: steps 2 and 3 can be done in either order. */
/* Here we use the library-supplied code to send compressed data to a
* stdio stream. You can also write your own code to do something else.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to write binary files.
*/
if ((outfile = fopen(filename, "wb")) == NULL)
{
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
/* Step 3: set parameters for compression */
/* First we supply a description of the input image.
* Four fields of the cinfo struct must be filled in:
*/
cinfo.image_width = image_width; /* image width and height, in pixels */
cinfo.image_height = image_height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
/* Now use the library's routine to set default compression parameters.
* (You must set at least cinfo.in_color_space before calling this,
* since the defaults depend on the source color space.)
*/
jpeg_set_defaults(&cinfo);
/* Now you can set any non-default parameters you wish to.
* Here we just illustrate the use of quality (quantization table) scaling:
*/
jpeg_set_quality(&cinfo, quality, true /* limit to baseline-JPEG values */);
/* Step 4: Start compressor */
/* true ensures that we will write a complete interchange-JPEG file.
* Pass true unless you are very sure of what you're doing.
*/
jpeg_start_compress(&cinfo, true);
/* Step 5: while (scan lines remain to be written) */
/* jpeg_write_scanlines(...); */
/* Here we use the library's state variable cinfo.next_scanline as the
* loop counter, so that we don't have to keep track ourselves.
* To keep things simple, we pass one scanline per call; you can pass
* more if you wish, though.
*/
row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height)
{
/* jpeg_write_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could pass
* more than one scanline at a time if that's more convenient.
*/
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
/* After finish_compress, we can close the output file. */
fclose(outfile);
/* Step 7: release JPEG compression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_compress(&cinfo);
delete []image_buffer;
/* And we're done! */
return true;
}
#if defined(_MSC_VER)
# pragma pack(push, 1)
#endif
// This is the defenition of TGA header. We need it to function bellow
struct TGA_HEADER
{
u8 identsize; // size of ID field that follows 18 u8 header (0 usually)
u8 colourmaptype; // type of colour map 0=none, 1=has palette
u8 imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
s16 colourmapstart; // first colour map entry in palette
s16 colourmaplength; // number of colours in palette
u8 colourmapbits; // number of bits per palette entry 15,16,24,32
s16 xstart; // image x origin
s16 ystart; // image y origin
s16 width; // image width in pixels
s16 height; // image height in pixels
u8 bits; // image bits per pixel 8,16,24,32
u8 descriptor; // image descriptor bits (vh flip bits)
// pixel data follows header
#if defined(_MSC_VER)
};
# pragma pack(pop)
# else
}
__attribute__((packed));
#endif
// Save image as TGA
bool SaveTGA(const char* filename, int width, int height, void* pdata)
{
TGA_HEADER hdr;
FILE* f = fopen(filename, "wb");
if (f == NULL) return false;
assert(sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18);
memset(&hdr, 0, sizeof(hdr));
hdr.imagetype = 2;
hdr.bits = 32;
hdr.width = width;
hdr.height = height;
hdr.descriptor |= 8 | (1 << 5); // 8bit alpha, flip vertical
fwrite(&hdr, sizeof(hdr), 1, f);
fwrite(pdata, width * height * 4, 1, f);
fclose(f);
return true;
}
// AVI capture stuff
// AVI start -- set needed global variables
void StartCapture()
{
if (conf.captureAvi()) return;
if (!s_aviinit)
{
#ifdef _WIN32
START_AVI("zerogs.avi");
#else // linux
//TODO
#endif
s_aviinit = 1;
}
else
{
ZZLog::Error_Log("Continuing from previous capture.");
}
s_avicapturing = 1;
conf.setCaptureAvi(true);
ZZLog::Warn_Log("Started recording zerogs.avi.");
}
// Stop.
void StopCapture()
{
if (!conf.captureAvi()) return;
s_avicapturing = 0;
conf.setCaptureAvi(false);
ZZLog::Warn_Log("Stopped recording.");
}
// And capture frame does not work on linux.
void CaptureFrame()
{
if ((!s_avicapturing) || (!s_aviinit)) return;
vector<u32> data(GLWin.backbuffer.w * GLWin.backbuffer.h);
glReadPixels(0, 0, GLWin.backbuffer.w, GLWin.backbuffer.h, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
if (glGetError() != GL_NO_ERROR) return;
#ifdef _WIN32
int fps = SMODE1->CMOD == 3 ? 50 : 60;
bool bSuccess = ADD_FRAME_FROM_DIB_TO_AVI("AAAA", fps, GLWin.backbuffer.w, GLWin.backbuffer.h, 32, &data[0]);
if (!bSuccess)
{
s_avicapturing = 0;
STOP_AVI();
ZZAddMessage("Failed to create avi");
return;
}
#else // linux
//TODO
#endif // _WIN32
}
// It's nearly the same as save texture
void
SaveTex(tex0Info* ptex, int usevid)
{
vector<u32> data(ptex->tw*ptex->th);
vector<u8> srcdata;
u32* dst = &data[0];
u8* psrc = g_pbyGSMemory;
CMemoryTarget* pmemtarg = NULL;
if (usevid)
{
pmemtarg = g_MemTargs.GetMemoryTarget(*ptex, 0);
assert(pmemtarg != NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, pmemtarg->ptex->tex);
srcdata.resize(4 * pmemtarg->texW * pmemtarg->texH);
// FIXME strangely this function call seem to crash pcsx2 on atelier of iris 1
// Note: fmt is GL_UNSIGNED_SHORT_1_5_5_5_REV
glGetTexImage(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, pmemtarg->fmt, &srcdata[0]);
u32 offset = MemorySize(pmemtarg->realy);
if (ptex->psm == PSMT8)
offset *= CLUT_PIXEL_SIZE(ptex->cpsm);
else if (ptex->psm == PSMT4)
offset *= CLUT_PIXEL_SIZE(ptex->cpsm) * 2;
psrc = &srcdata[0] - offset;
}
for (int i = 0; i < ptex->th; ++i)
{
for (int j = 0; j < ptex->tw; ++j)
{
u32 u = 0;
u32 addr;
switch (ptex->psm)
{
case PSMCT32:
addr = getPixelAddress32(j, i, ptex->tbp0, ptex->tbw);
if (addr * 4 < MEMORY_END)
u = readPixel32(psrc, j, i, ptex->tbp0, ptex->tbw);
else
u = 0;
break;
case PSMCT24:
addr = getPixelAddress24(j, i, ptex->tbp0, ptex->tbw);
if (addr * 4 < MEMORY_END)
u = readPixel24(psrc, j, i, ptex->tbp0, ptex->tbw);
else
u = 0;
break;
case PSMCT16:
addr = getPixelAddress16(j, i, ptex->tbp0, ptex->tbw);
if (addr * 2 < MEMORY_END)
{
u = readPixel16(psrc, j, i, ptex->tbp0, ptex->tbw);
u = RGBA16to32(u);
}
else
{
u = 0;
}
break;
case PSMCT16S:
addr = getPixelAddress16(j, i, ptex->tbp0, ptex->tbw);
if (addr * 2 < MEMORY_END)
{
u = readPixel16S(psrc, j, i, ptex->tbp0, ptex->tbw);
u = RGBA16to32(u);
}
else
{
u = 0;
}
break;
case PSMT8:
addr = getPixelAddress8(j, i, ptex->tbp0, ptex->tbw);
if (addr < MEMORY_END)
{
if (usevid)
{
if (PSMT_IS32BIT(ptex->cpsm))
u = *(u32*)(psrc + 4 * addr);
else
u = RGBA16to32(*(u16*)(psrc + 2 * addr));
}
else
{
u = readPixel8(psrc, j, i, ptex->tbp0, ptex->tbw);
}
}
else
{
u = 0;
}
break;
case PSMT4:
addr = getPixelAddress4(j, i, ptex->tbp0, ptex->tbw);
if (addr < 2*MEMORY_END)
{
if (usevid)
{
if (PSMT_IS32BIT(ptex->cpsm))
u = *(u32*)(psrc + 4 * addr);
else
u = RGBA16to32(*(u16*)(psrc + 2 * addr));
}
else
{
u = readPixel4(psrc, j, i, ptex->tbp0, ptex->tbw);
}
}
else
{
u = 0;
}
break;
case PSMT8H:
addr = getPixelAddress8H(j, i, ptex->tbp0, ptex->tbw);
if (4*addr < MEMORY_END)
{
if (usevid)
{
if (PSMT_IS32BIT(ptex->cpsm))
u = *(u32*)(psrc + 4 * addr);
else
u = RGBA16to32(*(u16*)(psrc + 2 * addr));
}
else
{
u = readPixel8H(psrc, j, i, ptex->tbp0, ptex->tbw);
}
}
else
{
u = 0;
}
break;
case PSMT4HL:
addr = getPixelAddress4HL(j, i, ptex->tbp0, ptex->tbw);
if (4*addr < MEMORY_END)
{
if (usevid)
{
if (PSMT_IS32BIT(ptex->cpsm))
u = *(u32*)(psrc + 4 * addr);
else
u = RGBA16to32(*(u16*)(psrc + 2 * addr));
}
else
{
u = readPixel4HL(psrc, j, i, ptex->tbp0, ptex->tbw);
}
}
else
{
u = 0;
}
break;
case PSMT4HH:
addr = getPixelAddress4HH(j, i, ptex->tbp0, ptex->tbw);
if (4*addr < MEMORY_END)
{
if (usevid)
{
if (PSMT_IS32BIT(ptex->cpsm))
u = *(u32*)(psrc + 4 * addr);
else
u = RGBA16to32(*(u16*)(psrc + 2 * addr));
}
else
{
u = readPixel4HH(psrc, j, i, ptex->tbp0, ptex->tbw);
}
}
else
{
u = 0;
}
break;
case PSMT32Z:
addr = getPixelAddress32Z(j, i, ptex->tbp0, ptex->tbw);
if (4*addr < MEMORY_END)
u = readPixel32Z(psrc, j, i, ptex->tbp0, ptex->tbw);
else
u = 0;
break;
case PSMT24Z:
addr = getPixelAddress24Z(j, i, ptex->tbp0, ptex->tbw);
if (4*addr < MEMORY_END)
u = readPixel24Z(psrc, j, i, ptex->tbp0, ptex->tbw);
else
u = 0;
break;
case PSMT16Z:
addr = getPixelAddress16Z(j, i, ptex->tbp0, ptex->tbw);
if (2*addr < MEMORY_END)
u = readPixel16Z(psrc, j, i, ptex->tbp0, ptex->tbw);
else
u = 0;
break;
case PSMT16SZ:
addr = getPixelAddress16SZ(j, i, ptex->tbp0, ptex->tbw);
if (2*addr < MEMORY_END)
u = readPixel16SZ(psrc, j, i, ptex->tbp0, ptex->tbw);
else
u = 0;
break;
default:
assert(0);
}
*dst++ = u;
}
}
char Name[TGA_FILE_NAME_MAX_LENGTH];
snprintf(Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber);
SaveTGA(Name, ptex->tw, ptex->th, &data[0]);
TexNumber++;
if (TexNumber > MAX_NUMBER_SAVED_TGA) TexNumber = 0;
}
// Do the save texture and return file name of it
// Do not forget to call free(), other wise there would be memory leak!
char* NamedSaveTex(tex0Info* ptex, int usevid)
{
SaveTex(ptex, usevid);
char* Name = (char*)malloc(TGA_FILE_NAME_MAX_LENGTH);
snprintf(Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber);
return Name;
}
// Special function, which is safe to call from any other file, without aviutils problems.
void Stop_Avi()
{
#ifdef _WIN32
STOP_AVI();
#else
// Does not support yet
#endif
}
void Delete_Avi_Capture()
{
if (s_aviinit)
{
StopCapture();
Stop_Avi();
ZZLog::Error_Log("zerogs.avi stopped.");
s_aviinit = 0;
}
}

View File

@ -1,42 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef ZZOGLSHOOTS_H_INCLUDED
#define ZZOGLSHOOTS_H_INCLUDED
void SaveSnapshot(const char* filename);
bool SaveRenderTarget(const char* filename, int width, int height, int jpeg);
bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height, int ext_format = 0);
bool SaveJPEG(const char* filename, int width, int height, const void* pdata, int quality);
bool SaveTGA(const char* filename, int width, int height, void* pdata);
bool SaveBMP(const char* filename, int width, int height, void* pdata);
void Stop_Avi();
void Delete_Avi_Capture();
void StartCapture();
void StopCapture();
void CaptureFrame();
enum {
EXT_TGA = 0,
EXT_BMP = 1,
EXT_JPG = 2
};
#endif // ZZOGLSHOOTS_H_INCLUDED

View File

@ -1,506 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
// Zerogs:VB implementation.
// VB stands for Visual Buffer, as I think
//------------------- Includes
#include "Util.h"
#include "targets.h"
#include "ZZoglVB.h"
#include "GS.h"
#include "Mem.h"
extern float fiTexWidth[2], fiTexHeight[2]; // current tex width and height
// ----------------- Defines
#define MINMAX_SHIFT 3
//------------------ Constants
// ----------------- Global Variables
int maxmin = 608;
// ----------------- Code
// Constructor. Set width and height to 1
VB::VB()
{
memset(this, 0, sizeof(VB));
tex0.tw = 1;
tex0.th = 1;
}
// Destructor
VB::~VB()
{
Destroy();
}
void VB::Destroy()
{
_aligned_free(pBufferData);
pBufferData = NULL;
nNumVertices = 0;
prndr = NULL;
pdepth = NULL;
}
int ConstraintReason;
// Return number of 64-pixels block, that guaranted could be hold in memory
// from gsfb.fbp and tbp (textrure pase), zbuf.zbp (Z-buffer), frame.fbp
// (previous frame).
inline int VB::FindMinimalMemoryConstrain(int tbp, int maxpos)
{
int MinConstraint = maxpos;
// make sure texture is far away from tbp
{
int Constraint = tbp - gsfb.fbp;
if ((0 < Constraint) && (Constraint < MinConstraint))
{
MinConstraint = Constraint;
ConstraintReason = 1;
}
}
// offroad uses 0x80 fbp which messes up targets
// special case when double buffering (hamsterball)
// Suikoden 3 require e00 have this issue too. P3 - 0x1000.
if (prndr != NULL)
{
int Constraint = frame.fbp - gsfb.fbp;
if ((0x0 < Constraint) && (Constraint < MinConstraint))
{
MinConstraint = Constraint;
ConstraintReason = 2;
}
}
// old caching method
// zmsk necessary for KH movie
if (!zbuf.zmsk)
{
int Constraint = zbuf.zbp - gsfb.fbp;
if ((0 < Constraint) && (Constraint < MinConstraint))
{
MinConstraint = Constraint;
ConstraintReason = 3;
}
}
// In 16Bit mode in one Word frame stored 2 pixels
if (PSMT_ISHALF(gsfb.psm)) MinConstraint *= 2;
return MinConstraint ;
}
// Return number of 64 pizel words that could be placed in Z-Buffer
// If no Z-buffer present return old constraint
inline int VB::FindZbufferMemoryConstrain(int tbp, int maxpos)
{
int MinConstraint = maxpos;
// Check tbp / zbuffer constraint
if (!zbuf.zmsk)
{
int Constraint = (tbp - zbuf.zbp) * (PSMT_ISHALF(zbuf.psm) ? 2 : 1);
if ((0 < Constraint) && (Constraint < MinConstraint))
{
MinConstraint = Constraint;
ConstraintReason = 4;
}
}
return MinConstraint;
}
// Return heights limiter from scissor...
inline int GetScissorY(int y)
{
int fbh = (y >> MINMAX_SHIFT) + 1;
if (fbh > 2 && (fbh & 1)) fbh -= 1;
return fbh;
}
//There is several reasons to limit a height of frame: maximum buffer size, calculated size
//from fbw and fbh and scissoring.
inline int VB::FindMinimalHeightConstrain(int maxpos)
{
int MinConstraint = maxpos;
if (maxmin < MinConstraint)
{
MinConstraint = maxmin;
ConstraintReason = 5;
}
if (gsfb.fbh < MinConstraint)
{
MinConstraint = gsfb.fbh;
ConstraintReason = 6;
}
int ScissorConstraint = GetScissorY(scissor.y1) ;
if (ScissorConstraint < MinConstraint)
{
MinConstraint = ScissorConstraint;
ConstraintReason = 7;
}
return MinConstraint;
}
// 32 bit frames have additional constraints to frame
// maxpos was maximum length of frame at normal constraints
inline void VB::CheckFrame32bitRes(int maxpos)
{
int fbh = frame.fbh;
if (frame.fbh >= 512)
{
// neopets hack
maxmin = min(maxmin, frame.fbh);
frame.fbh = maxmin;
ConstraintReason = 8;
}
// ffxii hack to stop resolving
if (frame.fbp >= 0x3000 && fbh >= 0x1a0)
{
int endfbp = frame.fbp + frame.fbw * fbh / (PSMT_ISHALF(gsfb.psm) ? 128 : 64);
// see if there is a previous render target in the way, reduce
for (CRenderTargetMngr::MAPTARGETS::iterator itnew = s_RTs.mapTargets.begin(); itnew != s_RTs.mapTargets.end(); ++itnew)
{
if (itnew->second->fbp > frame.fbp && endfbp > itnew->second->fbp)
{
endfbp = itnew->second->fbp;
}
}
frame.fbh = (endfbp - frame.fbp) * (PSMT_ISHALF(gsfb.psm) ? 128 : 64) / frame.fbw;
if (frame.fbh < fbh) ConstraintReason = 9;
}
}
// This is the main code for frame resizing.
// It checks for several reasons to resize and resizes if it needs to.
// 4Mb memory in 64 bit (4 bytes) words.
// |------------------------|---------------------|----------|----------|---------------------|
// 0 gsfb.fbp zbuff.zpb tbp frame.fbp 2^20/64
inline int VB::CheckFrameAddConstraints(int tbp)
{
if (gsfb.fbw <= 0)
{
ERROR_LOG_SPAM("render target null, no constraints. Ignoring\n");
return -1;
}
// Memory region after fbp
int maxmemorypos = 0x4000 - gsfb.fbp;
ConstraintReason = 0;
maxmemorypos = FindMinimalMemoryConstrain(tbp, maxmemorypos);
maxmemorypos = FindZbufferMemoryConstrain(tbp, maxmemorypos);
int maxpos = 64 * maxmemorypos ;
maxpos /= gsfb.fbw;
//? atelier iris crashes without it
if (maxpos > 256) maxpos &= ~0x1f;
#ifdef DEVBUILD
int noscissorpos = maxpos;
int ConstrainR1 = ConstraintReason;
#endif
maxpos = FindMinimalHeightConstrain(maxpos);
frame = gsfb;
frame.fbh = maxpos;
if (!PSMT_ISHALF(frame.psm) || !(conf.settings().full_16_bit_res)) CheckFrame32bitRes(maxpos);
#ifdef DEVBUILD
if (frame.fbh == 0xe2)
ZZLog::Debug_Log("Const: %x %x %d| %x %d %x %x", frame.fbh, frame.fbw, ConstraintReason, noscissorpos, ConstrainR1, tbp, frame.fbp);
#endif
// Fixme: Reserved psm for framebuffers
// gsfb.psm &= 0xf; // shadow tower
return 0;
}
// Check if after resizing new depth target is needed to be used.
// it returns 2 if a new depth target is used.
inline int VB::CheckFrameResolveDepth(int tbp)
{
int result = 0;
CDepthTarget* pprevdepth = pdepth;
pdepth = NULL;
// just z changed
frameInfo f = CreateFrame(zbuf.zbp, prndr->fbw, prndr->fbh, zbuf.psm, (zbuf.psm == 0x31) ? 0xff000000 : 0);
CDepthTarget* pnewdepth = (CDepthTarget*)s_DepthRTs.GetTarg(f, CRenderTargetMngr::TO_DepthBuffer | CRenderTargetMngr::TO_StrictHeight |
(zbuf.zmsk ? CRenderTargetMngr::TO_Virtual : 0), get_maxheight(zbuf.zbp, gsfb.fbw, 0));
assert(pnewdepth != NULL && prndr != NULL);
if (pnewdepth->fbh != prndr->fbh) ZZLog::Debug_Log("pnewdepth->fbh(0x%x) != prndr->fbh(0x%x)", pnewdepth->fbh, prndr->fbh);
//assert(pnewdepth->fbh == prndr->fbh);
if ((pprevdepth != pnewdepth) || (pprevdepth != NULL && (pprevdepth->status & CRenderTarget::TS_NeedUpdate)))
result = 2;
pdepth = pnewdepth;
return result;
}
// Check if after resizing, a new render target is needed to be used. Also perform deptarget check.
// Returns 1 if only 1 render target is changed and 3 -- if both.
inline int VB::CheckFrameResolveRender(int tbp)
{
int result = 0;
CRenderTarget* pprevrndr = prndr;
prndr = NULL;
CDepthTarget* pprevdepth = pdepth;
pdepth = NULL;
// Set renderes to NULL to prevent Flushing.
CRenderTarget* pnewtarg = s_RTs.GetTarg(frame, 0, maxmin);
assert(pnewtarg != NULL);
// pnewtarg->fbh >= 0x1c0 needed for ffx
if ((pnewtarg->fbh >= 0x1c0) && pnewtarg->fbh > frame.fbh && zbuf.zbp < tbp && !zbuf.zmsk)
{
// check if zbuf is in the way of the texture (suikoden5)
int maxallowedfbh = (tbp - zbuf.zbp) * (PSMT_ISHALF(zbuf.psm) ? 128 : 64) / gsfb.fbw;
if (PSMT_ISHALF(gsfb.psm)) maxallowedfbh *= 2;
if (pnewtarg->fbh > maxallowedfbh + 32) // +32 needed for ffx2
{
// destroy and recreate
s_RTs.DestroyAllTargs(0, 0x100, pnewtarg->fbw);
pnewtarg = s_RTs.GetTarg(frame, 0, maxmin);
assert(pnewtarg != NULL);
}
}
ZZLog::Prim_Log("frame_%d: fbp=0x%x fbw=%d fbh=%d(%d) psm=0x%x fbm=0x%x\n", ictx, gsfb.fbp, gsfb.fbw, gsfb.fbh, pnewtarg->fbh, gsfb.psm, gsfb.fbm);
if ((pprevrndr != pnewtarg) || (pprevrndr != NULL && (pprevrndr->status & CRenderTarget::TS_NeedUpdate)))
result = 1;
prndr = pnewtarg;
pdepth = pprevdepth;
result |= CheckFrameResolveDepth(tbp);
return result;
}
// After frame resetting, it is possible that 16 to 32 or 32 to 16 (color bits) conversion should be made.
inline void VB::CheckFrame16vs32Conversion()
{
if (prndr->status & CRenderTarget::TS_NeedConvert32)
{
if (pdepth->pdepth != 0) pdepth->SetDepthStencilSurface();
prndr->fbh *= 2;
prndr->ConvertTo32();
prndr->status &= ~CRenderTarget::TS_NeedConvert32;
}
else if (prndr->status & CRenderTarget::TS_NeedConvert16)
{
if (pdepth->pdepth != 0) pdepth->SetDepthStencilSurface();
prndr->fbh /= 2;
prndr->ConvertTo16();
prndr->status &= ~CRenderTarget::TS_NeedConvert16;
}
}
void SetContextTarget(int context);
// A lot of times, the target is too big and overwrites the texture.
// If tbp != 0, use it to bound.
void VB::CheckFrame(int tbp)
{
GL_REPORT_ERRORD();
static int bChanged;
if (bNeedZCheck)
{
ZZLog::Prim_Log("zbuf_%d: zbp=0x%x psm=0x%x, zmsk=%d\n", ictx, zbuf.zbp, zbuf.psm, zbuf.zmsk);
//zbuf = *zb;
}
if (m_Blocks[gsfb.psm].bpp == 0)
{
ZZLog::Error_Log("CheckFrame invalid bpp %d.", gsfb.psm);
return;
}
bChanged = 0;
if (bNeedFrameCheck)
{
// important to set before calling GetTarg
bNeedFrameCheck = 0;
bNeedZCheck = 0;
if (CheckFrameAddConstraints(tbp) == -1) return;
if ((prndr != NULL) && (prndr->psm != gsfb.psm))
{
// behavior for dest alpha varies
// ResetAlphaVariables();
}
bChanged = CheckFrameResolveRender(tbp);
CheckFrame16vs32Conversion();
}
else if (bNeedZCheck)
{
bNeedZCheck = 0;
if (prndr != NULL && gsfb.fbw > 0) CheckFrameResolveDepth(tbp);
}
if (prndr != NULL) SetContextTarget(ictx);
GL_REPORT_ERRORD();
}
// This is the case, most easy to perform, when nothing was changed
inline void VB::FlushTexUnchangedClutDontUpdate()
{
if (ZZOglGet_cld_TexBits(uNextTex0Data[1]))
{
texClutWrite(ictx);
// invalidate to make sure target didn't change!
bVarsTexSync = false;
}
}
// The second of easy branch. We does not change storage model, so we don't need to
// update anything except texture itself
inline void VB::FlushTexClutDontUpdate()
{
if (!ZZOglClutStorageUnchanged(uCurTex0Data, uNextTex0Data)) Flush(ictx);
// clut memory isn't going to be loaded so can ignore, but at least update CSA and CPSM!
uCurTex0Data[1] = (uCurTex0Data[1] & CPSM_CSA_NOTMASK) | (uNextTex0Data[1] & CPSM_CSA_BITMASK);
tex0.csa = ZZOglGet_csa_TexBits(uNextTex0Data[1]);
tex0.cpsm = ZZOglGet_cpsm_TexBits(uNextTex0Data[1]);
texClutWrite(ictx);
bVarsTexSync = false;
}
// Set texture variables after big change
inline void VB::FlushTexSetNewVars(u32 psm)
{
tex0.tbp0 = ZZOglGet_tbp0_TexBits(uNextTex0Data[0]);
tex0.tbw = ZZOglGet_tbw_TexBitsMult(uNextTex0Data[0]);
tex0.psm = psm;
tex0.tw = ZZOglGet_tw_TexBitsExp(uNextTex0Data[0]);
tex0.th = ZZOglGet_th_TexBitsExp(uNextTex0Data[0], uNextTex0Data[1]);
tex0.tcc = ZZOglGet_tcc_TexBits(uNextTex0Data[1]);
tex0.tfx = ZZOglGet_tfx_TexBits(uNextTex0Data[1]);
fiTexWidth[ictx] = (1 / 16.0f) / tex0.tw;
fiTexHeight[ictx] = (1 / 16.0f) / tex0.th;
}
// Flush == draw on screen
// This function made VB state consistant before real Flush.
void VB::FlushTexData()
{
GL_REPORT_ERRORD();
//assert(bNeedTexCheck);
if (bNeedTexCheck)
{
bNeedTexCheck = 0;
u32 psm = ZZOglGet_psm_TexBitsFix(uNextTex0Data[0]);
// don't update unless necessary
if (ZZOglAllExceptClutIsSame(uCurTex0Data, uNextTex0Data))
{
// Don't need to do anything if there is no clutting and VB tex data was not changed
if (!PSMT_ISCLUT(psm)) return;
// have to write the CLUT again if only CLD was changed
if (ZZOglClutMinusCLDunchanged(uCurTex0Data, uNextTex0Data))
{
FlushTexUnchangedClutDontUpdate();
return;
}
// Cld bit is 0 means that clut buffer stay unchanged
if (ZZOglGet_cld_TexBits(uNextTex0Data[1]) == 0)
{
FlushTexClutDontUpdate();
return;
}
}
// Made the full update
Flush(ictx);
bVarsTexSync = false;
bTexConstsSync = false;
uCurTex0Data[0] = uNextTex0Data[0];
uCurTex0Data[1] = uNextTex0Data[1];
FlushTexSetNewVars(psm);
if (PSMT_ISCLUT(psm)) CluttingForFlushedTex(&tex0, uNextTex0Data[1], ictx) ;
GL_REPORT_ERRORD();
}
}

View File

@ -1,158 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
// Zerogs:VB implementation.
// VB stands for Visual Buffer, as I think
#ifndef ZZOGLVB_H_INCLUDED
#define ZZOGLVB_H_INCLUDED
#include "targets.h"
extern const GLenum primtype[8];
class VB
{
public:
VB();
~VB();
void Destroy();
inline bool CheckPrim()
{
static const int PRIMMASK = 0x0e; // for now ignore 0x10 (AA)
if ((PRIMMASK & prim->_val) != (PRIMMASK & curprim._val) || primtype[prim->prim] != primtype[curprim.prim])
return nCount > 0;
return false;
}
void SetCurrentPrim()
{
curprim._val = prim->_val;
curprim.prim = prim->prim;
}
void CheckFrame(int tbp);
// context specific state
Point offset;
Rect2 scissor;
tex0Info tex0;
tex1Info tex1;
miptbpInfo miptbp0;
miptbpInfo miptbp1;
alphaInfo alpha;
fbaInfo fba;
clampInfo clamp;
pixTest test;
u32 ptexClamp[2]; // textures for x and y dir region clamping
void FlushTexData();
inline int CheckFrameAddConstraints(int tbp);
inline void CheckScissors(int maxpos);
inline void CheckFrame32bitRes(int maxpos);
inline int FindMinimalMemoryConstrain(int tbp, int maxpos);
inline int FindZbufferMemoryConstrain(int tbp, int maxpos);
inline int FindMinimalHeightConstrain(int maxpos);
inline int CheckFrameResolveRender(int tbp);
inline void CheckFrame16vs32Conversion();
inline int CheckFrameResolveDepth(int tbp);
inline void FlushTexUnchangedClutDontUpdate() ;
inline void FlushTexClutDontUpdate() ;
inline void FlushTexClutting() ;
inline void FlushTexSetNewVars(u32 psm) ;
// Increase the size of pbuf
void IncreaseVertexBuffer()
{
assert(pBufferData != NULL);
nNumVertices *= 2;
VertexGPU* ptemp = (VertexGPU*)_aligned_malloc(sizeof(VertexGPU) * nNumVertices, 256);
memcpy(ptemp, pBufferData, sizeof(VertexGPU) * nCount);
assert(nCount <= nNumVertices);
_aligned_free(pBufferData);
pBufferData = ptemp;
}
void Init(int nVerts)
{
if (pBufferData == NULL && nVerts > 0)
{
pBufferData = (VertexGPU*)_aligned_malloc(sizeof(VertexGPU) * nVerts, 256);
nNumVertices = nVerts;
}
nCount = 0;
}
u8 bNeedFrameCheck;
u8 bNeedZCheck;
u8 bNeedTexCheck;
u8 dummy0;
union
{
struct
{
u8 bTexConstsSync; // only pixel shader constants that context owns
u8 bVarsTexSync; // texture info
u8 bVarsSetTarg;
u8 dummy1;
};
u32 bSyncVars;
};
int ictx;
VertexGPU* pBufferData; // current allocated data
int nNumVertices; // size of pBufferData in terms of VertexGPU objects
int nCount;
primInfo curprim; // the previous prim the current buffers are set to
zbufInfo zbuf;
frameInfo gsfb; // the real info set by FRAME cmd
frameInfo frame;
int zprimmask; // zmask for incoming points
union
{
u32 uCurTex0Data[2]; // current tex0 data
GIFRegTEX0 uCurTex0;
};
u32 uNextTex0Data[2]; // tex0 data that has to be applied if bNeedTexCheck is 1
//int nFrameHeights[8]; // frame heights for the past frame changes
int nNextFrameHeight;
CMemoryTarget* pmemtarg; // the current mem target set
CRenderTarget* prndr;
CDepthTarget* pdepth;
};
// VB variables
extern VB vb[2];
#endif // ZZOGLVB_H_INCLUDED

View File

@ -1,57 +0,0 @@
# Check that people use the good file
if(NOT TOP_CMAKE_WAS_SOURCED)
message(FATAL_ERROR "
You did not 'cmake' the good CMakeLists.txt file. Use the one in the top dir.
It is advice to delete all wrongly generated cmake stuff => CMakeFiles & CMakeCache.txt")
endif()
# plugin name
set(Output zzogl-shader)
set(CommonFlags
-DZEROGS_SSE2
-fno-strict-aliasing
-Wstrict-aliasing # Allow to track strict aliasing issue.
-Wunused-variable
-DNVIDIA_CG_API
)
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(zerogsshadersFinalFlags
${CommonFlags} -D_DEBUG
)
elseif(CMAKE_BUILD_TYPE STREQUAL Devel)
set(zerogsshadersFinalFlags
${CommonFlags} -g -W -DZEROGS_DEVBUILD
)
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
set(zerogsshadersFinalFlags
${CommonFlags} -W
)
endif(CMAKE_BUILD_TYPE STREQUAL Release)
set(zerogsshadersFinalSources
zerogsshaders.cpp
zpipe.cpp
)
set(zerogsshadersFinalLibs
${ZLIB_LIBRARIES}
${CG_LIBRARIES}
${OPENGL_LIBRARIES}
)
add_pcsx2_executable(${Output} "${zerogsshadersFinalSources}" "${zerogsshadersFinalLibs}" "${zerogsshadersFinalFlags}")
# Now build the shader
add_custom_command(TARGET ${Output} POST_BUILD
COMMAND ${Output} ps2hw.fx ${CMAKE_CURRENT_BINARY_DIR}/ps2hw_cmake.dat
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/zzogl-pg/opengl
)
if(PACKAGE_MODE)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ps2hw_cmake.dat DESTINATION ${PLUGIN_DIR} RENAME ps2hw.dat)
else(PACKAGE_MODE)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ps2hw_cmake.dat DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins RENAME ps2hw.dat)
endif(PACKAGE_MODE)

View File

@ -1,23 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroGSShaders", "ZeroGSShaders_2005.vcproj", "{811D47CC-E5F0-456A-918E-5908005E8FC0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release (to Public)|Win32 = Release (to Public)|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{811D47CC-E5F0-456A-918E-5908005E8FC0}.Debug|Win32.ActiveCfg = Debug|Win32
{811D47CC-E5F0-456A-918E-5908005E8FC0}.Debug|Win32.Build.0 = Debug|Win32
{811D47CC-E5F0-456A-918E-5908005E8FC0}.Release (to Public)|Win32.ActiveCfg = Release (to Public)|Win32
{811D47CC-E5F0-456A-918E-5908005E8FC0}.Release (to Public)|Win32.Build.0 = Release (to Public)|Win32
{811D47CC-E5F0-456A-918E-5908005E8FC0}.Release|Win32.ActiveCfg = Release|Win32
{811D47CC-E5F0-456A-918E-5908005E8FC0}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1 +0,0 @@
copy .\Release\ZeroGSShaders.exe ..\

View File

@ -1,362 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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 _CRT_SECURE_NO_DEPRECATE
// Builds all possible shader files from ps2hw.fx and stores them in
// a preprocessed database
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <assert.h>
#ifdef _WIN32
# include <zlib/zlib.h>
#else
# include <zlib.h>
#endif
#include "zpipe.h"
#include <Cg/cg.h>
#include <Cg/cgGL.h>
#define SAFE_RELEASE(x) { if( (x) != NULL ) { (x)->Release(); x = NULL; } }
#include <map>
#include <vector>
using namespace std;
#include "zerogsshaders.h"
char* srcfilename = "ps2hw.fx";
char* dstfilename = "ps2hw.dat";
#ifndef ArraySize
#define ArraySize(x) (sizeof(x) / sizeof((x)[0]))
#endif
struct SHADERINFO
{
int type;
vector<char> buf;
};
map<int, SHADERINFO> mapShaders;
CGcontext g_cgcontext;
void LoadShader(int index, const char* pshader, CGprofile prof, vector<const char*>& vargs, int context)
{
vector<const char*> realargs;
realargs.reserve(16);
realargs.resize(vargs.size());
if( vargs.size() > 0 )
memcpy(&realargs[0], &vargs[0], realargs.size() * sizeof(realargs[0]));
realargs.push_back(context ? "-Ictx1" : "-Ictx0");
realargs.push_back(NULL);
CGprogram prog = cgCreateProgramFromFile(g_cgcontext, CG_SOURCE, srcfilename, prof, pshader, &realargs[0]);
if( !cgIsProgram(prog) ) {
printf("Failed to load shader %s: \n%s\n", pshader, cgGetLastListing(g_cgcontext));
return;
}
if( mapShaders.find(index) != mapShaders.end() ) {
printf("error: two shaders share the same index %d\n", index);
exit(0);
}
if( !cgIsProgramCompiled(prog) )
cgCompileProgram(prog);
const char* pstr = cgGetProgramString(prog, CG_COMPILED_PROGRAM);
const char* pprog = strstr(pstr, "#program");
if( pprog == NULL ) {
printf("program field not found!\n");
return;
}
pprog += 9;
const char* progend = strchr(pprog, '\r');
if( progend == NULL ) progend = strchr(pprog, '\n');
if( progend == NULL ) {
printf("prog end not found!\n");
return;
}
const char* defname = "main";
SHADERINFO info;
info.type = 0;
info.buf.resize(strlen(pstr)+1);
// change the program name to main
memset(&info.buf[0], 0, info.buf.size());
memcpy(&info.buf[0], pstr, pprog-pstr);
memcpy(&info.buf[pprog-pstr], defname, 4);
memcpy(&info.buf[pprog-pstr+4], progend, strlen(pstr)-(progend-pstr));
if( mapShaders.find(index) != mapShaders.end() )
printf("same shader\n");
assert( mapShaders.find(index) == mapShaders.end() );
mapShaders[index] = info;
cgDestroyProgram(prog);
}
int main(int argc, char** argv)
{
printf("usage: [src] [dst] [opts]\n");
if( argc >= 2 ) srcfilename = argv[1];
if( argc >= 3 ) dstfilename = argv[2];
FILE* fsrc = fopen(srcfilename, "r");
if( fsrc == NULL ) {
printf("cannot open %s\n", srcfilename);
return 0;
}
fclose(fsrc);
g_cgcontext = cgCreateContext();
if( !cgIsContext(g_cgcontext) ) {
printf("failed to create cg context\n");
return -1;
}
CGprofile cgvProf = CG_PROFILE_ARBVP1;
CGprofile cgfProf = CG_PROFILE_ARBFP1;
if( !cgGLIsProfileSupported(cgvProf) != CG_TRUE ) {
printf("arbvp1 not supported\n");
return 0;
}
if( !cgGLIsProfileSupported(cgfProf) != CG_TRUE ) {
printf("arbfp1 not supported\n");
return 0;
}
cgGLEnableProfile(cgvProf);
cgGLEnableProfile(cgfProf);
cgGLSetOptimalOptions(cgvProf);
cgGLSetOptimalOptions(cgfProf);
vector<const char*> vmacros;
LoadShader(SH_BITBLTVS, "BitBltVS", cgvProf, vmacros, 0);
LoadShader(SH_BITBLTPS, "BitBltPS", cgfProf, vmacros, 0);
LoadShader(SH_BITBLTDEPTHPS, "BitBltDepthPS", cgfProf, vmacros, 0);
LoadShader(SH_BITBLTDEPTHMRTPS, "BitBltDepthMRTPS", cgfProf, vmacros, 0);
LoadShader(SH_CRTCTARGPS, "CRTCTargPS", cgfProf, vmacros, 0);
LoadShader(SH_CRTCPS, "CRTCPS", cgfProf, vmacros, 0);
LoadShader(SH_CRTC_NEARESTPS, "CRTCPS_Nearest", cgfProf, vmacros, 0);
LoadShader(SH_CRTC24PS, "CRTC24PS", cgfProf, vmacros, 0);
LoadShader(SH_ZEROPS, "ZeroPS", cgfProf, vmacros, 0);
LoadShader(SH_BASETEXTUREPS, "BaseTexturePS", cgfProf, vmacros, 0);
LoadShader(SH_BITBLTAAPS, "BitBltPS", cgfProf, vmacros, 0);
LoadShader(SH_CRTCTARGINTERPS, "CRTCTargInterPS", cgfProf, vmacros, 0);
LoadShader(SH_CRTCINTERPS, "CRTCInterPS", cgfProf, vmacros, 0);
LoadShader(SH_CRTCINTER_NEARESTPS, "CRTCInterPS_Nearest", cgfProf, vmacros, 0);
LoadShader(SH_CRTC24INTERPS, "CRTC24InterPS", cgfProf, vmacros, 0);
LoadShader(SH_CONVERT16TO32PS, "Convert16to32PS", cgfProf, vmacros, 0);
LoadShader(SH_CONVERT32TO16PS, "Convert32to16PS", cgfProf, vmacros, 0);
const int vsshaders[4] = { SH_REGULARVS, SH_TEXTUREVS, SH_REGULARFOGVS, SH_TEXTUREFOGVS };
const char* pvsshaders[4] = { "RegularVS", "TextureVS", "RegularFogVS", "TextureFogVS" };
// load the texture shaders
char str[255], strdir[255];
strcpy(strdir, srcfilename);
int i = (int)strlen(strdir);
while(i > 0) {
if( strdir[i-1] == '/' || strdir[i-1] == '\\' )
break;
--i;
}
strdir[i] = 0;
for(i = 0; i < ArraySize(vsshaders); ++i) {
for(int writedepth = 0; writedepth < 2; ++writedepth ) {
if( writedepth ) vmacros.push_back("-DWRITE_DEPTH");
LoadShader(vsshaders[i]|(writedepth?SH_WRITEDEPTH:0), pvsshaders[i], cgvProf, vmacros, 0);
LoadShader(vsshaders[i]|(writedepth?SH_WRITEDEPTH:0)|SH_CONTEXT1, pvsshaders[i], cgvProf, vmacros, 1);
if( writedepth ) vmacros.pop_back();
}
}
const int psshaders[2] = { SH_REGULARPS, SH_REGULARFOGPS };
const char* ppsshaders[2] = { "RegularPS", "RegularFogPS" };
for(i = 0; i < ArraySize(psshaders); ++i) {
for(int writedepth = 0; writedepth < 2; ++writedepth ) {
if( writedepth ) vmacros.push_back("-DWRITE_DEPTH");
LoadShader(psshaders[i]|(writedepth?SH_WRITEDEPTH:0), ppsshaders[i], cgfProf, vmacros, 0);
if( writedepth ) vmacros.pop_back();
}
}
printf("creating shaders, note that ctx0/ps2hw_ctx.fx, and ctx1/ps2hw_ctx.fx are required\n");
vmacros.resize(0);
for(int texwrap = 0; texwrap < NUM_TEXWRAPS; ++texwrap ) {
if( g_pPsTexWrap[texwrap] != NULL )
vmacros.push_back(g_pPsTexWrap[texwrap]);
for(int context = 0; context < 2; ++context) {
for(int texfilter = 0; texfilter < NUM_FILTERS; ++texfilter) {
for(int fog = 0; fog < 2; ++fog ) {
for(int writedepth = 0; writedepth < 2; ++writedepth ) {
if( writedepth )
vmacros.push_back("-DWRITE_DEPTH");
for(int testaem = 0; testaem < 2; ++testaem ) {
if( testaem )
vmacros.push_back("-DTEST_AEM");
for(int exactcolor = 0; exactcolor < 2; ++exactcolor ) {
if( exactcolor )
vmacros.push_back("-DEXACT_COLOR");
// 32
sprintf(str, "Texture%s%d_32PS", fog?"Fog":"", texfilter);
vmacros.push_back("-DACCURATE_DECOMPRESSION");
LoadShader(GET_SHADER_INDEX(0, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, SHADER_ACCURATE), str, cgfProf, vmacros, context);
vmacros.pop_back();
LoadShader(GET_SHADER_INDEX(0, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, 0), str, cgfProf, vmacros, context);
if( texfilter == 0 ) {
// tex32
sprintf(str, "Texture%s%d_tex32PS", fog?"Fog":"", texfilter);
// vmacros.push_back("-DACCURATE_DECOMPRESSION");
// LoadShader(GET_SHADER_INDEX(1, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, SHADER_ACCURATE), str, cgfProf, vmacros, context);
// vmacros.pop_back();
LoadShader(GET_SHADER_INDEX(1, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, 0), str, cgfProf, vmacros, context);
// clut32
sprintf(str, "Texture%s%d_clut32PS", fog?"Fog":"", texfilter);
// vmacros.push_back("-DACCURATE_DECOMPRESSION");
// LoadShader(GET_SHADER_INDEX(2, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, SHADER_ACCURATE), str, cgfProf, vmacros, context);
// vmacros.pop_back();
LoadShader(GET_SHADER_INDEX(2, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, 0), str, cgfProf, vmacros, context);
// tex32to16
sprintf(str, "Texture%s%d_tex32to16PS", fog?"Fog":"", texfilter);
// vmacros.push_back("-DACCURATE_DECOMPRESSION");
// LoadShader(GET_SHADER_INDEX(3, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, SHADER_ACCURATE), str, cgfProf, vmacros, context);
// vmacros.pop_back();
LoadShader(GET_SHADER_INDEX(3, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, 0), str, cgfProf, vmacros, context);
// tex16to8h
sprintf(str, "Texture%s%d_tex16to8hPS", fog?"Fog":"", texfilter);
// vmacros.push_back("-DACCURATE_DECOMPRESSION");
// LoadShader(GET_SHADER_INDEX(4, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, SHADER_ACCURATE), str, cgfProf, vmacros, context);
// vmacros.pop_back();
LoadShader(GET_SHADER_INDEX(4, texfilter, texwrap, fog, writedepth, testaem, exactcolor, context, 0), str, cgfProf, vmacros, context);
}
if( exactcolor )
vmacros.pop_back();
}
if( testaem )
vmacros.pop_back();
}
if( writedepth )
vmacros.pop_back();
}
}
}
}
if( g_pPsTexWrap[texwrap] != NULL )
vmacros.pop_back();
}
if( vmacros.size() != 0 )
printf("error with macros!\n");
// create the database
int num = (int)mapShaders.size();
// first compress
vector<char> buffer;
buffer.reserve(10000000); // 10mb
buffer.resize(sizeof(SHADERHEADER)*num);
i = 0;
for(map<int, SHADERINFO>::iterator it = mapShaders.begin(); it != mapShaders.end(); ++it, ++i) {
SHADERHEADER h;
h.index = it->first | it->second.type;
h.offset = (int)buffer.size();
h.size = (int)it->second.buf.size();
memcpy(&buffer[0] + i*sizeof(SHADERHEADER), &h, sizeof(SHADERHEADER));
size_t cur = buffer.size();
buffer.resize(cur + it->second.buf.size());
memcpy(&buffer[cur], &it->second.buf[0], it->second.buf.size());
}
int compressed_size;
int real_size = (int)buffer.size();
vector<char> dst;
dst.resize(buffer.size());
def(&buffer[0], &dst[0], (int)buffer.size(), &compressed_size);
// write to file
// fmt: num shaders, size of compressed, compressed data
FILE* fdst = fopen(dstfilename, "wb");
if( fdst == NULL ) {
printf("failed to open %s\n", dstfilename);
return 0;
}
fwrite(&num, 4, 1, fdst);
fwrite(&compressed_size, 4, 1, fdst);
fwrite(&real_size, 4, 1, fdst);
fwrite(&dst[0], compressed_size, 1, fdst);
fclose(fdst);
printf("wrote %s\n", dstfilename);
cgDestroyContext(g_cgcontext);
return 0;
}

View File

@ -1,120 +0,0 @@
/* ZZ Open GL graphics plugin
* Copyright on Zerofrog's ZeroGS KOSMOS (c)2005-2008
*
* 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
*/
#ifndef __ZEROGS_SHADERS_H__
#define __ZEROGS_SHADERS_H__
#include <Cg/cg.h>
#include <Cg/cgGL.h>
#include "PS2Edefs.h"
#include <cstdio>
#include <vector>
#define ZZshProgram CGprogram
#define ZZshContext CGcontext
using namespace std;
#define NUM_FILTERS 2 // texture filtering
#define NUM_TYPES 5 // types of texture read modes
#define NUM_TEXWRAPS 4 // texture wrapping
#define SHADER_REDUCED 1 // equivalent to ps2.0
#define SHADER_ACCURATE 2 // for older cards with less accurate math (ps2.x+)
#define NUM_SHADERS (NUM_FILTERS*NUM_TYPES*NUM_TEXWRAPS*32) // # shaders for a given ps
const static char* g_pPsTexWrap[] = { "-DREPEAT", "-DCLAMP", "-DREGION_REPEAT", NULL };
const static char* g_pTexTypes[] = { "32", "tex32", "clut32", "tex32to16", "tex16to8h" };
#define TEXWRAP_REPEAT 0
#define TEXWRAP_CLAMP 1
#define TEXWRAP_REGION_REPEAT 2
#define TEXWRAP_REPEAT_CLAMP 3
static __forceinline int GET_SHADER_INDEX(int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int context, int ps)
{
return type + texfilter*NUM_TYPES + NUM_FILTERS*NUM_TYPES*texwrap + NUM_TEXWRAPS*NUM_FILTERS*NUM_TYPES*(fog+2*writedepth+4*testaem+8*exactcolor+16*context+32*ps);
}
extern ZZshContext g_cgcontext;
static CGprogram LoadShaderFromType(const char* srcdir, const char* srcfile, int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int ps, int context)
{
assert( texwrap < NUM_TEXWRAPS);
assert( type < NUM_TYPES );
char str[255], strctx[255];
sprintf(str, "Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]);
sprintf(strctx, "-I%s%s", srcdir, context?"ctx1":"ctx0");
vector<const char*> macros;
macros.push_back(strctx);
#ifdef _DEBUG
macros.push_back("-bestprecision");
#endif
if( g_pPsTexWrap[texwrap] != NULL ) macros.push_back(g_pPsTexWrap[texwrap]);
if( writedepth ) macros.push_back("-DWRITE_DEPTH");
if( testaem ) macros.push_back("-DTEST_AEM");
if( exactcolor ) macros.push_back("-DEXACT_COLOR");
if( ps & SHADER_ACCURATE ) macros.push_back("-DACCURATE_DECOMPRESSION");
macros.push_back(NULL);
ZZshProgram prog = cgCreateProgramFromFile(g_cgcontext, CG_SOURCE, srcfile, CG_PROFILE_ARBFP1, str, &macros[0]);
if( !cgIsProgram(prog) ) {
printf("Failed to load shader %s: \n%s\n", str, cgGetLastListing(g_cgcontext));
return NULL;
}
return prog;
}
struct SHADERHEADER
{
unsigned int index, offset, size; // if highest bit of index is set, pixel shader
};
#define SH_WRITEDEPTH 0x2000 // depth is written
#define SH_CONTEXT1 0x1000 // context1 is used
#define SH_REGULARVS 0x8000
#define SH_TEXTUREVS 0x8001
#define SH_REGULARFOGVS 0x8002
#define SH_TEXTUREFOGVS 0x8003
#define SH_REGULARPS 0x8004
#define SH_REGULARFOGPS 0x8005
#define SH_BITBLTVS 0x8006
#define SH_BITBLTPS 0x8007
#define SH_BITBLTDEPTHPS 0x8009
#define SH_CRTCTARGPS 0x800a
#define SH_CRTCPS 0x800b
#define SH_CRTC24PS 0x800c
#define SH_ZEROPS 0x800e
#define SH_BASETEXTUREPS 0x800f
#define SH_BITBLTAAPS 0x8010
#define SH_CRTCTARGINTERPS 0x8012
#define SH_CRTCINTERPS 0x8013
#define SH_CRTC24INTERPS 0x8014
#define SH_BITBLTDEPTHMRTPS 0x8016
#define SH_CONVERT16TO32PS 0x8020
#define SH_CONVERT32TO16PS 0x8021
#define SH_CRTC_NEARESTPS 0x8022
#define SH_CRTCINTER_NEARESTPS 0x8023
#endif

View File

@ -1,441 +0,0 @@
/* crc32.h -- tables for rapid CRC calculation
* Generated automatically by crc32.c
*/
local const unsigned long FAR crc_table[TBLS][256] =
{
{
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
#ifdef BYFOUR
},
{
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
0x9324fd72UL
},
{
0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
0xbe9834edUL
},
{
0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
0xde0506f1UL
},
{
0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
0x8def022dUL
},
{
0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
0x72fd2493UL
},
{
0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
0xed3498beUL
},
{
0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
0xf10605deUL
#endif
}
};

View File

@ -1,331 +0,0 @@
/* deflate.h -- internal compression state
* Copyright (C) 1995-2004 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id: deflate.h,v 1.2 2006/03/02 00:10:34 zerocool Exp $ */
#ifndef DEFLATE_H
#define DEFLATE_H
#include "zutil.h"
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer creation by deflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip encoding
should be left enabled. */
#ifndef NO_GZIP
# define GZIP
#endif
/* ===========================================================================
* Internal compression state.
*/
#define LENGTH_CODES 29
/* number of length codes, not counting the special END_BLOCK code */
#define LITERALS 256
/* number of literal bytes 0..255 */
#define L_CODES (LITERALS+1+LENGTH_CODES)
/* number of Literal or Length codes, including the END_BLOCK code */
#define D_CODES 30
/* number of distance codes */
#define BL_CODES 19
/* number of codes used to transfer the bit lengths */
#define HEAP_SIZE (2*L_CODES+1)
/* maximum heap size */
#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
#define INIT_STATE 42
#define EXTRA_STATE 69
#define NAME_STATE 73
#define COMMENT_STATE 91
#define HCRC_STATE 103
#define BUSY_STATE 113
#define FINISH_STATE 666
/* Stream status */
/* Data structure describing a single value and its code string. */
typedef struct ct_data_s {
union {
ush freq; /* frequency count */
ush code; /* bit string */
} fc;
union {
ush dad; /* father node in Huffman tree */
ush len; /* length of bit string */
} dl;
} FAR ct_data;
#define Freq fc.freq
#define Code fc.code
#define Dad dl.dad
#define Len dl.len
typedef struct static_tree_desc_s static_tree_desc;
typedef struct tree_desc_s {
ct_data *dyn_tree; /* the dynamic tree */
int max_code; /* largest code with non zero frequency */
static_tree_desc *stat_desc; /* the corresponding static tree */
} FAR tree_desc;
typedef ush Pos;
typedef Pos FAR Posf;
typedef unsigned IPos;
/* A Pos is an index in the character window. We use short instead of int to
* save space in the various tables. IPos is used only for parameter passing.
*/
typedef struct internal_state {
z_streamp strm; /* pointer back to this zlib stream */
int status; /* as the name implies */
Bytef *pending_buf; /* output still pending */
ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */
uInt pending; /* nb of bytes in the pending buffer */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
gz_headerp gzhead; /* gzip header information to write */
uInt gzindex; /* where in extra, name, or comment */
Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */
uInt w_size; /* LZ77 window size (32K by default) */
uInt w_bits; /* log2(w_size) (8..16) */
uInt w_mask; /* w_size - 1 */
Bytef *window;
/* Sliding window. Input bytes are read into the second half of the window,
* and move to the first half later to keep a dictionary of at least wSize
* bytes. With this organization, matches are limited to a distance of
* wSize-MAX_MATCH bytes, but this ensures that IO is always
* performed with a length multiple of the block size. Also, it limits
* the window size to 64K, which is quite useful on MSDOS.
* To do: use the user input buffer as sliding window.
*/
ulg window_size;
/* Actual size of window: 2*wSize, except when the user input buffer
* is directly used as sliding window.
*/
Posf *prev;
/* Link to older string with same hash index. To limit the size of this
* array to 64K, this link is maintained only for the last 32K strings.
* An index in this array is thus a window index modulo 32K.
*/
Posf *head; /* Heads of the hash chains or NIL. */
uInt ins_h; /* hash index of string to be inserted */
uInt hash_size; /* number of elements in hash table */
uInt hash_bits; /* log2(hash_size) */
uInt hash_mask; /* hash_size-1 */
uInt hash_shift;
/* Number of bits by which ins_h must be shifted at each input
* step. It must be such that after MIN_MATCH steps, the oldest
* byte no longer takes part in the hash key, that is:
* hash_shift * MIN_MATCH >= hash_bits
*/
long block_start;
/* Window position at the beginning of the current output block. Gets
* negative when the window is moved backwards.
*/
uInt match_length; /* length of best match */
IPos prev_match; /* previous match */
int match_available; /* set if previous match exists */
uInt strstart; /* start of string to insert */
uInt match_start; /* start of matching string */
uInt lookahead; /* number of valid bytes ahead in window */
uInt prev_length;
/* Length of the best match at previous step. Matches not greater than this
* are discarded. This is used in the lazy match evaluation.
*/
uInt max_chain_length;
/* To speed up deflation, hash chains are never searched beyond this
* length. A higher limit improves compression ratio but degrades the
* speed.
*/
uInt max_lazy_match;
/* Attempt to find a better match only when the current match is strictly
* smaller than this value. This mechanism is used only for compression
* levels >= 4.
*/
# define max_insert_length max_lazy_match
/* Insert new strings in the hash table only if the match length is not
* greater than this length. This saves time but degrades compression.
* max_insert_length is used only for compression levels <= 3.
*/
int level; /* compression level (1..9) */
int strategy; /* favor or force Huffman coding*/
uInt good_match;
/* Use a faster search when the previous match is longer than this */
int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */
/* Didn't use ct_data typedef below to supress compiler warning */
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
struct tree_desc_s l_desc; /* desc. for literal tree */
struct tree_desc_s d_desc; /* desc. for distance tree */
struct tree_desc_s bl_desc; /* desc. for bit length tree */
ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
int heap_len; /* number of elements in the heap */
int heap_max; /* element of largest frequency */
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
* The same heap array is used to build all trees.
*/
uch depth[2*L_CODES+1];
/* Depth of each subtree used as tie breaker for trees of equal frequency
*/
uchf *l_buf; /* buffer for literals or lengths */
uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for
* limiting lit_bufsize to 64K:
* - frequencies can be kept in 16 bit counters
* - if compression is not successful for the first block, all input
* data is still in the window so we can still emit a stored block even
* when input comes from standard input. (This can also be done for
* all blocks if lit_bufsize is not greater than 32K.)
* - if compression is not successful for a file smaller than 64K, we can
* even emit a stored file instead of a stored block (saving 5 bytes).
* This is applicable only for zip (not gzip or zlib).
* - creating new Huffman trees less frequently may not provide fast
* adaptation to changes in the input data statistics. (Take for
* example a binary file with poorly compressible code followed by
* a highly compressible string table.) Smaller buffer sizes give
* fast adaptation but have of course the overhead of transmitting
* trees more frequently.
* - I can't count above 4
*/
uInt last_lit; /* running index in l_buf */
ushf *d_buf;
/* Buffer for distances. To simplify the code, d_buf and l_buf have
* the same number of elements. To use different lengths, an extra flag
* array would be necessary.
*/
ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */
uInt matches; /* number of string matches in current block */
int last_eob_len; /* bit length of EOB code for last block */
#ifdef DEBUG
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
#endif
ush bi_buf;
/* Output buffer. bits are inserted starting at the bottom (least
* significant bits).
*/
int bi_valid;
/* Number of valid bits in bi_buf. All bits above the last valid bit
* are always zero.
*/
} FAR deflate_state;
/* Output a byte on the stream.
* IN assertion: there is enough room in pending_buf.
*/
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
/* Minimum amount of lookahead, except at the end of the input file.
* See deflate.c for comments about the MIN_MATCH+1.
*/
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
/* In order to simplify the code, particularly on 16 bit machines, match
* distances are limited to MAX_DIST instead of WSIZE.
*/
/* in trees.c */
void _tr_init OF((deflate_state *s));
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
void _tr_align OF((deflate_state *s));
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
* must not have side effects. _dist_code[256] and _dist_code[257] are never
* used.
*/
#ifndef DEBUG
/* Inline versions of _tr_tally for speed: */
#if defined(GEN_TREES_H) || !defined(STDC)
extern uch _length_code[];
extern uch _dist_code[];
#else
extern const uch _length_code[];
extern const uch _dist_code[];
#endif
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->d_buf[s->last_lit] = 0; \
s->l_buf[s->last_lit++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (length); \
ush dist = (distance); \
s->d_buf[s->last_lit] = dist; \
s->l_buf[s->last_lit++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \
flush = _tr_tally(s, distance, length)
#endif
#endif /* DEFLATE_H */

View File

@ -1,11 +0,0 @@
/* inffast.h -- header to use inffast.c
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
void inflate_fast OF((z_streamp strm, unsigned start));

View File

@ -1,94 +0,0 @@
/* inffixed.h -- table for decoding fixed codes
* Generated automatically by makefixed().
*/
/* WARNING: this file should *not* be used by applications. It
is part of the implementation of the compression library and
is subject to change. Applications should only use zlib.h.
*/
static const code lenfix[512] = {
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
{0,9,255}
};
static const code distfix[32] = {
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
{22,5,193},{64,5,0}
};

View File

@ -1,115 +0,0 @@
/* inflate.h -- internal inflate state definition
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip decoding
should be left enabled. */
#ifndef NO_GZIP
# define GUNZIP
#endif
/* Possible inflate modes between inflate() calls */
typedef enum {
HEAD, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN, /* i: waiting for length/lit code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
LENGTH, /* i: waiting for 32-bit length (gzip) */
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
} inflate_mode;
/*
State transitions between above modes -
(most modes can go to the BAD or MEM mode -- not shown for clarity)
Process header:
HEAD -> (gzip) or (zlib)
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
NAME -> COMMENT -> HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
Read deflate blocks:
TYPE -> STORED or TABLE or LEN or CHECK
STORED -> COPY -> TYPE
TABLE -> LENLENS -> CODELENS -> LEN
Read deflate codes:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
Process trailer:
CHECK -> LENGTH -> DONE
*/
/* state maintained between inflate() calls. Approximately 7K bytes. */
struct inflate_state {
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
};

View File

@ -1,55 +0,0 @@
/* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* Structure for decoding tables. Each entry provides either the
information needed to do the operation requested by the code that
indexed that table entry, or it provides a pointer to another
table that indexes more bits of the code. op indicates whether
the entry is a pointer to another table, a literal, a length or
distance, an end-of-block, or an invalid code. For a table
pointer, the low four bits of op is the number of index bits of
that table. For a length or distance, the low four bits of op
is the number of extra bits to get after the code. bits is
the number of bits in this code or part of the code to drop off
of the bit buffer. val is the actual byte to output in the case
of a literal, the base length or distance, or the offset from
the current table to the next table. Each entry is four bytes. */
typedef struct {
unsigned char op; /* operation, extra bits, table bits */
unsigned char bits; /* bits in this part of the code */
unsigned short val; /* offset in table or code value */
} code;
/* op values as set by inflate_table():
00000000 - literal
0000tttt - table link, tttt != 0 is the number of table index bits
0001eeee - length or distance, eeee is the number of extra bits
01100000 - end of block
01000000 - invalid code
*/
/* Maximum size of dynamic tree. The maximum found in a long but non-
exhaustive search was 1444 code structures (852 for length/literals
and 592 for distances, the latter actually the result of an
exhaustive search). The true maximum is not known, but the value
below is more than safe. */
#define ENOUGH 2048
#define MAXD 592
/* Type of code to build for inftable() */
typedef enum {
CODES,
LENS,
DISTS
} codetype;
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work));

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