mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
328e358b21
commit
f6c138ca7e
|
@ -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
|
||||
|
|
4
build.sh
4
build.sh
|
@ -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
|
||||
|
|
|
@ -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)")
|
||||
|
|
|
@ -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
|
||||
#---------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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/" | \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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
|
Binary file not shown.
|
@ -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
|
|
@ -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
|
|
@ -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 |
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
};
|
|
@ -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
|
|
@ -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
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
copy .\Release\ZeroGSShaders.exe ..\
|
|
@ -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;
|
||||
}
|
|
@ -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, ¯os[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
|
|
@ -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
|
||||
}
|
||||
};
|
|
@ -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 */
|
|
@ -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));
|
|
@ -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}
|
||||
};
|
|
@ -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 */
|
||||
};
|
|
@ -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
Loading…
Reference in New Issue