aboutsummaryrefslogtreecommitdiff
path: root/plugins/dfxvideo
diff options
context:
space:
mode:
authorPCSX* teams2010-11-16 14:15:22 +0200
committerGrazvydas Ignotas2010-11-16 14:15:22 +0200
commitef79bbde537d6b9c745a7d86cb9df1d04c35590d (patch)
treeef8d2520dbb9e1e345b41b12c9959f300ca8fd10 /plugins/dfxvideo
downloadpcsx_rearmed-ef79bbde537d6b9c745a7d86cb9df1d04c35590d.tar.gz
pcsx_rearmed-ef79bbde537d6b9c745a7d86cb9df1d04c35590d.tar.bz2
pcsx_rearmed-ef79bbde537d6b9c745a7d86cb9df1d04c35590d.zip
pcsxr-1.9.92
Diffstat (limited to 'plugins/dfxvideo')
-rw-r--r--plugins/dfxvideo/Makefile.am36
-rw-r--r--plugins/dfxvideo/Makefile.in626
-rw-r--r--plugins/dfxvideo/cfg.c318
-rw-r--r--plugins/dfxvideo/cfg.h28
-rw-r--r--plugins/dfxvideo/draw.c2047
-rw-r--r--plugins/dfxvideo/draw.h46
-rw-r--r--plugins/dfxvideo/externals.h315
-rw-r--r--plugins/dfxvideo/fps.c357
-rw-r--r--plugins/dfxvideo/fps.h31
-rw-r--r--plugins/dfxvideo/gpu.c1952
-rw-r--r--plugins/dfxvideo/gpu.h60
-rw-r--r--plugins/dfxvideo/gpucfg-0.1df/dfxvideo.glade2625
-rw-r--r--plugins/dfxvideo/gpucfg-0.1df/main.c464
-rw-r--r--plugins/dfxvideo/hq2x.h1870
-rw-r--r--plugins/dfxvideo/hq3x.h2970
-rw-r--r--plugins/dfxvideo/i386.asm67
-rw-r--r--plugins/dfxvideo/interp.h298
-rw-r--r--plugins/dfxvideo/key.c95
-rw-r--r--plugins/dfxvideo/key.h24
-rw-r--r--plugins/dfxvideo/macros.inc40
-rw-r--r--plugins/dfxvideo/menu.c167
-rw-r--r--plugins/dfxvideo/menu.h27
-rw-r--r--plugins/dfxvideo/prim.c1661
-rw-r--r--plugins/dfxvideo/prim.h24
-rw-r--r--plugins/dfxvideo/soft.c8483
-rw-r--r--plugins/dfxvideo/soft.h42
-rw-r--r--plugins/dfxvideo/swap.h71
-rw-r--r--plugins/dfxvideo/zn.c255
28 files changed, 22999 insertions, 0 deletions
diff --git a/plugins/dfxvideo/Makefile.am b/plugins/dfxvideo/Makefile.am
new file mode 100644
index 0000000..89ba770
--- /dev/null
+++ b/plugins/dfxvideo/Makefile.am
@@ -0,0 +1,36 @@
+STRIP_FPIC = sh $(top_srcdir)/strip_fPIC.sh
+
+SUFFIXES = .asm
+
+.asm.lo:
+ $(LIBTOOL) --tag=CC --mode=compile \
+ $(STRIP_FPIC) $(NASM) -f elf -d ELF -I${srcdir}/ $<
+
+INCLUDES = -DPIXMAPDIR=\"${datadir}/pixmaps/\" \
+ -DLOCALE_DIR=\"${datadir}/locale/\" \
+ -DDATADIR=\"${datadir}/psemu/\" \
+ $(GTK2_CFLAGS) $(GLADE2_CFLAGS) -I/usr/X11R6/include \
+ -I../../libpcsxcore \
+ -I../../include
+
+bindir = @libdir@/games/psemu/
+libdir = @libdir@/games/psemu/
+
+lib_LTLIBRARIES = libDFXVideo.la
+
+libDFXVideo_la_SOURCES = gpu.c cfg.c draw.c fps.c key.c menu.c prim.c soft.c zn.c
+if X86_NASM
+libDFXVideo_la_SOURCES += i386.asm
+INCLUDES += -DUSE_NASM=1
+endif
+libDFXVideo_la_LDFLAGS = -module -avoid-version
+libDFXVideo_la_LDFLAGS += -L/usr/X11R6/lib64 -L/usr/X11R6/lib \
+ -lX11 -lXv -lXext -lm
+
+bin_PROGRAMS = cfgDFXVideo
+cfgDFXVideo_SOURCES = gpucfg-0.1df/main.c
+cfgDFXVideo_LDADD = $(GTK2_LIBS) $(GLADE2_LIBS) -L/usr/X11R6/lib -lXext
+
+glade_DATA = gpucfg-0.1df/dfxvideo.glade2
+gladedir = $(datadir)/psemu/
+EXTRA_DIST = $(glade_DATA)
diff --git a/plugins/dfxvideo/Makefile.in b/plugins/dfxvideo/Makefile.in
new file mode 100644
index 0000000..6bacfcf
--- /dev/null
+++ b/plugins/dfxvideo/Makefile.in
@@ -0,0 +1,626 @@
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@X86_NASM_TRUE@am__append_1 = i386.asm
+@X86_NASM_TRUE@am__append_2 = -DUSE_NASM=1
+bin_PROGRAMS = cfgDFXVideo$(EXEEXT)
+subdir = plugins/dfxvideo
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(gladedir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libDFXVideo_la_LIBADD =
+am__libDFXVideo_la_SOURCES_DIST = gpu.c cfg.c draw.c fps.c key.c \
+ menu.c prim.c soft.c zn.c i386.asm
+@X86_NASM_TRUE@am__objects_1 = i386.lo
+am_libDFXVideo_la_OBJECTS = gpu.lo cfg.lo draw.lo fps.lo key.lo \
+ menu.lo prim.lo soft.lo zn.lo $(am__objects_1)
+libDFXVideo_la_OBJECTS = $(am_libDFXVideo_la_OBJECTS)
+libDFXVideo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libDFXVideo_la_LDFLAGS) $(LDFLAGS) -o $@
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_cfgDFXVideo_OBJECTS = main.$(OBJEXT)
+cfgDFXVideo_OBJECTS = $(am_cfgDFXVideo_OBJECTS)
+am__DEPENDENCIES_1 =
+cfgDFXVideo_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libDFXVideo_la_SOURCES) $(cfgDFXVideo_SOURCES)
+DIST_SOURCES = $(am__libDFXVideo_la_SOURCES_DIST) \
+ $(cfgDFXVideo_SOURCES)
+gladeDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(glade_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALSA_CFLAGS = @ALSA_CFLAGS@
+ALSA_LIBS = @ALSA_LIBS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLADE2_CFLAGS = @GLADE2_CFLAGS@
+GLADE2_LIBS = @GLADE2_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+GTK2_CFLAGS = @GTK2_CFLAGS@
+GTK2_LIBS = @GTK2_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBCDIO_CFLAGS = @LIBCDIO_CFLAGS@
+LIBCDIO_LIBS = @LIBCDIO_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NASM = @NASM@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PEOPSXGL = @PEOPSXGL@
+PKG_CONFIG = @PKG_CONFIG@
+POSUB = @POSUB@
+PULSEAUDIO_CFLAGS = @PULSEAUDIO_CFLAGS@
+PULSEAUDIO_LIBS = @PULSEAUDIO_LIBS@
+RANLIB = @RANLIB@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_CONFIG = @SDL_CONFIG@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @libdir@/games/psemu/
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@/games/psemu/
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+STRIP_FPIC = sh $(top_srcdir)/strip_fPIC.sh
+SUFFIXES = .asm
+INCLUDES = -DPIXMAPDIR=\"${datadir}/pixmaps/\" \
+ -DLOCALE_DIR=\"${datadir}/locale/\" \
+ -DDATADIR=\"${datadir}/psemu/\" $(GTK2_CFLAGS) \
+ $(GLADE2_CFLAGS) -I/usr/X11R6/include -I../../libpcsxcore \
+ -I../../include $(am__append_2)
+lib_LTLIBRARIES = libDFXVideo.la
+libDFXVideo_la_SOURCES = gpu.c cfg.c draw.c fps.c key.c menu.c prim.c \
+ soft.c zn.c $(am__append_1)
+libDFXVideo_la_LDFLAGS = -module -avoid-version -L/usr/X11R6/lib64 \
+ -L/usr/X11R6/lib -lX11 -lXv -lXext -lm
+cfgDFXVideo_SOURCES = gpucfg-0.1df/main.c
+cfgDFXVideo_LDADD = $(GTK2_LIBS) $(GLADE2_LIBS) -L/usr/X11R6/lib -lXext
+glade_DATA = gpucfg-0.1df/dfxvideo.glade2
+gladedir = $(datadir)/psemu/
+EXTRA_DIST = $(glade_DATA)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .asm .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plugins/dfxvideo/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu plugins/dfxvideo/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libDFXVideo.la: $(libDFXVideo_la_OBJECTS) $(libDFXVideo_la_DEPENDENCIES)
+ $(libDFXVideo_la_LINK) -rpath $(libdir) $(libDFXVideo_la_OBJECTS) $(libDFXVideo_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+cfgDFXVideo$(EXEEXT): $(cfgDFXVideo_OBJECTS) $(cfgDFXVideo_DEPENDENCIES)
+ @rm -f cfgDFXVideo$(EXEEXT)
+ $(LINK) $(cfgDFXVideo_OBJECTS) $(cfgDFXVideo_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/draw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fps.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prim.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/soft.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zn.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+main.o: gpucfg-0.1df/main.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT main.o -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.o `test -f 'gpucfg-0.1df/main.c' || echo '$(srcdir)/'`gpucfg-0.1df/main.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpucfg-0.1df/main.c' object='main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o main.o `test -f 'gpucfg-0.1df/main.c' || echo '$(srcdir)/'`gpucfg-0.1df/main.c
+
+main.obj: gpucfg-0.1df/main.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT main.obj -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.obj `if test -f 'gpucfg-0.1df/main.c'; then $(CYGPATH_W) 'gpucfg-0.1df/main.c'; else $(CYGPATH_W) '$(srcdir)/gpucfg-0.1df/main.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpucfg-0.1df/main.c' object='main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o main.obj `if test -f 'gpucfg-0.1df/main.c'; then $(CYGPATH_W) 'gpucfg-0.1df/main.c'; else $(CYGPATH_W) '$(srcdir)/gpucfg-0.1df/main.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-gladeDATA: $(glade_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(gladedir)" || $(MKDIR_P) "$(DESTDIR)$(gladedir)"
+ @list='$(glade_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(gladeDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(gladedir)/$$f'"; \
+ $(gladeDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(gladedir)/$$f"; \
+ done
+
+uninstall-gladeDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(glade_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(gladedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(gladedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(gladedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-gladeDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-gladeDATA \
+ uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libLTLIBRARIES clean-libtool ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-gladeDATA install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-gladeDATA uninstall-libLTLIBRARIES
+
+
+.asm.lo:
+ $(LIBTOOL) --tag=CC --mode=compile \
+ $(STRIP_FPIC) $(NASM) -f elf -d ELF -I${srcdir}/ $<
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/plugins/dfxvideo/cfg.c b/plugins/dfxvideo/cfg.c
new file mode 100644
index 0000000..9baf8bc
--- /dev/null
+++ b/plugins/dfxvideo/cfg.c
@@ -0,0 +1,318 @@
+/***************************************************************************
+ cfg.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_CFG
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#undef FALSE
+#undef TRUE
+#define MAKELONG(low,high) ((unsigned long)(((unsigned short)(low)) | (((unsigned long)((unsigned short)(high))) << 16)))
+
+#include "externals.h"
+#include "cfg.h"
+#include "gpu.h"
+
+char * pConfigFile = NULL;
+
+// CONFIG FILE helpers....
+// some helper macros:
+
+#define GetValue(name, var) \
+ p = strstr(pB, name); \
+ if (p != NULL) { \
+ p+=strlen(name); \
+ while ((*p == ' ') || (*p == '=')) p++; \
+ if (*p != '\n') var = atoi(p); \
+ }
+
+#define GetFloatValue(name, var) \
+ p = strstr(pB, name); \
+ if (p != NULL) { \
+ p+=strlen(name); \
+ while ((*p == ' ') || (*p == '=')) p++; \
+ if (*p != '\n') var = (float)atof(p); \
+ }
+
+#define SetValue(name, var) \
+ p = strstr(pB, name); \
+ if (p != NULL) { \
+ p+=strlen(name); \
+ while ((*p == ' ') || (*p == '=')) p++; \
+ if (*p != '\n') { \
+ len = sprintf(t1, "%d", var); \
+ strncpy(p, t1, len); \
+ if (p[len] != ' ' && p[len] != '\n' && p[len] != 0) p[len] = ' '; \
+ } \
+ } \
+ else { \
+ size+=sprintf(pB+size, "%s = %d\n", name, var); \
+ }
+
+#define SetFloatValue(name, var) \
+ p = strstr(pB, name); \
+ if (p != NULL) { \
+ p+=strlen(name); \
+ while ((*p == ' ') || (*p == '=')) p++; \
+ if (*p != '\n') { \
+ len = sprintf(t1, "%.1f", (double)var); \
+ strncpy(p, t1, len); \
+ if (p[len] != ' ' && p[len] != '\n' && p[len] != 0) p[len] = ' '; \
+ } \
+ } \
+ else { \
+ size+=sprintf(pB+size, "%s = %.1f\n", name, (double)var); \
+ }
+
+void ReadConfigFile()
+{
+ struct stat buf;
+ FILE *in;char t[256];int len, size;
+ char * pB, * p;
+
+ if(pConfigFile)
+ strcpy(t,pConfigFile);
+ else
+ {
+ strcpy(t,"dfxvideo.cfg");
+ in = fopen(t,"rb");
+ if (!in)
+ {
+ strcpy(t,"cfg/dfxvideo.cfg");
+ in = fopen(t,"rb");
+ if(!in) sprintf(t,"%s/.pcsx/plugins/dfxvideo.cfg",getenv("HOME"));
+ else fclose(in);
+ }
+ else fclose(in);
+ }
+
+ if (stat(t, &buf) == -1) return;
+ size = buf.st_size;
+
+ in = fopen(t,"rb");
+ if (!in) return;
+
+ pB=(char *)malloc(size + 1);
+ memset(pB,0,size + 1);
+
+ len = fread(pB, 1, size, in);
+ fclose(in);
+
+ GetValue("ResX", iResX);
+ if(iResX<20) iResX=20;
+ iResX=(iResX/4)*4;
+
+ GetValue("ResY", iResY);
+ if(iResY<20) iResY=20;
+ iResY=(iResY/4)*4;
+
+ iWinSize=MAKELONG(iResX,iResY);
+
+ GetValue("NoStretch", iUseNoStretchBlt);
+
+ GetValue("Dithering", iUseDither);
+
+ GetValue("FullScreen", iWindowMode);
+ if(iWindowMode!=0) iWindowMode=0;
+ else iWindowMode=1;
+
+ GetValue("ShowFPS", iShowFPS);
+ if(iShowFPS<0) iShowFPS=0;
+ if(iShowFPS>1) iShowFPS=1;
+
+ GetValue("Maintain43", iMaintainAspect);
+ if(iMaintainAspect<0) iMaintainAspect=0;
+ if(iMaintainAspect>1) iMaintainAspect=1;
+
+ GetValue("UseFrameLimit", UseFrameLimit);
+ if(UseFrameLimit<0) UseFrameLimit=0;
+ if(UseFrameLimit>1) UseFrameLimit=1;
+
+ GetValue("UseFrameSkip", UseFrameSkip);
+ if(UseFrameSkip<0) UseFrameSkip=0;
+ if(UseFrameSkip>1) UseFrameSkip=1;
+
+ GetValue("FPSDetection", iFrameLimit);
+ if(iFrameLimit<1) iFrameLimit=1;
+ if(iFrameLimit>2) iFrameLimit=2;
+
+ GetFloatValue("FrameRate", fFrameRate);
+ fFrameRate/=10;
+ if(fFrameRate<10.0f) fFrameRate=10.0f;
+ if(fFrameRate>1000.0f) fFrameRate=1000.0f;
+
+ GetValue("CfgFixes", dwCfgFixes);
+
+ GetValue("UseFixes", iUseFixes);
+ if(iUseFixes<0) iUseFixes=0;
+ if(iUseFixes>1) iUseFixes=1;
+
+ free(pB);
+}
+
+void ExecCfg(char *arg) {
+ char cfg[256];
+ struct stat buf;
+
+ strcpy(cfg, "./cfgDFXVideo");
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgDFXVideo", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ strcpy(cfg, "./cfg/cfgDFXVideo");
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgDFXVideo", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ sprintf(cfg, "%s/.pcsx/plugins/cfg/cfgDFXVideo", getenv("HOME"));
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgDFXVideo", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ printf("ERROR: cfgDFXVideo file not found!\n");
+}
+
+void SoftDlgProc(void)
+{
+ ExecCfg("CFG");
+}
+
+void AboutDlgProc(void)
+{
+ char args[256];
+
+ sprintf(args, "ABOUT");
+ ExecCfg(args);
+}
+
+void ReadConfig(void)
+{
+ // defaults
+ iResX=640;iResY=480;
+ iWinSize=MAKELONG(iResX,iResY);
+ iColDepth=32;
+ iWindowMode=1;
+ iMaintainAspect=0;
+ UseFrameLimit=1;
+ UseFrameSkip=0;
+ iFrameLimit=2;
+ fFrameRate=200.0f;
+ dwCfgFixes=0;
+ iUseFixes=0;
+ iUseNoStretchBlt=0;
+ iUseDither=0;
+ iShowFPS=0;
+
+ // read sets
+ ReadConfigFile();
+
+ // additional checks
+ if(!iColDepth) iColDepth=32;
+ if(iUseFixes) dwActFixes=dwCfgFixes;
+ SetFixes();
+}
+
+void WriteConfig(void) {
+
+ struct stat buf;
+ FILE *out;char t[256];int len, size;
+ char * pB, * p; char t1[8];
+
+ if(pConfigFile)
+ strcpy(t,pConfigFile);
+ else
+ {
+ strcpy(t,"dfxvideo.cfg");
+ out = fopen(t,"rb");
+ if (!out)
+ {
+ strcpy(t,"cfg/dfxvideo.cfg");
+ out = fopen(t,"rb");
+ if(!out) sprintf(t,"%s/.pcsx/plugins/dfxvideo.cfg",getenv("HOME"));
+ else fclose(out);
+ }
+ else fclose(out);
+ }
+
+ if (stat(t, &buf) != -1) size = buf.st_size;
+ else size = 0;
+
+ out = fopen(t,"rb");
+ if (!out) {
+ // defaults
+ iResX=640;iResY=480;
+ iColDepth=32;
+ iWindowMode=1;
+ iMaintainAspect=0;
+ UseFrameLimit=0;
+ UseFrameSkip=0;
+ iFrameLimit=2;
+ fFrameRate=200.0f;
+ dwCfgFixes=0;
+ iUseFixes=0;
+ iUseNoStretchBlt=0;
+ iUseDither=0;
+ iShowFPS=0;
+
+ size = 0;
+ pB=(char *)malloc(4096);
+ memset(pB,0,4096);
+ }
+ else {
+ pB=(char *)malloc(size+4096);
+ memset(pB,0,size+4096);
+
+ len = fread(pB, 1, size, out);
+ fclose(out);
+ }
+
+ SetValue("ResX", iResX);
+ SetValue("ResY", iResY);
+ SetValue("NoStretch", iUseNoStretchBlt);
+ SetValue("Dithering", iUseDither);
+ SetValue("FullScreen", !iWindowMode);
+ SetValue("ShowFPS", iShowFPS);
+ SetValue("Maintain43", iMaintainAspect);
+ SetValue("UseFrameLimit", UseFrameLimit);
+ SetValue("UseFrameSkip", UseFrameSkip);
+ SetValue("FPSDetection", iFrameLimit);
+ SetFloatValue("FrameRate", fFrameRate);
+ SetValue("CfgFixes", (unsigned int)dwCfgFixes);
+ SetValue("UseFixes", iUseFixes);
+
+ out = fopen(t,"wb");
+ if (!out) return;
+
+ len = fwrite(pB, 1, size, out);
+ fclose(out);
+
+ free(pB);
+}
diff --git a/plugins/dfxvideo/cfg.h b/plugins/dfxvideo/cfg.h
new file mode 100644
index 0000000..fa259f3
--- /dev/null
+++ b/plugins/dfxvideo/cfg.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+ cfg.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _GPU_CFG_H_
+#define _GPU_CFG_H_
+
+void ReadConfig(void);
+void WriteConfig(void);
+void ReadWinSizeConfig(void);
+
+void SoftDlgProc(void);
+void AboutDlgProc(void);
+
+#endif // _GPU_CFG_H_
diff --git a/plugins/dfxvideo/draw.c b/plugins/dfxvideo/draw.c
new file mode 100644
index 0000000..fe7f87a
--- /dev/null
+++ b/plugins/dfxvideo/draw.c
@@ -0,0 +1,2047 @@
+/***************************************************************************
+ draw.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_DRAW
+
+#include "externals.h"
+#include "gpu.h"
+#include "draw.h"
+#include "prim.h"
+#include "menu.h"
+#include "interp.h"
+#include "swap.h"
+
+// misc globals
+int iResX;
+int iResY;
+long lLowerpart;
+BOOL bIsFirstFrame = TRUE;
+BOOL bCheckMask = FALSE;
+unsigned short sSetMask = 0;
+unsigned long lSetMask = 0;
+int iDesktopCol = 16;
+int iShowFPS = 0;
+int iWinSize;
+int iMaintainAspect = 0;
+int iUseNoStretchBlt = 0;
+int iFastFwd = 0;
+int iDebugMode = 0;
+int iFVDisplay = 0;
+PSXPoint_t ptCursorPoint[8];
+unsigned short usCursorActive = 0;
+
+//unsigned int LUT16to32[65536];
+//unsigned int RGBtoYUV[65536];
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XShm.h>
+int xv_port = -1;
+int xv_id = -1;
+int xv_depth = 0;
+int yuv_port = -1;
+int yuv_id = -1;
+int use_yuv = 0;
+int xv_vsync = 0;
+
+XShmSegmentInfo shminfo;
+int finalw,finalh;
+
+extern XvImage *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*);
+
+#include <time.h>
+
+// prototypes
+void hq2x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height);
+void hq3x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height);
+
+////////////////////////////////////////////////////////////////////////
+// generic 2xSaI helpers
+////////////////////////////////////////////////////////////////////////
+
+void * pSaISmallBuff=NULL;
+void * pSaIBigBuff=NULL;
+
+#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
+
+static __inline int GetResult1(DWORD A, DWORD B, DWORD C, DWORD D, DWORD E)
+{
+ int x = 0;
+ int y = 0;
+ int r = 0;
+ if (A == C) x+=1; else if (B == C) y+=1;
+ if (A == D) x+=1; else if (B == D) y+=1;
+ if (x <= 1) r+=1;
+ if (y <= 1) r-=1;
+ return r;
+}
+
+static __inline int GetResult2(DWORD A, DWORD B, DWORD C, DWORD D, DWORD E)
+{
+ int x = 0;
+ int y = 0;
+ int r = 0;
+ if (A == C) x+=1; else if (B == C) y+=1;
+ if (A == D) x+=1; else if (B == D) y+=1;
+ if (x <= 1) r-=1;
+ if (y <= 1) r+=1;
+ return r;
+}
+
+#define colorMask8 0x00FEFEFE
+#define lowPixelMask8 0x00010101
+#define qcolorMask8 0x00FCFCFC
+#define qlowpixelMask8 0x00030303
+
+#define INTERPOLATE8(A, B) ((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8)))
+#define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) \
+ + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))))
+
+
+void Super2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ DWORD srcPitchHalf = srcPitch>>1;
+ int finWidth = srcPitch>>2;
+ DWORD line;
+ DWORD *dP;
+ DWORD *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA0, colorA1, colorA2, colorA3,
+ colorB0, colorB1, colorB2, colorB3,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ finalw=width<<1;
+ finalh=height<<1;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (DWORD *)srcPtr;
+ dP = (DWORD *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//--------------------------------------- B1 B2
+// 4 5 6 S2
+// 1 2 3 S1
+// A1 A2
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) {iYA=0;}
+ else {iYA=finWidth;}
+ if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorB0 = *(bP- iYA - iXA);
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+ colorB3 = *(bP- iYA + iXC);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA0 = *(bP + iYC - iXA);
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+ colorA3 = *(bP + iYC + iXC);
+
+ if (color2 == color6 && color5 != color3)
+ {
+ product2b = product1b = color2;
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1b = color5;
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
+
+ if (r > 0)
+ product2b = product1b = color6;
+ else
+ if (r < 0)
+ product2b = product1b = color5;
+ else
+ {
+ product2b = product1b = INTERPOLATE8(color5, color6);
+ }
+ }
+ else
+ {
+ if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
+ product2b = Q_INTERPOLATE8 (color3, color3, color3, color2);
+ else
+ if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
+ product2b = Q_INTERPOLATE8 (color2, color2, color2, color3);
+ else
+ product2b = INTERPOLATE8 (color2, color3);
+
+ if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
+ product1b = Q_INTERPOLATE8 (color6, color6, color6, color5);
+ else
+ if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
+ product1b = Q_INTERPOLATE8 (color6, color5, color5, color5);
+ else
+ product1b = INTERPOLATE8 (color5, color6);
+ }
+
+ if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
+ product2a = INTERPOLATE8(color2, color5);
+ else
+ if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
+ product2a = INTERPOLATE8(color2, color5);
+ else
+ product2a = color2;
+
+ if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
+ product1a = INTERPOLATE8(color2, color5);
+ else
+ if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
+ product1a = INTERPOLATE8(color2, color5);
+ else
+ product1a = color5;
+
+ *dP=product1a;
+ *(dP+1)=product1b;
+ *(dP+(srcPitchHalf))=product2a;
+ *(dP+1+(srcPitchHalf))=product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void Std2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ DWORD srcPitchHalf = srcPitch>>1;
+ int finWidth = srcPitch>>2;
+ DWORD line;
+ DWORD *dP;
+ DWORD *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+
+ finalw=width<<1;
+ finalh=height<<1;
+
+ DWORD colorA, colorB;
+ DWORD colorC, colorD,
+ colorE, colorF, colorG, colorH,
+ colorI, colorJ, colorK, colorL,
+ colorM, colorN, colorO, colorP;
+ DWORD product, product1, product2;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (DWORD *)srcPtr;
+ dP = (DWORD *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//---------------------------------------
+// Map of the pixels: I|E F|J
+// G|A B|K
+// H|C D|L
+// M|N O|P
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) {iYA=0;}
+ else {iYA=finWidth;}
+ if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorI = *(bP- iYA - iXA);
+ colorE = *(bP- iYA);
+ colorF = *(bP- iYA + iXB);
+ colorJ = *(bP- iYA + iXC);
+
+ colorG = *(bP - iXA);
+ colorA = *(bP);
+ colorB = *(bP + iXB);
+ colorK = *(bP + iXC);
+
+ colorH = *(bP + iYB - iXA);
+ colorC = *(bP + iYB);
+ colorD = *(bP + iYB + iXB);
+ colorL = *(bP + iYB + iXC);
+
+ colorM = *(bP + iYC - iXA);
+ colorN = *(bP + iYC);
+ colorO = *(bP + iYC + iXB);
+ colorP = *(bP + iYC + iXC);
+
+
+ if((colorA == colorD) && (colorB != colorC))
+ {
+ if(((colorA == colorE) && (colorB == colorL)) ||
+ ((colorA == colorC) && (colorA == colorF) &&
+ (colorB != colorE) && (colorB == colorJ)))
+ {
+ product = colorA;
+ }
+ else
+ {
+ product = INTERPOLATE8(colorA, colorB);
+ }
+
+ if(((colorA == colorG) && (colorC == colorO)) ||
+ ((colorA == colorB) && (colorA == colorH) &&
+ (colorG != colorC) && (colorC == colorM)))
+ {
+ product1 = colorA;
+ }
+ else
+ {
+ product1 = INTERPOLATE8(colorA, colorC);
+ }
+ product2 = colorA;
+ }
+ else
+ if((colorB == colorC) && (colorA != colorD))
+ {
+ if(((colorB == colorF) && (colorA == colorH)) ||
+ ((colorB == colorE) && (colorB == colorD) &&
+ (colorA != colorF) && (colorA == colorI)))
+ {
+ product = colorB;
+ }
+ else
+ {
+ product = INTERPOLATE8(colorA, colorB);
+ }
+
+ if(((colorC == colorH) && (colorA == colorF)) ||
+ ((colorC == colorG) && (colorC == colorD) &&
+ (colorA != colorH) && (colorA == colorI)))
+ {
+ product1 = colorC;
+ }
+ else
+ {
+ product1=INTERPOLATE8(colorA, colorC);
+ }
+ product2 = colorB;
+ }
+ else
+ if((colorA == colorD) && (colorB == colorC))
+ {
+ if (colorA == colorB)
+ {
+ product = colorA;
+ product1 = colorA;
+ product2 = colorA;
+ }
+ else
+ {
+ register int r = 0;
+ product1 = INTERPOLATE8(colorA, colorC);
+ product = INTERPOLATE8(colorA, colorB);
+
+ r += GetResult1 (colorA&0x00FFFFFF, colorB&0x00FFFFFF, colorG&0x00FFFFFF, colorE&0x00FFFFFF, colorI&0x00FFFFFF);
+ r += GetResult2 (colorB&0x00FFFFFF, colorA&0x00FFFFFF, colorK&0x00FFFFFF, colorF&0x00FFFFFF, colorJ&0x00FFFFFF);
+ r += GetResult2 (colorB&0x00FFFFFF, colorA&0x00FFFFFF, colorH&0x00FFFFFF, colorN&0x00FFFFFF, colorM&0x00FFFFFF);
+ r += GetResult1 (colorA&0x00FFFFFF, colorB&0x00FFFFFF, colorL&0x00FFFFFF, colorO&0x00FFFFFF, colorP&0x00FFFFFF);
+
+ if (r > 0)
+ product2 = colorA;
+ else
+ if (r < 0)
+ product2 = colorB;
+ else
+ {
+ product2 = Q_INTERPOLATE8(colorA, colorB, colorC, colorD);
+ }
+ }
+ }
+ else
+ {
+ product2 = Q_INTERPOLATE8(colorA, colorB, colorC, colorD);
+
+ if ((colorA == colorC) && (colorA == colorF) &&
+ (colorB != colorE) && (colorB == colorJ))
+ {
+ product = colorA;
+ }
+ else
+ if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
+ {
+ product = colorB;
+ }
+ else
+ {
+ product = INTERPOLATE8(colorA, colorB);
+ }
+
+ if ((colorA == colorB) && (colorA == colorH) &&
+ (colorG != colorC) && (colorC == colorM))
+ {
+ product1 = colorA;
+ }
+ else
+ if ((colorC == colorG) && (colorC == colorD) &&
+ (colorA != colorH) && (colorA == colorI))
+ {
+ product1 = colorC;
+ }
+ else
+ {
+ product1 = INTERPOLATE8(colorA, colorC);
+ }
+ }
+
+//////////////////////////
+
+ *dP=colorA;
+ *(dP+1)=product;
+ *(dP+(srcPitchHalf))=product1;
+ *(dP+1+(srcPitchHalf))=product2;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void SuperEagle_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ DWORD srcPitchHalf = srcPitch>>1;
+ int finWidth = srcPitch>>2;
+ DWORD line;
+ DWORD *dP;
+ DWORD *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA1, colorA2,
+ colorB1, colorB2,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ finalw=width<<1;
+ finalh=height<<1;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (DWORD *)srcPtr;
+ dP = (DWORD *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) {iYA=0;}
+ else {iYA=finWidth;}
+ if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+
+ if(color2 == color6 && color5 != color3)
+ {
+ product1b = product2a = color2;
+ if((color1 == color2) ||
+ (color6 == colorB2))
+ {
+ product1a = INTERPOLATE8(color2, color5);
+ product1a = INTERPOLATE8(color2, product1a);
+ }
+ else
+ {
+ product1a = INTERPOLATE8(color5, color6);
+ }
+
+ if((color6 == colorS2) ||
+ (color2 == colorA1))
+ {
+ product2b = INTERPOLATE8(color2, color3);
+ product2b = INTERPOLATE8(color2, product2b);
+ }
+ else
+ {
+ product2b = INTERPOLATE8(color2, color3);
+ }
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1a = color5;
+
+ if ((colorB1 == color5) ||
+ (color3 == colorS1))
+ {
+ product1b = INTERPOLATE8(color5, color6);
+ product1b = INTERPOLATE8(color5, product1b);
+ }
+ else
+ {
+ product1b = INTERPOLATE8(color5, color6);
+ }
+
+ if ((color3 == colorA2) ||
+ (color4 == color5))
+ {
+ product2a = INTERPOLATE8(color5, color2);
+ product2a = INTERPOLATE8(color5, product2a);
+ }
+ else
+ {
+ product2a = INTERPOLATE8(color2, color3);
+ }
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
+
+ if (r > 0)
+ {
+ product1b = product2a = color2;
+ product1a = product2b = INTERPOLATE8(color5, color6);
+ }
+ else
+ if (r < 0)
+ {
+ product2b = product1a = color5;
+ product1b = product2a = INTERPOLATE8(color5, color6);
+ }
+ else
+ {
+ product2b = product1a = color5;
+ product1b = product2a = color2;
+ }
+ }
+ else
+ {
+ product2b = product1a = INTERPOLATE8(color2, color6);
+ product2b = Q_INTERPOLATE8(color3, color3, color3, product2b);
+ product1a = Q_INTERPOLATE8(color5, color5, color5, product1a);
+
+ product2a = product1b = INTERPOLATE8(color5, color3);
+ product2a = Q_INTERPOLATE8(color2, color2, color2, product2a);
+ product1b = Q_INTERPOLATE8(color6, color6, color6, product1b);
+ }
+
+////////////////////////////////
+
+ *dP=product1a;
+ *(dP+1)=product1b;
+ *(dP+(srcPitchHalf))=product2a;
+ *(dP+1+(srcPitchHalf))=product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+/////////////////////////
+
+//#include <assert.h>
+
+static __inline void scale2x_32_def_whole(uint32_t* dst0, uint32_t* dst1, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count)
+{
+
+ //assert(count >= 2);
+
+ // first pixel
+ if (src0[0] != src2[0] && src1[0] != src1[1]) {
+ dst0[0] = src1[0] == src0[0] ? src0[0] : src1[0];
+ dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
+ dst1[0] = src1[0] == src2[0] ? src2[0] : src1[0];
+ dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ }
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 2;
+ dst1 += 2;
+
+ // central pixels
+ count -= 2;
+ while (count) {
+ if (src0[0] != src2[0] && src1[-1] != src1[1]) {
+ dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
+ dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
+ dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
+ dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ }
+
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 2;
+ dst1 += 2;
+ --count;
+ }
+
+ // last pixel
+ if (src0[0] != src2[0] && src1[-1] != src1[0]) {
+ dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
+ dst0[1] = src1[0] == src0[0] ? src0[0] : src1[0];
+ dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
+ dst1[1] = src1[0] == src2[0] ? src2[0] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ }
+}
+
+void Scale2x_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstPtr, int width, int height)
+{
+ //const int srcpitch = srcPitch;
+ const int dstPitch = srcPitch<<1;
+
+ int count = height;
+
+ finalw=width<<1;
+ finalh=height<<1;
+
+ uint32_t *dst0 = (uint32_t *)dstPtr;
+ uint32_t *dst1 = dst0 + (dstPitch >> 2);
+
+ uint32_t *src0 = (uint32_t *)srcPtr;
+ uint32_t *src1 = src0 + (srcPitch >> 2);
+ uint32_t *src2 = src1 + (srcPitch >> 2);
+ scale2x_32_def_whole(dst0, dst1, src0, src0, src1, width);
+
+ count -= 2;
+ while(count) {
+ dst0 += dstPitch >> 1;
+ dst1 += dstPitch >> 1;
+ scale2x_32_def_whole(dst0, dst1, src0, src0, src1, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+ dst0 += dstPitch >> 1;
+ dst1 += dstPitch >> 1;
+ scale2x_32_def_whole(dst0, dst1, src0, src1, src1, width);
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static __inline void scale3x_32_def_whole(uint32_t* dst0, uint32_t* dst1, uint32_t* dst2, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count)
+{
+ //assert(count >= 2);
+
+ //first pixel
+ if (src0[0] != src2[0] && src1[0] != src1[1]) {
+ dst0[0] = src1[0];
+ dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
+ dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
+ dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
+ dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+
+ //central pixels
+ count -= 2;
+ while (count) {
+ if (src0[0] != src2[0] && src1[-1] != src1[1]) {
+ dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
+ dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
+ dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
+ dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
+ dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
+ dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
+ dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+ --count;
+ }
+
+ // last pixel
+ if (src0[0] != src2[0] && src1[-1] != src1[0]) {
+ dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
+ dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
+ dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
+ dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
+ dst2[2] = src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+}
+
+
+void Scale3x_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstPtr, int width, int height)
+{
+ int count = height;
+
+ int dstPitch = srcPitch*3;
+ int dstRowPixels = dstPitch>>2;
+
+ finalw=width*3;
+ finalh=height*3;
+
+ uint32_t *dst0 = (uint32_t *)dstPtr;
+ uint32_t *dst1 = dst0 + dstRowPixels;
+ uint32_t *dst2 = dst1 + dstRowPixels;
+
+ uint32_t *src0 = (uint32_t *)srcPtr;
+ uint32_t *src1 = src0 + (srcPitch >> 2);
+ uint32_t *src2 = src1 + (srcPitch >> 2);
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src0, src2, width);
+
+ count -= 2;
+ while(count) {
+ dst0 += dstRowPixels*3;
+ dst1 += dstRowPixels*3;
+ dst2 += dstRowPixels*3;
+
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+
+ dst0 += dstRowPixels*3;
+ dst1 += dstRowPixels*3;
+ dst2 += dstRowPixels*3;
+
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src1, width);
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+
+////////////////////////////////////////////////////////////////////////
+// X STUFF :)
+////////////////////////////////////////////////////////////////////////
+
+
+static Cursor cursor;
+XVisualInfo vi;
+static XVisualInfo *myvisual;
+Display *display;
+static Colormap colormap;
+Window window;
+static GC hGC;
+static XImage * Ximage;
+static XvImage * XCimage;
+static XImage * XFimage;
+static XImage * XPimage=0 ;
+char * Xpixels;
+char * pCaptionText;
+
+static int fx=0;
+
+
+static Atom xv_intern_atom_if_exists( Display *display, char const * atom_name )
+{
+ XvAttribute * attributes;
+ int attrib_count,i;
+ Atom xv_atom = None;
+
+ attributes = XvQueryPortAttributes( display, xv_port, &attrib_count );
+ if( attributes!=NULL )
+ {
+ for ( i = 0; i < attrib_count; ++i )
+ {
+ if ( strcmp(attributes[i].name, atom_name ) == 0 )
+ {
+ xv_atom = XInternAtom( display, atom_name, False );
+ break; // found what we want, break out
+ }
+ }
+ XFree( attributes );
+ }
+
+ return xv_atom;
+}
+
+
+
+// close display
+
+void DestroyDisplay(void)
+{
+ if(display)
+ {
+ XFreeColormap(display, colormap);
+ if(hGC)
+ {
+ XFreeGC(display,hGC);
+ hGC = 0;
+ }
+ if(Ximage)
+ {
+ XDestroyImage(Ximage);
+ Ximage=0;
+ }
+ if(XCimage)
+ {
+ XFree(XCimage);
+ XCimage=0;
+ }
+ if(XFimage)
+ {
+ XDestroyImage(XFimage);
+ XFimage=0;
+ }
+
+ XShmDetach(display,&shminfo);
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid,IPC_RMID,NULL);
+
+ Atom atom_vsync = xv_intern_atom_if_exists(display, "XV_SYNC_TO_VBLANK");
+ if (atom_vsync != None) {
+ XvSetPortAttribute(display, xv_port, atom_vsync, xv_vsync);
+ }
+
+ XSync(display,False);
+
+ XCloseDisplay(display);
+ }
+}
+
+static int depth=0;
+int root_window_id=0;
+
+
+// Create display
+
+void CreateDisplay(void)
+{
+ XSetWindowAttributes winattr;
+ int myscreen;
+ Screen * screen;
+ XEvent event;
+ XSizeHints hints;
+ XWMHints wm_hints;
+ MotifWmHints mwmhints;
+ Atom mwmatom;
+
+ Atom delwindow;
+
+ XGCValues gcv;
+ int i;
+
+ int ret, j, p;
+ int formats;
+ unsigned int p_num_adaptors=0, p_num_ports=0;
+
+ XvAdaptorInfo *ai;
+ XvImageFormatValues *fo;
+
+ // Open display
+ display = XOpenDisplay(NULL);
+
+ if (!display)
+ {
+ fprintf (stderr,"Failed to open display!!!\n");
+ DestroyDisplay();
+ return;
+ }
+
+ myscreen=DefaultScreen(display);
+
+ // desktop fullscreen switch
+ if (!iWindowMode) fx = 1;
+
+ screen=DefaultScreenOfDisplay(display);
+
+ root_window_id=RootWindow(display,DefaultScreen(display));
+
+ //Look for an Xvideo RGB port
+ ret = XvQueryAdaptors(display, root_window_id, &p_num_adaptors, &ai);
+ if (ret != Success) {
+ if (ret == XvBadExtension)
+ printf("XvBadExtension returned at XvQueryExtension.\n");
+ else
+ if (ret == XvBadAlloc)
+ printf("XvBadAlloc returned at XvQueryExtension.\n");
+ else
+ printf("other error happaned at XvQueryAdaptors.\n");
+
+ exit(-1);
+ }
+
+ depth = DefaultDepth(display, myscreen);
+
+ for (i = 0; i < p_num_adaptors; i++) {
+ p_num_ports = ai[i].base_id + ai[i].num_ports;
+ for (p = ai[i].base_id; p < p_num_ports; p++) {
+ fo = XvListImageFormats(display, p, &formats);
+ for (j = 0; j < formats; j++) {
+ //backup YUV mode
+ //hmm, should I bother check guid == 55595659-0000-0010-8000-00aa00389b71?
+ //and check byte order? fo[j].byte_order == LSBFirst
+#ifdef __BIG_ENDIAN__
+ if ( fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 && fo[j].format == XvPacked && strncmp("YUYV", fo[j].component_order, 5) == 0 )
+#else
+ if ( fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 && fo[j].format == XvPacked && strncmp("UYVY", fo[j].component_order, 5) == 0 )
+#endif
+ {
+ yuv_port = p;
+ yuv_id = fo[j].id;
+ }
+ if (fo[j].type == XvRGB && fo[j].bits_per_pixel == 32)
+ {
+ xv_port = p;
+ xv_id = fo[j].id;
+ xv_depth = fo[j].depth;
+ printf("RGB mode found. id: %x, depth: %d\n", xv_id, xv_depth);
+
+ if (xv_depth != depth) {
+ printf("Warning: Depth does not match screen depth (%d)\n", depth);
+ }
+ else {
+ //break out of loops
+ j = formats;
+ p = p_num_ports;
+ i = p_num_adaptors;
+ }
+ }
+ }
+ if (fo)
+ XFree(fo);
+ }
+ }
+ if (p_num_adaptors > 0)
+ XvFreeAdaptorInfo(ai);
+ if (xv_port == -1 && yuv_port == -1)
+ {
+ printf("RGB & YUV not found. Quitting.\n");
+ exit(-1);
+ }
+ else if (xv_port == -1 && yuv_port != -1)
+ {
+ use_yuv = 1;
+ printf("RGB not found. Using YUV.\n");
+ xv_port = yuv_port;
+ xv_id = yuv_id;
+ }
+ else if (xv_depth && xv_depth != depth && yuv_port != -1)
+ {
+ use_yuv = 1;
+ printf("Acceptable RGB mode not found. Using YUV.\n");
+ xv_port = yuv_port;
+ xv_id = yuv_id;
+ }
+
+ Atom atom_vsync = xv_intern_atom_if_exists(display, "XV_SYNC_TO_VBLANK");
+ if (atom_vsync != None) {
+ XvGetPortAttribute(display, xv_port, atom_vsync, &xv_vsync);
+ XvSetPortAttribute(display, xv_port, atom_vsync, 0);
+ }
+
+myvisual = 0;
+
+if(XMatchVisualInfo(display,myscreen, depth, TrueColor, &vi))
+ myvisual = &vi;
+
+if (!myvisual)
+{
+ fprintf(stderr,"Failed to obtain visual!\n");
+ DestroyDisplay();
+ return;
+}
+
+ if(myvisual->red_mask==0x00007c00 &&
+ myvisual->green_mask==0x000003e0 &&
+ myvisual->blue_mask==0x0000001f)
+ {iColDepth=15;}
+ else
+ if(myvisual->red_mask==0x0000f800 &&
+ myvisual->green_mask==0x000007e0 &&
+ myvisual->blue_mask==0x0000001f)
+ {iColDepth=16;}
+ else
+ if(myvisual->red_mask==0x00ff0000 &&
+ myvisual->green_mask==0x0000ff00 &&
+ myvisual->blue_mask==0x000000ff)
+ {iColDepth=32;}
+ else
+ {
+ iColDepth=0;
+/* fprintf(stderr,"COLOR DEPTH NOT SUPPORTED!\n");
+ fprintf(stderr,"r: %08lx\n",myvisual->red_mask);
+ fprintf(stderr,"g: %08lx\n",myvisual->green_mask);
+ fprintf(stderr,"b: %08lx\n",myvisual->blue_mask);
+ DestroyDisplay();
+ return;*/
+ }
+
+ // pffff... much work for a simple blank cursor... oh, well...
+ if(iWindowMode) cursor=XCreateFontCursor(display,XC_trek);
+ else
+ {
+ Pixmap p1,p2;
+ XImage * img;
+ XColor b,w;
+ char * idata;
+ XGCValues GCv;
+ GC GCc;
+
+ memset(&b,0,sizeof(XColor));
+ memset(&w,0,sizeof(XColor));
+ idata=(char *)malloc(8);
+ memset(idata,0,8);
+
+ p1=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1);
+ p2=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1);
+
+ img = XCreateImage(display,myvisual->visual,
+ 1,XYBitmap,0,idata,8,8,8,1);
+
+ GCv.function = GXcopy;
+ GCv.foreground = ~0;
+ GCv.background = 0;
+ GCv.plane_mask = AllPlanes;
+ GCc = XCreateGC(display,p1,
+ (GCFunction|GCForeground|GCBackground|GCPlaneMask),&GCv);
+
+ XPutImage(display, p1,GCc,img,0,0,0,0,8,8);
+ XPutImage(display, p2,GCc,img,0,0,0,0,8,8);
+ XFreeGC(display, GCc);
+
+ cursor = XCreatePixmapCursor(display,p1,p2,&b,&w,0,0);
+
+ XFreePixmap(display,p1);
+ XFreePixmap(display,p2);
+ XDestroyImage(img); // will free idata as well
+ }
+
+ colormap=XCreateColormap(display,root_window_id,
+ myvisual->visual,AllocNone);
+
+ winattr.background_pixel=0;
+ winattr.border_pixel=WhitePixelOfScreen(screen);
+ winattr.bit_gravity=ForgetGravity;
+ winattr.win_gravity=NorthWestGravity;
+ winattr.backing_store=NotUseful;
+
+ winattr.override_redirect=False;
+ winattr.save_under=False;
+ winattr.event_mask=0;
+ winattr.do_not_propagate_mask=0;
+ winattr.colormap=colormap;
+ winattr.cursor=None;
+
+ window=XCreateWindow(display,root_window_id,
+ 0,0,iResX,iResY,
+ 0,myvisual->depth,
+ InputOutput,myvisual->visual,
+ CWBorderPixel | CWBackPixel |
+ CWEventMask | CWDontPropagate |
+ CWColormap | CWCursor,
+ &winattr);
+
+ if(!window)
+ {
+ fprintf(stderr,"Failed in XCreateWindow()!!!\n");
+ DestroyDisplay();
+ return;
+ }
+
+ delwindow = XInternAtom(display,"WM_DELETE_WINDOW",0);
+ XSetWMProtocols(display, window, &delwindow, 1);
+
+ hints.flags=USPosition|USSize;
+ hints.base_width = iResX;
+ hints.base_height = iResY;
+
+ wm_hints.input=1;
+ wm_hints.flags=InputHint;
+
+ XSetWMHints(display,window,&wm_hints);
+ XSetWMNormalHints(display,window,&hints);
+ if(pCaptionText)
+ XStoreName(display,window,pCaptionText);
+ else XStoreName(display,window,"P.E.Op.S SoftX PSX Gpu");
+
+ XDefineCursor(display,window,cursor);
+
+ // hack to get rid of window title bar
+ if (fx)
+ {
+ mwmhints.flags=MWM_HINTS_DECORATIONS;
+ mwmhints.decorations=0;
+ mwmatom=XInternAtom(display,"_MOTIF_WM_HINTS",0);
+ XChangeProperty(display,window,mwmatom,mwmatom,32,
+ PropModeReplace,(unsigned char *)&mwmhints,4);
+ }
+
+ // key stuff
+ XSelectInput(display,
+ window,
+ FocusChangeMask | ExposureMask |
+ KeyPressMask | KeyReleaseMask
+ );
+
+ XMapRaised(display,window);
+ XClearWindow(display,window);
+ XWindowEvent(display,window,ExposureMask,&event);
+
+ if (fx) // fullscreen
+ {
+ XResizeWindow(display,window,screen->width,screen->height);
+
+ hints.min_width = hints.max_width = hints.base_width = screen->width;
+ hints.min_height= hints.max_height = hints.base_height = screen->height;
+
+ XSetWMNormalHints(display,window,&hints);
+
+ // set the window layer for GNOME
+ {
+ XEvent xev;
+
+ memset(&xev, 0, sizeof(xev));
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = 1;
+ xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
+ xev.xclient.window = window;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0);
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(display, root_window_id, 0,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ }
+ }
+
+ gcv.graphics_exposures = False;
+ hGC = XCreateGC(display,window,
+ GCGraphicsExposures, &gcv);
+ if(!hGC)
+ {
+ fprintf(stderr,"No gfx context!!!\n");
+ DestroyDisplay();
+ }
+
+
+
+ Xpixels = (char *)malloc(220*15*4);
+ memset(Xpixels,255,220*15*4);
+ XFimage = XCreateImage(display,myvisual->visual,
+ depth, ZPixmap, 0,
+ (char *)Xpixels,
+ 220, 15,
+ depth>16 ? 32 : 16,
+ 0);
+
+ Xpixels = (char *)malloc(8*8*4);
+ memset(Xpixels,0,8*8*4);
+ XCimage = XvCreateImage(display,xv_port,xv_id,
+ (char *)Xpixels, 8, 8);
+
+
+/*
+Allocate max that could be needed:
+Big(est?) PSX res: 640x512
+32bpp (times 4)
+2xsai func= 3xwidth,3xheight
+= approx 11.8mb
+*/
+shminfo.shmid = shmget(IPC_PRIVATE, 640*512*4*3*3, IPC_CREAT | 0777);
+shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
+shminfo.readOnly = 0;
+
+ if (!XShmAttach(display, &shminfo)) {
+ printf("XShmAttach failed !\n");
+ exit (-1);
+ }
+}
+
+void (*p2XSaIFunc) (unsigned char *, DWORD, unsigned char *, int, int);
+unsigned char *pBackBuffer = 0;
+
+void BlitScreen32(unsigned char *surf, int32_t x, int32_t y)
+{
+ unsigned char *pD;
+ unsigned int startxy;
+ uint32_t lu;
+ unsigned short s;
+ unsigned short row, column;
+ unsigned short dx = PreviousPSXDisplay.Range.x1;
+ unsigned short dy = PreviousPSXDisplay.DisplayMode.y;
+
+ int32_t lPitch = PSXDisplay.DisplayMode.x << 2;
+
+ uint32_t *destpix;
+
+ if (PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ memset(surf, 0, (PreviousPSXDisplay.Range.y0 >> 1) * lPitch);
+
+ dy -= PreviousPSXDisplay.Range.y0;
+ surf += (PreviousPSXDisplay.Range.y0 >> 1) * lPitch;
+
+ memset(surf + dy * lPitch,
+ 0, ((PreviousPSXDisplay.Range.y0 + 1) >> 1) * lPitch);
+ }
+
+ if (PreviousPSXDisplay.Range.x0)
+ {
+ for (column = 0; column < dy; column++)
+ {
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ memset(destpix, 0, PreviousPSXDisplay.Range.x0 << 2);
+ }
+ surf += PreviousPSXDisplay.Range.x0 << 2;
+ }
+
+ if (PSXDisplay.RGB24)
+ {
+ for (column = 0; column < dy; column++)
+ {
+ startxy = ((1024) * (column + y)) + x;
+ pD = (unsigned char *)&psxVuw[startxy];
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < dx; row++)
+ {
+ lu = *((uint32_t *)pD);
+ destpix[row] =
+ 0xff000000 | (RED(lu) << 16) | (GREEN(lu) << 8) | (BLUE(lu));
+ pD += 3;
+ }
+ }
+ }
+ else
+ {
+ for (column = 0;column<dy;column++)
+ {
+ startxy = (1024 * (column + y)) + x;
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < dx; row++)
+ {
+ s = GETLE16(&psxVuw[startxy++]);
+ destpix[row] =
+ (((s << 19) & 0xf80000) | ((s << 6) & 0xf800) | ((s >> 7) & 0xf8)) | 0xff000000;
+ }
+ }
+ }
+}
+
+void BlitToYUV(unsigned char * surf,int32_t x,int32_t y)
+{
+ unsigned char * pD;
+ unsigned int startxy;
+ uint32_t lu;unsigned short s;
+ unsigned short row,column;
+ unsigned short dx = PreviousPSXDisplay.Range.x1;
+ unsigned short dy = PreviousPSXDisplay.DisplayMode.y;
+ int Y,U,V, R,G,B;
+
+ int32_t lPitch = PSXDisplay.DisplayMode.x << 2;
+ uint32_t *destpix;
+
+ if (PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ for (column = 0; column < (PreviousPSXDisplay.Range.y0 >> 1); column++)
+ {
+ destpix = (uint32_t *)(surf + column * lPitch);
+ for (row = 0; row < dx; row++)
+ {
+ destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
+ }
+ }
+
+ dy -= PreviousPSXDisplay.Range.y0;
+ surf += (PreviousPSXDisplay.Range.y0 >> 1) * lPitch;
+
+ for (column = 0; column < (PreviousPSXDisplay.Range.y0 + 1) >> 1; column++)
+ {
+ destpix = (uint32_t *)(surf + (dy + column) * lPitch);
+ for (row = 0; row < dx; row++)
+ {
+ destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
+ }
+ }
+ }
+
+ if (PreviousPSXDisplay.Range.x0)
+ {
+ for (column = 0; column < dy; column++)
+ {
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < PreviousPSXDisplay.Range.x0; row++)
+ {
+ destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
+ }
+ }
+ surf += PreviousPSXDisplay.Range.x0 << 2;
+ }
+
+ if (PSXDisplay.RGB24)
+ {
+ for (column = 0; column < dy; column++)
+ {
+ startxy = (1024 * (column + y)) + x;
+ pD = (unsigned char *)&psxVuw[startxy];
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < dx; row++)
+ {
+ lu = *((uint32_t *)pD);
+
+ R = RED(lu);
+ G = GREEN(lu);
+ B = BLUE(lu);
+
+ Y = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
+ U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240);
+ V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240);
+
+#ifdef __BIG_ENDIAN__
+ destpix[row] = Y << 24 | U << 16 | Y << 8 | V;
+#else
+ destpix[row] = Y << 24 | V << 16 | Y << 8 | U;
+#endif
+ pD += 3;
+ }
+ }
+ }
+ else
+ {
+ for (column = 0; column < dy; column++)
+ {
+ startxy = (1024 * (column + y)) + x;
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < dx; row++)
+ {
+ s = GETLE16(&psxVuw[startxy++]);
+
+ R = (s << 3) &0xf8;
+ G = (s >> 2) &0xf8;
+ B = (s >> 7) &0xf8;
+
+ Y = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
+ U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240);
+ V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240);
+
+#ifdef __BIG_ENDIAN__
+ destpix[row] = Y << 24 | U << 16 | Y << 8 | V;
+#else
+ destpix[row] = Y << 24 | V << 16 | Y << 8 | U;
+#endif
+ }
+ }
+ }
+}
+
+//dst will have half the pitch (32bit to 16bit)
+void RGB2YUV(uint32_t *s, int width, int height, uint32_t *d)
+{
+ int x,y;
+ int R,G,B, Y1,Y2,U,V;
+
+ for (y=0; y<height; y++) {
+ for(x=0; x<width>>1; x++) {
+ R = (*s >> 16) & 0xff;
+ G = (*s >> 8) & 0xff;
+ B = *s & 0xff;
+ s++;
+
+ Y1 = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
+ U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240);
+ V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240);
+
+ R = (*s >> 16) & 0xff;
+ G = (*s >> 8) & 0xff;
+ B = *s & 0xff;
+ s++;
+
+ Y2 = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
+
+#ifdef __BIG_ENDIAN__
+ *d = V | Y2 << 8 | U << 16 | Y1 << 24;
+#else
+ *d = U | Y1 << 8 | V << 16 | Y2 << 24;
+#endif
+ d++;
+ }
+ }
+}
+
+extern time_t tStart;
+
+//Note: dest x,y,w,h are both input and output variables
+inline void MaintainAspect(unsigned int *dx,unsigned int *dy,unsigned int *dw,unsigned int *dh)
+{
+ //Currently just 4/3 aspect ratio
+ int t;
+
+ if (*dw * 3 > *dh * 4) {
+ t = *dh * 4.0f / 3; //new width aspect
+ *dx = (*dw - t) / 2; //centering
+ *dw = t;
+ } else {
+ t = *dw * 3.0f / 4;
+ *dy = (*dh - t) / 2;
+ *dh = t;
+ }
+}
+
+void DoBufferSwap(void)
+{
+ Screen *screen;
+ Window _dw;
+ XvImage *xvi;
+ unsigned int dstx, dsty, srcy = 0;
+ unsigned int _d, _w, _h; //don't care about _d
+
+ finalw = PSXDisplay.DisplayMode.x;
+ finalh = PSXDisplay.DisplayMode.y;
+
+ if (finalw == 0 || finalh == 0)
+ return;
+
+ XSync(display,False);
+
+ if(use_yuv) {
+ if (iUseNoStretchBlt==0 || finalw > 320 || finalh > 256) {
+ BlitToYUV((unsigned char *)shminfo.shmaddr, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ finalw <<= 1;
+ } else {
+ BlitScreen32((unsigned char *)pBackBuffer, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ p2XSaIFunc(pBackBuffer, finalw<<2, (unsigned char *)pSaIBigBuff,finalw,finalh);
+ RGB2YUV( (uint32_t*)pSaIBigBuff, finalw, finalh, (uint32_t*)shminfo.shmaddr);
+ }
+ } else if(iUseNoStretchBlt==0 || finalw > 320 || finalh > 256) {
+ BlitScreen32((unsigned char *)shminfo.shmaddr, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ } else {
+ BlitScreen32((unsigned char *)pBackBuffer, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ p2XSaIFunc(pBackBuffer, finalw<<2, (unsigned char *)shminfo.shmaddr,finalw,finalh);
+ }
+
+ XGetGeometry(display, window, &_dw, (int *)&_d, (int *)&_d, &_w, &_h, &_d, &_d);
+ if (use_yuv) {
+ xvi = XvShmCreateImage(display, yuv_port, yuv_id, 0, finalw, finalh, &shminfo);
+ } else
+ xvi = XvShmCreateImage(display, xv_port, xv_id, 0, finalw, finalh, &shminfo);
+
+ xvi->data = shminfo.shmaddr;
+
+ screen=DefaultScreenOfDisplay(display);
+ //screennum = DefaultScreen(display);
+
+ if (!iWindowMode) {
+ _w = screen->width;
+ _h = screen->height;
+ }
+
+ dstx = 0;
+ dsty = 0;
+
+ if (iMaintainAspect)
+ MaintainAspect(&dstx, &dsty, &_w, &_h);
+
+ if (ulKeybits&KEY_SHOWFPS) //to avoid flicker, don't paint overtop FPS bar
+ {
+ srcy = 15 * finalh / _h;
+ dsty += 15;
+ }
+
+ XvShmPutImage(display, xv_port, window, hGC, xvi,
+ 0,srcy, //src x,y
+ finalw,finalh, //src w,h
+ dstx,dsty, //dst x,y
+ _w,_h, //dst w,h
+ 1
+ );
+
+ if(ulKeybits&KEY_SHOWFPS) //DisplayText(); // paint menu text
+ {
+ if(szDebugText[0] && ((time(NULL) - tStart) < 2))
+ {
+ strcpy(szDispBuf,szDebugText);
+ }
+ else
+ {
+ szDebugText[0]=0;
+ strcat(szDispBuf,szMenuBuf);
+ }
+
+ //XPutImage(display,window,hGC, XFimage,
+ // 0, 0, 0, 0, 220,15);
+ XFree(xvi);
+ xvi = XvCreateImage(display, xv_port, xv_id, XFimage->data, 220, 15);
+ XvPutImage(display, xv_port, window, hGC, xvi,
+ 0,0, //src x,y
+ 220,15, //src w,h
+ 0,0, //dst x,y
+ 220,15 //dst w,h
+ );
+
+ XDrawString(display,window,hGC,2,13,szDispBuf,strlen(szDispBuf));
+ }
+
+ //if(XPimage) DisplayPic();
+
+
+ XFree(xvi);
+}
+
+void DoClearScreenBuffer(void) // CLEAR DX BUFFER
+{
+ Window _dw;
+ unsigned int _d, _w, _h; //don't care about _d
+
+ XGetGeometry(display, window, &_dw, (int *)&_d, (int *)&_d, &_w, &_h, &_d, &_d);
+
+ XvPutImage(display, xv_port, window, hGC, XCimage,
+ 0, 0, 8, 8, 0, 0, _w, _h);
+ //XSync(display,False);
+}
+
+void DoClearFrontBuffer(void) // CLEAR DX BUFFER
+{/*
+ XPutImage(display,window,hGC, XCimage,
+ 0, 0, 0, 0, iResX, iResY);
+ XSync(display,False);*/
+}
+
+int Xinitialize()
+{
+ iDesktopCol=32;
+
+
+ if(iUseNoStretchBlt>0)
+ {
+ pBackBuffer=(unsigned char *)malloc(640*512*sizeof(uint32_t));
+ memset(pBackBuffer,0,640*512*sizeof(uint32_t));
+ if (use_yuv) {
+ pSaIBigBuff=malloc(640*512*4*3*3);
+ memset(pSaIBigBuff,0,640*512*4*3*3);
+ }
+ }
+
+ p2XSaIFunc=NULL;
+
+ if(iUseNoStretchBlt==1)
+ {
+ p2XSaIFunc=Std2xSaI_ex8;
+ }
+
+ if(iUseNoStretchBlt==2)
+ {
+ p2XSaIFunc=Super2xSaI_ex8;
+ }
+
+ if(iUseNoStretchBlt==3)
+ {
+ p2XSaIFunc=SuperEagle_ex8;
+ }
+
+ if(iUseNoStretchBlt==4)
+ {
+ p2XSaIFunc=Scale2x_ex8;
+ }
+ if(iUseNoStretchBlt==5)
+ {
+ p2XSaIFunc=Scale3x_ex8;
+ }
+ if(iUseNoStretchBlt==6)
+ {
+ p2XSaIFunc=hq2x_32;
+ }
+ if(iUseNoStretchBlt==7)
+ {
+ p2XSaIFunc=hq3x_32;
+ }
+
+ bUsingTWin=FALSE;
+
+ InitMenu();
+
+ bIsFirstFrame = FALSE; // done
+
+ if(iShowFPS)
+ {
+ iShowFPS=0;
+ ulKeybits|=KEY_SHOWFPS;
+ szDispBuf[0]=0;
+ BuildDispMenu(0);
+ }
+
+ return 0;
+}
+
+void Xcleanup() // X CLEANUP
+{
+ CloseMenu();
+
+ if(iUseNoStretchBlt>0)
+ {
+ if(pBackBuffer) free(pBackBuffer);
+ pBackBuffer=0;
+ if(pSaIBigBuff) free(pSaIBigBuff);
+ pSaIBigBuff=0;
+ }
+}
+
+unsigned long ulInitDisplay(void)
+{
+ CreateDisplay(); // x stuff
+ Xinitialize(); // init x
+ return (unsigned long)display;
+}
+
+void CloseDisplay(void)
+{
+ Xcleanup(); // cleanup dx
+ DestroyDisplay();
+}
+
+void CreatePic(unsigned char * pMem)
+{
+ unsigned char * p=(unsigned char *)malloc(128*96*4);
+ unsigned char * ps; int x,y;
+
+ ps=p;
+
+ if(iDesktopCol==16)
+ {
+ unsigned short s;
+ for(y=0;y<96;y++)
+ {
+ for(x=0;x<128;x++)
+ {
+ s=(*(pMem+0))>>3;
+ s|=((*(pMem+1))&0xfc)<<3;
+ s|=((*(pMem+2))&0xf8)<<8;
+ pMem+=3;
+ *((unsigned short *)(ps+y*256+x*2))=s;
+ }
+ }
+ }
+ else
+ if(iDesktopCol==15)
+ {
+ unsigned short s;
+ for(y=0;y<96;y++)
+ {
+ for(x=0;x<128;x++)
+ {
+ s=(*(pMem+0))>>3;
+ s|=((*(pMem+1))&0xfc)<<2;
+ s|=((*(pMem+2))&0xf8)<<7;
+ pMem+=3;
+ *((unsigned short *)(ps+y*256+x*2))=s;
+ }
+ }
+ }
+ else
+ if(iDesktopCol==32)
+ {
+ uint32_t l;
+ for(y=0;y<96;y++)
+ {
+ for(x=0;x<128;x++)
+ {
+ l= *(pMem+0);
+ l|=(*(pMem+1))<<8;
+ l|=(*(pMem+2))<<16;
+ pMem+=3;
+ *((uint32_t *)(ps+y*512+x*4))=l;
+ }
+ }
+ }
+
+ XPimage = XCreateImage(display,myvisual->visual,
+ depth, ZPixmap, 0,
+ (char *)p,
+ 128, 96,
+ depth>16 ? 32 : 16,
+ 0);
+}
+
+void DestroyPic(void)
+{
+ if(XPimage)
+ { /*
+ XPutImage(display,window,hGC, XCimage,
+ 0, 0, 0, 0, iResX, iResY);*/
+ XDestroyImage(XPimage);
+ XPimage=0;
+ }
+}
+
+void DisplayPic(void)
+{
+ XPutImage(display,window,hGC, XPimage,
+ 0, 0, iResX-128, 0,128,96);
+}
+
+void ShowGpuPic(void)
+{
+}
+
+void ShowTextGpuPic(void)
+{
+}
+
+static void hq2x_32_def(uint32_t * dst0, uint32_t * dst1, const uint32_t * src0, const uint32_t * src1, const uint32_t * src2, unsigned count)
+{
+ static unsigned char cache_vert_mask[640];
+ unsigned char cache_horiz_mask = 0;
+
+ unsigned i;
+ unsigned char mask;
+ uint32_t c[9];
+
+ if (src0 == src1) //processing first row
+ memset(cache_vert_mask, 0, count);
+
+ for(i=0;i<count;++i) {
+ c[1] = src0[0];
+ c[4] = src1[0];
+ c[7] = src2[0];
+
+ if (i>0) {
+ c[0] = src0[-1];
+ c[3] = src1[-1];
+ c[6] = src2[-1];
+ } else {
+ c[0] = c[1];
+ c[3] = c[4];
+ c[6] = c[7];
+ }
+
+ if (i<count-1) {
+ c[2] = src0[1];
+ c[5] = src1[1];
+ c[8] = src2[1];
+ } else {
+ c[2] = c[1];
+ c[5] = c[4];
+ c[8] = c[7];
+ }
+
+ mask = 0;
+
+ mask |= interp_32_diff(c[0], c[4]) << 0;
+ mask |= cache_vert_mask[i];
+ mask |= interp_32_diff(c[2], c[4]) << 2;
+ mask |= cache_horiz_mask;
+ cache_horiz_mask = interp_32_diff(c[5], c[4]) << 3;
+ mask |= cache_horiz_mask << 1; // << 3 << 1 == << 4
+ mask |= interp_32_diff(c[6], c[4]) << 5;
+ cache_vert_mask[i] = interp_32_diff(c[7], c[4]) << 1;
+ mask |= cache_vert_mask[i] << 5; // << 1 << 5 == << 6
+ mask |= interp_32_diff(c[8], c[4]) << 7;
+
+
+ switch (mask) {
+#include "hq2x.h"
+ }
+
+
+ src0 += 1;
+ src1 += 1;
+ src2 += 1;
+ dst0 += 2;
+ dst1 += 2;
+ }
+}
+
+void hq2x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height)
+{
+ const int dstPitch = srcPitch<<1;
+
+ int count = height;
+
+ finalw=width*2;
+ finalh=height*2;
+
+ uint32_t *dst0 = (uint32_t *)dstPtr;
+ uint32_t *dst1 = dst0 + (dstPitch >> 2);
+
+ uint32_t *src0 = (uint32_t *)srcPtr;
+ uint32_t *src1 = src0 + (srcPitch >> 2);
+ uint32_t *src2 = src1 + (srcPitch >> 2);
+ hq2x_32_def(dst0, dst1, src0, src0, src1, width);
+
+
+ count -= 2;
+ while(count) {
+ dst0 += dstPitch >> 1; //next 2 lines (dstPitch / 4 char per int * 2)
+ dst1 += dstPitch >> 1;
+ hq2x_32_def(dst0, dst1, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+ dst0 += dstPitch >> 1;
+ dst1 += dstPitch >> 1;
+ hq2x_32_def(dst0, dst1, src0, src1, src1, width);
+}
+
+static void hq3x_32_def(uint32_t* dst0, uint32_t* dst1, uint32_t* dst2, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count)
+{
+ static unsigned char cache_vert_mask[640];
+ unsigned char cache_horiz_mask = 0;
+
+ unsigned i;
+ unsigned char mask;
+ uint32_t c[9];
+
+ if (src0 == src1) //processing first row
+ memset(cache_vert_mask, 0, count);
+
+ for(i=0;i<count;++i) {
+ c[1] = src0[0];
+ c[4] = src1[0];
+ c[7] = src2[0];
+
+ if (i>0) {
+ c[0] = src0[-1];
+ c[3] = src1[-1];
+ c[6] = src2[-1];
+ } else {
+ c[0] = c[1];
+ c[3] = c[4];
+ c[6] = c[7];
+ }
+
+ if (i<count-1) {
+ c[2] = src0[1];
+ c[5] = src1[1];
+ c[8] = src2[1];
+ } else {
+ c[2] = c[1];
+ c[5] = c[4];
+ c[8] = c[7];
+ }
+
+ mask = 0;
+
+ mask |= interp_32_diff(c[0], c[4]) << 0;
+ mask |= cache_vert_mask[i];
+ mask |= interp_32_diff(c[2], c[4]) << 2;
+ mask |= cache_horiz_mask;
+ cache_horiz_mask = interp_32_diff(c[5], c[4]) << 3;
+ mask |= cache_horiz_mask << 1; // << 3 << 1 == << 4
+ mask |= interp_32_diff(c[6], c[4]) << 5;
+ cache_vert_mask[i] = interp_32_diff(c[7], c[4]) << 1;
+ mask |= cache_vert_mask[i] << 5; // << 1 << 5 == << 6
+ mask |= interp_32_diff(c[8], c[4]) << 7;
+
+ switch (mask) {
+#include "hq3x.h"
+ }
+
+ src0 += 1;
+ src1 += 1;
+ src2 += 1;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+ }
+}
+
+void hq3x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height)
+{
+ int count = height;
+
+ int dstPitch = srcPitch*3;
+ int dstRowPixels = dstPitch>>2;
+
+ finalw=width*3;
+ finalh=height*3;
+
+ uint32_t *dst0 = (uint32_t *)dstPtr;
+ uint32_t *dst1 = dst0 + dstRowPixels;
+ uint32_t *dst2 = dst1 + dstRowPixels;
+
+ uint32_t *src0 = (uint32_t *)srcPtr;
+ uint32_t *src1 = src0 + (srcPitch >> 2);
+ uint32_t *src2 = src1 + (srcPitch >> 2);
+ hq3x_32_def(dst0, dst1, dst2, src0, src0, src2, width);
+
+ count -= 2;
+ while(count) {
+ dst0 += dstRowPixels * 3;
+ dst1 += dstRowPixels * 3;
+ dst2 += dstRowPixels * 3;
+
+ hq3x_32_def(dst0, dst1, dst2, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+ dst0 += dstRowPixels * 3;
+ dst1 += dstRowPixels * 3;
+ dst2 += dstRowPixels * 3;
+
+ hq3x_32_def(dst0, dst1, dst2, src0, src1, src1, width);
+
+}
diff --git a/plugins/dfxvideo/draw.h b/plugins/dfxvideo/draw.h
new file mode 100644
index 0000000..2454a1f
--- /dev/null
+++ b/plugins/dfxvideo/draw.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ draw.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _GPU_DRAW_H_
+#define _GPU_DRAW_H_
+
+void DoBufferSwap(void);
+void DoClearScreenBuffer(void);
+void DoClearFrontBuffer(void);
+unsigned long ulInitDisplay(void);
+void CloseDisplay(void);
+void CreatePic(unsigned char * pMem);
+void DestroyPic(void);
+void DisplayPic(void);
+void ShowGpuPic(void);
+void ShowTextGpuPic(void);
+
+typedef struct {
+#define MWM_HINTS_DECORATIONS 2
+ long flags;
+ long functions;
+ long decorations;
+ long input_mode;
+} MotifWmHints;
+
+#ifdef _WINDOWS
+void MoveScanLineArea(HWND hwnd);
+#endif
+
+///////////////////////////////////////////////////////////////////////
+
+#endif // _GPU_DRAW_H_
diff --git a/plugins/dfxvideo/externals.h b/plugins/dfxvideo/externals.h
new file mode 100644
index 0000000..2c29faf
--- /dev/null
+++ b/plugins/dfxvideo/externals.h
@@ -0,0 +1,315 @@
+/***************************************************************************
+ externals.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define INFO_TW 0
+#define INFO_DRAWSTART 1
+#define INFO_DRAWEND 2
+#define INFO_DRAWOFF 3
+
+#define SHADETEXBIT(x) ((x>>24) & 0x1)
+#define SEMITRANSBIT(x) ((x>>25) & 0x1)
+#define PSXRGB(r,g,b) ((g<<10)|(b<<5)|r)
+
+#define DATAREGISTERMODES unsigned short
+
+#define DR_NORMAL 0
+#define DR_VRAMTRANSFER 1
+
+
+#define GPUSTATUS_ODDLINES 0x80000000
+#define GPUSTATUS_DMABITS 0x60000000 // Two bits
+#define GPUSTATUS_READYFORCOMMANDS 0x10000000
+#define GPUSTATUS_READYFORVRAM 0x08000000
+#define GPUSTATUS_IDLE 0x04000000
+#define GPUSTATUS_DISPLAYDISABLED 0x00800000
+#define GPUSTATUS_INTERLACED 0x00400000
+#define GPUSTATUS_RGB24 0x00200000
+#define GPUSTATUS_PAL 0x00100000
+#define GPUSTATUS_DOUBLEHEIGHT 0x00080000
+#define GPUSTATUS_WIDTHBITS 0x00070000 // Three bits
+#define GPUSTATUS_MASKENABLED 0x00001000
+#define GPUSTATUS_MASKDRAWN 0x00000800
+#define GPUSTATUS_DRAWINGALLOWED 0x00000400
+#define GPUSTATUS_DITHER 0x00000200
+
+#define GPUIsBusy (lGPUstatusRet &= ~GPUSTATUS_IDLE)
+#define GPUIsIdle (lGPUstatusRet |= GPUSTATUS_IDLE)
+
+#define GPUIsNotReadyForCommands (lGPUstatusRet &= ~GPUSTATUS_READYFORCOMMANDS)
+#define GPUIsReadyForCommands (lGPUstatusRet |= GPUSTATUS_READYFORCOMMANDS)
+
+#define __X11_C_
+//X11 render
+#define __inline inline
+#define CALLBACK
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#ifndef _MACGL
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+#include <math.h>
+#include <X11/cursorfont.h>
+#include <stdint.h>
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef struct VRAMLOADTTAG
+{
+ short x;
+ short y;
+ short Width;
+ short Height;
+ short RowsRemaining;
+ short ColsRemaining;
+ unsigned short *ImagePtr;
+} VRAMLoad_t;
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef struct PSXPOINTTAG
+{
+ int32_t x;
+ int32_t y;
+} PSXPoint_t;
+
+typedef struct PSXSPOINTTAG
+{
+ short x;
+ short y;
+} PSXSPoint_t;
+
+typedef struct PSXRECTTAG
+{
+ short x0;
+ short x1;
+ short y0;
+ short y1;
+} PSXRect_t;
+
+// linux defines for some windows stuff
+
+#define FALSE 0
+#define TRUE 1
+#define BOOL unsigned short
+#define LOWORD(l) ((unsigned short)(l))
+#define HIWORD(l) ((unsigned short)(((uint32_t)(l) >> 16) & 0xFFFF))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define DWORD uint32_t
+#define __int64 long long int
+
+typedef struct RECTTAG
+{
+ int left;
+ int top;
+ int right;
+ int bottom;
+}RECT;
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef struct TWINTAG
+{
+ PSXRect_t Position;
+} TWin_t;
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef struct PSXDISPLAYTAG
+{
+ PSXPoint_t DisplayModeNew;
+ PSXPoint_t DisplayMode;
+ PSXPoint_t DisplayPosition;
+ PSXPoint_t DisplayEnd;
+
+ int32_t Double;
+ int32_t Height;
+ int32_t PAL;
+ int32_t InterlacedNew;
+ int32_t Interlaced;
+ int32_t RGB24New;
+ int32_t RGB24;
+ PSXSPoint_t DrawOffset;
+ int32_t Disabled;
+ PSXRect_t Range;
+
+} PSXDisplay_t;
+
+/////////////////////////////////////////////////////////////////////////////
+
+// draw.c
+
+#ifndef _IN_DRAW
+
+extern char * pCaptionText;
+
+extern int iResX;
+extern int iResY;
+extern int32_t GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;
+extern int32_t GlobalTextREST,GlobalTextABR,GlobalTextPAGE;
+extern short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;
+extern long lLowerpart;
+extern BOOL bIsFirstFrame;
+extern int iWinSize;
+extern BOOL bCheckMask;
+extern unsigned short sSetMask;
+extern unsigned long lSetMask;
+extern BOOL bDeviceOK;
+extern short g_m1;
+extern short g_m2;
+extern short g_m3;
+extern short DrawSemiTrans;
+extern int iUseGammaVal;
+extern int iMaintainAspect;
+extern int iDesktopCol;
+extern int iUseNoStretchBlt;
+extern int iShowFPS;
+extern int iFastFwd;
+extern int iDebugMode;
+extern int iFVDisplay;
+extern PSXPoint_t ptCursorPoint[];
+extern unsigned short usCursorActive;
+
+
+#endif
+
+// prim.c
+
+#ifndef _IN_PRIMDRAW
+
+extern BOOL bUsingTWin;
+extern TWin_t TWin;
+//extern unsigned long clutid;
+extern void (*primTableJ[256])(unsigned char *);
+extern void (*primTableSkip[256])(unsigned char *);
+extern unsigned short usMirror;
+extern int iDither;
+extern uint32_t dwCfgFixes;
+extern uint32_t dwActFixes;
+extern uint32_t dwEmuFixes;
+extern int iUseFixes;
+extern int iUseDither;
+extern BOOL bDoVSyncUpdate;
+extern int32_t drawX;
+extern int32_t drawY;
+extern int32_t drawW;
+extern int32_t drawH;
+
+#endif
+
+// gpu.c
+
+#ifndef _IN_GPU
+
+extern VRAMLoad_t VRAMWrite;
+extern VRAMLoad_t VRAMRead;
+extern DATAREGISTERMODES DataWriteMode;
+extern DATAREGISTERMODES DataReadMode;
+extern int iColDepth;
+extern int iWindowMode;
+extern char szDispBuf[];
+extern char szMenuBuf[];
+extern char szDebugText[];
+extern short sDispWidths[];
+extern BOOL bDebugText;
+//extern unsigned int iMaxDMACommandCounter;
+//extern unsigned long dwDMAChainStop;
+extern PSXDisplay_t PSXDisplay;
+extern PSXDisplay_t PreviousPSXDisplay;
+extern BOOL bSkipNextFrame;
+extern long lGPUstatusRet;
+//extern long drawingLines;
+extern unsigned char * psxVSecure;
+extern unsigned char * psxVub;
+extern signed char * psxVsb;
+extern unsigned short * psxVuw;
+extern signed short * psxVsw;
+extern uint32_t * psxVul;
+extern int32_t * psxVsl;
+extern unsigned short * psxVuw_eom;
+extern BOOL bChangeWinMode;
+extern long lSelectedSlot;
+extern BOOL bInitCap;
+extern DWORD dwLaceCnt;
+extern uint32_t lGPUInfoVals[];
+extern uint32_t ulStatusControl[];
+
+#endif
+
+// menu.c
+
+#ifndef _IN_MENU
+
+extern uint32_t dwCoreFlags;
+
+#endif
+
+// key.c
+
+#ifndef _IN_KEY
+
+extern unsigned long ulKeybits;
+
+#endif
+
+// fps.c
+
+#ifndef _IN_FPS
+
+extern int UseFrameLimit;
+extern int UseFrameSkip;
+extern float fFrameRate;
+extern int iFrameLimit;
+extern float fFrameRateHz;
+extern float fps_skip;
+extern float fps_cur;
+
+#endif
+
+// key.c
+
+#ifndef _IN_KEY
+
+#endif
+
+// cfg.c
+
+#ifndef _IN_CFG
+
+extern char * pConfigFile;
+
+#endif
+
+// zn.c
+
+#ifndef _IN_ZN
+
+extern uint32_t dwGPUVersion;
+extern int iGPUHeight;
+extern int iGPUHeightMask;
+extern int GlobalTextIL;
+extern int iTileCheat;
+
+#endif
+
+
diff --git a/plugins/dfxvideo/fps.c b/plugins/dfxvideo/fps.c
new file mode 100644
index 0000000..2edcd30
--- /dev/null
+++ b/plugins/dfxvideo/fps.c
@@ -0,0 +1,357 @@
+/***************************************************************************
+ fps.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_FPS
+
+#include <unistd.h>
+
+#include "externals.h"
+#include "fps.h"
+#include "gpu.h"
+
+// FPS stuff
+float fFrameRateHz=0;
+DWORD dwFrameRateTicks=16;
+float fFrameRate;
+int iFrameLimit;
+int UseFrameLimit=0;
+int UseFrameSkip=0;
+
+// FPS skipping / limit
+BOOL bInitCap = TRUE;
+float fps_skip = 0;
+float fps_cur = 0;
+
+#define MAXLACE 16
+
+void CheckFrameRate(void)
+{
+ if(UseFrameSkip) // skipping mode?
+ {
+ if(!(dwActFixes&0x80)) // not old skipping mode?
+ {
+ dwLaceCnt++; // -> store cnt of vsync between frames
+ if(dwLaceCnt>=MAXLACE && UseFrameLimit) // -> if there are many laces without screen toggling,
+ { // do std frame limitation
+ if(dwLaceCnt==MAXLACE) bInitCap=TRUE;
+ FrameCap();
+ }
+ }
+ else if(UseFrameLimit) FrameCap();
+ calcfps(); // -> calc fps display in skipping mode
+ }
+ else // non-skipping mode:
+ {
+ if(UseFrameLimit) FrameCap(); // -> do it
+ if(ulKeybits&KEY_SHOWFPS) calcfps(); // -> and calc fps display
+ }
+}
+
+#define TIMEBASE 100000
+
+unsigned long timeGetTime()
+{
+ struct timeval tv;
+ gettimeofday(&tv, 0); // well, maybe there are better ways
+ return tv.tv_sec * 100000 + tv.tv_usec/10; // to do that, but at least it works
+}
+
+void FrameCap (void)
+{
+ static unsigned long curticks, lastticks, _ticks_since_last_update;
+ static unsigned int TicksToWait = 0;
+ int overslept=0, tickstogo=0;
+ BOOL Waiting = TRUE;
+
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+
+ if((_ticks_since_last_update > TicksToWait) ||
+ (curticks <lastticks))
+ {
+ lastticks = curticks;
+ overslept = _ticks_since_last_update - TicksToWait;
+ if((_ticks_since_last_update-TicksToWait) > dwFrameRateTicks)
+ TicksToWait=0;
+ else
+ TicksToWait=dwFrameRateTicks - overslept;
+ }
+ else
+ {
+ while (Waiting)
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+ tickstogo = TicksToWait - _ticks_since_last_update;
+ if ((_ticks_since_last_update > TicksToWait) ||
+ (curticks < lastticks) || tickstogo < overslept)
+ {
+ Waiting = FALSE;
+ lastticks = curticks;
+ overslept = _ticks_since_last_update - TicksToWait;
+ TicksToWait = dwFrameRateTicks - overslept;
+ return;
+ }
+ if (tickstogo >= 200 && !(dwActFixes&16))
+ usleep(tickstogo*10 - 200);
+ }
+ }
+ }
+}
+
+#define MAXSKIP 120
+
+void FrameSkip(void)
+{
+ static int iNumSkips=0,iAdditionalSkip=0; // number of additional frames to skip
+ static DWORD dwLastLace=0; // helper var for frame limitation
+ static DWORD curticks, lastticks, _ticks_since_last_update;
+ int tickstogo=0;
+ static int overslept=0;
+
+ if(!dwLaceCnt) return; // important: if no updatelace happened, we ignore it completely
+
+ if(iNumSkips) // we are in skipping mode?
+ {
+ dwLastLace+=dwLaceCnt; // -> calc frame limit helper (number of laces)
+ bSkipNextFrame = TRUE; // -> we skip next frame
+ iNumSkips--; // -> ok, one done
+ }
+ else // ok, no additional skipping has to be done...
+ { // we check now, if some limitation is needed, or a new skipping has to get started
+ DWORD dwWaitTime;
+
+ if(bInitCap || bSkipNextFrame) // first time or we skipped before?
+ {
+ if(UseFrameLimit && !bInitCap) // frame limit wanted and not first time called?
+ {
+ DWORD dwT=_ticks_since_last_update; // -> that's the time of the last drawn frame
+ dwLastLace+=dwLaceCnt; // -> and that's the number of updatelace since the start of the last drawn frame
+
+ curticks = timeGetTime(); // -> now we calc the time of the last drawn frame + the time we spent skipping
+ _ticks_since_last_update= dwT+curticks - lastticks;
+
+ dwWaitTime=dwLastLace*dwFrameRateTicks; // -> and now we calc the time the real psx would have needed
+
+ if(_ticks_since_last_update<dwWaitTime) // -> we were too fast?
+ {
+ if((dwWaitTime-_ticks_since_last_update)> // -> some more security, to prevent
+ (60*dwFrameRateTicks)) // wrong waiting times
+ _ticks_since_last_update=dwWaitTime;
+
+ while(_ticks_since_last_update<dwWaitTime) // -> loop until we have reached the real psx time
+ { // (that's the additional limitation, yup)
+ curticks = timeGetTime();
+ _ticks_since_last_update = dwT+curticks - lastticks;
+ }
+ }
+ else // we were still too slow ?!!?
+ {
+ if(iAdditionalSkip<MAXSKIP) // -> well, somewhen we really have to stop skipping on very slow systems
+ {
+ iAdditionalSkip++; // -> inc our watchdog var
+ dwLaceCnt=0; // -> reset lace count
+ lastticks = timeGetTime();
+ return; // -> done, we will skip next frame to get more speed
+ }
+ }
+ }
+
+ bInitCap=FALSE; // -> ok, we have inited the frameskip func
+ iAdditionalSkip=0; // -> init additional skip
+ bSkipNextFrame=FALSE; // -> we don't skip the next frame
+ lastticks = timeGetTime(); // -> we store the start time of the next frame
+ dwLaceCnt=0; // -> and we start to count the laces
+ dwLastLace=0;
+ _ticks_since_last_update=0;
+ return; // -> done, the next frame will get drawn
+ }
+
+ bSkipNextFrame=FALSE; // init the frame skip signal to 'no skipping' first
+
+ curticks = timeGetTime(); // get the current time (we are now at the end of one drawn frame)
+ _ticks_since_last_update = curticks - lastticks;
+
+ dwLastLace=dwLaceCnt; // store curr count (frame limitation helper)
+ dwWaitTime=dwLaceCnt*dwFrameRateTicks; // calc the 'real psx lace time'
+ if (dwWaitTime >= overslept)
+ dwWaitTime-=overslept;
+
+ if(_ticks_since_last_update>dwWaitTime) // hey, we needed way too long for that frame...
+ {
+ if(UseFrameLimit) // if limitation, we skip just next frame,
+ { // and decide after, if we need to do more
+ iNumSkips=0;
+ }
+ else
+ {
+ iNumSkips=_ticks_since_last_update/dwWaitTime; // -> calc number of frames to skip to catch up
+ iNumSkips--; // -> since we already skip next frame, one down
+ if(iNumSkips>MAXSKIP) iNumSkips=MAXSKIP; // -> well, somewhere we have to draw a line
+ }
+ bSkipNextFrame = TRUE; // -> signal for skipping the next frame
+ }
+ else // we were faster than real psx? fine :)
+ if(UseFrameLimit) // frame limit used? so we wait til the 'real psx time' has been reached
+ {
+ if(dwLaceCnt>MAXLACE) // -> security check
+ _ticks_since_last_update=dwWaitTime;
+
+ while(_ticks_since_last_update<dwWaitTime) // -> just do a waiting loop...
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+
+ tickstogo = dwWaitTime - _ticks_since_last_update;
+ if (tickstogo-overslept >= 200 && !(dwActFixes&16))
+ usleep(tickstogo*10 - 200);
+ }
+ }
+ overslept = _ticks_since_last_update - dwWaitTime;
+ if (overslept < 0)
+ overslept = 0;
+ lastticks = timeGetTime(); // ok, start time of the next frame
+ }
+
+ dwLaceCnt=0; // init lace counter
+}
+
+void calcfps(void)
+{
+ static unsigned long curticks,_ticks_since_last_update,lastticks;
+ static long fps_cnt = 0;
+ static unsigned long fps_tck = 1;
+ static long fpsskip_cnt = 0;
+ static unsigned long fpsskip_tck = 1;
+
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update=curticks-lastticks;
+
+ if(UseFrameSkip && !UseFrameLimit && _ticks_since_last_update)
+ fps_skip=min(fps_skip,((float)TIMEBASE/(float)_ticks_since_last_update+1.0f));
+
+ lastticks = curticks;
+ }
+
+ if(UseFrameSkip && UseFrameLimit)
+ {
+ fpsskip_tck += _ticks_since_last_update;
+
+ if(++fpsskip_cnt==2)
+ {
+ fps_skip = (float)2000/(float)fpsskip_tck;
+ fps_skip +=6.0f;
+ fpsskip_cnt = 0;
+ fpsskip_tck = 1;
+ }
+ }
+
+ fps_tck += _ticks_since_last_update;
+
+ if(++fps_cnt==20)
+ {
+ fps_cur = (float)(TIMEBASE*20)/(float)fps_tck;
+
+ fps_cnt = 0;
+ fps_tck = 1;
+
+ //if(UseFrameLimit && fps_cur>fFrameRateHz) // optical adjust ;) avoids flickering fps display
+ //fps_cur=fFrameRateHz;
+ }
+
+}
+
+void PCFrameCap (void)
+{
+ static unsigned long curticks, lastticks, _ticks_since_last_update;
+ static unsigned long TicksToWait = 0;
+ BOOL Waiting = TRUE;
+
+ while (Waiting)
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+ if ((_ticks_since_last_update > TicksToWait) ||
+ (curticks < lastticks))
+ {
+ Waiting = FALSE;
+ lastticks = curticks;
+ TicksToWait = (TIMEBASE/ (unsigned long)fFrameRateHz);
+ }
+ }
+}
+
+void PCcalcfps(void)
+{
+ static unsigned long curticks,_ticks_since_last_update,lastticks;
+ static long fps_cnt = 0;
+ static float fps_acc = 0;
+ float CurrentFPS=0;
+
+ curticks = timeGetTime();
+ _ticks_since_last_update=curticks-lastticks;
+ if(_ticks_since_last_update)
+ CurrentFPS=(float)TIMEBASE/(float)_ticks_since_last_update;
+ else CurrentFPS = 0;
+ lastticks = curticks;
+
+ fps_acc += CurrentFPS;
+
+ if(++fps_cnt==10)
+ {
+ fps_cur = fps_acc / 10;
+ fps_acc = 0;
+ fps_cnt = 0;
+ }
+
+ fps_skip=CurrentFPS+1.0f;
+}
+
+void SetAutoFrameCap(void)
+{
+ if(iFrameLimit==1)
+ {
+ fFrameRateHz = fFrameRate;
+ dwFrameRateTicks=(TIMEBASE*100 / (unsigned long)(fFrameRateHz*100));
+ return;
+ }
+
+ if(dwActFixes&32)
+ {
+ if (PSXDisplay.Interlaced)
+ fFrameRateHz = PSXDisplay.PAL?50.0f:60.0f;
+ else fFrameRateHz = PSXDisplay.PAL?25.0f:30.0f;
+ }
+ else
+ {
+ fFrameRateHz = PSXDisplay.PAL?50.0f:59.94f;
+ dwFrameRateTicks=(TIMEBASE*100 / (unsigned long)(fFrameRateHz*100));
+ }
+}
+
+void SetFPSHandler(void)
+{
+}
+
+void InitFPS(void)
+{
+ if(!fFrameRate) fFrameRate=200.0f;
+ if(fFrameRateHz==0) fFrameRateHz=fFrameRate; // set user framerate
+ dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz);
+}
diff --git a/plugins/dfxvideo/fps.h b/plugins/dfxvideo/fps.h
new file mode 100644
index 0000000..ff7e72b
--- /dev/null
+++ b/plugins/dfxvideo/fps.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ fps.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _FPS_INTERNALS_H
+#define _FPS_INTERNALS_H
+
+void FrameCap(void);
+void FrameSkip(void);
+void calcfps(void);
+void PCFrameCap (void);
+void PCcalcfps(void);
+void SetAutoFrameCap(void);
+void SetFPSHandler(void);
+void InitFPS(void);
+void CheckFrameRate(void);
+
+#endif // _FPS_INTERNALS_H
diff --git a/plugins/dfxvideo/gpu.c b/plugins/dfxvideo/gpu.c
new file mode 100644
index 0000000..7dd359f
--- /dev/null
+++ b/plugins/dfxvideo/gpu.c
@@ -0,0 +1,1952 @@
+/***************************************************************************
+ gpu.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _MACGL
+#include "config.h"
+#endif
+
+#define _IN_GPU
+
+#include "externals.h"
+#include "gpu.h"
+#include "draw.h"
+#include "cfg.h"
+#include "prim.h"
+#include "stdint.h"
+#include "psemu_plugin_defs.h"
+#include "menu.h"
+#include "key.h"
+#include "fps.h"
+#include "swap.h"
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#include <locale.h>
+#define _(x) gettext(x)
+#define N_(x) (x)
+#else
+#define _(x) (x)
+#define N_(x) (x)
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// PPDK developer must change libraryName field and can change revision and build
+////////////////////////////////////////////////////////////////////////
+
+const unsigned char version = 1; // do not touch - library for PSEmu 1.x
+const unsigned char revision = 1;
+const unsigned char build = 17; // increase that with each version
+
+#ifdef _MACGL
+static char *libraryName = N_("SoftGL Driver");
+static char *libraryInfo = N_("P.E.Op.S. SoftGL Driver V1.17\nCoded by Pete Bernert and the P.E.Op.S. team\n");
+#else
+static char *libraryName = N_("XVideo Driver");
+static char *libraryInfo = N_("P.E.Op.S. Xvideo Driver V1.17\nCoded by Pete Bernert and the P.E.Op.S. team\n");
+#endif
+
+static char *PluginAuthor = N_("Pete Bernert and the P.E.Op.S. team");
+
+////////////////////////////////////////////////////////////////////////
+// memory image of the PSX vram
+////////////////////////////////////////////////////////////////////////
+
+unsigned char *psxVSecure;
+unsigned char *psxVub;
+signed char *psxVsb;
+unsigned short *psxVuw;
+unsigned short *psxVuw_eom;
+signed short *psxVsw;
+uint32_t *psxVul;
+int32_t *psxVsl;
+
+////////////////////////////////////////////////////////////////////////
+// GPU globals
+////////////////////////////////////////////////////////////////////////
+
+static long lGPUdataRet;
+long lGPUstatusRet;
+char szDispBuf[64];
+char szMenuBuf[36];
+char szDebugText[512];
+uint32_t ulStatusControl[256];
+
+static uint32_t gpuDataM[256];
+static unsigned char gpuCommand = 0;
+static long gpuDataC = 0;
+static long gpuDataP = 0;
+
+VRAMLoad_t VRAMWrite;
+VRAMLoad_t VRAMRead;
+DATAREGISTERMODES DataWriteMode;
+DATAREGISTERMODES DataReadMode;
+
+BOOL bSkipNextFrame = FALSE;
+DWORD dwLaceCnt=0;
+int iColDepth;
+int iWindowMode;
+short sDispWidths[8] = {256,320,512,640,368,384,512,640};
+PSXDisplay_t PSXDisplay;
+PSXDisplay_t PreviousPSXDisplay;
+long lSelectedSlot=0;
+BOOL bChangeWinMode=FALSE;
+BOOL bDoLazyUpdate=FALSE;
+uint32_t lGPUInfoVals[16];
+static int iFakePrimBusy=0;
+
+////////////////////////////////////////////////////////////////////////
+// some misc external display funcs
+////////////////////////////////////////////////////////////////////////
+
+#include <time.h>
+time_t tStart;
+
+void CALLBACK GPUdisplayText(char * pText) // some debug func
+{
+ if(!pText) {szDebugText[0]=0;return;}
+ if(strlen(pText)>511) return;
+ time(&tStart);
+ strcpy(szDebugText,pText);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUdisplayFlags(unsigned long dwFlags) // some info func
+{
+ dwCoreFlags=dwFlags;
+ BuildDispMenu(0);
+}
+
+////////////////////////////////////////////////////////////////////////
+// stuff to make this a true PDK module
+////////////////////////////////////////////////////////////////////////
+
+char * CALLBACK PSEgetLibName(void)
+{
+ return _(libraryName);
+}
+
+unsigned long CALLBACK PSEgetLibType(void)
+{
+ return PSE_LT_GPU;
+}
+
+unsigned long CALLBACK PSEgetLibVersion(void)
+{
+ return version<<16|revision<<8|build;
+}
+
+char * GPUgetLibInfos(void)
+{
+ return _(libraryInfo);
+}
+
+////////////////////////////////////////////////////////////////////////
+// Snapshot func
+////////////////////////////////////////////////////////////////////////
+
+static char * pGetConfigInfos(int iCfg)
+{
+ char szO[2][4]={"off","on "};
+ char szTxt[256];
+ char * pB = (char *)malloc(32767);
+
+ if (!pB) return NULL;
+ *pB = 0;
+ //----------------------------------------------------//
+ sprintf(szTxt,"Plugin: %s %d.%d.%d\r\n",libraryName,version,revision,build);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"Author: %s\r\n\r\n",PluginAuthor);
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+ if(iCfg && iWindowMode)
+ sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize));
+ else
+ sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY);
+ strcat(pB,szTxt);
+ if(iWindowMode && iCfg)
+ strcpy(szTxt,"Window mode\r\n");
+ else
+ if(iWindowMode)
+ sprintf(szTxt,"Window mode - [%d Bit]\r\n",iDesktopCol);
+ else
+ sprintf(szTxt,"Fullscreen - [%d Bit]\r\n",iColDepth);
+ strcat(pB,szTxt);
+
+ sprintf(szTxt,"Stretch mode: %d\r\n",iUseNoStretchBlt);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"Dither mode: %d\r\n\r\n",iUseDither);
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+ sprintf(szTxt,"Framerate:\r\n- FPS limit: %s\r\n",szO[UseFrameLimit]);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Frame skipping: %s",szO[UseFrameSkip]);
+ strcat(pB,szTxt);
+ if(iFastFwd) strcat(pB," (fast forward)");
+ strcat(pB,"\r\n");
+ if(iFrameLimit==2)
+ strcpy(szTxt,"- FPS limit: Auto\r\n\r\n");
+ else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate);
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+#ifndef _MACGL
+ strcpy(szTxt,"Misc:\r\n- MaintainAspect: ");
+ if(iMaintainAspect == 0) strcat(szTxt,"disabled");
+ else
+ if(iMaintainAspect == 1) strcat(szTxt,"enabled");
+ strcat(szTxt,"\r\n");
+ strcat(pB,szTxt);
+#endif
+ sprintf(szTxt,"- Game fixes: %s [%08x]\r\n",szO[iUseFixes],dwCfgFixes);
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+ return pB;
+}
+
+static void DoTextSnapShot(int iNum)
+{
+ FILE *txtfile;
+ char szTxt[256];
+ char *pB;
+
+ sprintf(szTxt,"%s/pcsx%04d.txt",getenv("HOME"),iNum);
+
+ if ((txtfile = fopen(szTxt, "wb")) == NULL)
+ return;
+
+ pB = pGetConfigInfos(0);
+ if (pB)
+ {
+ fwrite(pB, strlen(pB), 1, txtfile);
+ free(pB);
+ }
+ fclose(txtfile);
+}
+
+void CALLBACK GPUmakeSnapshot(void)
+{
+ FILE *bmpfile;
+ char filename[256];
+ unsigned char header[0x36];
+ long size, height;
+ unsigned char line[1024 * 3];
+ short i, j;
+ unsigned char empty[2] = {0,0};
+ unsigned short color;
+ unsigned long snapshotnr = 0;
+ unsigned char *pD;
+
+ height = PreviousPSXDisplay.DisplayMode.y;
+
+ size = height * PreviousPSXDisplay.Range.x1 * 3 + 0x38;
+
+ // fill in proper values for BMP
+
+ // hardcoded BMP header
+ memset(header, 0, 0x36);
+ header[0] = 'B';
+ header[1] = 'M';
+ header[2] = size & 0xff;
+ header[3] = (size >> 8) & 0xff;
+ header[4] = (size >> 16) & 0xff;
+ header[5] = (size >> 24) & 0xff;
+ header[0x0a] = 0x36;
+ header[0x0e] = 0x28;
+ header[0x12] = PreviousPSXDisplay.Range.x1 % 256;
+ header[0x13] = PreviousPSXDisplay.Range.x1 / 256;
+ header[0x16] = height % 256;
+ header[0x17] = height / 256;
+ header[0x1a] = 0x01;
+ header[0x1c] = 0x18;
+ header[0x26] = 0x12;
+ header[0x27] = 0x0B;
+ header[0x2A] = 0x12;
+ header[0x2B] = 0x0B;
+
+ // increment snapshot value & try to get filename
+ do
+ {
+ snapshotnr++;
+ sprintf(filename, "%s/pcsx%04ld.bmp", getenv("HOME"), snapshotnr);
+
+ bmpfile = fopen(filename,"rb");
+ if (bmpfile == NULL)
+ break;
+
+ fclose(bmpfile);
+ }
+ while(TRUE);
+
+ // try opening new snapshot file
+ if ((bmpfile = fopen(filename,"wb")) == NULL)
+ return;
+
+ fwrite(header, 0x36, 1, bmpfile);
+ for (i = height + PSXDisplay.DisplayPosition.y - 1; i >= PSXDisplay.DisplayPosition.y; i--)
+ {
+ pD = (unsigned char *)&psxVuw[i * 1024 + PSXDisplay.DisplayPosition.x];
+ for (j = 0; j < PreviousPSXDisplay.Range.x1; j++)
+ {
+ if (PSXDisplay.RGB24)
+ {
+ uint32_t lu = *(uint32_t *)pD;
+ line[j * 3 + 2] = RED(lu);
+ line[j * 3 + 1] = GREEN(lu);
+ line[j * 3 + 0] = BLUE(lu);
+ pD += 3;
+ }
+ else
+ {
+ color = GETLE16(pD);
+ line[j * 3 + 2] = (color << 3) & 0xf1;
+ line[j * 3 + 1] = (color >> 2) & 0xf1;
+ line[j * 3 + 0] = (color >> 7) & 0xf1;
+ pD += 2;
+ }
+ }
+ fwrite(line, PreviousPSXDisplay.Range.x1 * 3, 1, bmpfile);
+ }
+ fwrite(empty, 0x2, 1, bmpfile);
+ fclose(bmpfile);
+
+ DoTextSnapShot(snapshotnr);
+}
+
+////////////////////////////////////////////////////////////////////////
+// INIT, will be called after lib load... well, just do some var init...
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUinit() // GPU INIT
+{
+ memset(ulStatusControl,0,256*sizeof(uint32_t)); // init save state scontrol field
+
+ szDebugText[0] = 0; // init debug text buffer
+
+ psxVSecure = (unsigned char *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security
+ if (!psxVSecure)
+ return -1;
+
+ //!!! ATTENTION !!!
+ psxVub=psxVSecure + 512 * 1024; // security offset into double sized psx vram!
+
+ psxVsb=(signed char *)psxVub; // different ways of accessing PSX VRAM
+ psxVsw=(signed short *)psxVub;
+ psxVsl=(int32_t *)psxVub;
+ psxVuw=(unsigned short *)psxVub;
+ psxVul=(uint32_t *)psxVub;
+
+ psxVuw_eom=psxVuw+1024*iGPUHeight; // pre-calc of end of vram
+
+ memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024));
+ memset(lGPUInfoVals,0x00,16*sizeof(uint32_t));
+
+ SetFPSHandler();
+
+ PSXDisplay.RGB24 = FALSE; // init some stuff
+ PSXDisplay.Interlaced = FALSE;
+ PSXDisplay.DrawOffset.x = 0;
+ PSXDisplay.DrawOffset.y = 0;
+ PSXDisplay.DisplayMode.x= 320;
+ PSXDisplay.DisplayMode.y= 240;
+ PreviousPSXDisplay.DisplayMode.x= 320;
+ PreviousPSXDisplay.DisplayMode.y= 240;
+ PSXDisplay.Disabled = FALSE;
+ PreviousPSXDisplay.Range.x0 =0;
+ PreviousPSXDisplay.Range.y0 =0;
+ PSXDisplay.Range.x0=0;
+ PSXDisplay.Range.x1=0;
+ PreviousPSXDisplay.DisplayModeNew.y=0;
+ PSXDisplay.Double = 1;
+ lGPUdataRet = 0x400;
+
+ DataWriteMode = DR_NORMAL;
+
+ // Reset transfer values, to prevent mis-transfer of data
+ memset(&VRAMWrite, 0, sizeof(VRAMLoad_t));
+ memset(&VRAMRead, 0, sizeof(VRAMLoad_t));
+
+ // device initialised already !
+ lGPUstatusRet = 0x14802000;
+ GPUIsIdle;
+ GPUIsReadyForCommands;
+ bDoVSyncUpdate = TRUE;
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Here starts all...
+////////////////////////////////////////////////////////////////////////
+
+
+long GPUopen(unsigned long * disp,char * CapText,char * CfgFile)
+{
+ unsigned long d;
+
+ pCaptionText=CapText;
+
+
+ ReadConfig(); // read registry
+
+ InitFPS();
+
+ bIsFirstFrame = TRUE; // we have to init later
+ bDoVSyncUpdate = TRUE;
+
+ d=ulInitDisplay(); // setup x
+
+ if(disp)
+ *disp=d; // wanna x pointer? ok
+
+ if(d) return 0;
+ return -1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// time to leave...
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUclose() // GPU CLOSE
+{
+
+ ReleaseKeyHandler(); // de-subclass window
+
+ CloseDisplay(); // shutdown direct draw
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// I shot the sheriff
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUshutdown() // GPU SHUTDOWN
+{
+ free(psxVSecure);
+
+ return 0; // nothinh to do
+}
+
+////////////////////////////////////////////////////////////////////////
+// Update display (swap buffers)
+////////////////////////////////////////////////////////////////////////
+
+void updateDisplay(void) // UPDATE DISPLAY
+{
+ if(PSXDisplay.Disabled) // disable?
+ {
+ DoClearFrontBuffer(); // -> clear frontbuffer
+ return; // -> and bye
+ }
+
+ if(dwActFixes&32) // pc fps calculation fix
+ {
+ if(UseFrameLimit) PCFrameCap(); // -> brake
+ if(UseFrameSkip || ulKeybits&KEY_SHOWFPS)
+ PCcalcfps();
+ }
+
+ if(ulKeybits&KEY_SHOWFPS) // make fps display buf
+ {
+ sprintf(szDispBuf,"FPS %06.1f",fps_cur);
+ }
+
+ if(iFastFwd) // fastfwd ?
+ {
+ static int fpscount; UseFrameSkip=1;
+
+ if(!bSkipNextFrame) DoBufferSwap(); // -> to skip or not to skip
+ if(fpscount%6) // -> skip 6/7 frames
+ bSkipNextFrame = TRUE;
+ else bSkipNextFrame = FALSE;
+ fpscount++;
+ if(fpscount >= (int)fFrameRateHz) fpscount = 0;
+ return;
+ }
+
+ if(UseFrameSkip) // skip ?
+ {
+ if(!bSkipNextFrame) DoBufferSwap(); // -> to skip or not to skip
+ if(dwActFixes&0xa0) // -> pc fps calculation fix/old skipping fix
+ {
+ if((fps_skip < fFrameRateHz) && !(bSkipNextFrame)) // -> skip max one in a row
+ {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}
+ else bSkipNextFrame = FALSE;
+ }
+ else FrameSkip();
+ }
+ else // no skip ?
+ {
+ DoBufferSwap(); // -> swap
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// roughly emulated screen centering bits... not complete !!!
+////////////////////////////////////////////////////////////////////////
+
+void ChangeDispOffsetsX(void) // X CENTER
+{
+ long lx,l;
+
+ if(!PSXDisplay.Range.x1) return;
+
+ l=PreviousPSXDisplay.DisplayMode.x;
+
+ l*=(long)PSXDisplay.Range.x1;
+ l/=2560;lx=l;l&=0xfffffff8;
+
+ if(l==PreviousPSXDisplay.Range.y1) return; // abusing range.y1 for
+ PreviousPSXDisplay.Range.y1=(short)l; // storing last x range and test
+
+ if(lx>=PreviousPSXDisplay.DisplayMode.x)
+ {
+ PreviousPSXDisplay.Range.x1=
+ (short)PreviousPSXDisplay.DisplayMode.x;
+ PreviousPSXDisplay.Range.x0=0;
+ }
+ else
+ {
+ PreviousPSXDisplay.Range.x1=(short)l;
+
+ PreviousPSXDisplay.Range.x0=
+ (PSXDisplay.Range.x0-500)/8;
+
+ if(PreviousPSXDisplay.Range.x0<0)
+ PreviousPSXDisplay.Range.x0=0;
+
+ if((PreviousPSXDisplay.Range.x0+lx)>
+ PreviousPSXDisplay.DisplayMode.x)
+ {
+ PreviousPSXDisplay.Range.x0=
+ (short)(PreviousPSXDisplay.DisplayMode.x-lx);
+ PreviousPSXDisplay.Range.x0+=2; //???
+
+ PreviousPSXDisplay.Range.x1+=(short)(lx-l);
+
+ PreviousPSXDisplay.Range.x1-=2; // makes linux stretching easier
+
+ }
+
+
+ // some linux alignment security
+ PreviousPSXDisplay.Range.x0=PreviousPSXDisplay.Range.x0>>1;
+ PreviousPSXDisplay.Range.x0=PreviousPSXDisplay.Range.x0<<1;
+ PreviousPSXDisplay.Range.x1=PreviousPSXDisplay.Range.x1>>1;
+ PreviousPSXDisplay.Range.x1=PreviousPSXDisplay.Range.x1<<1;
+
+
+ DoClearScreenBuffer();
+ }
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void ChangeDispOffsetsY(void) // Y CENTER
+{
+ int iT,iO=PreviousPSXDisplay.Range.y0;
+ int iOldYOffset=PreviousPSXDisplay.DisplayModeNew.y;
+
+// new
+
+ if((PreviousPSXDisplay.DisplayModeNew.x+PSXDisplay.DisplayModeNew.y)>iGPUHeight)
+ {
+ int dy1=iGPUHeight-PreviousPSXDisplay.DisplayModeNew.x;
+ int dy2=(PreviousPSXDisplay.DisplayModeNew.x+PSXDisplay.DisplayModeNew.y)-iGPUHeight;
+
+ if(dy1>=dy2)
+ {
+ PreviousPSXDisplay.DisplayModeNew.y=-dy2;
+ }
+ else
+ {
+ PSXDisplay.DisplayPosition.y=0;
+ PreviousPSXDisplay.DisplayModeNew.y=-dy1;
+ }
+ }
+ else PreviousPSXDisplay.DisplayModeNew.y=0;
+
+// eon
+
+ if(PreviousPSXDisplay.DisplayModeNew.y!=iOldYOffset) // if old offset!=new offset: recalc height
+ {
+ PSXDisplay.Height = PSXDisplay.Range.y1 -
+ PSXDisplay.Range.y0 +
+ PreviousPSXDisplay.DisplayModeNew.y;
+ PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;
+ }
+
+//
+
+ if(PSXDisplay.PAL) iT=48; else iT=28;
+
+ if(PSXDisplay.Range.y0>=iT)
+ {
+ PreviousPSXDisplay.Range.y0=
+ (short)((PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double);
+ if(PreviousPSXDisplay.Range.y0<0)
+ PreviousPSXDisplay.Range.y0=0;
+ PSXDisplay.DisplayModeNew.y+=
+ PreviousPSXDisplay.Range.y0;
+ }
+ else
+ PreviousPSXDisplay.Range.y0=0;
+
+ if(iO!=PreviousPSXDisplay.Range.y0)
+ {
+ DoClearScreenBuffer();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// check if update needed
+////////////////////////////////////////////////////////////////////////
+
+void updateDisplayIfChanged(void) // UPDATE DISPLAY IF CHANGED
+{
+ if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) &&
+ (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))
+ {
+ if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) &&
+ (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) return;
+ }
+
+ PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos
+
+ PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;
+ PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;
+ PreviousPSXDisplay.DisplayMode.x= // previous will hold
+ min(640,PSXDisplay.DisplayMode.x); // max 640x512... that's
+ PreviousPSXDisplay.DisplayMode.y= // the size of my
+ min(512,PSXDisplay.DisplayMode.y); // back buffer surface
+ PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;
+
+ PSXDisplay.DisplayEnd.x= // calc end of display
+ PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
+ PSXDisplay.DisplayEnd.y=
+ PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
+ PreviousPSXDisplay.DisplayEnd.x=
+ PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
+ PreviousPSXDisplay.DisplayEnd.y=
+ PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
+
+ ChangeDispOffsetsX();
+
+ if(iFrameLimit==2) SetAutoFrameCap(); // -> set it
+
+ if(UseFrameSkip) updateDisplay(); // stupid stuff when frame skipping enabled
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifndef _MACGL
+
+#include "draw.h"
+
+void ChangeWindowMode(void) // TOGGLE FULLSCREEN - WINDOW
+{
+ extern Display *display;
+ extern Window window;
+ extern int root_window_id;
+ Screen *screen;
+ XSizeHints hints;
+ MotifWmHints mwmhints;
+ Atom mwmatom;
+
+ screen=DefaultScreenOfDisplay(display);
+ iWindowMode=!iWindowMode;
+
+ if(!iWindowMode) // fullscreen
+ {
+ mwmhints.flags=MWM_HINTS_DECORATIONS;
+ mwmhints.functions=0;
+ mwmhints.decorations=0;
+ mwmhints.input_mode=0;
+ mwmatom=XInternAtom(display,"_MOTIF_WM_HINTS",0);
+ XChangeProperty(display,window,mwmatom,mwmatom,32,
+ PropModeReplace,(unsigned char *)&mwmhints,5);
+
+ XResizeWindow(display,window,screen->width,screen->height);
+
+ hints.min_width = hints.max_width = hints.base_width = screen->width;
+ hints.min_height= hints.max_height = hints.base_height = screen->height;
+
+ XSetWMNormalHints(display,window,&hints);
+
+ {
+ XEvent xev;
+
+ memset(&xev, 0, sizeof(xev));
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = 1;
+ xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
+ xev.xclient.window = window;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0);
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(display, root_window_id, 0,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ }
+ } else {
+ {
+ XEvent xev;
+
+ memset(&xev, 0, sizeof(xev));
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = 1;
+ xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
+ xev.xclient.window = window;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 0;
+ xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0);
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(display, root_window_id, 0,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ }
+
+ mwmhints.flags=MWM_HINTS_DECORATIONS;
+ mwmhints.functions=0;
+ mwmhints.decorations=1;
+ mwmhints.input_mode=0;
+ mwmatom=XInternAtom(display,"_MOTIF_WM_HINTS",0);
+
+ //This shouldn't work on 64 bit longs, but it does...in fact, it breaks when I change all the mwmhints to int.
+ //I don't pretend to understand it.
+ XChangeProperty(display,window,mwmatom,mwmatom,32,
+ PropModeReplace,(unsigned char *)&mwmhints,5);
+
+ hints.flags=USPosition|USSize;
+ hints.base_width = iResX;
+ hints.base_height = iResY;
+ XSetWMNormalHints(display,window,&hints);
+
+ XResizeWindow(display,window,iResX,iResY);
+}
+
+ DoClearScreenBuffer();
+
+ bChangeWinMode=FALSE;
+ bDoVSyncUpdate=TRUE;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// gun cursor func: player=0-7, x=0-511, y=0-255
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUcursor(int iPlayer,int x,int y)
+{
+ if(iPlayer<0) return;
+ if(iPlayer>7) return;
+
+ usCursorActive|=(1<<iPlayer);
+
+ if(x<0) x=0;
+ if(x>511) x=511;
+ if(y<0) y=0;
+ if(y>255) y=255;
+
+ ptCursorPoint[iPlayer].x=x;
+ ptCursorPoint[iPlayer].y=y;
+}
+
+////////////////////////////////////////////////////////////////////////
+// update lace is called evry VSync
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUupdateLace(void) // VSYNC
+{
+ if(!(dwActFixes&1))
+ lGPUstatusRet^=0x80000000; // odd/even bit
+
+ if(!(dwActFixes&32)) // std fps limitation?
+ CheckFrameRate();
+
+ if(PSXDisplay.Interlaced) // interlaced mode?
+ {
+ if(bDoVSyncUpdate && PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)
+ {
+ updateDisplay();
+ }
+ }
+ else // non-interlaced?
+ {
+ if(dwActFixes&64) // lazy screen update fix
+ {
+ if(bDoLazyUpdate && !UseFrameSkip)
+ updateDisplay();
+ bDoLazyUpdate=FALSE;
+ }
+ else
+ {
+ if(bDoVSyncUpdate && !UseFrameSkip) // some primitives drawn?
+ updateDisplay(); // -> update display
+ }
+ }
+#ifndef _MACGL
+ if(bChangeWinMode) ChangeWindowMode(); // toggle full - window mode
+#endif
+ bDoVSyncUpdate=FALSE; // vsync done
+}
+
+////////////////////////////////////////////////////////////////////////
+// process read request from GPU status register
+////////////////////////////////////////////////////////////////////////
+
+
+uint32_t CALLBACK GPUreadStatus(void) // READ STATUS
+{
+ if(dwActFixes&1)
+ {
+ static int iNumRead=0; // odd/even hack
+ if((iNumRead++)==2)
+ {
+ iNumRead=0;
+ lGPUstatusRet^=0x80000000; // interlaced bit toggle... we do it on every 3 read status... needed by some games (like ChronoCross) with old epsxe versions (1.5.2 and older)
+ }
+ }
+
+ if(iFakePrimBusy) // 27.10.2007 - PETE : emulating some 'busy' while drawing... pfff
+ {
+ iFakePrimBusy--;
+
+ if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims
+ {
+ GPUIsBusy;
+ GPUIsNotReadyForCommands;
+ }
+ else
+ {
+ GPUIsIdle;
+ GPUIsReadyForCommands;
+ }
+ }
+ return lGPUstatusRet;
+}
+
+////////////////////////////////////////////////////////////////////////
+// processes data send to GPU status register
+// these are always single packet commands.
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUwriteStatus(uint32_t gdata) // WRITE STATUS
+{
+ uint32_t lCommand=(gdata>>24)&0xff;
+
+ ulStatusControl[lCommand]=gdata; // store command for freezing
+
+ switch(lCommand)
+ {
+ //--------------------------------------------------//
+ // reset gpu
+ case 0x00:
+ memset(lGPUInfoVals,0x00,16*sizeof(uint32_t));
+ lGPUstatusRet=0x14802000;
+ PSXDisplay.Disabled=1;
+ DataWriteMode=DataReadMode=DR_NORMAL;
+ PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;
+ drawX=drawY=0;drawW=drawH=0;
+ sSetMask=0;lSetMask=0;bCheckMask=FALSE;
+ usMirror=0;
+ GlobalTextAddrX=0;GlobalTextAddrY=0;
+ GlobalTextTP=0;GlobalTextABR=0;
+ PSXDisplay.RGB24=FALSE;
+ PSXDisplay.Interlaced=FALSE;
+ bUsingTWin = FALSE;
+ return;
+ //--------------------------------------------------//
+ // dis/enable display
+ case 0x03:
+
+ PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;
+ PSXDisplay.Disabled = (gdata & 1);
+
+ if(PSXDisplay.Disabled)
+ lGPUstatusRet|=GPUSTATUS_DISPLAYDISABLED;
+ else lGPUstatusRet&=~GPUSTATUS_DISPLAYDISABLED;
+ return;
+
+ //--------------------------------------------------//
+ // setting transfer mode
+ case 0x04:
+ gdata &= 0x03; // Only want the lower two bits
+
+ DataWriteMode=DataReadMode=DR_NORMAL;
+ if(gdata==0x02) DataWriteMode=DR_VRAMTRANSFER;
+ if(gdata==0x03) DataReadMode =DR_VRAMTRANSFER;
+ lGPUstatusRet&=~GPUSTATUS_DMABITS; // Clear the current settings of the DMA bits
+ lGPUstatusRet|=(gdata << 29); // Set the DMA bits according to the received data
+
+ return;
+ //--------------------------------------------------//
+ // setting display position
+ case 0x05:
+ {
+ PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
+ PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
+
+////////
+/*
+ PSXDisplay.DisplayPosition.y = (short)((gdata>>10)&0x3ff);
+ if (PSXDisplay.DisplayPosition.y & 0x200)
+ PSXDisplay.DisplayPosition.y |= 0xfffffc00;
+ if(PSXDisplay.DisplayPosition.y<0)
+ {
+ PreviousPSXDisplay.DisplayModeNew.y=PSXDisplay.DisplayPosition.y/PSXDisplay.Double;
+ PSXDisplay.DisplayPosition.y=0;
+ }
+ else PreviousPSXDisplay.DisplayModeNew.y=0;
+*/
+
+// new
+ if(iGPUHeight==1024)
+ {
+ if(dwGPUVersion==2)
+ PSXDisplay.DisplayPosition.y = (short)((gdata>>12)&0x3ff);
+ else PSXDisplay.DisplayPosition.y = (short)((gdata>>10)&0x3ff);
+ }
+ else PSXDisplay.DisplayPosition.y = (short)((gdata>>10)&0x1ff);
+
+ // store the same val in some helper var, we need it on later compares
+ PreviousPSXDisplay.DisplayModeNew.x=PSXDisplay.DisplayPosition.y;
+
+ if((PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayMode.y)>iGPUHeight)
+ {
+ int dy1=iGPUHeight-PSXDisplay.DisplayPosition.y;
+ int dy2=(PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayMode.y)-iGPUHeight;
+
+ if(dy1>=dy2)
+ {
+ PreviousPSXDisplay.DisplayModeNew.y=-dy2;
+ }
+ else
+ {
+ PSXDisplay.DisplayPosition.y=0;
+ PreviousPSXDisplay.DisplayModeNew.y=-dy1;
+ }
+ }
+ else PreviousPSXDisplay.DisplayModeNew.y=0;
+// eon
+
+ PSXDisplay.DisplayPosition.x = (short)(gdata & 0x3ff);
+ PSXDisplay.DisplayEnd.x=
+ PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
+ PSXDisplay.DisplayEnd.y=
+ PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y + PreviousPSXDisplay.DisplayModeNew.y;
+ PreviousPSXDisplay.DisplayEnd.x=
+ PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
+ PreviousPSXDisplay.DisplayEnd.y=
+ PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y + PreviousPSXDisplay.DisplayModeNew.y;
+
+ bDoVSyncUpdate=TRUE;
+
+ if (!(PSXDisplay.Interlaced)) // stupid frame skipping option
+ {
+ if(UseFrameSkip) updateDisplay();
+ if(dwActFixes&64) bDoLazyUpdate=TRUE;
+ }
+ }return;
+ //--------------------------------------------------//
+ // setting width
+ case 0x06:
+
+ PSXDisplay.Range.x0=(short)(gdata & 0x7ff);
+ PSXDisplay.Range.x1=(short)((gdata>>12) & 0xfff);
+
+ PSXDisplay.Range.x1-=PSXDisplay.Range.x0;
+
+ ChangeDispOffsetsX();
+
+ return;
+ //--------------------------------------------------//
+ // setting height
+ case 0x07:
+ {
+
+ PSXDisplay.Range.y0=(short)(gdata & 0x3ff);
+ PSXDisplay.Range.y1=(short)((gdata>>10) & 0x3ff);
+
+ PreviousPSXDisplay.Height = PSXDisplay.Height;
+
+ PSXDisplay.Height = PSXDisplay.Range.y1 -
+ PSXDisplay.Range.y0 +
+ PreviousPSXDisplay.DisplayModeNew.y;
+
+ if(PreviousPSXDisplay.Height!=PSXDisplay.Height)
+ {
+ PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;
+
+ ChangeDispOffsetsY();
+
+ updateDisplayIfChanged();
+ }
+ return;
+ }
+ //--------------------------------------------------//
+ // setting display infos
+ case 0x08:
+
+ PSXDisplay.DisplayModeNew.x =
+ sDispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];
+
+ if (gdata&0x04) PSXDisplay.Double=2;
+ else PSXDisplay.Double=1;
+
+ PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;
+
+ ChangeDispOffsetsY();
+
+ PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC
+ PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor
+ PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace
+
+ lGPUstatusRet&=~GPUSTATUS_WIDTHBITS; // Clear the width bits
+ lGPUstatusRet|=
+ (((gdata & 0x03) << 17) |
+ ((gdata & 0x40) << 10)); // Set the width bits
+
+ if(PSXDisplay.InterlacedNew)
+ {
+ if(!PSXDisplay.Interlaced)
+ {
+ PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
+ PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
+ }
+ lGPUstatusRet|=GPUSTATUS_INTERLACED;
+ }
+ else lGPUstatusRet&=~GPUSTATUS_INTERLACED;
+
+ if (PSXDisplay.PAL)
+ lGPUstatusRet|=GPUSTATUS_PAL;
+ else lGPUstatusRet&=~GPUSTATUS_PAL;
+
+ if (PSXDisplay.Double==2)
+ lGPUstatusRet|=GPUSTATUS_DOUBLEHEIGHT;
+ else lGPUstatusRet&=~GPUSTATUS_DOUBLEHEIGHT;
+
+ if (PSXDisplay.RGB24New)
+ lGPUstatusRet|=GPUSTATUS_RGB24;
+ else lGPUstatusRet&=~GPUSTATUS_RGB24;
+
+ updateDisplayIfChanged();
+
+ return;
+ //--------------------------------------------------//
+ // ask about GPU version and other stuff
+ case 0x10:
+
+ gdata&=0xff;
+
+ switch(gdata)
+ {
+ case 0x02:
+ lGPUdataRet=lGPUInfoVals[INFO_TW]; // tw infos
+ return;
+ case 0x03:
+ lGPUdataRet=lGPUInfoVals[INFO_DRAWSTART]; // draw start
+ return;
+ case 0x04:
+ lGPUdataRet=lGPUInfoVals[INFO_DRAWEND]; // draw end
+ return;
+ case 0x05:
+ case 0x06:
+ lGPUdataRet=lGPUInfoVals[INFO_DRAWOFF]; // draw offset
+ return;
+ case 0x07:
+ if(dwGPUVersion==2)
+ lGPUdataRet=0x01;
+ else lGPUdataRet=0x02; // gpu type
+ return;
+ case 0x08:
+ case 0x0F: // some bios addr?
+ lGPUdataRet=0xBFC03720;
+ return;
+ }
+ return;
+ //--------------------------------------------------//
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// vram read/write helpers, needed by LEWPY's optimized vram read/write :)
+////////////////////////////////////////////////////////////////////////
+
+__inline void FinishedVRAMWrite(void)
+{
+/*
+// NEWX
+ if(!PSXDisplay.Interlaced && UseFrameSkip) // stupid frame skipping
+ {
+ VRAMWrite.Width +=VRAMWrite.x;
+ VRAMWrite.Height+=VRAMWrite.y;
+ if(VRAMWrite.x<PSXDisplay.DisplayEnd.x &&
+ VRAMWrite.Width >=PSXDisplay.DisplayPosition.x &&
+ VRAMWrite.y<PSXDisplay.DisplayEnd.y &&
+ VRAMWrite.Height>=PSXDisplay.DisplayPosition.y)
+ updateDisplay();
+ }
+*/
+
+ // Set register to NORMAL operation
+ DataWriteMode = DR_NORMAL;
+ // Reset transfer values, to prevent mis-transfer of data
+ VRAMWrite.x = 0;
+ VRAMWrite.y = 0;
+ VRAMWrite.Width = 0;
+ VRAMWrite.Height = 0;
+ VRAMWrite.ColsRemaining = 0;
+ VRAMWrite.RowsRemaining = 0;
+}
+
+__inline void FinishedVRAMRead(void)
+{
+ // Set register to NORMAL operation
+ DataReadMode = DR_NORMAL;
+ // Reset transfer values, to prevent mis-transfer of data
+ VRAMRead.x = 0;
+ VRAMRead.y = 0;
+ VRAMRead.Width = 0;
+ VRAMRead.Height = 0;
+ VRAMRead.ColsRemaining = 0;
+ VRAMRead.RowsRemaining = 0;
+
+ // Indicate GPU is no longer ready for VRAM data in the STATUS REGISTER
+ lGPUstatusRet&=~GPUSTATUS_READYFORVRAM;
+}
+
+////////////////////////////////////////////////////////////////////////
+// core read from vram
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUreadDataMem(uint32_t * pMem, int iSize)
+{
+ int i;
+
+ if(DataReadMode!=DR_VRAMTRANSFER) return;
+
+ GPUIsBusy;
+
+ // adjust read ptr, if necessary
+ while(VRAMRead.ImagePtr>=psxVuw_eom)
+ VRAMRead.ImagePtr-=iGPUHeight*1024;
+ while(VRAMRead.ImagePtr<psxVuw)
+ VRAMRead.ImagePtr+=iGPUHeight*1024;
+
+ for(i=0;i<iSize;i++)
+ {
+ // do 2 seperate 16bit reads for compatibility (wrap issues)
+ if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))
+ {
+ // lower 16 bit
+ lGPUdataRet=(uint32_t)GETLE16(VRAMRead.ImagePtr);
+
+ VRAMRead.ImagePtr++;
+ if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
+ VRAMRead.RowsRemaining --;
+
+ if(VRAMRead.RowsRemaining<=0)
+ {
+ VRAMRead.RowsRemaining = VRAMRead.Width;
+ VRAMRead.ColsRemaining--;
+ VRAMRead.ImagePtr += 1024 - VRAMRead.Width;
+ if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
+ }
+
+ // higher 16 bit (always, even if it's an odd width)
+ lGPUdataRet|=(uint32_t)GETLE16(VRAMRead.ImagePtr)<<16;
+ PUTLE32(pMem, lGPUdataRet); pMem++;
+
+ if(VRAMRead.ColsRemaining <= 0)
+ {FinishedVRAMRead();goto ENDREAD;}
+
+ VRAMRead.ImagePtr++;
+ if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
+ VRAMRead.RowsRemaining--;
+ if(VRAMRead.RowsRemaining<=0)
+ {
+ VRAMRead.RowsRemaining = VRAMRead.Width;
+ VRAMRead.ColsRemaining--;
+ VRAMRead.ImagePtr += 1024 - VRAMRead.Width;
+ if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
+ }
+ if(VRAMRead.ColsRemaining <= 0)
+ {FinishedVRAMRead();goto ENDREAD;}
+ }
+ else {FinishedVRAMRead();goto ENDREAD;}
+ }
+
+ENDREAD:
+ GPUIsIdle;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+uint32_t CALLBACK GPUreadData(void)
+{
+ uint32_t l;
+ GPUreadDataMem(&l,1);
+ return lGPUdataRet;
+}
+
+////////////////////////////////////////////////////////////////////////
+// processes data send to GPU data register
+// extra table entries for fixing polyline troubles
+////////////////////////////////////////////////////////////////////////
+
+const unsigned char primTableCX[256] =
+{
+ // 00
+ 0,0,3,0,0,0,0,0,
+ // 08
+ 0,0,0,0,0,0,0,0,
+ // 10
+ 0,0,0,0,0,0,0,0,
+ // 18
+ 0,0,0,0,0,0,0,0,
+ // 20
+ 4,4,4,4,7,7,7,7,
+ // 28
+ 5,5,5,5,9,9,9,9,
+ // 30
+ 6,6,6,6,9,9,9,9,
+ // 38
+ 8,8,8,8,12,12,12,12,
+ // 40
+ 3,3,3,3,0,0,0,0,
+ // 48
+// 5,5,5,5,6,6,6,6, // FLINE
+ 254,254,254,254,254,254,254,254,
+ // 50
+ 4,4,4,4,0,0,0,0,
+ // 58
+// 7,7,7,7,9,9,9,9, // GLINE
+ 255,255,255,255,255,255,255,255,
+ // 60
+ 3,3,3,3,4,4,4,4,
+ // 68
+ 2,2,2,2,3,3,3,3, // 3=SPRITE1???
+ // 70
+ 2,2,2,2,3,3,3,3,
+ // 78
+ 2,2,2,2,3,3,3,3,
+ // 80
+ 4,0,0,0,0,0,0,0,
+ // 88
+ 0,0,0,0,0,0,0,0,
+ // 90
+ 0,0,0,0,0,0,0,0,
+ // 98
+ 0,0,0,0,0,0,0,0,
+ // a0
+ 3,0,0,0,0,0,0,0,
+ // a8
+ 0,0,0,0,0,0,0,0,
+ // b0
+ 0,0,0,0,0,0,0,0,
+ // b8
+ 0,0,0,0,0,0,0,0,
+ // c0
+ 3,0,0,0,0,0,0,0,
+ // c8
+ 0,0,0,0,0,0,0,0,
+ // d0
+ 0,0,0,0,0,0,0,0,
+ // d8
+ 0,0,0,0,0,0,0,0,
+ // e0
+ 0,1,1,1,1,1,1,0,
+ // e8
+ 0,0,0,0,0,0,0,0,
+ // f0
+ 0,0,0,0,0,0,0,0,
+ // f8
+ 0,0,0,0,0,0,0,0
+};
+
+void CALLBACK GPUwriteDataMem(uint32_t * pMem, int iSize)
+{
+ unsigned char command;
+ uint32_t gdata=0;
+ int i=0;
+ GPUIsBusy;
+ GPUIsNotReadyForCommands;
+
+STARTVRAM:
+
+ if(DataWriteMode==DR_VRAMTRANSFER)
+ {
+ BOOL bFinished=FALSE;
+
+ // make sure we are in vram
+ while(VRAMWrite.ImagePtr>=psxVuw_eom)
+ VRAMWrite.ImagePtr-=iGPUHeight*1024;
+ while(VRAMWrite.ImagePtr<psxVuw)
+ VRAMWrite.ImagePtr+=iGPUHeight*1024;
+
+ // now do the loop
+ while(VRAMWrite.ColsRemaining>0)
+ {
+ while(VRAMWrite.RowsRemaining>0)
+ {
+ if(i>=iSize) {goto ENDVRAM;}
+ i++;
+
+ gdata=GETLE32(pMem); pMem++;
+
+ PUTLE16(VRAMWrite.ImagePtr, (unsigned short)gdata); VRAMWrite.ImagePtr++;
+ if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;
+ VRAMWrite.RowsRemaining --;
+
+ if(VRAMWrite.RowsRemaining <= 0)
+ {
+ VRAMWrite.ColsRemaining--;
+ if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width
+ {
+ gdata=(gdata&0xFFFF)|(((uint32_t)GETLE16(VRAMWrite.ImagePtr))<<16);
+ FinishedVRAMWrite();
+ bDoVSyncUpdate=TRUE;
+ goto ENDVRAM;
+ }
+ VRAMWrite.RowsRemaining = VRAMWrite.Width;
+ VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
+ }
+
+ PUTLE16(VRAMWrite.ImagePtr, (unsigned short)(gdata>>16)); VRAMWrite.ImagePtr++;
+ if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;
+ VRAMWrite.RowsRemaining --;
+ }
+
+ VRAMWrite.RowsRemaining = VRAMWrite.Width;
+ VRAMWrite.ColsRemaining--;
+ VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
+ bFinished=TRUE;
+ }
+
+ FinishedVRAMWrite();
+ if(bFinished) bDoVSyncUpdate=TRUE;
+ }
+
+ENDVRAM:
+
+ if(DataWriteMode==DR_NORMAL)
+ {
+ void (* *primFunc)(unsigned char *);
+ if(bSkipNextFrame) primFunc=primTableSkip;
+ else primFunc=primTableJ;
+
+ for(;i<iSize;)
+ {
+ if(DataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;
+
+ gdata=GETLE32(pMem); pMem++; i++;
+
+ if(gpuDataC == 0)
+ {
+ command = (unsigned char)((gdata>>24) & 0xff);
+
+//if(command>=0xb0 && command<0xc0) auxprintf("b0 %x!!!!!!!!!\n",command);
+
+ if(primTableCX[command])
+ {
+ gpuDataC = primTableCX[command];
+ gpuCommand = command;
+ PUTLE32(&gpuDataM[0], gdata);
+ gpuDataP = 1;
+ }
+ else continue;
+ }
+ else
+ {
+ PUTLE32(&gpuDataM[gpuDataP], gdata);
+ if(gpuDataC>128)
+ {
+ if((gpuDataC==254 && gpuDataP>=3) ||
+ (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))
+ {
+ if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)
+ gpuDataP=gpuDataC-1;
+ }
+ }
+ gpuDataP++;
+ }
+
+ if(gpuDataP == gpuDataC)
+ {
+ gpuDataC=gpuDataP=0;
+ primFunc[gpuCommand]((unsigned char *)gpuDataM);
+ if(dwEmuFixes&0x0001 || dwActFixes&0x0400) // hack for emulating "gpu busy" in some games
+ iFakePrimBusy=4; }
+ }
+ }
+
+ lGPUdataRet=gdata;
+
+ GPUIsReadyForCommands;
+ GPUIsIdle;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUwriteData(uint32_t gdata)
+{
+ PUTLE32(&gdata, gdata);
+ GPUwriteDataMem(&gdata,1);
+}
+
+////////////////////////////////////////////////////////////////////////
+// this functions will be removed soon (or 'soonish')... not really needed, but some emus want them
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUsetMode(unsigned long gdata)
+{
+// Peops does nothing here...
+// DataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;
+// DataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;
+}
+
+long CALLBACK GPUgetMode(void)
+{
+ long iT=0;
+
+ if(DataWriteMode==DR_VRAMTRANSFER) iT|=0x1;
+ if(DataReadMode ==DR_VRAMTRANSFER) iT|=0x2;
+ return iT;
+}
+
+////////////////////////////////////////////////////////////////////////
+// call config dlg
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUconfigure(void)
+{
+ SoftDlgProc();
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// sets all kind of act fixes
+////////////////////////////////////////////////////////////////////////
+
+void SetFixes(void)
+ {
+ if(dwActFixes&0x02) sDispWidths[4]=384;
+ else sDispWidths[4]=368;
+ }
+
+////////////////////////////////////////////////////////////////////////
+// process gpu commands
+////////////////////////////////////////////////////////////////////////
+
+unsigned long lUsedAddr[3];
+
+__inline BOOL CheckForEndlessLoop(unsigned long laddr)
+{
+ if(laddr==lUsedAddr[1]) return TRUE;
+ if(laddr==lUsedAddr[2]) return TRUE;
+
+ if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;
+ else lUsedAddr[2]=laddr;
+ lUsedAddr[0]=laddr;
+ return FALSE;
+}
+
+long CALLBACK GPUdmaChain(uint32_t * baseAddrL, uint32_t addr)
+{
+ uint32_t dmaMem;
+ unsigned char * baseAddrB;
+ short count;unsigned int DMACommandCounter = 0;
+
+ GPUIsBusy;
+
+ lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;
+
+ baseAddrB = (unsigned char*) baseAddrL;
+
+ do
+ {
+ if(iGPUHeight==512) addr&=0x1FFFFC;
+ if(DMACommandCounter++ > 2000000) break;
+ if(CheckForEndlessLoop(addr)) break;
+
+ count = baseAddrB[addr+3];
+
+ dmaMem=addr+4;
+
+ if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);
+
+ addr = GETLE32(&baseAddrL[addr>>2])&0xffffff;
+ }
+ while (addr != 0xffffff);
+
+ GPUIsIdle;
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// show about dlg
+////////////////////////////////////////////////////////////////////////
+
+
+void CALLBACK GPUabout(void) // ABOUT
+{
+ AboutDlgProc();
+ return;
+}
+
+////////////////////////////////////////////////////////////////////////
+// We are ever fine ;)
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUtest(void)
+{
+ // if test fails this function should return negative value for error (unable to continue)
+ // and positive value for warning (can continue but output might be crappy)
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Freeze
+////////////////////////////////////////////////////////////////////////
+
+typedef struct GPUFREEZETAG
+{
+ uint32_t ulFreezeVersion; // should be always 1 for now (set by main emu)
+ uint32_t ulStatus; // current gpu status
+ uint32_t ulControl[256]; // latest control register values
+ unsigned char psxVRam[1024*1024*2]; // current VRam image (full 2 MB for ZN)
+} GPUFreeze_t;
+
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUfreeze(uint32_t ulGetFreezeData,GPUFreeze_t * pF)
+{
+ //----------------------------------------------------//
+ if(ulGetFreezeData==2) // 2: info, which save slot is selected? (just for display)
+ {
+ long lSlotNum=*((long *)pF);
+ if(lSlotNum<0) return 0;
+ if(lSlotNum>8) return 0;
+ lSelectedSlot=lSlotNum+1;
+ BuildDispMenu(0);
+ return 1;
+ }
+ //----------------------------------------------------//
+ if(!pF) return 0; // some checks
+ if(pF->ulFreezeVersion!=1) return 0;
+
+ if(ulGetFreezeData==1) // 1: get data
+ {
+ pF->ulStatus=lGPUstatusRet;
+ memcpy(pF->ulControl,ulStatusControl,256*sizeof(uint32_t));
+ memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2);
+
+ return 1;
+ }
+
+ if(ulGetFreezeData!=0) return 0; // 0: set data
+
+ lGPUstatusRet=pF->ulStatus;
+ memcpy(ulStatusControl,pF->ulControl,256*sizeof(uint32_t));
+ memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2);
+
+// RESET TEXTURE STORE HERE, IF YOU USE SOMETHING LIKE THAT
+
+ GPUwriteStatus(ulStatusControl[0]);
+ GPUwriteStatus(ulStatusControl[1]);
+ GPUwriteStatus(ulStatusControl[2]);
+ GPUwriteStatus(ulStatusControl[3]);
+ GPUwriteStatus(ulStatusControl[8]); // try to repair things
+ GPUwriteStatus(ulStatusControl[6]);
+ GPUwriteStatus(ulStatusControl[7]);
+ GPUwriteStatus(ulStatusControl[5]);
+ GPUwriteStatus(ulStatusControl[4]);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// SAVE STATE DISPLAY STUFF
+////////////////////////////////////////////////////////////////////////
+
+// font 0-9, 24x20 pixels, 1 byte = 4 dots
+// 00 = black
+// 01 = white
+// 10 = red
+// 11 = transparent
+
+unsigned char cFont[10][120]=
+{
+// 0
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 1
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x05,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x05,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 2
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x01,0x40,0x00,0x00,
+ 0x80,0x00,0x05,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 3
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x01,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 4
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x54,0x00,0x00,
+ 0x80,0x00,0x01,0x54,0x00,0x00,
+ 0x80,0x00,0x01,0x54,0x00,0x00,
+ 0x80,0x00,0x05,0x14,0x00,0x00,
+ 0x80,0x00,0x14,0x14,0x00,0x00,
+ 0x80,0x00,0x15,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 5
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x55,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 6
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x01,0x54,0x00,0x00,
+ 0x80,0x00,0x05,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x54,0x00,0x00,
+ 0x80,0x00,0x15,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 7
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x55,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x01,0x40,0x00,0x00,
+ 0x80,0x00,0x01,0x40,0x00,0x00,
+ 0x80,0x00,0x05,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 8
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 9
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x15,0x00,0x00,
+ 0x80,0x00,0x05,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x05,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+}
+};
+
+////////////////////////////////////////////////////////////////////////
+
+void PaintPicDot(unsigned char * p,unsigned char c)
+{
+
+ if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;} // black
+ if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;} // white
+ if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;} // red
+ // transparent
+}
+
+////////////////////////////////////////////////////////////////////////
+// the main emu allocs 128x96x3 bytes, and passes a ptr
+// to it in pMem... the plugin has to fill it with
+// 8-8-8 bit BGR screen data (Win 24 bit BMP format
+// without header).
+// Beware: the func can be called at any time,
+// so you have to use the frontbuffer to get a fully
+// rendered picture
+
+// LINUX version:
+
+extern char * Xpixels;
+
+void GPUgetScreenPic(unsigned char * pMem)
+{
+/*
+ unsigned short c;unsigned char * pf;int x,y;
+
+ float XS=(float)iResX/128;
+ float YS=(float)iResY/96;
+
+ pf=pMem;
+ memset(pMem, 0, 128*96*3);
+
+ if(Xpixels)
+ {
+ unsigned char * ps=(unsigned char *)Xpixels;
+ {
+ long lPitch=iResX<<2;
+ uint32_t sx;
+
+ for(y=0;y<96;y++)
+ {
+ for(x=0;x<128;x++)
+ {
+ sx=*((uint32_t *)((ps)+
+ (((int)((float)y*YS))*lPitch)+
+ ((int)((float)x*XS))*4));
+ *(pf+0)=(sx&0xff);
+ *(pf+1)=(sx&0xff00)>>8;
+ *(pf+2)=(sx&0xff0000)>>16;
+ pf+=3;
+ }
+ }
+ }
+ }
+
+
+ /////////////////////////////////////////////////////////////////////
+ // generic number/border painter
+
+ pf=pMem+(103*3); // offset to number rect
+
+ for(y=0;y<20;y++) // loop the number rect pixel
+ {
+ for(x=0;x<6;x++)
+ {
+ c=cFont[lSelectedSlot][x+y*6]; // get 4 char dot infos at once (number depends on selected slot)
+ PaintPicDot(pf,(c&0xc0)>>6);pf+=3; // paint the dots into the rect
+ PaintPicDot(pf,(c&0x30)>>4);pf+=3;
+ PaintPicDot(pf,(c&0x0c)>>2);pf+=3;
+ PaintPicDot(pf,(c&0x03)); pf+=3;
+ }
+ pf+=104*3; // next rect y line
+ }
+
+ pf=pMem; // ptr to first pos in 128x96 pic
+ for(x=0;x<128;x++) // loop top/bottom line
+ {
+ *(pf+(95*128*3))=0x00;*pf++=0x00;
+ *(pf+(95*128*3))=0x00;*pf++=0x00; // paint it red
+ *(pf+(95*128*3))=0xff;*pf++=0xff;
+ }
+ pf=pMem; // ptr to first pos
+ for(y=0;y<96;y++) // loop left/right line
+ {
+ *(pf+(127*3))=0x00;*pf++=0x00;
+ *(pf+(127*3))=0x00;*pf++=0x00; // paint it red
+ *(pf+(127*3))=0xff;*pf++=0xff;
+ pf+=127*3; // offset to next line
+ }
+*/
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// func will be called with 128x96x3 BGR data.
+// the plugin has to store the data and display
+// it in the upper right corner.
+// If the func is called with a NULL ptr, you can
+// release your picture data and stop displaying
+// the screen pic
+
+void CALLBACK GPUshowScreenPic(unsigned char * pMem)
+{
+ DestroyPic(); // destroy old pic data
+ if(pMem==0) return; // done
+ CreatePic(pMem); // create new pic... don't free pMem or something like that... just read from it
+}
+
+void CALLBACK GPUsetfix(uint32_t dwFixBits)
+{
+ dwEmuFixes=dwFixBits;
+}
diff --git a/plugins/dfxvideo/gpu.h b/plugins/dfxvideo/gpu.h
new file mode 100644
index 0000000..e8730f2
--- /dev/null
+++ b/plugins/dfxvideo/gpu.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ gpu.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _GPU_INTERNALS_H
+#define _GPU_INTERNALS_H
+
+#define OPAQUEON 10
+#define OPAQUEOFF 11
+
+#define KEY_RESETTEXSTORE 1
+#define KEY_SHOWFPS 2
+#define KEY_RESETOPAQUE 4
+#define KEY_RESETDITHER 8
+#define KEY_RESETFILTER 16
+#define KEY_RESETADVBLEND 32
+//#define KEY_BLACKWHITE 64
+#define KEY_BADTEXTURES 128
+#define KEY_CHECKTHISOUT 256
+
+#if !defined(__BIG_ENDIAN__) || defined(__x86_64__) || defined(__i386__)
+#ifndef __LITTLE_ENDIAN__
+#define __LITTLE_ENDIAN__
+#endif
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define RED(x) (x & 0xff)
+#define BLUE(x) ((x>>16) & 0xff)
+#define GREEN(x) ((x>>8) & 0xff)
+#define COLOR(x) (x & 0xffffff)
+#elif defined __BIG_ENDIAN__
+#define RED(x) ((x>>24) & 0xff)
+#define BLUE(x) ((x>>8) & 0xff)
+#define GREEN(x) ((x>>16) & 0xff)
+#define COLOR(x) SWAP32(x & 0xffffff)
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+void updateDisplay(void);
+void SetAutoFrameCap(void);
+void SetFixes(void);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // _GPU_INTERNALS_H
diff --git a/plugins/dfxvideo/gpucfg-0.1df/dfxvideo.glade2 b/plugins/dfxvideo/gpucfg-0.1df/dfxvideo.glade2
new file mode 100644
index 0000000..ded3c1a
--- /dev/null
+++ b/plugins/dfxvideo/gpucfg-0.1df/dfxvideo.glade2
@@ -0,0 +1,625 @@
+<?xml version="1.0"?>
+<glade-interface>
+ <!-- interface-requires gtk+ 2.8 -->
+ <!-- interface-naming-policy project-wide -->
+ <widget class="GtkWindow" id="CfgWnd">
+ <property name="visible">True</property>
+ <property name="border_width">10</property>
+ <property name="title" translatable="yes">Configure X11 Video</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window_position">center</property>
+ <property name="type_hint">dialog</property>
+ <signal name="destroy" handler="on_CfgWnd_destroy"/>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">6</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox7">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">30</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Initial Window Size:</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Stretching:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Dithering:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="stretchCombo2">
+ <property name="visible">True</property>
+ <property name="active">0</property>
+ <property name="items" translatable="yes">0: None
+1: 2xSai
+2: 2xSuperSai
+3: SuperEagle
+4: Scale2x
+5: Scale3x
+6: HQ2X
+7: HQ3X</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="ditherCombo2">
+ <property name="visible">True</property>
+ <property name="active">1</property>
+ <property name="items" translatable="yes">0: Off (fastest)
+1: Game dependant
+2: Always</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="spacing">10</property>
+ <child>
+ <widget class="GtkComboBox" id="resCombo2">
+ <property name="visible">True</property>
+ <property name="active">2</property>
+ <property name="items" translatable="yes">320x240
+640x480
+800x600
+1024x768
+1152x864
+1280x1024
+1600x1200</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFullscreen">
+ <property name="label" translatable="yes">Fullscreen</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Toggle windowed/fullscreen mode.</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="maintain43">
+ <property name="label" translatable="yes">Maintain 4:3 Aspect Ratio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Screen&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">6</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkCheckButton" id="checkShowFPS">
+ <property name="label" translatable="yes">Show FPS</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Toggle whether the FPS will be shown.</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFrameSkip">
+ <property name="label" translatable="yes">Enable frame skipping</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Skip frames when rendering.</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table2">
+ <property name="visible">True</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <widget class="GtkCheckButton" id="checkSetFPS">
+ <property name="label" translatable="yes">Set FPS</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Enable this if games display too quickly.</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entryFPS">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="width_chars">4</property>
+ <property name="text" translatable="yes">200.0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkAutoFPSLimit">
+ <property name="label" translatable="yes">Autodetect FPS limit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Framerate&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment3">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">6</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkCheckButton" id="checkUseFixes">
+ <property name="label" translatable="yes">Use game fixes</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment5">
+ <property name="visible">True</property>
+ <property name="left_padding">19</property>
+ <child>
+ <widget class="GtkTable" id="table_fixes">
+ <property name="visible">True</property>
+ <property name="n_rows">6</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">16</property>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix5">
+ <property name="label" translatable="yes">Disable CPU Saving</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">For precise framerate</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix1">
+ <property name="label" translatable="yes">Odd/even bit hack</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Chrono Cross</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix6">
+ <property name="label" translatable="yes">PC FPS calculation</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Better FPS limit in some</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix2">
+ <property name="label" translatable="yes">Expand screen width</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Capcom fighting games</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix3">
+ <property name="label" translatable="yes">Ignore brightness color</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Black screens in Lunar</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix4">
+ <property name="label" translatable="yes">Disable coordinate check</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Compatibility mode</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix7">
+ <property name="label" translatable="yes">Lazy screen update</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Pandemonium 2</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix8">
+ <property name="label" translatable="yes">Old frame skipping</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Skip every second frame</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix9">
+ <property name="label" translatable="yes">Repeated flat tex triangles</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Needed by Dark Forces</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix10">
+ <property name="label" translatable="yes">Draw quads with triangles</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">better g-colors, worse textures</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="checkFix11">
+ <property name="label" translatable="yes">Fake 'gpu busy' states</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Toggle busy flags after drawing</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Compatibility&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <property name="layout_style">end</property>
+ <child>
+ <widget class="GtkButton" id="btn_close">
+ <property name="label">gtk-close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
diff --git a/plugins/dfxvideo/gpucfg-0.1df/main.c b/plugins/dfxvideo/gpucfg-0.1df/main.c
new file mode 100644
index 0000000..ddc9929
--- /dev/null
+++ b/plugins/dfxvideo/gpucfg-0.1df/main.c
@@ -0,0 +1,464 @@
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+#include "config.h"
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#include <locale.h>
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+void SaveConfig(GtkWidget *widget, gpointer user_datal);
+
+#define READBINARY "rb"
+#define WRITEBINARY "wb"
+#define CONFIG_FILENAME "dfxvideo.cfg"
+
+enum {
+ VIDMODE_320x200 = 0,
+ VIDMODE_640x480,
+ VIDMODE_800x600,
+ VIDMODE_1024x768,
+ VIDMODE_1152x864,
+ VIDMODE_1280x1024,
+ VIDMODE_1600x1200
+}; /* Video_modes */
+
+/*ADB static GtkWidget * wndMain=0;*/
+
+/* This function checks for the value being outside the accepted range,
+ and returns the appropriate boundary value */
+int set_limit (char *p, int len, int lower, int upper)
+{
+ int val = 0;
+
+ if (p)
+ val = atoi(p + len);
+ /* printf("Checking for val %d greater than %d and lower than %d, ", val, lower, upper);*/
+ if (val < lower)
+ val = lower;
+ if (val > upper)
+ val = upper;
+ /* printf ("val is now %d\n", val);*/
+ return val;
+}
+
+void on_about_clicked(GtkWidget *widget, gpointer user_data)
+{
+ gtk_widget_destroy (widget);
+ exit (0);
+}
+
+void set_widget_sensitive(GtkWidget *widget, gpointer user_data)
+{
+ gtk_widget_set_sensitive (widget, (int)user_data);
+}
+
+void on_fullscreen_toggled(GtkWidget *widget, gpointer user_data)
+{
+ GtkWidget *check, *resCombo2;
+ GladeXML *xml;
+ xml = (GladeXML*) user_data;
+
+ check = glade_xml_get_widget(xml, "checkFullscreen");
+ resCombo2 = glade_xml_get_widget(xml, "resCombo2");
+
+ set_widget_sensitive(resCombo2, !gtk_toggle_button_get_active(check));
+}
+
+void on_use_fixes_toggled(GtkWidget *widget, gpointer user_data)
+{
+ GtkWidget *check, *table_fixes;
+ GladeXML *xml;
+ xml = (GladeXML*) user_data;
+ check = glade_xml_get_widget (xml, "checkUseFixes");
+
+ table_fixes = glade_xml_get_widget (xml, "table_fixes");
+
+ /* Set the state of each of the fixes to the value of the use fixes toggle */
+ gtk_container_foreach (GTK_CONTAINER (table_fixes), (GtkCallback) set_widget_sensitive,
+ (void *)gtk_toggle_button_get_active (check));
+}
+
+void on_fps_toggled(GtkWidget *widget, gpointer user_data)
+{
+ GtkWidget *checkSetFPS, *checkAutoFPSLimit, *entryFPS;
+ GladeXML *xml;
+
+ xml = (GladeXML*) user_data;
+ checkSetFPS = glade_xml_get_widget(xml, "checkSetFPS");
+ checkAutoFPSLimit = glade_xml_get_widget(xml, "checkAutoFPSLimit");
+ entryFPS = glade_xml_get_widget(xml, "entryFPS");
+
+ set_widget_sensitive(entryFPS,
+ gtk_toggle_button_get_active(checkSetFPS) && !gtk_toggle_button_get_active(checkAutoFPSLimit));
+ set_widget_sensitive(checkAutoFPSLimit, gtk_toggle_button_get_active(checkSetFPS));
+}
+
+void OnConfigClose(GtkWidget *widget, gpointer user_data)
+{
+ GladeXML *xml = (GladeXML *)user_data;
+
+ gtk_widget_destroy(glade_xml_get_widget(xml, "CfgWnd"));
+ gtk_exit(0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ GtkWidget *CfgWnd, *widget;
+ GladeXML *xml;
+ FILE *in;char t[256];int len,val;
+ float valf;
+ char * pB, * p;
+ char cfg[255];
+ int i;
+ char tempstr[50];
+
+#ifdef ENABLE_NLS
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+#endif
+
+ if (argc!=2) {
+ printf("Usage: cfgDFXVideo {ABOUT | CFG}\n");
+ return 0;
+ }
+ if(strcmp(argv[1],"CFG")!=0 && strcmp(argv[1],"ABOUT")!=0) {
+ printf("Usage: cfgDFXVideo {ABOUT | CFG}\n");
+ return 0;
+ }
+
+ gtk_set_locale ();
+ gtk_init (&argc, &argv);
+
+
+ if (strcmp(argv[1], "ABOUT") == 0) {
+ const char *authors[]= {"Pete Bernert and the P.E.Op.S. team", "Ryan Schultz", "Andrew Burton", NULL};
+ widget = gtk_about_dialog_new ();
+ gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (widget), "P.E.Op.S PCSX Video Plugin");
+ gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (widget), "1.17");
+ gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (widget), authors);
+ gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (widget), "http://pcsx-df.sourceforge.net/");
+
+ g_signal_connect_data(GTK_OBJECT(widget), "response",
+ GTK_SIGNAL_FUNC(on_about_clicked), NULL, NULL, G_CONNECT_AFTER);
+
+ gtk_widget_show (widget);
+ gtk_main();
+
+ return 0;
+ }
+
+ xml = glade_xml_new(DATADIR "dfxvideo.glade2", "CfgWnd", NULL);
+ if (!xml) {
+ g_warning("We could not load the interface!");
+ return -1;
+ }
+
+ /*ADB wndMain = glade_xml_get_widget(xml, "CfgWnd");*/
+
+ strcpy(cfg, CONFIG_FILENAME);
+
+ in = fopen(cfg,READBINARY);
+ /* ADB TODO This is bad - asking for problems; need to read in line by line */
+ if(in)
+ {
+ pB=(char *)malloc(32767);
+ memset(pB,0,32767);
+ len = fread(pB, 1, 32767, in);
+ fclose(in);
+ }
+ else{ pB=0;printf("Couldn't find config file %s\n", cfg);}
+/* ADB TODO Parse this like we parse the config file in PCSX - use common functions! */
+ val=1;
+ if(pB)
+ {
+ strcpy(t,"\nResX");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+ val = set_limit (p, len, 0, 1600);
+ }
+
+ if (val == 1600) val = VIDMODE_1600x1200;
+ else if (val == 1280) val = VIDMODE_1280x1024;
+ else if (val == 1152) val = VIDMODE_1152x864;
+ else if (val == 1024) val = VIDMODE_1024x768;
+ else if (val == 800) val = VIDMODE_800x600;
+ else if (val == 640) val = VIDMODE_640x480;
+ else if (val == 320) val = VIDMODE_320x200;
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX (glade_xml_get_widget(xml, "resCombo2")), val);
+
+ val=0;
+ if(pB)
+ {
+ strcpy(t,"\nNoStretch");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+
+ val = set_limit (p, len, 0, 9);
+ }
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX (glade_xml_get_widget(xml, "stretchCombo2")), val);
+
+ val=0;
+ if(pB)
+ {
+ strcpy(t,"\nDithering");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+
+ val = set_limit (p, len, 0, 2);
+ }
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX (glade_xml_get_widget(xml, "ditherCombo2")), val);
+
+ val=0;
+ if(pB)
+ {
+ strcpy(t,"\nMaintain43");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+
+ val = set_limit (p, len, 0, 1);
+ }
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (glade_xml_get_widget(xml, "maintain43")), val);
+
+ val=0; //ADB Leave - these are default values
+ if(pB)
+ {
+ strcpy(t,"\nFullScreen");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+
+ val = set_limit (p, len, 0, 1);
+ }
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (glade_xml_get_widget(xml, "checkFullscreen")), val);
+
+ val=0;
+ if(pB)
+ {
+ strcpy(t,"\nShowFPS");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+
+ val = set_limit (p, len, 0, 1);
+ }
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (glade_xml_get_widget(xml, "checkShowFPS")), val);
+
+ val=1;
+ if(pB)
+ {
+ strcpy(t,"\nUseFrameLimit");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+
+ val = set_limit (p, len, 0, 1);
+ }
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (glade_xml_get_widget(xml, "checkSetFPS")), val);
+
+ val=0;
+ if(pB)
+ {
+ strcpy(t,"\nFPSDetection");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+
+ val = set_limit (p, len, 1, 2);
+ }
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (glade_xml_get_widget(xml, "checkAutoFPSLimit")), (val-1));
+
+ val=0;
+ if(pB)
+ {
+ strcpy(t,"\nUseFrameSkip");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+ val = set_limit (p, len, 0, 1);
+ }
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (glade_xml_get_widget(xml, "checkFrameSkip")), val);
+
+ valf=200;
+ if(pB)
+ {
+ strcpy(t,"\nFrameRate");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+ if(p) valf=(float)atoi(p+len) / 10;
+ if(valf<1) valf=1;
+ if(valf>500) valf=500;
+ }
+ sprintf(tempstr,"%.1f",valf);
+ gtk_entry_set_text(glade_xml_get_widget(xml, "entryFPS"),tempstr);
+
+ val=0;
+ if(pB)
+ {
+ strcpy(t,"\nUseFixes");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+
+ val = set_limit (p, len, 0, 1);
+ }
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (glade_xml_get_widget(xml, "checkUseFixes")), val);
+
+
+ if(pB)
+ {
+ strcpy(t,"\nCfgFixes");p=strstr(pB,t);if(p) {p=strstr(p,"=");len=1;}
+ if (p)
+ val = atoi(p + len);
+ }
+
+ for (i=0; i<11; i++)
+ {
+ sprintf(tempstr, "checkFix%d", i+1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, tempstr)), (val>>i)&1 );
+ }
+
+
+ if(pB) free(pB);
+
+ widget = glade_xml_get_widget(xml, "CfgWnd");
+ g_signal_connect_data(GTK_OBJECT(widget), "destroy",
+ GTK_SIGNAL_FUNC(SaveConfig), xml, NULL, 0);
+
+ widget = glade_xml_get_widget(xml, "btn_close");
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ GTK_SIGNAL_FUNC(OnConfigClose), xml, NULL, G_CONNECT_AFTER);
+
+ widget = glade_xml_get_widget(xml, "checkFullscreen");
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ GTK_SIGNAL_FUNC(on_fullscreen_toggled), xml, NULL, G_CONNECT_AFTER);
+
+ widget = glade_xml_get_widget(xml, "checkUseFixes");
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ GTK_SIGNAL_FUNC(on_use_fixes_toggled), xml, NULL, G_CONNECT_AFTER);
+
+ widget = glade_xml_get_widget(xml, "checkSetFPS");
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ GTK_SIGNAL_FUNC(on_fps_toggled), xml, NULL, G_CONNECT_AFTER);
+
+ widget = glade_xml_get_widget(xml, "checkAutoFPSLimit");
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ GTK_SIGNAL_FUNC(on_fps_toggled), xml, NULL, G_CONNECT_AFTER);
+
+ on_fullscreen_toggled(widget, (gpointer) xml);
+ on_fps_toggled(widget, (gpointer) xml);
+ on_use_fixes_toggled(widget, (gpointer) xml);
+
+ gtk_main ();
+ return 0;
+}
+
+
+void SetCfgVal(char * pB,char * pE,int val)
+{
+ char * p, *ps, *pC;char t[32];
+
+ sprintf(t,"%d",val);
+
+ p=strstr(pB,pE);
+ if(p)
+ {
+ p=strstr(p,"=");
+ if(!p) return;
+ p++;
+ while(*p && *p!='\n' && (*p<'0' || *p>'9')) p++;
+ if(*p==0 || *p=='\n') return;
+ ps=p;
+ while(*p>='0' && *p<='9') p++;
+ pC=(char *)malloc(32767);
+ strcpy(pC,p);
+ strcpy(ps,t);
+ strcat(pB,pC);
+ free(pC);
+ }
+ else
+ {
+ strcat(pB,pE);
+ strcat(pB," = ");
+ strcat(pB,t);
+ strcat(pB,"\n");
+ }
+}
+
+void SaveConfig(GtkWidget *widget, gpointer user_data)
+{
+ FILE *in;int len,val;char * pB;
+ GladeXML *xml;
+ char cfg[255];
+ char tempstr[50];
+ int i;
+ struct stat buf;
+
+ pB=(char *)malloc(32767);
+ memset(pB,0,32767);
+
+ strcpy(cfg, CONFIG_FILENAME);
+
+ /* ADB TODO Why do we read this in just to replace it again? */
+ in = fopen(cfg,READBINARY);
+ if(in)
+ {
+ len = fread(pB, 1, 32767, in);
+ fclose(in);
+ }
+ xml = (GladeXML*) user_data;
+
+ val = gtk_combo_box_get_active (GTK_COMBO_BOX (glade_xml_get_widget (xml, "resCombo2")));
+
+ if (val == VIDMODE_320x200) { SetCfgVal(pB,"\nResX",320); SetCfgVal(pB,"\nResY",240); }
+ else if (val == VIDMODE_640x480) { SetCfgVal(pB,"\nResX",640); SetCfgVal(pB,"\nResY",480); }
+ else if (val == VIDMODE_800x600) { SetCfgVal(pB,"\nResX",800); SetCfgVal(pB,"\nResY",600); }
+ else if (val == VIDMODE_1024x768) { SetCfgVal(pB,"\nResX",1024); SetCfgVal(pB,"\nResY",768); }
+ else if (val == VIDMODE_1152x864) { SetCfgVal(pB,"\nResX",1152); SetCfgVal(pB,"\nResY",864); }
+ else if (val == VIDMODE_1280x1024) { SetCfgVal(pB,"\nResX",1280); SetCfgVal(pB,"\nResY",1024); }
+ else if (val == VIDMODE_1600x1200) { SetCfgVal(pB,"\nResX",1600); SetCfgVal(pB,"\nResY",1200); }
+
+ val = gtk_combo_box_get_active (GTK_COMBO_BOX (glade_xml_get_widget (xml, "stretchCombo2")));
+ SetCfgVal(pB,"\nNoStretch",val);
+
+ val = gtk_combo_box_get_active (GTK_COMBO_BOX (glade_xml_get_widget (xml, "ditherCombo2")));
+ SetCfgVal(pB,"\nDithering",val);
+
+ val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "maintain43")));
+ SetCfgVal(pB,"\nMaintain43",val);
+
+ val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "checkFullscreen")));
+ SetCfgVal(pB,"\nFullScreen",val);
+
+ val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "checkShowFPS")));
+ SetCfgVal(pB,"\nShowFPS",val);
+
+ val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "checkSetFPS")));
+ SetCfgVal(pB,"\nUseFrameLimit",val);
+
+ val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "checkAutoFPSLimit")));
+ SetCfgVal(pB,"\nFPSDetection",val+1);
+
+ val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "checkFrameSkip")));
+ SetCfgVal(pB,"\nUseFrameSkip",val);
+
+ //Framerate stored *10
+ val = atof(gtk_entry_get_text(glade_xml_get_widget(xml, "entryFPS"))) * 10;
+ SetCfgVal(pB,"\nFrameRate",val);
+
+ val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "checkUseFixes")));
+ SetCfgVal(pB,"\nUseFixes",val);
+
+
+ val = 0;
+ for (i=0; i<11; i++)
+ {
+ sprintf(tempstr, "checkFix%d", i+1);
+ if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, tempstr))) )
+ val |= 1 << i;
+ }
+
+ SetCfgVal(pB,"\nCfgFixes",val);
+
+
+
+ if((in=fopen(cfg, WRITEBINARY))!=NULL)
+ {
+ fwrite(pB,strlen(pB),1,in);
+ fclose(in);
+ }
+
+ free(pB);
+
+ // Close the window and exit control from the plugin
+ gtk_exit (0);
+}
diff --git a/plugins/dfxvideo/hq2x.h b/plugins/dfxvideo/hq2x.h
new file mode 100644
index 0000000..e69b8e1
--- /dev/null
+++ b/plugins/dfxvideo/hq2x.h
@@ -0,0 +1,1870 @@
+#define P0 dst0[0]
+#define P1 dst0[1]
+#define P2 dst1[0]
+#define P3 dst1[1]
+#define MUR interp_32_diff(c[1], c[5])
+#define MDR interp_32_diff(c[5], c[7])
+#define MDL interp_32_diff(c[7], c[3])
+#define MUL interp_32_diff(c[3], c[1])
+#define IC(p0) c[p0]
+#define I11(p0,p1) interp_32_11(c[p0], c[p1])
+#define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
+#define I31(p0,p1) interp_32_31(c[p0], c[p1])
+#define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
+#define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
+#define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
+#define I53(p0,p1) interp_32_53(c[p0], c[p1])
+#define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
+#define I71(p0,p1) interp_32_71(c[p0], c[p1])
+#define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
+#define I97(p0,p1) interp_32_97(c[p0], c[p1])
+#define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
+#define I151(p0,p1) interp_32_151(c[p0], c[p1])
+
+case 0 :
+case 1 :
+case 4 :
+case 5 :
+case 32 :
+case 33 :
+case 36 :
+case 37 :
+case 128 :
+case 129 :
+case 132 :
+case 133 :
+case 160 :
+case 161 :
+case 164 :
+case 165 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I211(4, 1, 5);
+ P2 = I211(4, 3, 7);
+ P3 = I211(4, 5, 7);
+} break;
+case 2 :
+case 34 :
+case 130 :
+case 162 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I211(4, 3, 7);
+ P3 = I211(4, 5, 7);
+} break;
+case 3 :
+case 35 :
+case 131 :
+case 163 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 2);
+ P2 = I211(4, 3, 7);
+ P3 = I211(4, 5, 7);
+} break;
+case 6 :
+case 38 :
+case 134 :
+case 166 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 5);
+ P2 = I211(4, 3, 7);
+ P3 = I211(4, 5, 7);
+} break;
+case 7 :
+case 39 :
+case 135 :
+case 167 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 5);
+ P2 = I211(4, 3, 7);
+ P3 = I211(4, 5, 7);
+} break;
+case 8 :
+case 12 :
+case 136 :
+case 140 :
+{
+ P0 = I31(4, 0);
+ P1 = I211(4, 1, 5);
+ P2 = I31(4, 6);
+ P3 = I211(4, 5, 7);
+} break;
+case 9 :
+case 13 :
+case 137 :
+case 141 :
+{
+ P0 = I31(4, 1);
+ P1 = I211(4, 1, 5);
+ P2 = I31(4, 6);
+ P3 = I211(4, 5, 7);
+} break;
+case 10 :
+case 138 :
+{
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I211(4, 5, 7);
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 11 :
+case 139 :
+{
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I211(4, 5, 7);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 14 :
+case 142 :
+{
+ P2 = I31(4, 6);
+ P3 = I211(4, 5, 7);
+ if (MUL) {
+ P0 = I31(4, 0);
+ P1 = I31(4, 5);
+ } else {
+ P0 = I332(1, 3, 4);
+ P1 = I521(4, 1, 5);
+ }
+} break;
+case 15 :
+case 143 :
+{
+ P2 = I31(4, 6);
+ P3 = I211(4, 5, 7);
+ if (MUL) {
+ P0 = IC(4);
+ P1 = I31(4, 5);
+ } else {
+ P0 = I332(1, 3, 4);
+ P1 = I521(4, 1, 5);
+ }
+} break;
+case 16 :
+case 17 :
+case 48 :
+case 49 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 2);
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 8);
+} break;
+case 18 :
+case 50 :
+{
+ P0 = I31(4, 0);
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 8);
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 19 :
+case 51 :
+{
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 8);
+ if (MUR) {
+ P0 = I31(4, 3);
+ P1 = I31(4, 2);
+ } else {
+ P0 = I521(4, 1, 3);
+ P1 = I332(1, 5, 4);
+ }
+} break;
+case 20 :
+case 21 :
+case 52 :
+case 53 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 1);
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 8);
+} break;
+case 22 :
+case 54 :
+{
+ P0 = I31(4, 0);
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 8);
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 23 :
+case 55 :
+{
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 8);
+ if (MUR) {
+ P0 = I31(4, 3);
+ P1 = IC(4);
+ } else {
+ P0 = I521(4, 1, 3);
+ P1 = I332(1, 5, 4);
+ }
+} break;
+case 24 :
+case 66 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+} break;
+case 25 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+} break;
+case 26 :
+case 31 :
+case 95 :
+{
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 27 :
+case 75 :
+{
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 28 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 1);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+} break;
+case 29 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 1);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+} break;
+case 30 :
+case 86 :
+{
+ P0 = I31(4, 0);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 40 :
+case 44 :
+case 168 :
+case 172 :
+{
+ P0 = I31(4, 0);
+ P1 = I211(4, 1, 5);
+ P2 = I31(4, 7);
+ P3 = I211(4, 5, 7);
+} break;
+case 41 :
+case 45 :
+case 169 :
+case 173 :
+{
+ P0 = I31(4, 1);
+ P1 = I211(4, 1, 5);
+ P2 = I31(4, 7);
+ P3 = I211(4, 5, 7);
+} break;
+case 42 :
+case 170 :
+{
+ P1 = I31(4, 2);
+ P3 = I211(4, 5, 7);
+ if (MUL) {
+ P0 = I31(4, 0);
+ P2 = I31(4, 7);
+ } else {
+ P0 = I332(1, 3, 4);
+ P2 = I521(4, 3, 7);
+ }
+} break;
+case 43 :
+case 171 :
+{
+ P1 = I31(4, 2);
+ P3 = I211(4, 5, 7);
+ if (MUL) {
+ P0 = IC(4);
+ P2 = I31(4, 7);
+ } else {
+ P0 = I332(1, 3, 4);
+ P2 = I521(4, 3, 7);
+ }
+} break;
+case 46 :
+case 174 :
+{
+ P1 = I31(4, 5);
+ P2 = I31(4, 7);
+ P3 = I211(4, 5, 7);
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+} break;
+case 47 :
+case 175 :
+{
+ P1 = I31(4, 5);
+ P2 = I31(4, 7);
+ P3 = I211(4, 5, 7);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I1411(4, 1, 3);
+ }
+} break;
+case 56 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I31(4, 7);
+ P3 = I31(4, 8);
+} break;
+case 57 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 2);
+ P2 = I31(4, 7);
+ P3 = I31(4, 8);
+} break;
+case 58 :
+{
+ P2 = I31(4, 7);
+ P3 = I31(4, 8);
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 59 :
+{
+ P2 = I31(4, 7);
+ P3 = I31(4, 8);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 60 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 1);
+ P2 = I31(4, 7);
+ P3 = I31(4, 8);
+} break;
+case 61 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 1);
+ P2 = I31(4, 7);
+ P3 = I31(4, 8);
+} break;
+case 62 :
+{
+ P0 = I31(4, 0);
+ P2 = I31(4, 7);
+ P3 = I31(4, 8);
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 63 :
+{
+ P2 = I31(4, 7);
+ P3 = I31(4, 8);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I1411(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 64 :
+case 65 :
+case 68 :
+case 69 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I211(4, 1, 5);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+} break;
+case 67 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+} break;
+case 70 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 5);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+} break;
+case 71 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 5);
+ P2 = I31(4, 6);
+ P3 = I31(4, 8);
+} break;
+case 72 :
+case 76 :
+{
+ P0 = I31(4, 0);
+ P1 = I211(4, 1, 5);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+} break;
+case 73 :
+case 77 :
+{
+ P1 = I211(4, 1, 5);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P0 = I31(4, 1);
+ P2 = I31(4, 6);
+ } else {
+ P0 = I521(4, 3, 1);
+ P2 = I332(3, 7, 4);
+ }
+} break;
+case 74 :
+case 107 :
+case 123 :
+{
+ P1 = I31(4, 2);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 78 :
+{
+ P1 = I31(4, 5);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+} break;
+case 79 :
+{
+ P1 = I31(4, 5);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 80 :
+case 81 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+} break;
+case 82 :
+case 214 :
+case 222 :
+{
+ P0 = I31(4, 0);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 83 :
+{
+ P0 = I31(4, 3);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 84 :
+case 85 :
+{
+ P0 = I211(4, 1, 3);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P1 = I31(4, 1);
+ P3 = I31(4, 8);
+ } else {
+ P1 = I521(4, 5, 1);
+ P3 = I332(5, 7, 4);
+ }
+} break;
+case 87 :
+{
+ P0 = I31(4, 3);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 88 :
+case 248 :
+case 250 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+} break;
+case 89 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 2);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+} break;
+case 90 :
+{
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 91 :
+{
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 92 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 1);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+} break;
+case 93 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 1);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+} break;
+case 94 :
+{
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 96 :
+case 97 :
+case 100 :
+case 101 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I211(4, 1, 5);
+ P2 = I31(4, 3);
+ P3 = I31(4, 8);
+} break;
+case 98 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I31(4, 3);
+ P3 = I31(4, 8);
+} break;
+case 99 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 2);
+ P2 = I31(4, 3);
+ P3 = I31(4, 8);
+} break;
+case 102 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 5);
+ P2 = I31(4, 3);
+ P3 = I31(4, 8);
+} break;
+case 103 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 5);
+ P2 = I31(4, 3);
+ P3 = I31(4, 8);
+} break;
+case 104 :
+case 108 :
+{
+ P0 = I31(4, 0);
+ P1 = I211(4, 1, 5);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+} break;
+case 105 :
+case 109 :
+{
+ P1 = I211(4, 1, 5);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P0 = I31(4, 1);
+ P2 = IC(4);
+ } else {
+ P0 = I521(4, 3, 1);
+ P2 = I332(3, 7, 4);
+ }
+} break;
+case 106 :
+case 120 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+} break;
+case 110 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 5);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+} break;
+case 111 :
+{
+ P1 = I31(4, 5);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I1411(4, 1, 3);
+ }
+} break;
+case 112 :
+case 113 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 2);
+ if (MDR) {
+ P2 = I31(4, 3);
+ P3 = I31(4, 8);
+ } else {
+ P2 = I521(4, 7, 3);
+ P3 = I332(5, 7, 4);
+ }
+} break;
+case 114 :
+{
+ P0 = I31(4, 0);
+ P2 = I31(4, 3);
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 115 :
+{
+ P0 = I31(4, 3);
+ P2 = I31(4, 3);
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 116 :
+case 117 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 1);
+ P2 = I31(4, 3);
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+} break;
+case 118 :
+{
+ P0 = I31(4, 0);
+ P2 = I31(4, 3);
+ P3 = I31(4, 8);
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 119 :
+{
+ P2 = I31(4, 3);
+ P3 = I31(4, 8);
+ if (MUR) {
+ P0 = I31(4, 3);
+ P1 = IC(4);
+ } else {
+ P0 = I521(4, 1, 3);
+ P1 = I332(1, 5, 4);
+ }
+} break;
+case 121 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 2);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+} break;
+case 122 :
+{
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = I31(4, 8);
+ } else {
+ P3 = I611(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 124 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 1);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+} break;
+case 125 :
+{
+ P1 = I31(4, 1);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P0 = I31(4, 1);
+ P2 = IC(4);
+ } else {
+ P0 = I521(4, 3, 1);
+ P2 = I332(3, 7, 4);
+ }
+} break;
+case 126 :
+{
+ P0 = I31(4, 0);
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 127 :
+{
+ P3 = I31(4, 8);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I1411(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 144 :
+case 145 :
+case 176 :
+case 177 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 2);
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 7);
+} break;
+case 146 :
+case 178 :
+{
+ P0 = I31(4, 0);
+ P2 = I211(4, 3, 7);
+ if (MUR) {
+ P1 = I31(4, 2);
+ P3 = I31(4, 7);
+ } else {
+ P1 = I332(1, 5, 4);
+ P3 = I521(4, 5, 7);
+ }
+} break;
+case 147 :
+case 179 :
+{
+ P0 = I31(4, 3);
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 7);
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 148 :
+case 149 :
+case 180 :
+case 181 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 1);
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 7);
+} break;
+case 150 :
+case 182 :
+{
+ P0 = I31(4, 0);
+ P2 = I211(4, 3, 7);
+ if (MUR) {
+ P1 = IC(4);
+ P3 = I31(4, 7);
+ } else {
+ P1 = I332(1, 5, 4);
+ P3 = I521(4, 5, 7);
+ }
+} break;
+case 151 :
+case 183 :
+{
+ P0 = I31(4, 3);
+ P2 = I211(4, 3, 7);
+ P3 = I31(4, 7);
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I1411(4, 1, 5);
+ }
+} break;
+case 152 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 7);
+} break;
+case 153 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 7);
+} break;
+case 154 :
+{
+ P2 = I31(4, 6);
+ P3 = I31(4, 7);
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 155 :
+{
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 7);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 156 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 1);
+ P2 = I31(4, 6);
+ P3 = I31(4, 7);
+} break;
+case 157 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 1);
+ P2 = I31(4, 6);
+ P3 = I31(4, 7);
+} break;
+case 158 :
+{
+ P2 = I31(4, 6);
+ P3 = I31(4, 7);
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 159 :
+{
+ P2 = I31(4, 6);
+ P3 = I31(4, 7);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I1411(4, 1, 5);
+ }
+} break;
+case 184 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I31(4, 7);
+ P3 = I31(4, 7);
+} break;
+case 185 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 2);
+ P2 = I31(4, 7);
+ P3 = I31(4, 7);
+} break;
+case 186 :
+{
+ P2 = I31(4, 7);
+ P3 = I31(4, 7);
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 187 :
+{
+ P1 = I31(4, 2);
+ P3 = I31(4, 7);
+ if (MUL) {
+ P0 = IC(4);
+ P2 = I31(4, 7);
+ } else {
+ P0 = I332(1, 3, 4);
+ P2 = I521(4, 3, 7);
+ }
+} break;
+case 188 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 1);
+ P2 = I31(4, 7);
+ P3 = I31(4, 7);
+} break;
+case 189 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 1);
+ P2 = I31(4, 7);
+ P3 = I31(4, 7);
+} break;
+case 190 :
+{
+ P0 = I31(4, 0);
+ P2 = I31(4, 7);
+ if (MUR) {
+ P1 = IC(4);
+ P3 = I31(4, 7);
+ } else {
+ P1 = I332(1, 5, 4);
+ P3 = I521(4, 5, 7);
+ }
+} break;
+case 191 :
+{
+ P2 = I31(4, 7);
+ P3 = I31(4, 7);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I1411(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I1411(4, 1, 5);
+ }
+} break;
+case 192 :
+case 193 :
+case 196 :
+case 197 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I211(4, 1, 5);
+ P2 = I31(4, 6);
+ P3 = I31(4, 5);
+} break;
+case 194 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 5);
+} break;
+case 195 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 5);
+} break;
+case 198 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 5);
+ P2 = I31(4, 6);
+ P3 = I31(4, 5);
+} break;
+case 199 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 5);
+ P2 = I31(4, 6);
+ P3 = I31(4, 5);
+} break;
+case 200 :
+case 204 :
+{
+ P0 = I31(4, 0);
+ P1 = I211(4, 1, 5);
+ if (MDL) {
+ P2 = I31(4, 6);
+ P3 = I31(4, 5);
+ } else {
+ P2 = I332(3, 7, 4);
+ P3 = I521(4, 7, 5);
+ }
+} break;
+case 201 :
+case 205 :
+{
+ P0 = I31(4, 1);
+ P1 = I211(4, 1, 5);
+ P3 = I31(4, 5);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+} break;
+case 202 :
+{
+ P1 = I31(4, 2);
+ P3 = I31(4, 5);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+} break;
+case 203 :
+{
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ P3 = I31(4, 5);
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 206 :
+{
+ P1 = I31(4, 5);
+ P3 = I31(4, 5);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+} break;
+case 207 :
+{
+ P2 = I31(4, 6);
+ P3 = I31(4, 5);
+ if (MUL) {
+ P0 = IC(4);
+ P1 = I31(4, 5);
+ } else {
+ P0 = I332(1, 3, 4);
+ P1 = I521(4, 1, 5);
+ }
+} break;
+case 208 :
+case 209 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+} break;
+case 210 :
+case 216 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+} break;
+case 211 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+} break;
+case 212 :
+case 213 :
+{
+ P0 = I211(4, 1, 3);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P1 = I31(4, 1);
+ P3 = IC(4);
+ } else {
+ P1 = I521(4, 5, 1);
+ P3 = I332(5, 7, 4);
+ }
+} break;
+case 215 :
+{
+ P0 = I31(4, 3);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I1411(4, 1, 5);
+ }
+} break;
+case 217 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+} break;
+case 218 :
+{
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 219 :
+{
+ P1 = I31(4, 2);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 220 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 1);
+ if (MDL) {
+ P2 = I31(4, 6);
+ } else {
+ P2 = I611(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+} break;
+case 221 :
+{
+ P0 = I31(4, 1);
+ P2 = I31(4, 6);
+ if (MDR) {
+ P1 = I31(4, 1);
+ P3 = IC(4);
+ } else {
+ P1 = I521(4, 5, 1);
+ P3 = I332(5, 7, 4);
+ }
+} break;
+case 223 :
+{
+ P2 = I31(4, 6);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I1411(4, 1, 5);
+ }
+} break;
+case 224 :
+case 225 :
+case 228 :
+case 229 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I211(4, 1, 5);
+ P2 = I31(4, 3);
+ P3 = I31(4, 5);
+} break;
+case 226 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 2);
+ P2 = I31(4, 3);
+ P3 = I31(4, 5);
+} break;
+case 227 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 2);
+ P2 = I31(4, 3);
+ P3 = I31(4, 5);
+} break;
+case 230 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 5);
+ P2 = I31(4, 3);
+ P3 = I31(4, 5);
+} break;
+case 231 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 5);
+ P2 = I31(4, 3);
+ P3 = I31(4, 5);
+} break;
+case 232 :
+case 236 :
+{
+ P0 = I31(4, 0);
+ P1 = I211(4, 1, 5);
+ if (MDL) {
+ P2 = IC(4);
+ P3 = I31(4, 5);
+ } else {
+ P2 = I332(3, 7, 4);
+ P3 = I521(4, 7, 5);
+ }
+} break;
+case 233 :
+case 237 :
+{
+ P0 = I31(4, 1);
+ P1 = I211(4, 1, 5);
+ P3 = I31(4, 5);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I1411(4, 3, 7);
+ }
+} break;
+case 234 :
+{
+ P1 = I31(4, 2);
+ P3 = I31(4, 5);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = I31(4, 0);
+ } else {
+ P0 = I611(4, 1, 3);
+ }
+} break;
+case 235 :
+{
+ P1 = I31(4, 2);
+ P3 = I31(4, 5);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I1411(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 238 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 5);
+ if (MDL) {
+ P2 = IC(4);
+ P3 = I31(4, 5);
+ } else {
+ P2 = I332(3, 7, 4);
+ P3 = I521(4, 7, 5);
+ }
+} break;
+case 239 :
+{
+ P1 = I31(4, 5);
+ P3 = I31(4, 5);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I1411(4, 3, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I1411(4, 1, 3);
+ }
+} break;
+case 240 :
+case 241 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 2);
+ if (MDR) {
+ P2 = I31(4, 3);
+ P3 = IC(4);
+ } else {
+ P2 = I521(4, 7, 3);
+ P3 = I332(5, 7, 4);
+ }
+} break;
+case 242 :
+{
+ P0 = I31(4, 0);
+ P2 = I31(4, 3);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = I31(4, 2);
+ } else {
+ P1 = I611(4, 1, 5);
+ }
+} break;
+case 243 :
+{
+ P0 = I31(4, 3);
+ P1 = I31(4, 2);
+ if (MDR) {
+ P2 = I31(4, 3);
+ P3 = IC(4);
+ } else {
+ P2 = I521(4, 7, 3);
+ P3 = I332(5, 7, 4);
+ }
+} break;
+case 244 :
+case 245 :
+{
+ P0 = I211(4, 1, 3);
+ P1 = I31(4, 1);
+ P2 = I31(4, 3);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I1411(4, 5, 7);
+ }
+} break;
+case 246 :
+{
+ P0 = I31(4, 0);
+ P2 = I31(4, 3);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I1411(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 247 :
+{
+ P0 = I31(4, 3);
+ P2 = I31(4, 3);
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I1411(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I1411(4, 1, 5);
+ }
+} break;
+case 249 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 2);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I1411(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+} break;
+case 251 :
+{
+ P1 = I31(4, 2);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I1411(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I211(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I211(4, 1, 3);
+ }
+} break;
+case 252 :
+{
+ P0 = I31(4, 0);
+ P1 = I31(4, 1);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I1411(4, 5, 7);
+ }
+} break;
+case 253 :
+{
+ P0 = I31(4, 1);
+ P1 = I31(4, 1);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I1411(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I1411(4, 5, 7);
+ }
+} break;
+case 254 :
+{
+ P0 = I31(4, 0);
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I211(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I1411(4, 5, 7);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I211(4, 1, 5);
+ }
+} break;
+case 255 :
+{
+ if (MDL) {
+ P2 = IC(4);
+ } else {
+ P2 = I1411(4, 3, 7);
+ }
+ if (MDR) {
+ P3 = IC(4);
+ } else {
+ P3 = I1411(4, 5, 7);
+ }
+ if (MUL) {
+ P0 = IC(4);
+ } else {
+ P0 = I1411(4, 1, 3);
+ }
+ if (MUR) {
+ P1 = IC(4);
+ } else {
+ P1 = I1411(4, 1, 5);
+ }
+} break;
+
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef MUR
+#undef MDR
+#undef MDL
+#undef MUL
+#undef IC
+#undef I11
+#undef I211
+#undef I31
+#undef I332
+#undef I431
+#undef I521
+#undef I53
+#undef I611
+#undef I71
+#undef I772
+#undef I97
+#undef I1411
+#undef I151
diff --git a/plugins/dfxvideo/hq3x.h b/plugins/dfxvideo/hq3x.h
new file mode 100644
index 0000000..4809b79
--- /dev/null
+++ b/plugins/dfxvideo/hq3x.h
@@ -0,0 +1,2970 @@
+/*
+ * This file is part of the Advance project.
+ *
+ * Copyright (C) 2004 Andrea Mazzoleni
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * In addition, as a special exception, Andrea Mazzoleni
+ * gives permission to link the code of this program with
+ * the MAME library (or with modified versions of MAME that use the
+ * same license as MAME), and distribute linked combinations including
+ * the two. You must obey the GNU General Public License in all
+ * respects for all of the code used other than MAME. If you modify
+ * this file, you may extend this exception to your version of the
+ * file, but you are not obligated to do so. If you do not wish to
+ * do so, delete this exception statement from your version.
+ */
+
+/*
+ * This effect is a rewritten implementation of the hq effect made by Maxim Stepin
+ */
+
+#define P0 dst0[0]
+#define P1 dst0[1]
+#define P2 dst0[2]
+#define P3 dst1[0]
+#define P4 dst1[1]
+#define P5 dst1[2]
+#define P6 dst2[0]
+#define P7 dst2[1]
+#define P8 dst2[2]
+#define MUR interp_32_diff(c[1], c[5])
+#define MDR interp_32_diff(c[5], c[7])
+#define MDL interp_32_diff(c[7], c[3])
+#define MUL interp_32_diff(c[3], c[1])
+#define IC(p0) c[p0]
+#define I11(p0,p1) interp_32_11(c[p0], c[p1])
+#define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
+#define I31(p0,p1) interp_32_31(c[p0], c[p1])
+#define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
+#define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
+#define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
+#define I53(p0,p1) interp_32_53(c[p0], c[p1])
+#define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
+#define I71(p0,p1) interp_32_71(c[p0], c[p1])
+#define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
+#define I97(p0,p1) interp_32_97(c[p0], c[p1])
+#define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
+#define I151(p0,p1) interp_32_151(c[p0], c[p1])
+
+case 0 :
+case 1 :
+case 4 :
+case 5 :
+case 32 :
+case 33 :
+case 36 :
+case 37 :
+case 128 :
+case 129 :
+case 132 :
+case 133 :
+case 160 :
+case 161 :
+case 164 :
+case 165 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+
+} break;
+case 2 :
+case 34 :
+case 130 :
+case 162 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+} break;
+case 3 :
+case 35 :
+case 131 :
+case 163 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+} break;
+case 6 :
+case 38 :
+case 134 :
+case 166 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+} break;
+case 7 :
+case 39 :
+case 135 :
+case 167 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+} break;
+case 8 :
+case 12 :
+case 136 :
+case 140 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+} break;
+case 9 :
+case 13 :
+case 137 :
+case 141 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+} break;
+case 10 :
+case 138 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+if (MUL) {
+ P0 = I31(4, 0);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+} break;
+case 11 :
+case 139 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+} break;
+case 14 :
+case 142 :
+{
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+if (MUL) {
+ P0 = I31(4, 0);
+ P1 = IC(4);
+ P2 = I31(4,5);
+ P3 = IC(4);
+} else {
+ P0 = I11(1, 3);
+ P1 = I31(1, 4);
+ P2 = I211(4, 1, 5);
+ P3 = I31(4, 3);
+}
+} break;
+case 15 :
+case 143 :
+{
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P2 = I31(4,5);
+ P3 = IC(4);
+} else {
+ P0 = I11(1, 3);
+ P1 = I31(1, 4);
+ P2 = I211(4, 1, 5);
+ P3 = I31(4, 3);
+}
+} break;
+case 16 :
+case 17 :
+case 48 :
+case 49 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 18 :
+case 50 :
+{
+P0 = I31(4, 0);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUR) {
+ P1 = IC(4);
+ P2 = I31(4, 2);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 19 :
+case 51 :
+{
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUR) {
+ P0 = I31(4, 3);
+ P1 = IC(4);
+ P2 = I31(4, 2);
+ P5 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+ P1 = I31(1, 4);
+ P2 = I11(1, 5);
+ P5 = I31(4,5);
+}
+} break;
+case 20 :
+case 21 :
+case 52 :
+case 53 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 22 :
+case 54 :
+{
+P0 = I31(4, 0);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 23 :
+case 55 :
+{
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUR) {
+ P0 = I31(4, 3);
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+ P1 = I31(1, 4);
+ P2 = I11(1, 5);
+ P5 = I31(4,5);
+}
+} break;
+case 24 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 25 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 26 :
+case 31 :
+{
+P1 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUL) {
+ P0 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P3 = I71(4, 3);
+}
+if (MUR) {
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 27 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+} break;
+case 28 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 29 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 30 :
+{
+P0 = I31(4, 0);
+P3 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 40 :
+case 44 :
+case 168 :
+case 172 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+} break;
+case 41 :
+case 45 :
+case 169 :
+case 173 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+} break;
+case 42 :
+case 170 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+if (MUL) {
+ P0 = I31(4, 0);
+ P1 = IC(4);
+ P3 = IC(4);
+ P6 = I31(4, 7);
+} else {
+ P0 = I11(1, 3);
+ P1 = I31(4,1);
+ P3 = I31(3, 4);
+ P6 = I211(4, 3, 7);
+}
+} break;
+case 43 :
+case 171 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+ P6 = I31(4, 7);
+} else {
+ P0 = I11(1, 3);
+ P1 = I31(4,1);
+ P3 = I31(3, 4);
+ P6 = I211(4, 3, 7);
+}
+} break;
+case 46 :
+case 174 :
+{
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+} break;
+case 47 :
+case 175 :
+{
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I211(4, 5, 7);
+if (MUL) {
+ P0 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+}
+} break;
+case 56 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 57 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 58 :
+{
+P1 = IC(4);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 59 :
+{
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 60 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 61 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+} break;
+case 62 :
+{
+P0 = I31(4, 0);
+P3 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 63 :
+{
+P1 = IC(4);
+P3 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 8);
+if (MUL) {
+ P0 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 64 :
+case 65 :
+case 68 :
+case 69 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 66 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 67 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 70 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 71 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 72 :
+case 76 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4, 8);
+if (MDL) {
+ P3 = IC(4);
+ P6 = I31(4, 6);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+} break;
+case 73 :
+case 77 :
+{
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4, 8);
+if (MDL) {
+ P0 = I31(4,1);
+ P3 = IC(4);
+ P6 = I31(4, 6);
+ P7 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+ P3 = I31(3, 4);
+ P6 = I11(3, 7);
+ P7 = I31(4, 7);
+}
+} break;
+case 74 :
+case 107 :
+{
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4, 8);
+if (MDL) {
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+}
+} break;
+case 75 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4, 8);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+} break;
+case 78 :
+{
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = IC(4);
+P8 = I31(4, 8);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+} break;
+case 79 :
+{
+P2 = I31(4,5);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = IC(4);
+P8 = I31(4, 8);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+} break;
+case 80 :
+case 81 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = I31(4, 8);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 82 :
+case 214 :
+{
+P0 = I31(4, 0);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+}
+} break;
+case 83 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = IC(4);
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 84 :
+case 85 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P2 = I31(4,1);
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = I31(4, 8);
+} else {
+ P2 = I211(4, 1, 5);
+ P5 = I31(5, 4);
+ P7 = I31(4, 7);
+ P8 = I11(5, 7);
+}
+} break;
+case 86 :
+{
+P0 = I31(4, 0);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4, 8);
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 87 :
+{
+P0 = I31(4, 3);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 6);
+P7 = IC(4);
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 88 :
+case 248 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P4 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+}
+if (MDR) {
+ P5 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 89 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 90 :
+{
+P1 = IC(4);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 91 :
+{
+P4 = IC(4);
+P5 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 92 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 93 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 94 :
+{
+P3 = IC(4);
+P4 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 95 :
+{
+P1 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4, 8);
+if (MUL) {
+ P0 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P3 = I71(4, 3);
+}
+if (MUR) {
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 96 :
+case 97 :
+case 100 :
+case 101 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 98 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 99 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 102 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 103 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4, 8);
+} break;
+case 104 :
+case 108 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4, 8);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+} break;
+case 105 :
+case 109 :
+{
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4, 8);
+if (MDL) {
+ P0 = I31(4,1);
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+ P3 = I31(3, 4);
+ P6 = I11(3, 7);
+ P7 = I31(4, 7);
+}
+} break;
+case 106 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4, 8);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+} break;
+case 110 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4,5);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4, 8);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+} break;
+case 111 :
+{
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4, 8);
+if (MDL) {
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+}
+} break;
+case 112 :
+case 113 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+if (MDR) {
+ P5 = IC(4);
+ P6 = I31(4, 3);
+ P7 = IC(4);
+ P8 = I31(4, 8);
+} else {
+ P5 = I31(4,5);
+ P6 = I211(4, 3, 7);
+ P7 = I31(7, 4);
+ P8 = I11(5, 7);
+}
+} break;
+case 114 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 3);
+P7 = IC(4);
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 115 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 3);
+P7 = IC(4);
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 116 :
+case 117 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 3);
+P7 = IC(4);
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 118 :
+{
+P0 = I31(4, 0);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4, 8);
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 119 :
+{
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4, 8);
+if (MUR) {
+ P0 = I31(4, 3);
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+ P1 = I31(1, 4);
+ P2 = I11(1, 5);
+ P5 = I31(4,5);
+}
+} break;
+case 120 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = IC(4);
+P8 = I31(4, 8);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+} break;
+case 121 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = IC(4);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 122 :
+{
+P1 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+if (MDR) {
+ P8 = I31(4, 8);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 123 :
+{
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P8 = I31(4, 8);
+if (MDL) {
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+}
+} break;
+case 124 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P4 = IC(4);
+P5 = IC(4);
+P8 = I31(4, 8);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+} break;
+case 125 :
+{
+P1 = I31(4,1);
+P2 = I31(4,1);
+P4 = IC(4);
+P5 = IC(4);
+P8 = I31(4, 8);
+if (MDL) {
+ P0 = I31(4,1);
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+ P3 = I31(3, 4);
+ P6 = I11(3, 7);
+ P7 = I31(4, 7);
+}
+} break;
+case 126 :
+{
+P0 = I31(4, 0);
+P4 = IC(4);
+P8 = I31(4, 8);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 127 :
+{
+P4 = IC(4);
+P8 = I31(4, 8);
+if (MDL) {
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+if (MUR) {
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 144 :
+case 145 :
+case 176 :
+case 177 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 146 :
+case 178 :
+{
+P0 = I31(4, 0);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+if (MUR) {
+ P1 = IC(4);
+ P2 = I31(4, 2);
+ P5 = IC(4);
+ P8 = I31(4, 7);
+} else {
+ P1 = I31(4,1);
+ P2 = I11(1, 5);
+ P5 = I31(5, 4);
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 147 :
+case 179 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 148 :
+case 149 :
+case 180 :
+case 181 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 150 :
+case 182 :
+{
+P0 = I31(4, 0);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+ P8 = I31(4, 7);
+} else {
+ P1 = I31(4,1);
+ P2 = I11(1, 5);
+ P5 = I31(5, 4);
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 151 :
+case 183 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I211(4, 3, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUR) {
+ P2 = IC(4);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 152 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 153 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 154 :
+{
+P1 = IC(4);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 155 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+} break;
+case 156 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 157 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 158 :
+{
+P3 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+ P5 = I71(4, 5);
+}
+} break;
+case 159 :
+{
+P1 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUL) {
+ P0 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P3 = I71(4, 3);
+}
+if (MUR) {
+ P2 = IC(4);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 184 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 185 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 186 :
+{
+P1 = IC(4);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 187 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = IC(4);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+ P6 = I31(4, 7);
+} else {
+ P0 = I11(1, 3);
+ P1 = I31(4,1);
+ P3 = I31(3, 4);
+ P6 = I211(4, 3, 7);
+}
+} break;
+case 188 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 189 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+} break;
+case 190 :
+{
+P0 = I31(4, 0);
+P3 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+ P8 = I31(4, 7);
+} else {
+ P1 = I31(4,1);
+ P2 = I11(1, 5);
+ P5 = I31(5, 4);
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 191 :
+{
+P1 = IC(4);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 7);
+P7 = I31(4, 7);
+P8 = I31(4, 7);
+if (MUL) {
+ P0 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = IC(4);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 192 :
+case 193 :
+case 196 :
+case 197 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 194 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 195 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 198 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 199 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 200 :
+case 204 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P4 = IC(4);
+P5 = I31(4,5);
+if (MDL) {
+ P3 = IC(4);
+ P6 = I31(4, 6);
+ P7 = IC(4);
+ P8 = I31(4,5);
+} else {
+ P3 = I31(4, 3);
+ P6 = I11(3, 7);
+ P7 = I31(7, 4);
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 201 :
+case 205 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = IC(4);
+P8 = I31(4,5);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+} break;
+case 202 :
+{
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = IC(4);
+P8 = I31(4,5);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+} break;
+case 203 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4,5);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+} break;
+case 206 :
+{
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = IC(4);
+P8 = I31(4,5);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+} break;
+case 207 :
+{
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 6);
+P7 = IC(4);
+P8 = I31(4,5);
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P2 = I31(4,5);
+ P3 = IC(4);
+} else {
+ P0 = I11(1, 3);
+ P1 = I31(1, 4);
+ P2 = I211(4, 1, 5);
+ P3 = I31(4, 3);
+}
+} break;
+case 208 :
+case 209 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 210 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 211 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 212 :
+case 213 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P2 = I31(4,1);
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P2 = I211(4, 1, 5);
+ P5 = I31(5, 4);
+ P7 = I31(4, 7);
+ P8 = I11(5, 7);
+}
+} break;
+case 215 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+if (MUR) {
+ P2 = IC(4);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 216 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 217 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 218 :
+{
+P1 = IC(4);
+P3 = IC(4);
+P4 = IC(4);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 219 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+ P3 = I71(4, 3);
+}
+} break;
+case 220 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+if (MDL) {
+ P6 = I31(4, 6);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 221 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P2 = I31(4,1);
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P2 = I211(4, 1, 5);
+ P5 = I31(5, 4);
+ P7 = I31(4, 7);
+ P8 = I11(5, 7);
+}
+} break;
+case 222 :
+{
+P0 = I31(4, 0);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+}
+} break;
+case 223 :
+{
+P4 = IC(4);
+P6 = I31(4, 6);
+if (MDR) {
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+if (MUL) {
+ P0 = IC(4);
+ P3 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P3 = I71(4, 3);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+ P5 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I211(4, 1, 5);
+ P5 = I71(4, 5);
+}
+} break;
+case 224 :
+case 225 :
+case 228 :
+case 229 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 226 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 227 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 230 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 231 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = I31(4,5);
+P6 = I31(4, 3);
+P7 = IC(4);
+P8 = I31(4,5);
+} break;
+case 232 :
+case 236 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P4 = IC(4);
+P5 = I31(4,5);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+ P8 = I31(4,5);
+} else {
+ P3 = I31(4, 3);
+ P6 = I11(3, 7);
+ P7 = I31(7, 4);
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 233 :
+case 237 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I211(4, 1, 5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = IC(4);
+P8 = I31(4,5);
+if (MDL) {
+ P6 = IC(4);
+} else {
+ P6 = I211(4, 3, 7);
+}
+} break;
+case 234 :
+{
+P1 = IC(4);
+P2 = I31(4, 2);
+P4 = IC(4);
+P5 = I31(4,5);
+P8 = I31(4,5);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+ P7 = I71(4, 7);
+}
+if (MUL) {
+ P0 = I31(4, 0);
+} else {
+ P0 = I211(4, 1, 3);
+}
+} break;
+case 235 :
+{
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = IC(4);
+P8 = I31(4,5);
+if (MDL) {
+ P6 = IC(4);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+}
+} break;
+case 238 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4,5);
+P4 = IC(4);
+P5 = I31(4,5);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+ P8 = I31(4,5);
+} else {
+ P3 = I31(4, 3);
+ P6 = I11(3, 7);
+ P7 = I31(7, 4);
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 239 :
+{
+P1 = IC(4);
+P2 = I31(4,5);
+P3 = IC(4);
+P4 = IC(4);
+P5 = I31(4,5);
+P7 = IC(4);
+P8 = I31(4,5);
+if (MDL) {
+ P6 = IC(4);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+}
+} break;
+case 240 :
+case 241 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+if (MDR) {
+ P5 = IC(4);
+ P6 = I31(4, 3);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I31(4,5);
+ P6 = I211(4, 3, 7);
+ P7 = I31(7, 4);
+ P8 = I11(5, 7);
+}
+} break;
+case 242 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P3 = I31(4, 3);
+P4 = IC(4);
+P6 = I31(4, 3);
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I772(5, 7, 4);
+}
+if (MUR) {
+ P2 = I31(4, 2);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 243 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P2 = I31(4, 2);
+P3 = I31(4, 3);
+P4 = IC(4);
+if (MDR) {
+ P5 = IC(4);
+ P6 = I31(4, 3);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I31(4,5);
+ P6 = I211(4, 3, 7);
+ P7 = I31(7, 4);
+ P8 = I11(5, 7);
+}
+} break;
+case 244 :
+case 245 :
+{
+P0 = I211(4, 1, 3);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 3);
+P7 = IC(4);
+if (MDR) {
+ P8 = IC(4);
+} else {
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 246 :
+{
+P0 = I31(4, 0);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 3);
+P7 = IC(4);
+if (MDR) {
+ P8 = IC(4);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+}
+} break;
+case 247 :
+{
+P0 = I31(4, 3);
+P1 = IC(4);
+P3 = I31(4, 3);
+P4 = IC(4);
+P5 = IC(4);
+P6 = I31(4, 3);
+P7 = IC(4);
+if (MDR) {
+ P8 = IC(4);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUR) {
+ P2 = IC(4);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+case 249 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4, 2);
+P3 = IC(4);
+P4 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = IC(4);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P5 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 250 :
+{
+P0 = I31(4, 0);
+P1 = IC(4);
+P2 = I31(4, 2);
+P4 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+}
+if (MDR) {
+ P5 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P8 = I772(5, 7, 4);
+}
+} break;
+case 251 :
+{
+P2 = I31(4, 2);
+P4 = IC(4);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+ P7 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I211(4, 3, 7);
+ P7 = I71(4, 7);
+}
+if (MDR) {
+ P5 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P8 = I772(5, 7, 4);
+}
+if (MUL) {
+ P0 = IC(4);
+ P1 = IC(4);
+} else {
+ P0 = I772(1, 3, 4);
+ P1 = I71(4, 1);
+}
+} break;
+case 252 :
+{
+P0 = I31(4, 0);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P4 = IC(4);
+P5 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+}
+if (MDR) {
+ P8 = IC(4);
+} else {
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 253 :
+{
+P0 = I31(4,1);
+P1 = I31(4,1);
+P2 = I31(4,1);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = IC(4);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P8 = IC(4);
+} else {
+ P8 = I211(4, 5, 7);
+}
+} break;
+case 254 :
+{
+P0 = I31(4, 0);
+P4 = IC(4);
+if (MDL) {
+ P3 = IC(4);
+ P6 = IC(4);
+} else {
+ P3 = I71(4, 3);
+ P6 = I772(3, 7, 4);
+}
+if (MDR) {
+ P5 = IC(4);
+ P7 = IC(4);
+ P8 = IC(4);
+} else {
+ P5 = I71(4, 5);
+ P7 = I71(4, 7);
+ P8 = I211(4, 5, 7);
+}
+if (MUR) {
+ P1 = IC(4);
+ P2 = IC(4);
+} else {
+ P1 = I71(4, 1);
+ P2 = I772(1, 5, 4);
+}
+} break;
+case 255 :
+{
+P1 = IC(4);
+P3 = IC(4);
+P4 = IC(4);
+P5 = IC(4);
+P7 = IC(4);
+if (MDL) {
+ P6 = IC(4);
+} else {
+ P6 = I211(4, 3, 7);
+}
+if (MDR) {
+ P8 = IC(4);
+} else {
+ P8 = I211(4, 5, 7);
+}
+if (MUL) {
+ P0 = IC(4);
+} else {
+ P0 = I211(4, 1, 3);
+}
+if (MUR) {
+ P2 = IC(4);
+} else {
+ P2 = I211(4, 1, 5);
+}
+} break;
+
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+#undef MUR
+#undef MDR
+#undef MDL
+#undef MUL
+#undef IC
+#undef I11
+#undef I211
+#undef I31
+#undef I332
+#undef I431
+#undef I521
+#undef I53
+#undef I611
+#undef I71
+#undef I772
+#undef I97
+#undef I1411
+#undef I151
diff --git a/plugins/dfxvideo/i386.asm b/plugins/dfxvideo/i386.asm
new file mode 100644
index 0000000..86d6e23
--- /dev/null
+++ b/plugins/dfxvideo/i386.asm
@@ -0,0 +1,67 @@
+; i386.asm - description
+; -------------------
+; begin : Sun Nov 08 2001
+; copyright : (C) 2001 by Pete Bernert
+; email : BlackDove@addcom.de
+
+; ported from inline gcc to nasm by linuzappz
+
+
+; 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. See also the license.txt file for *
+; additional informations. *
+
+
+bits 32
+
+section .text
+
+%include "macros.inc"
+
+NEWSYM i386_BGR24to16
+ push ebp
+ mov ebp, esp
+ push ebx
+ push edx
+
+ mov eax, [ebp+8] ; this can hold the G value
+ mov ebx, eax ; this can hold the R value
+ mov edx, eax ; this can hold the B value
+ shr ebx, 3 ; move the R value
+ and edx, 00f80000h ; mask the B value
+ shr edx, 9 ; move the B value
+ and eax, 00f800h ; mask the G value
+ shr eax, 6 ; move the G value
+ and ebx, 0000001fh ; mask the R value
+ or eax, ebx ; add R to G value
+ or eax, edx ; add B to RG value
+ pop edx
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ ret
+
+NEWSYM i386_shl10idiv
+ push ebp
+ mov ebp, esp
+ push ebx
+ push edx
+
+ mov eax, [ebp+8]
+ mov ebx, [ebp+12]
+ mov edx, eax
+ shl eax, 10
+ sar edx, 22
+ idiv ebx
+
+ pop edx
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ ret
+%ifidn __OUTPUT_FORMAT__,elf
+section .note.GNU-stack noalloc noexec nowrite progbits
+%endif
+
diff --git a/plugins/dfxvideo/interp.h b/plugins/dfxvideo/interp.h
new file mode 100644
index 0000000..3043237
--- /dev/null
+++ b/plugins/dfxvideo/interp.h
@@ -0,0 +1,298 @@
+/*
+ * This file is part of the Advance project.
+ *
+ * Copyright (C) 2003 Andrea Mazzoleni
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * In addition, as a special exception, Andrea Mazzoleni
+ * gives permission to link the code of this program with
+ * the MAME library (or with modified versions of MAME that use the
+ * same license as MAME), and distribute linked combinations including
+ * the two. You must obey the GNU General Public License in all
+ * respects for all of the code used other than MAME. If you modify
+ * this file, you may extend this exception to your version of the
+ * file, but you are not obligated to do so. If you do not wish to
+ * do so, delete this exception statement from your version.
+ */
+
+#ifndef __INTERP_H
+#define __INTERP_H
+
+/***************************************************************************/
+/* Basic types */
+
+/***************************************************************************/
+/* interpolation */
+
+static unsigned interp_mask[2];
+static unsigned interp_bits_per_pixel;
+
+#define INTERP_16_MASK_1(v) (v & interp_mask[0])
+#define INTERP_16_MASK_2(v) (v & interp_mask[1])
+
+static __inline unsigned short interp_16_521(unsigned short p1, unsigned short p2, unsigned short p3)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*2 + INTERP_16_MASK_1(p3)*1) / 8)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*2 + INTERP_16_MASK_2(p3)*1) / 8);
+}
+
+static __inline unsigned short interp_16_332(unsigned short p1, unsigned short p2, unsigned short p3)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)*2) / 8)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)*2) / 8);
+}
+
+static __inline unsigned short interp_16_611(unsigned short p1, unsigned short p2, unsigned short p3)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8);
+}
+
+static __inline unsigned short interp_16_71(unsigned short p1, unsigned short p2)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*7 + INTERP_16_MASK_1(p2)) / 8)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*7 + INTERP_16_MASK_2(p2)) / 8);
+}
+
+static __inline unsigned short interp_16_211(unsigned short p1, unsigned short p2, unsigned short p3)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4);
+}
+
+static __inline unsigned short interp_16_772(unsigned short p1, unsigned short p2, unsigned short p3)
+{
+ return INTERP_16_MASK_1(((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2))*7 + INTERP_16_MASK_1(p3)*2) / 16)
+ | INTERP_16_MASK_2(((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2))*7 + INTERP_16_MASK_2(p3)*2) / 16);
+}
+
+static __inline unsigned short interp_16_11(unsigned short p1, unsigned short p2)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2);
+}
+
+static __inline unsigned short interp_16_31(unsigned short p1, unsigned short p2)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)) / 4)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)) / 4);
+}
+
+static __inline unsigned short interp_16_1411(unsigned short p1, unsigned short p2, unsigned short p3)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16);
+}
+
+static __inline unsigned short interp_16_431(unsigned short p1, unsigned short p2, unsigned short p3)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*4 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)) / 8)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*4 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)) / 8);
+}
+
+static __inline unsigned short interp_16_53(unsigned short p1, unsigned short p2)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*3) / 8)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*3) / 8);
+}
+
+static __inline unsigned short interp_16_151(unsigned short p1, unsigned short p2)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*15 + INTERP_16_MASK_1(p2)) / 16)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*15 + INTERP_16_MASK_2(p2)) / 16);
+}
+
+static __inline unsigned short interp_16_97(unsigned short p1, unsigned short p2)
+{
+ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*9 + INTERP_16_MASK_1(p2)*7) / 16)
+ | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*9 + INTERP_16_MASK_2(p2)*7) / 16);
+}
+
+#define INTERP_32_MASK_1(v) (v & 0xFF00FF)
+#define INTERP_32_MASK_2(v) (v & 0x00FF00)
+
+static __inline unsigned int interp_32_521(unsigned int p1, unsigned int p2, unsigned int p3)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*2 + INTERP_32_MASK_1(p3)*1) / 8)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*2 + INTERP_32_MASK_2(p3)*1) / 8);
+}
+
+static __inline unsigned int interp_32_332(unsigned int p1, unsigned int p2, unsigned int p3)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)*2) / 8)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)*2) / 8);
+}
+
+static __inline unsigned int interp_32_211(unsigned int p1, unsigned int p2, unsigned int p3)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4);
+}
+
+static __inline unsigned int interp_32_611(unsigned int p1, unsigned int p2, unsigned int p3)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8);
+}
+
+static __inline unsigned int interp_32_71(unsigned int p1, unsigned int p2)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*7 + INTERP_32_MASK_1(p2)) / 8)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*7 + INTERP_32_MASK_2(p2)) / 8);
+}
+
+static __inline unsigned int interp_32_772(unsigned int p1, unsigned int p2, unsigned int p3)
+{
+ return INTERP_32_MASK_1(((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2))*7 + INTERP_32_MASK_1(p3)*2) / 16)
+ | INTERP_32_MASK_2(((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2))*7 + INTERP_32_MASK_2(p3)*2) / 16);
+}
+
+static __inline unsigned int interp_32_11(unsigned int p1, unsigned int p2)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2);
+}
+
+static __inline unsigned int interp_32_31(unsigned int p1, unsigned int p2)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)) / 4)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)) / 4);
+}
+
+static __inline unsigned int interp_32_1411(unsigned int p1, unsigned int p2, unsigned int p3)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16);
+}
+
+static __inline unsigned int interp_32_431(unsigned int p1, unsigned int p2, unsigned int p3)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*4 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)) / 8)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*4 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)) / 8);
+}
+
+static __inline unsigned int interp_32_53(unsigned int p1, unsigned int p2)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*3) / 8)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*3) / 8);
+}
+
+static __inline unsigned int interp_32_151(unsigned int p1, unsigned int p2)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*15 + INTERP_32_MASK_1(p2)) / 16)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*15 + INTERP_32_MASK_2(p2)) / 16);
+}
+
+static __inline unsigned int interp_32_97(unsigned int p1, unsigned int p2)
+{
+ return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*9 + INTERP_32_MASK_1(p2)*7) / 16)
+ | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*9 + INTERP_32_MASK_2(p2)*7) / 16);
+}
+
+/***************************************************************************/
+/* diff */
+
+#define INTERP_Y_LIMIT (0x30*4)
+#define INTERP_U_LIMIT (0x07*4)
+#define INTERP_V_LIMIT (0x06*8)
+
+inline static int interp_16_diff(unsigned short p1, unsigned short p2)
+{
+ int r, g, b;
+ int y, u, v;
+
+ if (p1 == p2)
+ return 0;
+
+ if (interp_bits_per_pixel == 16) {
+ b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
+ g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3;
+ r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8;
+ } else {
+ b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
+ g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2;
+ r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7;
+ }
+
+ y = r + g + b;
+ u = r - b;
+ v = -r + 2*g - b;
+
+ if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
+ return 1;
+
+ if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
+ return 1;
+
+ if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
+ return 1;
+
+ return 0;
+}
+
+inline static int interp_32_diff(unsigned int p1, unsigned int p2)
+{
+ int r, g, b;
+ int y, u, v;
+
+ if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
+ return 0;
+
+ b = (int)((p1 & 0xFF) - (p2 & 0xFF));
+ g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
+ r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
+
+ y = r + g + b;
+ u = r - b;
+ v = -r + 2*g - b;
+
+ if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
+ return 1;
+
+ if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
+ return 1;
+
+ if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
+ return 1;
+
+ return 0;
+}
+
+#if 0
+
+static void interp_set(unsigned bits_per_pixel)
+{
+ interp_bits_per_pixel = bits_per_pixel;
+
+ switch (bits_per_pixel) {
+ case 15 :
+ interp_mask[0] = 0x7C1F;
+ interp_mask[1] = 0x03E0;
+ break;
+ case 16 :
+ interp_mask[0] = 0xF81F;
+ interp_mask[1] = 0x07E0;
+ break;
+ case 32 :
+ interp_mask[0] = 0xFF00FF;
+ interp_mask[1] = 0x00FF00;
+ break;
+ }
+}
+
+#endif
+
+#endif
diff --git a/plugins/dfxvideo/key.c b/plugins/dfxvideo/key.c
new file mode 100644
index 0000000..061bc0c
--- /dev/null
+++ b/plugins/dfxvideo/key.c
@@ -0,0 +1,95 @@
+/***************************************************************************
+ key.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_KEY
+
+#include "externals.h"
+#include "menu.h"
+#include "gpu.h"
+#include "draw.h"
+#include "key.h"
+
+#define VK_INSERT 65379
+#define VK_HOME 65360
+#define VK_PRIOR 65365
+#define VK_NEXT 65366
+#define VK_END 65367
+#define VK_DEL 65535
+#define VK_F5 65474
+
+void GPUmakeSnapshot(void);
+
+unsigned long ulKeybits=0;
+
+void GPUkeypressed(int keycode)
+{
+ switch(keycode)
+ {
+ case 0xFFC9: //X11 key: F12
+ case ((1<<29) | 0xFF0D): //special keycode from pcsx-df: alt-enter
+ bChangeWinMode=TRUE;
+ break;
+ case VK_F5:
+ GPUmakeSnapshot();
+ break;
+
+ case VK_INSERT:
+ if(iUseFixes) {iUseFixes=0;dwActFixes=0;}
+ else {iUseFixes=1;dwActFixes=dwCfgFixes;}
+ SetFixes();
+ if(iFrameLimit==2) SetAutoFrameCap();
+ break;
+
+ case VK_DEL:
+ if(ulKeybits&KEY_SHOWFPS)
+ {
+ ulKeybits&=~KEY_SHOWFPS;
+ DoClearScreenBuffer();
+ }
+ else
+ {
+ ulKeybits|=KEY_SHOWFPS;
+ szDispBuf[0]=0;
+ BuildDispMenu(0);
+ }
+ break;
+
+ case VK_PRIOR: BuildDispMenu(-1); break;
+ case VK_NEXT: BuildDispMenu( 1); break;
+ case VK_END: SwitchDispMenu(1); break;
+ case VK_HOME: SwitchDispMenu(-1); break;
+ case 0x60:
+ {
+ iFastFwd = 1 - iFastFwd;
+ bSkipNextFrame = FALSE;
+ UseFrameSkip = iFastFwd;
+ BuildDispMenu(0);
+ break;
+ }
+#ifdef _MACGL
+ default: { void HandleKey(int keycode); HandleKey(keycode); }
+#endif
+ }
+}
+
+void SetKeyHandler(void)
+{
+}
+
+void ReleaseKeyHandler(void)
+{
+}
diff --git a/plugins/dfxvideo/key.h b/plugins/dfxvideo/key.h
new file mode 100644
index 0000000..5f85cb6
--- /dev/null
+++ b/plugins/dfxvideo/key.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ key.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _KEY_INTERNALS_H
+#define _KEY_INTERNALS_H
+
+void SetKeyHandler(void);
+void ReleaseKeyHandler(void);
+
+#endif // _KEY_INTERNALS_H
diff --git a/plugins/dfxvideo/macros.inc b/plugins/dfxvideo/macros.inc
new file mode 100644
index 0000000..4782928
--- /dev/null
+++ b/plugins/dfxvideo/macros.inc
@@ -0,0 +1,40 @@
+; macros.inc - description
+; -------------------
+; begin : Sun Nov 08 2001
+; based on ZSNES macros.mac
+; email : linuzappz@pcsx.net
+
+; 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. See also the license.txt file for *
+; additional informations. *
+
+
+%ifdef __WIN32__
+
+%imacro EXTSYM 1-*
+%rep %0
+ extern _%1
+ %define %1 _%1
+%rotate 1
+%endrep
+%endmacro
+
+%imacro NEWSYM 1
+ global _%1
+ _%1:
+ %1:
+%endmacro
+
+%else
+
+%define EXTSYM extern
+
+%imacro NEWSYM 1
+ global %1
+ %1:
+%endmacro
+
+%endif
+
diff --git a/plugins/dfxvideo/menu.c b/plugins/dfxvideo/menu.c
new file mode 100644
index 0000000..33d111d
--- /dev/null
+++ b/plugins/dfxvideo/menu.c
@@ -0,0 +1,167 @@
+/***************************************************************************
+ menu.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_MENU
+
+#include "externals.h"
+#include "draw.h"
+#include "menu.h"
+#include "gpu.h"
+
+unsigned long dwCoreFlags = 0;
+
+// create lists/stuff for fonts (actually there are no more lists, but I am too lazy to change the func names ;)
+void InitMenu(void)
+{
+}
+
+// kill existing lists/fonts
+void CloseMenu(void)
+{
+ DestroyPic();
+}
+
+// DISPLAY FPS/MENU TEXT
+
+#include <time.h>
+extern time_t tStart;
+
+int iMPos=0; // menu arrow pos
+
+void DisplayText(void) // DISPLAY TEXT
+{
+}
+
+// Build Menu buffer (== Dispbuffer without FPS)...
+void BuildDispMenu(int iInc)
+{
+ if(!(ulKeybits&KEY_SHOWFPS)) return; // mmm, cheater ;)
+
+ iMPos+=iInc; // up or down
+ if(iMPos<0) iMPos=3; // wrap around
+ if(iMPos>3) iMPos=0;
+
+ strcpy(szMenuBuf," FL FS DI GF "); // main menu items
+
+ if(UseFrameLimit) // set marks
+ {
+ if(iFrameLimit==1) szMenuBuf[2] = '+';
+ else szMenuBuf[2] = '*';
+ }
+ if(iFastFwd) szMenuBuf[7] = '~';
+ else
+ if(UseFrameSkip) szMenuBuf[7] = '*';
+
+ if(iUseDither) // set marks
+ {
+ if(iUseDither==1) szMenuBuf[12] = '+';
+ else szMenuBuf[12] = '*';
+ }
+
+ if(dwActFixes) szMenuBuf[17] = '*';
+
+ if(dwCoreFlags&1) szMenuBuf[23] = 'A';
+ if(dwCoreFlags&2) szMenuBuf[23] = 'M';
+
+ if(dwCoreFlags&0xff00) //A/M/G/D
+ {
+ if((dwCoreFlags&0x0f00)==0x0000) // D
+ szMenuBuf[23] = 'D';
+ else
+ if((dwCoreFlags&0x0f00)==0x0100) // A
+ szMenuBuf[23] = 'A';
+ else
+ if((dwCoreFlags&0x0f00)==0x0200) // M
+ szMenuBuf[23] = 'M';
+ else
+ if((dwCoreFlags&0x0f00)==0x0300) // G
+ szMenuBuf[23] = 'G';
+
+ szMenuBuf[24]='0'+(char)((dwCoreFlags&0xf000)>>12); // number
+ }
+
+
+ if(lSelectedSlot) szMenuBuf[26] = '0'+(char)lSelectedSlot;
+
+ szMenuBuf[(iMPos+1)*5]='<'; // set arrow
+
+}
+
+// Some menu action...
+void SwitchDispMenu(int iStep) // SWITCH DISP MENU
+{
+ if(!(ulKeybits&KEY_SHOWFPS)) return; // tststs
+
+ switch(iMPos)
+ {
+ case 0: // frame limit
+ {
+ int iType=0;
+ bInitCap = TRUE;
+
+ if(UseFrameLimit) iType=iFrameLimit;
+ iType+=iStep;
+ if(iType<0) iType=2;
+ if(iType>2) iType=0;
+ if(iType==0) UseFrameLimit=0;
+ else
+ {
+ UseFrameLimit=1;
+ iFrameLimit=iType;
+ SetAutoFrameCap();
+ }
+ } break;
+
+ case 1: // frame skip
+ bInitCap = TRUE;
+ if(iStep>0)
+ {
+ if(!UseFrameSkip) {UseFrameSkip=1;iFastFwd = 0;}
+ else
+ {
+ if(!iFastFwd) iFastFwd=1;
+ else {UseFrameSkip=0;iFastFwd = 0;}
+ }
+ }
+ else
+ {
+ if(!UseFrameSkip) {UseFrameSkip=1;iFastFwd = 1;}
+ else
+ {
+ if(iFastFwd) iFastFwd=0;
+ else {UseFrameSkip=0;iFastFwd = 0;}
+ }
+ }
+ bSkipNextFrame=FALSE;
+ break;
+
+ case 2: // dithering
+ iUseDither+=iStep;
+ if(iUseDither<0) iUseDither=2;
+ if(iUseDither>2) iUseDither=0;
+ break;
+
+ case 3: // special fixes
+ if(iUseFixes) {iUseFixes=0;dwActFixes=0;}
+ else {iUseFixes=1;dwActFixes=dwCfgFixes;}
+ SetFixes();
+ if(iFrameLimit==2) SetAutoFrameCap();
+ break;
+ }
+
+ BuildDispMenu(0); // update info
+}
diff --git a/plugins/dfxvideo/menu.h b/plugins/dfxvideo/menu.h
new file mode 100644
index 0000000..ac24418
--- /dev/null
+++ b/plugins/dfxvideo/menu.h
@@ -0,0 +1,27 @@
+/***************************************************************************
+ menu.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _GPU_MENU_H_
+#define _GPU_MENU_H_
+
+void DisplayText(void);
+void CloseMenu(void);
+void InitMenu(void);
+void BuildDispMenu(int iInc);
+void SwitchDispMenu(int iStep);
+
+#endif // _GPU_MENU_H_
diff --git a/plugins/dfxvideo/prim.c b/plugins/dfxvideo/prim.c
new file mode 100644
index 0000000..097f202
--- /dev/null
+++ b/plugins/dfxvideo/prim.c
@@ -0,0 +1,1661 @@
+/***************************************************************************
+ prim.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_PRIMDRAW
+
+#include "externals.h"
+#include "gpu.h"
+#include "draw.h"
+#include "soft.h"
+#include "swap.h"
+
+////////////////////////////////////////////////////////////////////////
+// globals
+////////////////////////////////////////////////////////////////////////
+
+BOOL bUsingTWin=FALSE;
+TWin_t TWin;
+//unsigned long clutid; // global clut
+unsigned short usMirror=0; // sprite mirror
+int iDither=0;
+int32_t drawX;
+int32_t drawY;
+int32_t drawW;
+int32_t drawH;
+uint32_t dwCfgFixes;
+uint32_t dwActFixes=0;
+uint32_t dwEmuFixes=0;
+int iUseFixes;
+int iUseDither=0;
+BOOL bDoVSyncUpdate=FALSE;
+
+////////////////////////////////////////////////////////////////////////
+// Some ASM color convertion by LEWPY
+////////////////////////////////////////////////////////////////////////
+
+#ifdef USE_NASM
+
+#define BGR24to16 i386_BGR24to16
+__inline unsigned short BGR24to16 (uint32_t BGR);
+
+#else
+
+__inline unsigned short BGR24to16 (uint32_t BGR)
+{
+ return (unsigned short)(((BGR>>3)&0x1f)|((BGR&0xf80000)>>9)|((BGR&0xf800)>>6));
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Update global TP infos
+////////////////////////////////////////////////////////////////////////
+
+__inline void UpdateGlobalTP(unsigned short gdata)
+{
+ GlobalTextAddrX = (gdata << 6) & 0x3c0; // texture addr
+
+ if(iGPUHeight==1024)
+ {
+ if(dwGPUVersion==2)
+ {
+ GlobalTextAddrY =((gdata & 0x60 ) << 3);
+ GlobalTextIL =(gdata & 0x2000) >> 13;
+ GlobalTextABR = (unsigned short)((gdata >> 7) & 0x3);
+ GlobalTextTP = (gdata >> 9) & 0x3;
+ if(GlobalTextTP==3) GlobalTextTP=2;
+ usMirror =0;
+ lGPUstatusRet = (lGPUstatusRet & 0xffffe000 ) | (gdata & 0x1fff );
+
+ // tekken dithering? right now only if dithering is forced by user
+ if(iUseDither==2) iDither=2; else iDither=0;
+
+ return;
+ }
+ else
+ {
+ GlobalTextAddrY = (unsigned short)(((gdata << 4) & 0x100) | ((gdata >> 2) & 0x200));
+ }
+ }
+ else GlobalTextAddrY = (gdata << 4) & 0x100;
+
+ GlobalTextTP = (gdata >> 7) & 0x3; // tex mode (4,8,15)
+
+ if(GlobalTextTP==3) GlobalTextTP=2; // seen in Wild9 :(
+
+ GlobalTextABR = (gdata >> 5) & 0x3; // blend mode
+
+ lGPUstatusRet&=~0x000001ff; // Clear the necessary bits
+ lGPUstatusRet|=(gdata & 0x01ff); // set the necessary bits
+
+ switch(iUseDither)
+ {
+ case 0:
+ iDither=0;
+ break;
+ case 1:
+ if(lGPUstatusRet&0x0200) iDither=2;
+ else iDither=0;
+ break;
+ case 2:
+ iDither=2;
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void SetRenderMode(uint32_t DrawAttributes)
+{
+ DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? TRUE : FALSE;
+
+ if(SHADETEXBIT(DrawAttributes))
+ {g_m1=g_m2=g_m3=128;}
+ else
+ {
+ if((dwActFixes&4) && ((DrawAttributes&0x00ffffff)==0))
+ DrawAttributes|=0x007f7f7f;
+
+ g_m1=(short)(DrawAttributes&0xff);
+ g_m2=(short)((DrawAttributes>>8)&0xff);
+ g_m3=(short)((DrawAttributes>>16)&0xff);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// oki, here are the psx gpu coord rules: poly coords are
+// 11 bit signed values (-1024...1023). If the x or y distance
+// exceeds 1024, the polygon will not be drawn.
+// Since quads are treated as two triangles by the real gpu,
+// this 'discard rule' applies to each of the quad's triangle
+// (so one triangle can be drawn, the other one discarded).
+// Also, y drawing is wrapped at 512 one time,
+// then it will get negative (and therefore not drawn). The
+// 'CheckCoord' funcs are a simple (not comlete!) approach to
+// do things right, I will add a better detection soon... the
+// current approach will be easier to do in hw/accel plugins, imho
+
+// 11 bit signed
+#define SIGNSHIFT 21
+#define CHKMAX_X 1024
+#define CHKMAX_Y 512
+
+void AdjustCoord4()
+{
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
+ lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
+ lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
+ ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
+ ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
+}
+
+void AdjustCoord3()
+{
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
+ lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
+ ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
+}
+
+void AdjustCoord2()
+{
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
+}
+
+void AdjustCoord1()
+{
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+
+ if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
+ lx0+=2048;
+
+ if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
+ ly0+=2048;
+}
+
+////////////////////////////////////////////////////////////////////////
+// special checks... nascar, syphon filter 2, mgs
+////////////////////////////////////////////////////////////////////////
+
+// xenogears FT4: not removed correctly right now... the tri 0,1,2
+// should get removed, the tri 1,2,3 should stay... pfff
+
+// x -466 1023 180 1023
+// y 20 -228 222 -100
+
+// 0 __1
+// \ / \
+// 2___3
+
+__inline BOOL CheckCoord4()
+{
+ if(lx0<0)
+ {
+ if(((lx1-lx0)>CHKMAX_X) ||
+ ((lx2-lx0)>CHKMAX_X))
+ {
+ if(lx3<0)
+ {
+ if((lx1-lx3)>CHKMAX_X) return TRUE;
+ if((lx2-lx3)>CHKMAX_X) return TRUE;
+ }
+ }
+ }
+ if(lx1<0)
+ {
+ if((lx0-lx1)>CHKMAX_X) return TRUE;
+ if((lx2-lx1)>CHKMAX_X) return TRUE;
+ if((lx3-lx1)>CHKMAX_X) return TRUE;
+ }
+ if(lx2<0)
+ {
+ if((lx0-lx2)>CHKMAX_X) return TRUE;
+ if((lx1-lx2)>CHKMAX_X) return TRUE;
+ if((lx3-lx2)>CHKMAX_X) return TRUE;
+ }
+ if(lx3<0)
+ {
+ if(((lx1-lx3)>CHKMAX_X) ||
+ ((lx2-lx3)>CHKMAX_X))
+ {
+ if(lx0<0)
+ {
+ if((lx1-lx0)>CHKMAX_X) return TRUE;
+ if((lx2-lx0)>CHKMAX_X) return TRUE;
+ }
+ }
+ }
+
+
+ if(ly0<0)
+ {
+ if((ly1-ly0)>CHKMAX_Y) return TRUE;
+ if((ly2-ly0)>CHKMAX_Y) return TRUE;
+ }
+ if(ly1<0)
+ {
+ if((ly0-ly1)>CHKMAX_Y) return TRUE;
+ if((ly2-ly1)>CHKMAX_Y) return TRUE;
+ if((ly3-ly1)>CHKMAX_Y) return TRUE;
+ }
+ if(ly2<0)
+ {
+ if((ly0-ly2)>CHKMAX_Y) return TRUE;
+ if((ly1-ly2)>CHKMAX_Y) return TRUE;
+ if((ly3-ly2)>CHKMAX_Y) return TRUE;
+ }
+ if(ly3<0)
+ {
+ if((ly1-ly3)>CHKMAX_Y) return TRUE;
+ if((ly2-ly3)>CHKMAX_Y) return TRUE;
+ }
+
+ return FALSE;
+}
+
+__inline BOOL CheckCoord3()
+{
+ if(lx0<0)
+ {
+ if((lx1-lx0)>CHKMAX_X) return TRUE;
+ if((lx2-lx0)>CHKMAX_X) return TRUE;
+ }
+ if(lx1<0)
+ {
+ if((lx0-lx1)>CHKMAX_X) return TRUE;
+ if((lx2-lx1)>CHKMAX_X) return TRUE;
+ }
+ if(lx2<0)
+ {
+ if((lx0-lx2)>CHKMAX_X) return TRUE;
+ if((lx1-lx2)>CHKMAX_X) return TRUE;
+ }
+ if(ly0<0)
+ {
+ if((ly1-ly0)>CHKMAX_Y) return TRUE;
+ if((ly2-ly0)>CHKMAX_Y) return TRUE;
+ }
+ if(ly1<0)
+ {
+ if((ly0-ly1)>CHKMAX_Y) return TRUE;
+ if((ly2-ly1)>CHKMAX_Y) return TRUE;
+ }
+ if(ly2<0)
+ {
+ if((ly0-ly2)>CHKMAX_Y) return TRUE;
+ if((ly1-ly2)>CHKMAX_Y) return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+__inline BOOL CheckCoord2()
+{
+ if(lx0<0)
+ {
+ if((lx1-lx0)>CHKMAX_X) return TRUE;
+ }
+ if(lx1<0)
+ {
+ if((lx0-lx1)>CHKMAX_X) return TRUE;
+ }
+ if(ly0<0)
+ {
+ if((ly1-ly0)>CHKMAX_Y) return TRUE;
+ }
+ if(ly1<0)
+ {
+ if((ly0-ly1)>CHKMAX_Y) return TRUE;
+ }
+
+ return FALSE;
+}
+
+__inline BOOL CheckCoordL(short slx0,short sly0,short slx1,short sly1)
+{
+ if(slx0<0)
+ {
+ if((slx1-slx0)>CHKMAX_X) return TRUE;
+ }
+ if(slx1<0)
+ {
+ if((slx0-slx1)>CHKMAX_X) return TRUE;
+ }
+ if(sly0<0)
+ {
+ if((sly1-sly0)>CHKMAX_Y) return TRUE;
+ }
+ if(sly1<0)
+ {
+ if((sly0-sly1)>CHKMAX_Y) return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// mask stuff... used in silent hill
+////////////////////////////////////////////////////////////////////////
+
+void cmdSTP(unsigned char * baseAddr)
+{
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ lGPUstatusRet&=~0x1800; // Clear the necessary bits
+ lGPUstatusRet|=((gdata & 0x03) << 11); // Set the necessary bits
+
+ if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;}
+ else {sSetMask=0; lSetMask=0; }
+
+ if(gdata&2) bCheckMask=TRUE;
+ else bCheckMask=FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: Set texture page infos
+////////////////////////////////////////////////////////////////////////
+
+void cmdTexturePage(unsigned char * baseAddr)
+{
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ lGPUstatusRet&=~0x000007ff;
+ lGPUstatusRet|=(gdata & 0x07ff);
+
+ usMirror=gdata&0x3000;
+
+ UpdateGlobalTP((unsigned short)gdata);
+ GlobalTextREST = (gdata&0x00ffffff)>>9;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: turn on/off texture window
+////////////////////////////////////////////////////////////////////////
+
+void cmdTextureWindow(unsigned char *baseAddr)
+{
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ uint32_t YAlign,XAlign;
+
+ lGPUInfoVals[INFO_TW]=gdata&0xFFFFF;
+
+ if(gdata & 0x020)
+ TWin.Position.y1 = 8; // xxxx1
+ else if (gdata & 0x040)
+ TWin.Position.y1 = 16; // xxx10
+ else if (gdata & 0x080)
+ TWin.Position.y1 = 32; // xx100
+ else if (gdata & 0x100)
+ TWin.Position.y1 = 64; // x1000
+ else if (gdata & 0x200)
+ TWin.Position.y1 = 128; // 10000
+ else
+ TWin.Position.y1 = 256; // 00000
+
+ // Texture window size is determined by the least bit set of the relevant 5 bits
+
+ if (gdata & 0x001)
+ TWin.Position.x1 = 8; // xxxx1
+ else if (gdata & 0x002)
+ TWin.Position.x1 = 16; // xxx10
+ else if (gdata & 0x004)
+ TWin.Position.x1 = 32; // xx100
+ else if (gdata & 0x008)
+ TWin.Position.x1 = 64; // x1000
+ else if (gdata & 0x010)
+ TWin.Position.x1 = 128; // 10000
+ else
+ TWin.Position.x1 = 256; // 00000
+
+ // Re-calculate the bit field, because we can't trust what is passed in the data
+
+
+ YAlign = (uint32_t)(32 - (TWin.Position.y1 >> 3));
+ XAlign = (uint32_t)(32 - (TWin.Position.x1 >> 3));
+
+ // Absolute position of the start of the texture window
+
+ TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);
+ TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);
+
+ if((TWin.Position.x0 == 0 && // tw turned off
+ TWin.Position.y0 == 0 &&
+ TWin.Position.x1 == 0 &&
+ TWin.Position.y1 == 0) ||
+ (TWin.Position.x1 == 256 &&
+ TWin.Position.y1 == 256))
+ {
+ bUsingTWin = FALSE; // -> just do it
+ }
+ else // otherwise
+ {
+ bUsingTWin = TRUE; // -> tw turned on
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: start of drawing area... primitives will be clipped inside
+////////////////////////////////////////////////////////////////////////
+
+
+
+void cmdDrawAreaStart(unsigned char * baseAddr)
+{
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ drawX = gdata & 0x3ff; // for soft drawing
+
+ if(dwGPUVersion==2)
+ {
+ lGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF;
+ drawY = (gdata>>12)&0x3ff;
+ if(drawY>=1024) drawY=1023; // some security
+ }
+ else
+ {
+ lGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;
+ drawY = (gdata>>10)&0x3ff;
+ if(drawY>=512) drawY=511; // some security
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: end of drawing area... primitives will be clipped inside
+////////////////////////////////////////////////////////////////////////
+
+void cmdDrawAreaEnd(unsigned char * baseAddr)
+{
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ drawW = gdata & 0x3ff; // for soft drawing
+
+ if(dwGPUVersion==2)
+ {
+ lGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF;
+ drawH = (gdata>>12)&0x3ff;
+ if(drawH>=1024) drawH=1023; // some security
+ }
+ else
+ {
+ lGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;
+ drawH = (gdata>>10)&0x3ff;
+ if(drawH>=512) drawH=511; // some security
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw offset... will be added to prim coords
+////////////////////////////////////////////////////////////////////////
+
+void cmdDrawOffset(unsigned char * baseAddr)
+{
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);
+
+ if(dwGPUVersion==2)
+ {
+ lGPUInfoVals[INFO_DRAWOFF]=gdata&0x7FFFFF;
+ PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff);
+ }
+ else
+ {
+ lGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;
+ PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);
+ }
+
+ PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);
+ PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: load image to vram
+////////////////////////////////////////////////////////////////////////
+
+void primLoadImage(unsigned char * baseAddr)
+{
+ unsigned short *sgpuData = ((unsigned short *) baseAddr);
+
+ VRAMWrite.x = GETLEs16(&sgpuData[2])&0x3ff;
+ VRAMWrite.y = GETLEs16(&sgpuData[3])&iGPUHeightMask;
+ VRAMWrite.Width = GETLEs16(&sgpuData[4]);
+ VRAMWrite.Height = GETLEs16(&sgpuData[5]);
+
+ DataWriteMode = DR_VRAMTRANSFER;
+
+ VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;
+ VRAMWrite.RowsRemaining = VRAMWrite.Width;
+ VRAMWrite.ColsRemaining = VRAMWrite.Height;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: vram -> psx mem
+////////////////////////////////////////////////////////////////////////
+
+void primStoreImage(unsigned char * baseAddr)
+{
+ unsigned short *sgpuData = ((unsigned short *) baseAddr);
+
+ VRAMRead.x = GETLEs16(&sgpuData[2])&0x03ff;
+ VRAMRead.y = GETLEs16(&sgpuData[3])&iGPUHeightMask;
+ VRAMRead.Width = GETLEs16(&sgpuData[4]);
+ VRAMRead.Height = GETLEs16(&sgpuData[5]);
+
+ VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;
+ VRAMRead.RowsRemaining = VRAMRead.Width;
+ VRAMRead.ColsRemaining = VRAMRead.Height;
+
+ DataReadMode = DR_VRAMTRANSFER;
+
+ lGPUstatusRet |= GPUSTATUS_READYFORVRAM;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: blkfill - NO primitive! Doesn't care about draw areas...
+////////////////////////////////////////////////////////////////////////
+
+void primBlkFill(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ short sX = GETLEs16(&sgpuData[2]);
+ short sY = GETLEs16(&sgpuData[3]);
+ short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
+ short sH = GETLEs16(&sgpuData[5]) & 0x3ff;
+
+ sW = (sW+15) & ~15;
+
+ // Increase H & W if they are one short of full values, because they never can be full values
+ if (sH >= 1023) sH=1024;
+ if (sW >= 1023) sW=1024;
+
+ // x and y of end pos
+ sW+=sX;
+ sH+=sY;
+
+ FillSoftwareArea(sX, sY, sW, sH, BGR24to16(GETLE32(&gpuData[0])));
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: move image vram -> vram
+////////////////////////////////////////////////////////////////////////
+
+void primMoveImage(unsigned char * baseAddr)
+{
+ short *sgpuData = ((short *) baseAddr);
+
+ short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;
+
+ imageX0 = GETLEs16(&sgpuData[2])&0x03ff;
+ imageY0 = GETLEs16(&sgpuData[3])&iGPUHeightMask;
+ imageX1 = GETLEs16(&sgpuData[4])&0x03ff;
+ imageY1 = GETLEs16(&sgpuData[5])&iGPUHeightMask;
+ imageSX = GETLEs16(&sgpuData[6]);
+ imageSY = GETLEs16(&sgpuData[7]);
+
+ if((imageX0 == imageX1) && (imageY0 == imageY1)) return;
+ if(imageSX<=0) return;
+ if(imageSY<=0) return;
+
+ // ZN SF2: screwed moves
+ //
+ // move sgpuData[2],sgpuData[3],sgpuData[4],sgpuData[5],sgpuData[6],sgpuData[7]
+ //
+ // move 365 182 32723 -21846 17219 15427
+ // move 127 160 147 -1 20817 13409
+ // move 141 165 16275 -21862 -32126 13442
+ // move 161 136 24620 -1 16962 13388
+ // move 168 138 32556 -13090 -29556 15500
+ //
+ // and here's the hack for it:
+
+ if(iGPUHeight==1024 && GETLEs16(&sgpuData[7])>1024) return;
+
+ if((imageY0+imageSY)>iGPUHeight ||
+ (imageX0+imageSX)>1024 ||
+ (imageY1+imageSY)>iGPUHeight ||
+ (imageX1+imageSX)>1024)
+ {
+ int i,j;
+ for(j=0;j<imageSY;j++)
+ for(i=0;i<imageSX;i++)
+ psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]=
+ psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)];
+
+ bDoVSyncUpdate=TRUE;
+
+ return;
+ }
+
+ if(imageSX&1) // not dword aligned? slower func
+ {
+ unsigned short *SRCPtr, *DSTPtr;
+ unsigned short LineOffset;
+
+ SRCPtr = psxVuw + (1024*imageY0) + imageX0;
+ DSTPtr = psxVuw + (1024*imageY1) + imageX1;
+
+ LineOffset = 1024 - imageSX;
+
+ for(j=0;j<imageSY;j++)
+ {
+ for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;
+ SRCPtr += LineOffset;
+ DSTPtr += LineOffset;
+ }
+ }
+ else // dword aligned
+ {
+ uint32_t *SRCPtr, *DSTPtr;
+ unsigned short LineOffset;
+ int dx=imageSX>>1;
+
+ SRCPtr = (uint32_t *)(psxVuw + (1024*imageY0) + imageX0);
+ DSTPtr = (uint32_t *)(psxVuw + (1024*imageY1) + imageX1);
+
+ LineOffset = 512 - dx;
+
+ for(j=0;j<imageSY;j++)
+ {
+ for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;
+ SRCPtr += LineOffset;
+ DSTPtr += LineOffset;
+ }
+ }
+
+ imageSX+=imageX1;
+ imageSY+=imageY1;
+
+/*
+ if(!PSXDisplay.Interlaced) // stupid frame skip stuff
+ {
+ if(UseFrameSkip &&
+ imageX1<PSXDisplay.DisplayEnd.x &&
+ imageSX>=PSXDisplay.DisplayPosition.x &&
+ imageY1<PSXDisplay.DisplayEnd.y &&
+ imageSY>=PSXDisplay.DisplayPosition.y)
+ updateDisplay();
+ }
+*/
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw free-size Tile
+////////////////////////////////////////////////////////////////////////
+
+//#define SMALLDEBUG
+//#include <dbgout.h>
+
+void primTileS(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t*)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
+ short sH = GETLEs16(&sgpuData[5]) & iGPUHeightMask; // mmm... limit tiles to 0x1ff or height?
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+
+ if(!(dwActFixes&8)) AdjustCoord1();
+
+ // x and y of start
+ ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
+ ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
+ lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
+ lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
+
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ if(!(iTileCheat && sH==32 && GETLE32(&gpuData[0])==0x60ffffff)) // special cheat for certain ZiNc games
+ FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
+ BGR24to16(GETLE32(&gpuData[0])));
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 1 dot Tile (point)
+////////////////////////////////////////////////////////////////////////
+
+void primTile1(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t*)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sH = 1;
+ short sW = 1;
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+
+ if(!(dwActFixes&8)) AdjustCoord1();
+
+ // x and y of start
+ ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
+ ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
+ lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
+ lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
+
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
+ BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 8 dot Tile (small rect)
+////////////////////////////////////////////////////////////////////////
+
+void primTile8(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t*)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sH = 8;
+ short sW = 8;
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+
+ if(!(dwActFixes&8)) AdjustCoord1();
+
+ // x and y of start
+ ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
+ ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
+ lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
+ lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
+
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
+ BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 16 dot Tile (medium rect)
+////////////////////////////////////////////////////////////////////////
+
+void primTile16(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t*)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sH = 16;
+ short sW = 16;
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+
+ if(!(dwActFixes&8)) AdjustCoord1();
+
+ // x and y of start
+ ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
+ ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
+ lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
+ lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
+
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
+ BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: small sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+void primSprt8(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+
+ if(!(dwActFixes&8)) AdjustCoord1();
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);
+ else
+ if(usMirror) DrawSoftwareSpriteMirror(baseAddr,8,8);
+ else DrawSoftwareSprite(baseAddr,8,8,
+ baseAddr[8],
+ baseAddr[9]);
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: medium sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+void primSprt16(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+
+ if(!(dwActFixes&8)) AdjustCoord1();
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);
+ else
+ if(usMirror) DrawSoftwareSpriteMirror(baseAddr,16,16);
+ else DrawSoftwareSprite(baseAddr,16,16,
+ baseAddr[8],
+ baseAddr[9]);
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: free-size sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+// func used on texture coord wrap
+void primSprtSRest(unsigned char * baseAddr,unsigned short type)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ unsigned short sTypeRest=0;
+
+ short s;
+ short sX = GETLEs16(&sgpuData[2]);
+ short sY = GETLEs16(&sgpuData[3]);
+ short sW = GETLEs16(&sgpuData[6]) & 0x3ff;
+ short sH = GETLEs16(&sgpuData[7]) & 0x1ff;
+ short tX = baseAddr[8];
+ short tY = baseAddr[9];
+
+ switch(type)
+ {
+ case 1:
+ s=256-baseAddr[8];
+ sW-=s;
+ sX+=s;
+ tX=0;
+ break;
+ case 2:
+ s=256-baseAddr[9];
+ sH-=s;
+ sY+=s;
+ tY=0;
+ break;
+ case 3:
+ s=256-baseAddr[8];
+ sW-=s;
+ sX+=s;
+ tX=0;
+ s=256-baseAddr[9];
+ sH-=s;
+ sY+=s;
+ tY=0;
+ break;
+ case 4:
+ s=512-baseAddr[8];
+ sW-=s;
+ sX+=s;
+ tX=0;
+ break;
+ case 5:
+ s=512-baseAddr[9];
+ sH-=s;
+ sY+=s;
+ tY=0;
+ break;
+ case 6:
+ s=512-baseAddr[8];
+ sW-=s;
+ sX+=s;
+ tX=0;
+ s=512-baseAddr[9];
+ sH-=s;
+ sY+=s;
+ tY=0;
+ break;
+ }
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ if(tX+sW>256) {sW=256-tX;sTypeRest+=1;}
+ if(tY+sH>256) {sH=256-tY;sTypeRest+=2;}
+
+ lx0 = sX;
+ ly0 = sY;
+
+ if(!(dwActFixes&8)) AdjustCoord1();
+
+ DrawSoftwareSprite(baseAddr,sW,sH,tX,tY);
+
+ if(sTypeRest && type<4)
+ {
+ if(sTypeRest&1 && type==1) primSprtSRest(baseAddr,4);
+ if(sTypeRest&2 && type==2) primSprtSRest(baseAddr,5);
+ if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void primSprtS(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sW,sH;
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+
+ if(!(dwActFixes&8)) AdjustCoord1();
+
+ sW = GETLEs16(&sgpuData[6]) & 0x3ff;
+ sH = GETLEs16(&sgpuData[7]) & 0x1ff;
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sW,sH);
+ else
+ if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sW,sH);
+ else
+ {
+ unsigned short sTypeRest=0;
+ short tX=baseAddr[8];
+ short tY=baseAddr[9];
+
+ if(tX+sW>256) {sW=256-tX;sTypeRest+=1;}
+ if(tY+sH>256) {sH=256-tY;sTypeRest+=2;}
+
+ DrawSoftwareSprite(baseAddr,sW,sH,tX,tY);
+
+ if(sTypeRest)
+ {
+ if(sTypeRest&1) primSprtSRest(baseAddr,1);
+ if(sTypeRest&2) primSprtSRest(baseAddr,2);
+ if(sTypeRest==3) primSprtSRest(baseAddr,3);
+ }
+
+ }
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Poly4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyF4(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[4]);
+ ly1 = GETLEs16(&sgpuData[5]);
+ lx2 = GETLEs16(&sgpuData[6]);
+ ly2 = GETLEs16(&sgpuData[7]);
+ lx3 = GETLEs16(&sgpuData[8]);
+ ly3 = GETLEs16(&sgpuData[9]);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord4();
+ if(CheckCoord4()) return;
+ }
+
+ offsetPSX4();
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ drawPoly4F(GETLE32(&gpuData[0]));
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyG4(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[6]);
+ ly1 = GETLEs16(&sgpuData[7]);
+ lx2 = GETLEs16(&sgpuData[10]);
+ ly2 = GETLEs16(&sgpuData[11]);
+ lx3 = GETLEs16(&sgpuData[14]);
+ ly3 = GETLEs16(&sgpuData[15]);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord4();
+ if(CheckCoord4()) return;
+ }
+
+ offsetPSX4();
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ drawPoly4G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]),
+ GETLE32(&gpuData[4]), GETLE32(&gpuData[6]));
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Texture3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyFT3(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[6]);
+ ly1 = GETLEs16(&sgpuData[7]);
+ lx2 = GETLEs16(&sgpuData[10]);
+ ly2 = GETLEs16(&sgpuData[11]);
+
+ lLowerpart=GETLE32(&gpuData[4])>>16;
+ UpdateGlobalTP((unsigned short)lLowerpart);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord3();
+ if(CheckCoord3()) return;
+ }
+
+ offsetPSX3();
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ drawPoly3FT(baseAddr);
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Texture4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyFT4(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[6]);
+ ly1 = GETLEs16(&sgpuData[7]);
+ lx2 = GETLEs16(&sgpuData[10]);
+ ly2 = GETLEs16(&sgpuData[11]);
+ lx3 = GETLEs16(&sgpuData[14]);
+ ly3 = GETLEs16(&sgpuData[15]);
+
+ lLowerpart=GETLE32(&gpuData[4])>>16;
+ UpdateGlobalTP((unsigned short)lLowerpart);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord4();
+ if(CheckCoord4()) return;
+ }
+
+ offsetPSX4();
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ drawPoly4FT(baseAddr);
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Texture3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyGT3(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[8]);
+ ly1 = GETLEs16(&sgpuData[9]);
+ lx2 = GETLEs16(&sgpuData[14]);
+ ly2 = GETLEs16(&sgpuData[15]);
+
+ lLowerpart=GETLE32(&gpuData[5])>>16;
+ UpdateGlobalTP((unsigned short)lLowerpart);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord3();
+ if(CheckCoord3()) return;
+ }
+
+ offsetPSX3();
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ if(SHADETEXBIT(GETLE32(&gpuData[0])))
+ {
+ gpuData[0] = (gpuData[0]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
+ gpuData[3] = (gpuData[3]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
+ gpuData[6] = (gpuData[6]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
+ }
+
+ drawPoly3GT(baseAddr);
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyG3(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[6]);
+ ly1 = GETLEs16(&sgpuData[7]);
+ lx2 = GETLEs16(&sgpuData[10]);
+ ly2 = GETLEs16(&sgpuData[11]);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord3();
+ if(CheckCoord3()) return;
+ }
+
+ offsetPSX3();
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ drawPoly3G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]), GETLE32(&gpuData[4]));
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Texture4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyGT4(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[8]);
+ ly1 = GETLEs16(&sgpuData[9]);
+ lx2 = GETLEs16(&sgpuData[14]);
+ ly2 = GETLEs16(&sgpuData[15]);
+ lx3 = GETLEs16(&sgpuData[20]);
+ ly3 = GETLEs16(&sgpuData[21]);
+
+ lLowerpart=GETLE32(&gpuData[5])>>16;
+ UpdateGlobalTP((unsigned short)lLowerpart);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord4();
+ if(CheckCoord4()) return;
+ }
+
+ offsetPSX4();
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ if(SHADETEXBIT(GETLE32(&gpuData[0])))
+ {
+ gpuData[0] = (gpuData[0]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
+ gpuData[3] = (gpuData[3]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
+ gpuData[6] = (gpuData[6]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
+ gpuData[9] = (gpuData[9]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
+ }
+
+ drawPoly4GT(baseAddr);
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyF3(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[4]);
+ ly1 = GETLEs16(&sgpuData[5]);
+ lx2 = GETLEs16(&sgpuData[6]);
+ ly2 = GETLEs16(&sgpuData[7]);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord3();
+ if(CheckCoord3()) return;
+ }
+
+ offsetPSX3();
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ drawPoly3F(GETLE32(&gpuData[0]));
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: skipping shaded polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineGSkip(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int iMax=255;
+ int i=2;
+
+ ly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
+ lx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
+
+ while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=4))
+ {
+ i++;
+ ly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
+ lx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
+ i++;if(i>iMax) break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: shaded polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineGEx(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int iMax=255;
+ uint32_t lc0,lc1;
+ short slx0,slx1,sly0,sly1;int i=2;BOOL bDraw=TRUE;
+
+ sly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
+ slx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
+
+ if(!(dwActFixes&8))
+ {
+ slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
+ sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
+ }
+
+ lc1 = gpuData[0] & 0xffffff;
+
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+
+ while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=4))
+ {
+ sly0=sly1; slx0=slx1; lc0=lc1;
+ lc1=GETLE32(&gpuData[i]) & 0xffffff;
+
+ i++;
+
+ // no check needed on gshaded polyline positions
+ // if((gpuData[i] & 0xF000F000) == 0x50005000) break;
+
+ sly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
+ slx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
+
+ if(!(dwActFixes&8))
+ {
+ slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
+ sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
+ if(CheckCoordL(slx0,sly0,slx1,sly1)) bDraw=FALSE; else bDraw=TRUE;
+ }
+
+ if ((lx0 != lx1) || (ly0 != ly1))
+ {
+ ly0=sly0;
+ lx0=slx0;
+ ly1=sly1;
+ lx1=slx1;
+
+ offsetPSX2();
+ if(bDraw) DrawSoftwareLineShade(lc0, lc1);
+ }
+ i++;
+ if(i>iMax) break;
+ }
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: shaded polyline2
+////////////////////////////////////////////////////////////////////////
+
+void primLineG2(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[6]);
+ ly1 = GETLEs16(&sgpuData[7]);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord2();
+ if(CheckCoord2()) return;
+ }
+
+ if((lx0 == lx1) && (ly0 == ly1)) {lx1++;ly1++;}
+
+ DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
+ offsetPSX2();
+ DrawSoftwareLineShade(GETLE32(&gpuData[0]),GETLE32(&gpuData[2]));
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: skipping flat polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineFSkip(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int i=2,iMax=255;
+
+ ly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
+ lx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
+
+ while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=3))
+ {
+ ly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
+ lx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
+ i++;if(i>iMax) break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: drawing flat polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineFEx(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int iMax;
+ short slx0,slx1,sly0,sly1;int i=2;BOOL bDraw=TRUE;
+
+ iMax=255;
+
+ sly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
+ slx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
+ if(!(dwActFixes&8))
+ {
+ slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
+ sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
+ }
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=3))
+ {
+ sly0 = sly1;slx0=slx1;
+ sly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
+ slx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
+ if(!(dwActFixes&8))
+ {
+ slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
+ sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
+
+ if(CheckCoordL(slx0,sly0,slx1,sly1)) bDraw=FALSE; else bDraw=TRUE;
+ }
+
+ ly0=sly0;
+ lx0=slx0;
+ ly1=sly1;
+ lx1=slx1;
+
+ offsetPSX2();
+ if(bDraw) DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
+
+ i++;if(i>iMax) break;
+ }
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: drawing flat polyline2
+////////////////////////////////////////////////////////////////////////
+
+void primLineF2(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = GETLEs16(&sgpuData[2]);
+ ly0 = GETLEs16(&sgpuData[3]);
+ lx1 = GETLEs16(&sgpuData[4]);
+ ly1 = GETLEs16(&sgpuData[5]);
+
+ if(!(dwActFixes&8))
+ {
+ AdjustCoord2();
+ if(CheckCoord2()) return;
+ }
+
+ if((lx0 == lx1) && (ly0 == ly1)) {lx1++;ly1++;}
+
+ offsetPSX2();
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
+
+ bDoVSyncUpdate=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: well, easiest command... not implemented
+////////////////////////////////////////////////////////////////////////
+
+void primNI(unsigned char *bA)
+{
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd func ptr table
+////////////////////////////////////////////////////////////////////////
+
+
+void (*primTableJ[256])(unsigned char *) =
+{
+ // 00
+ primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
+ // 08
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 10
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 18
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 20
+ primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3,
+ // 28
+ primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4,
+ // 30
+ primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3,
+ // 38
+ primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4,
+ // 40
+ primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI,
+ // 48
+ primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,
+ // 50
+ primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI,
+ // 58
+ primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,
+ // 60
+ primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS,
+ // 68
+ primTile1,primTile1,primTile1,primTile1,primNI,primNI,primNI,primNI,
+ // 70
+ primTile8,primTile8,primTile8,primTile8,primSprt8,primSprt8,primSprt8,primSprt8,
+ // 78
+ primTile16,primTile16,primTile16,primTile16,primSprt16,primSprt16,primSprt16,primSprt16,
+ // 80
+ primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 88
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 90
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 98
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // a0
+ primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // a8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // b0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // b8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // c0
+ primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // c8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // d0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // d8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // e0
+ primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
+ // e8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // f0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // f8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
+};
+
+////////////////////////////////////////////////////////////////////////
+// cmd func ptr table for skipping
+////////////////////////////////////////////////////////////////////////
+
+void (*primTableSkip[256])(unsigned char *) =
+{
+ // 00
+ primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
+ // 08
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 10
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 18
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 20
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 28
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 30
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 38
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 40
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 48
+ primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,
+ // 50
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 58
+ primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,
+ // 60
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 68
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 70
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 78
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 80
+ primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 88
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 90
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 98
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // a0
+ primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // a8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // b0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // b8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // c0
+ primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // c8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // d0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // d8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // e0
+ primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
+ // e8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // f0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // f8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
+};
diff --git a/plugins/dfxvideo/prim.h b/plugins/dfxvideo/prim.h
new file mode 100644
index 0000000..c37c12b
--- /dev/null
+++ b/plugins/dfxvideo/prim.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ prim.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _PRIMDRAW_H_
+#define _PRIMDRAW_H_
+
+void UploadScreen (long Position);
+void PrepareFullScreenUpload (long Position);
+
+#endif // _PRIMDRAW_H_
diff --git a/plugins/dfxvideo/soft.c b/plugins/dfxvideo/soft.c
new file mode 100644
index 0000000..2162566
--- /dev/null
+++ b/plugins/dfxvideo/soft.c
@@ -0,0 +1,8483 @@
+/***************************************************************************
+ soft.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_SOFT
+
+#include "externals.h"
+#include "soft.h"
+
+//#define VC_INLINE
+#include "gpu.h"
+#include "prim.h"
+#include "menu.h"
+#include "swap.h"
+
+////////////////////////////////////////////////////////////////////////////////////
+// "NO EDGE BUFFER" POLY VERSION... FUNCS BASED ON FATMAP.TXT FROM MRI / Doomsday
+////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// defines
+////////////////////////////////////////////////////////////////////////////////////
+
+// switches for painting textured quads as 2 triangles (small glitches, but better shading!)
+// can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled!
+
+#define POLYQUAD3
+#define POLYQUAD3GT
+
+// fast solid loops... a bit more additional code, of course
+
+#define FASTSOLID
+
+// psx blending mode 3 with 25% incoming color (instead 50% without the define)
+
+#define HALFBRIGHTMODE3
+
+// color decode defines
+
+#define XCOL1(x) (x & 0x1f)
+#define XCOL2(x) (x & 0x3e0)
+#define XCOL3(x) (x & 0x7c00)
+
+#define XCOL1D(x) (x & 0x1f)
+#define XCOL2D(x) ((x>>5) & 0x1f)
+#define XCOL3D(x) ((x>>10) & 0x1f)
+
+#define X32TCOL1(x) ((x & 0x001f001f)<<7)
+#define X32TCOL2(x) ((x & 0x03e003e0)<<2)
+#define X32TCOL3(x) ((x & 0x7c007c00)>>3)
+
+#define X32COL1(x) (x & 0x001f001f)
+#define X32COL2(x) ((x>>5) & 0x001f001f)
+#define X32COL3(x) ((x>>10) & 0x001f001f)
+
+#define X32ACOL1(x) (x & 0x001e001e)
+#define X32ACOL2(x) ((x>>5) & 0x001e001e)
+#define X32ACOL3(x) ((x>>10) & 0x001e001e)
+
+#define X32BCOL1(x) (x & 0x001c001c)
+#define X32BCOL2(x) ((x>>5) & 0x001c001c)
+#define X32BCOL3(x) ((x>>10) & 0x001c001c)
+
+#define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r)
+
+#define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f))
+
+////////////////////////////////////////////////////////////////////////////////////
+// soft globals
+////////////////////////////////////////////////////////////////////////////////////
+
+short g_m1=255,g_m2=255,g_m3=255;
+short DrawSemiTrans=FALSE;
+short Ymin;
+short Ymax;
+
+short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3; // global psx vertex coords
+int32_t GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;
+int32_t GlobalTextREST,GlobalTextABR,GlobalTextPAGE;
+
+////////////////////////////////////////////////////////////////////////
+// POLYGON OFFSET FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void offsetPSXLine(void)
+{
+ short x0,x1,y0,y1,dx,dy;float px,py;
+
+ x0 = lx0+1+PSXDisplay.DrawOffset.x;
+ x1 = lx1+1+PSXDisplay.DrawOffset.x;
+ y0 = ly0+1+PSXDisplay.DrawOffset.y;
+ y1 = ly1+1+PSXDisplay.DrawOffset.y;
+
+ dx=x1-x0;
+ dy=y1-y0;
+
+ // tricky line width without sqrt
+
+ if(dx>=0)
+ {
+ if(dy>=0)
+ {
+ px=0.5f;
+ if(dx>dy) py=-0.5f;
+ else if(dx<dy) py= 0.5f;
+ else py= 0.0f;
+ }
+ else
+ {
+ py=-0.5f;
+ dy=-dy;
+ if(dx>dy) px= 0.5f;
+ else if(dx<dy) px=-0.5f;
+ else px= 0.0f;
+ }
+ }
+ else
+ {
+ if(dy>=0)
+ {
+ py=0.5f;
+ dx=-dx;
+ if(dx>dy) px=-0.5f;
+ else if(dx<dy) px= 0.5f;
+ else px= 0.0f;
+ }
+ else
+ {
+ px=-0.5f;
+ if(dx>dy) py=-0.5f;
+ else if(dx<dy) py= 0.5f;
+ else py= 0.0f;
+ }
+ }
+
+ lx0=(short)((float)x0-px);
+ lx3=(short)((float)x0+py);
+
+ ly0=(short)((float)y0-py);
+ ly3=(short)((float)y0-px);
+
+ lx1=(short)((float)x1-py);
+ lx2=(short)((float)x1+px);
+
+ ly1=(short)((float)y1+px);
+ ly2=(short)((float)y1+py);
+}
+
+void offsetPSX2(void)
+{
+ lx0 += PSXDisplay.DrawOffset.x;
+ ly0 += PSXDisplay.DrawOffset.y;
+ lx1 += PSXDisplay.DrawOffset.x;
+ ly1 += PSXDisplay.DrawOffset.y;
+}
+
+void offsetPSX3(void)
+{
+ lx0 += PSXDisplay.DrawOffset.x;
+ ly0 += PSXDisplay.DrawOffset.y;
+ lx1 += PSXDisplay.DrawOffset.x;
+ ly1 += PSXDisplay.DrawOffset.y;
+ lx2 += PSXDisplay.DrawOffset.x;
+ ly2 += PSXDisplay.DrawOffset.y;
+}
+
+void offsetPSX4(void)
+{
+ lx0 += PSXDisplay.DrawOffset.x;
+ ly0 += PSXDisplay.DrawOffset.y;
+ lx1 += PSXDisplay.DrawOffset.x;
+ ly1 += PSXDisplay.DrawOffset.y;
+ lx2 += PSXDisplay.DrawOffset.x;
+ ly2 += PSXDisplay.DrawOffset.y;
+ lx3 += PSXDisplay.DrawOffset.x;
+ ly3 += PSXDisplay.DrawOffset.y;
+}
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+// PER PIXEL FUNCS
+////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+
+unsigned char dithertable[16] =
+{
+ 7, 0, 6, 1,
+ 2, 5, 3, 4,
+ 1, 6, 0, 7,
+ 4, 3, 5, 2
+};
+
+void Dither16(unsigned short * pdest,uint32_t r,uint32_t g,uint32_t b,unsigned short sM)
+{
+ unsigned char coeff;
+ unsigned char rlow, glow, blow;
+ int x,y;
+
+ x=pdest-psxVuw;
+ y=x>>10;
+ x-=(y<<10);
+
+ coeff = dithertable[(y&3)*4+(x&3)];
+
+ rlow = r&7; glow = g&7; blow = b&7;
+
+ r>>=3; g>>=3; b>>=3;
+
+ if ((r < 0x1F) && rlow > coeff) r++;
+ if ((g < 0x1F) && glow > coeff) g++;
+ if ((b < 0x1F) && blow > coeff) b++;
+
+ PUTLE16(pdest, ((unsigned short)b<<10) |
+ ((unsigned short)g<<5) |
+ (unsigned short)r | sM);
+}
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+__inline void GetShadeTransCol_Dither(unsigned short * pdest, int32_t m1, int32_t m2, int32_t m3)
+{
+ int32_t r,g,b;
+
+ if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
+
+ if(DrawSemiTrans)
+ {
+ r=((XCOL1D(GETLE16(pdest)))<<3);
+ b=((XCOL2D(GETLE16(pdest)))<<3);
+ g=((XCOL3D(GETLE16(pdest)))<<3);
+
+ if(GlobalTextABR==0)
+ {
+ r=(r>>1)+(m1>>1);
+ b=(b>>1)+(m2>>1);
+ g=(g>>1)+(m3>>1);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r+=m1;
+ b+=m2;
+ g+=m3;
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r-=m1;
+ b-=m2;
+ g-=m3;
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r+=(m1>>2);
+ b+=(m2>>2);
+ g+=(m3>>2);
+#else
+ r+=(m1>>1);
+ b+=(m2>>1);
+ g+=(m3>>1);
+#endif
+ }
+ }
+ else
+ {
+ r=m1;
+ b=m2;
+ g=m3;
+ }
+
+ if(r&0x7FFFFF00) r=0xff;
+ if(b&0x7FFFFF00) b=0xff;
+ if(g&0x7FFFFF00) g=0xff;
+
+ Dither16(pdest,r,b,g,sSetMask);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetShadeTransCol(unsigned short * pdest,unsigned short color)
+{
+ if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
+
+ if(DrawSemiTrans)
+ {
+ int32_t r,g,b;
+
+ if(GlobalTextABR==0)
+ {
+ PUTLE16(pdest, (((GETLE16(pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|sSetMask);//0x8000;
+ return;
+/*
+ r=(XCOL1(*pdest)>>1)+((XCOL1(color))>>1);
+ b=(XCOL2(*pdest)>>1)+((XCOL2(color))>>1);
+ g=(XCOL3(*pdest)>>1)+((XCOL3(color))>>1);
+*/
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(XCOL1(GETLE16(pdest)))+((XCOL1(color)));
+ b=(XCOL2(GETLE16(pdest)))+((XCOL2(color)));
+ g=(XCOL3(GETLE16(pdest)))+((XCOL3(color)));
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r=(XCOL1(GETLE16(pdest)))-((XCOL1(color)));
+ b=(XCOL2(GETLE16(pdest)))-((XCOL2(color)));
+ g=(XCOL3(GETLE16(pdest)))-((XCOL3(color)));
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>2);
+ b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>2);
+ g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>2);
+#else
+ r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>1);
+ b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>1);
+ g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>1);
+#endif
+ }
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask);//0x8000;
+ }
+ else PUTLE16(pdest, color|sSetMask);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetShadeTransCol32(uint32_t * pdest,uint32_t color)
+{
+ if(DrawSemiTrans)
+ {
+ int32_t r,g,b;
+
+ if(GlobalTextABR==0)
+ {
+ if(!bCheckMask)
+ {
+ PUTLE32(pdest, (((GETLE32(pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|lSetMask);//0x80008000;
+ return;
+ }
+ r=(X32ACOL1(GETLE32(pdest))>>1)+((X32ACOL1(color))>>1);
+ b=(X32ACOL2(GETLE32(pdest))>>1)+((X32ACOL2(color))>>1);
+ g=(X32ACOL3(GETLE32(pdest))>>1)+((X32ACOL3(color))>>1);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(X32COL1(GETLE32(pdest)))+((X32COL1(color)));
+ b=(X32COL2(GETLE32(pdest)))+((X32COL2(color)));
+ g=(X32COL3(GETLE32(pdest)))+((X32COL3(color)));
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ int32_t sr,sb,sg,src,sbc,sgc,c;
+ src=XCOL1(color);sbc=XCOL2(color);sgc=XCOL3(color);
+ c=GETLE32(pdest)>>16;
+ sr=(XCOL1(c))-src; if(sr&0x8000) sr=0;
+ sb=(XCOL2(c))-sbc; if(sb&0x8000) sb=0;
+ sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
+ r=((int32_t)sr)<<16;b=((int32_t)sb)<<11;g=((int32_t)sg)<<6;
+ c=LOWORD(GETLE32(pdest));
+ sr=(XCOL1(c))-src; if(sr&0x8000) sr=0;
+ sb=(XCOL2(c))-sbc; if(sb&0x8000) sb=0;
+ sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
+ r|=sr;b|=sb>>5;g|=sg>>10;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(X32COL1(GETLE32(pdest)))+((X32BCOL1(color))>>2);
+ b=(X32COL2(GETLE32(pdest)))+((X32BCOL2(color))>>2);
+ g=(X32COL3(GETLE32(pdest)))+((X32BCOL3(color))>>2);
+#else
+ r=(X32COL1(GETLE32(pdest)))+((X32ACOL1(color))>>1);
+ b=(X32COL2(GETLE32(pdest)))+((X32ACOL2(color))>>1);
+ g=(X32COL3(GETLE32(pdest)))+((X32ACOL3(color))>>1);
+#endif
+ }
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if(bCheckMask)
+ {
+ uint32_t ma=GETLE32(pdest);
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
+ if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(*pdest&0xFFFF));
+ if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF) |(*pdest&0xFFFF0000));
+ return;
+ }
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
+ }
+ else
+ {
+ if(bCheckMask)
+ {
+ uint32_t ma=GETLE32(pdest);
+ PUTLE32(pdest, color|lSetMask);//0x80008000;
+ if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
+ if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
+ return;
+ }
+
+ PUTLE32(pdest, color|lSetMask);//0x80008000;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG(unsigned short * pdest,unsigned short color)
+{
+ int32_t r,g,b;unsigned short l;
+
+ if(color==0) return;
+
+ if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
+
+ l=sSetMask|(color&0x8000);
+
+ if(DrawSemiTrans && (color&0x8000))
+ {
+ if(GlobalTextABR==0)
+ {
+ unsigned short d;
+ d =(GETLE16(pdest)&0x7bde)>>1;
+ color =((color) &0x7bde)>>1;
+ r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
+
+/*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_m3)>>7);
+*/
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
+#else
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
+#endif
+ }
+ }
+ else
+ {
+ r=((XCOL1(color))* g_m1)>>7;
+ b=((XCOL2(color))* g_m2)>>7;
+ g=((XCOL3(color))* g_m3)>>7;
+ }
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG_S(unsigned short * pdest,unsigned short color)
+{
+ int32_t r,g,b;unsigned short l;
+
+ if(color==0) return;
+
+ l=sSetMask|(color&0x8000);
+
+ r=((XCOL1(color))* g_m1)>>7;
+ b=((XCOL2(color))* g_m2)>>7;
+ g=((XCOL3(color))* g_m3)>>7;
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG_SPR(unsigned short * pdest,unsigned short color)
+{
+ int32_t r,g,b;unsigned short l;
+
+ if(color==0) return;
+
+ if(bCheckMask && (GETLE16(pdest) & 0x8000)) return;
+
+ l=sSetMask|(color&0x8000);
+
+ if(DrawSemiTrans && (color&0x8000))
+ {
+ if(GlobalTextABR==0)
+ {
+ unsigned short d;
+ d =(GETLE16(pdest)&0x7bde)>>1;
+ color =((color) &0x7bde)>>1;
+ r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
+
+/*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_m3)>>7);
+*/
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
+#else
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
+#endif
+ }
+ }
+ else
+ {
+ r=((XCOL1(color))* g_m1)>>7;
+ b=((XCOL2(color))* g_m2)>>7;
+ g=((XCOL3(color))* g_m3)>>7;
+ }
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG32(uint32_t * pdest,uint32_t color)
+{
+ int32_t r,g,b,l;
+
+ if(color==0) return;
+
+ l=lSetMask|(color&0x80008000);
+
+ if(DrawSemiTrans && (color&0x80008000))
+ {
+ if(GlobalTextABR==0)
+ {
+ r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
+ b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
+ g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ int32_t t;
+ r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
+ t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
+ r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
+ r|=t;
+
+ b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
+ t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
+ b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
+ b|=t;
+
+ g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
+ t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
+ g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
+ g|=t;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
+#else
+ r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
+#endif
+ }
+
+ if(!(color&0x8000))
+ {
+ r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
+ b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
+ g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
+ }
+ if(!(color&0x80000000))
+ {
+ r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
+ b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
+ g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
+ }
+
+ }
+ else
+ {
+ r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
+ b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
+ g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
+ }
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if(bCheckMask)
+ {
+ uint32_t ma=GETLE32(pdest);
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
+
+ if((color&0xffff)==0 ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
+ if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
+ if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
+ if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
+
+ return;
+ }
+ if((color&0xffff)==0 ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000));return;}
+ if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff));return;}
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG32_S(uint32_t * pdest,uint32_t color)
+{
+ int32_t r,g,b;
+
+ if(color==0) return;
+
+ r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
+ b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
+ g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if((color&0xffff)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
+ if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG32_SPR(uint32_t * pdest,uint32_t color)
+{
+ int32_t r,g,b;
+
+ if(color==0) return;
+
+ if(DrawSemiTrans && (color&0x80008000))
+ {
+ if(GlobalTextABR==0)
+ {
+ r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
+ b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
+ g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ int32_t t;
+ r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
+ t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
+ r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
+ r|=t;
+
+ b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
+ t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
+ b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
+ b|=t;
+
+ g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
+ t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
+ g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
+ g|=t;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
+#else
+ r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
+#endif
+ }
+
+ if(!(color&0x8000))
+ {
+ r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
+ b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
+ g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
+ }
+ if(!(color&0x80000000))
+ {
+ r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
+ b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
+ g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
+ }
+
+ }
+ else
+ {
+ r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
+ b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
+ g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
+ }
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if(bCheckMask)
+ {
+ uint32_t ma=GETLE32(pdest);
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
+
+ if((color&0xffff)==0 ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
+ if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
+ if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
+ if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
+
+ return;
+ }
+ if((color&0xffff)==0 ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
+ if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColGX_Dither(unsigned short * pdest,unsigned short color,int32_t m1,int32_t m2,int32_t m3)
+{
+ int32_t r,g,b;
+
+ if(color==0) return;
+
+ if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
+
+ m1=(((XCOL1D(color)))*m1)>>4;
+ m2=(((XCOL2D(color)))*m2)>>4;
+ m3=(((XCOL3D(color)))*m3)>>4;
+
+ if(DrawSemiTrans && (color&0x8000))
+ {
+ r=((XCOL1D(GETLE16(pdest)))<<3);
+ b=((XCOL2D(GETLE16(pdest)))<<3);
+ g=((XCOL3D(GETLE16(pdest)))<<3);
+
+ if(GlobalTextABR==0)
+ {
+ r=(r>>1)+(m1>>1);
+ b=(b>>1)+(m2>>1);
+ g=(g>>1)+(m3>>1);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r+=m1;
+ b+=m2;
+ g+=m3;
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r-=m1;
+ b-=m2;
+ g-=m3;
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r+=(m1>>2);
+ b+=(m2>>2);
+ g+=(m3>>2);
+#else
+ r+=(m1>>1);
+ b+=(m2>>1);
+ g+=(m3>>1);
+#endif
+ }
+ }
+ else
+ {
+ r=m1;
+ b=m2;
+ g=m3;
+ }
+
+ if(r&0x7FFFFF00) r=0xff;
+ if(b&0x7FFFFF00) b=0xff;
+ if(g&0x7FFFFF00) g=0xff;
+
+ Dither16(pdest,r,b,g,sSetMask|(color&0x8000));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColGX(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
+{
+ int32_t r,g,b;unsigned short l;
+
+ if(color==0) return;
+
+ if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
+
+ l=sSetMask|(color&0x8000);
+
+ if(DrawSemiTrans && (color&0x8000))
+ {
+ if(GlobalTextABR==0)
+ {
+ unsigned short d;
+ d =(GETLE16(pdest)&0x7bde)>>1;
+ color =((color) &0x7bde)>>1;
+ r=(XCOL1(d))+((((XCOL1(color)))* m1)>>7);
+ b=(XCOL2(d))+((((XCOL2(color)))* m2)>>7);
+ g=(XCOL3(d))+((((XCOL3(color)))* m3)>>7);
+/*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* m3)>>7);
+*/
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* m3)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* m3)>>7);
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* m3)>>7);
+#else
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* m3)>>7);
+#endif
+ }
+ }
+ else
+ {
+ r=((XCOL1(color))* m1)>>7;
+ b=((XCOL2(color))* m2)>>7;
+ g=((XCOL3(color))* m3)>>7;
+ }
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColGX_S(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
+{
+ int32_t r,g,b;
+
+ if(color==0) return;
+
+ r=((XCOL1(color))* m1)>>7;
+ b=((XCOL2(color))* m2)>>7;
+ g=((XCOL3(color))* m3)>>7;
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask|(color&0x8000));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColGX32_S(uint32_t * pdest,uint32_t color,short m1,short m2,short m3)
+{
+ int32_t r,g,b;
+
+ if(color==0) return;
+
+ r=(((X32COL1(color))* m1)&0xFF80FF80)>>7;
+ b=(((X32COL2(color))* m2)&0xFF80FF80)>>7;
+ g=(((X32COL3(color))* m3)&0xFF80FF80)>>7;
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if((color&0xffff)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
+ if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
+}
+
+////////////////////////////////////////////////////////////////////////
+// FILL FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void FillSoftwareAreaTrans(short x0,short y0,short x1, // FILL AREA TRANS
+ short y1,unsigned short col)
+{
+ short j,i,dx,dy;
+
+ if(y0>y1) return;
+ if(x0>x1) return;
+
+ if(x1<drawX) return;
+ if(y1<drawY) return;
+ if(x0>drawW) return;
+ if(y0>drawH) return;
+
+ x1=min(x1,drawW+1);
+ y1=min(y1,drawH+1);
+ x0=max(x0,drawX);
+ y0=max(y0,drawY);
+
+ if(y0>=iGPUHeight) return;
+ if(x0>1023) return;
+
+ if(y1>iGPUHeight) y1=iGPUHeight;
+ if(x1>1024) x1=1024;
+
+ dx=x1-x0;dy=y1-y0;
+
+ if(dx==1 && dy==1 && x0==1020 && y0==511) // special fix for pinball game... emu protection???
+ {
+/*
+m->v 1020 511 1 1
+writedatamem 0x00000000 1
+tile1 newcol 7fff (orgcol 0xffffff), oldvram 0
+v->m 1020 511 1 1
+readdatamem 0x00007fff 1
+m->v 1020 511 1 1
+writedatamem 0x00000000 1
+tile1 newcol 8000 (orgcol 0xffffff), oldvram 0
+v->m 1020 511 1 1
+readdatamem 0x00008000 1
+*/
+
+ static int iCheat=0;
+ col+=iCheat;
+ if(iCheat==1) iCheat=0; else iCheat=1;
+ }
+
+
+ if(dx&1) // slow fill
+ {
+ unsigned short *DSTPtr;
+ unsigned short LineOffset;
+ DSTPtr = psxVuw + (1024*y0) + x0;
+ LineOffset = 1024 - dx;
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++)
+ GetShadeTransCol(DSTPtr++,col);
+ DSTPtr += LineOffset;
+ }
+ }
+ else // fast fill
+ {
+ uint32_t *DSTPtr;
+ unsigned short LineOffset;
+ uint32_t lcol=lSetMask|(((uint32_t)(col))<<16)|col;
+ dx>>=1;
+ DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
+ LineOffset = 512 - dx;
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
+ DSTPtr += LineOffset;
+ }
+ }
+ else
+ {
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++)
+ GetShadeTransCol32(DSTPtr++,lcol);
+ DSTPtr += LineOffset;
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void FillSoftwareArea(short x0,short y0,short x1, // FILL AREA (BLK FILL)
+ short y1,unsigned short col) // no draw area check here!
+{
+ short j,i,dx,dy;
+
+ if(y0>y1) return;
+ if(x0>x1) return;
+
+ if(y0>=iGPUHeight) return;
+ if(x0>1023) return;
+
+ if(y1>iGPUHeight) y1=iGPUHeight;
+ if(x1>1024) x1=1024;
+
+ dx=x1-x0;dy=y1-y0;
+ if(dx&1)
+ {
+ unsigned short *DSTPtr;
+ unsigned short LineOffset;
+
+ DSTPtr = psxVuw + (1024*y0) + x0;
+ LineOffset = 1024 - dx;
+
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++) { PUTLE16(DSTPtr, col); DSTPtr++; }
+ DSTPtr += LineOffset;
+ }
+ }
+ else
+ {
+ uint32_t *DSTPtr;
+ unsigned short LineOffset;
+ uint32_t lcol=(((int32_t)col)<<16)|col;
+ dx>>=1;
+ DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
+ LineOffset = 512 - dx;
+
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
+ DSTPtr += LineOffset;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+// EDGE INTERPOLATION
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+typedef struct SOFTVTAG
+{
+ int x,y;
+ int u,v;
+ int32_t R,G,B;
+} soft_vertex;
+
+static soft_vertex vtx[4];
+static soft_vertex * left_array[4], * right_array[4];
+static int left_section, right_section;
+static int left_section_height, right_section_height;
+static int left_x, delta_left_x, right_x, delta_right_x;
+static int left_u, delta_left_u, left_v, delta_left_v;
+static int right_u, delta_right_u, right_v, delta_right_v;
+static int left_R, delta_left_R, right_R, delta_right_R;
+static int left_G, delta_left_G, right_G, delta_right_G;
+static int left_B, delta_left_B, right_B, delta_right_B;
+
+#ifdef USE_NASM
+
+// NASM version (external):
+#define shl10idiv i386_shl10idiv
+
+__inline int shl10idiv(int x, int y);
+
+#else
+
+__inline int shl10idiv(int x, int y)
+{
+ __int64 bi=x;
+ bi<<=10;
+ return bi/y;
+}
+
+#endif
+
+#if 0
+
+// GNUC long long int version:
+
+__inline int shl10idiv(int x, int y)
+{
+ long long int bi=x;
+ bi<<=10;
+ return bi/y;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+__inline int RightSection_F(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline int LeftSection_F(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ left_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL NextRow_F(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section <= 0) {return TRUE;}
+ if(LeftSection_F() <= 0) {return TRUE;}
+ }
+ else
+ {
+ left_x += delta_left_x;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section<=0) {return TRUE;}
+ if(RightSection_F() <=0) {return TRUE;}
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL SetupSections_F(short x1, short y1, short x2, short y2, short x3, short y3)
+{
+ soft_vertex * v1, * v2, * v3;
+ int height,longest;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+
+ height = v3->y - v1->y;
+ if(height == 0) {return FALSE;}
+ longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest == 0) {return FALSE;}
+
+ if(longest < 0)
+ {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if(LeftSection_F() <= 0) return FALSE;
+ if(RightSection_F() <= 0)
+ {
+ right_section--;
+ if(RightSection_F() <= 0) return FALSE;
+ }
+ }
+ else
+ {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if(RightSection_F() <= 0) return FALSE;
+ if(LeftSection_F() <= 0)
+ {
+ left_section--;
+ if(LeftSection_F() <= 0) return FALSE;
+ }
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v3->y-1,drawH);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+__inline int RightSection_G(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline int LeftSection_G(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_R = ((v2->R - v1->R)) / height;
+ left_R = v1->R;
+ delta_left_G = ((v2->G - v1->G)) / height;
+ left_G = v1->G;
+ delta_left_B = ((v2->B - v1->B)) / height;
+ left_B = v1->B;
+
+ left_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL NextRow_G(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section <= 0) {return TRUE;}
+ if(LeftSection_G() <= 0) {return TRUE;}
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section<=0) {return TRUE;}
+ if(RightSection_G() <=0) {return TRUE;}
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL SetupSections_G(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb1, int32_t rgb2, int32_t rgb3)
+{
+ soft_vertex * v1, * v2, * v3;
+ int height,longest,temp;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->R=(rgb1) & 0x00ff0000;
+ v1->G=(rgb1<<8) & 0x00ff0000;
+ v1->B=(rgb1<<16) & 0x00ff0000;
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->R=(rgb2) & 0x00ff0000;
+ v2->G=(rgb2<<8) & 0x00ff0000;
+ v2->B=(rgb2<<16) & 0x00ff0000;
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->R=(rgb3) & 0x00ff0000;
+ v3->G=(rgb3<<8) & 0x00ff0000;
+ v3->B=(rgb3<<16) & 0x00ff0000;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+
+ height = v3->y - v1->y;
+ if(height == 0) {return FALSE;}
+ temp=(((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest == 0) {return FALSE;}
+
+ if(longest < 0)
+ {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if(LeftSection_G() <= 0) return FALSE;
+ if(RightSection_G() <= 0)
+ {
+ right_section--;
+ if(RightSection_G() <= 0) return FALSE;
+ }
+ if(longest > -0x1000) longest = -0x1000;
+ }
+ else
+ {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if(RightSection_G() <= 0) return FALSE;
+ if(LeftSection_G() <= 0)
+ {
+ left_section--;
+ if(LeftSection_G() <= 0) return FALSE;
+ }
+ if(longest < 0x1000) longest = 0x1000;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v3->y-1,drawH);
+
+ delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
+ delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
+ delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+__inline int RightSection_FT(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline int LeftSection_FT(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_u = ((v2->u - v1->u)) / height;
+ left_u = v1->u;
+ delta_left_v = ((v2->v - v1->v)) / height;
+ left_v = v1->v;
+
+ left_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL NextRow_FT(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section <= 0) {return TRUE;}
+ if(LeftSection_FT() <= 0) {return TRUE;}
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section<=0) {return TRUE;}
+ if(RightSection_FT() <=0) {return TRUE;}
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL SetupSections_FT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
+{
+ soft_vertex * v1, * v2, * v3;
+ int height,longest,temp;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->u=tx1<<16;v1->v=ty1<<16;
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->u=tx2<<16;v2->v=ty2<<16;
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->u=tx3<<16;v3->v=ty3<<16;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+
+ height = v3->y - v1->y;
+ if(height == 0) {return FALSE;}
+
+ temp=(((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+
+ if(longest == 0) {return FALSE;}
+
+ if(longest < 0)
+ {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if(LeftSection_FT() <= 0) return FALSE;
+ if(RightSection_FT() <= 0)
+ {
+ right_section--;
+ if(RightSection_FT() <= 0) return FALSE;
+ }
+ if(longest > -0x1000) longest = -0x1000;
+ }
+ else
+ {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if(RightSection_FT() <= 0) return FALSE;
+ if(LeftSection_FT() <= 0)
+ {
+ left_section--;
+ if(LeftSection_FT() <= 0) return FALSE;
+ }
+ if(longest < 0x1000) longest = 0x1000;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v3->y-1,drawH);
+
+ delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
+ delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
+
+/*
+Mmm... adjust neg tex deltas... will sometimes cause slight
+texture distortions
+
+ longest>>=16;
+ if(longest)
+ {
+ if(longest<0) longest=-longest;
+ if(delta_right_u<0)
+ delta_right_u-=delta_right_u/longest;
+ if(delta_right_v<0)
+ delta_right_v-=delta_right_v/longest;
+ }
+*/
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+__inline int RightSection_GT(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline int LeftSection_GT(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_u = ((v2->u - v1->u)) / height;
+ left_u = v1->u;
+ delta_left_v = ((v2->v - v1->v)) / height;
+ left_v = v1->v;
+
+ delta_left_R = ((v2->R - v1->R)) / height;
+ left_R = v1->R;
+ delta_left_G = ((v2->G - v1->G)) / height;
+ left_G = v1->G;
+ delta_left_B = ((v2->B - v1->B)) / height;
+ left_B = v1->B;
+
+ left_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL NextRow_GT(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section <= 0) {return TRUE;}
+ if(LeftSection_GT() <= 0) {return TRUE;}
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section<=0) {return TRUE;}
+ if(RightSection_GT() <=0) {return TRUE;}
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL SetupSections_GT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int32_t rgb1, int32_t rgb2, int32_t rgb3)
+{
+ soft_vertex * v1, * v2, * v3;
+ int height,longest,temp;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->u=tx1<<16;v1->v=ty1<<16;
+ v1->R=(rgb1) & 0x00ff0000;
+ v1->G=(rgb1<<8) & 0x00ff0000;
+ v1->B=(rgb1<<16) & 0x00ff0000;
+
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->u=tx2<<16;v2->v=ty2<<16;
+ v2->R=(rgb2) & 0x00ff0000;
+ v2->G=(rgb2<<8) & 0x00ff0000;
+ v2->B=(rgb2<<16) & 0x00ff0000;
+
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->u=tx3<<16;v3->v=ty3<<16;
+ v3->R=(rgb3) & 0x00ff0000;
+ v3->G=(rgb3<<8) & 0x00ff0000;
+ v3->B=(rgb3<<16) & 0x00ff0000;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+
+ height = v3->y - v1->y;
+ if(height == 0) {return FALSE;}
+
+ temp=(((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+
+ if(longest == 0) {return FALSE;}
+
+ if(longest < 0)
+ {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if(LeftSection_GT() <= 0) return FALSE;
+ if(RightSection_GT() <= 0)
+ {
+ right_section--;
+ if(RightSection_GT() <= 0) return FALSE;
+ }
+
+ if(longest > -0x1000) longest = -0x1000;
+ }
+ else
+ {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if(RightSection_GT() <= 0) return FALSE;
+ if(LeftSection_GT() <= 0)
+ {
+ left_section--;
+ if(LeftSection_GT() <= 0) return FALSE;
+ }
+ if(longest < 0x1000) longest = 0x1000;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v3->y-1,drawH);
+
+ delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
+ delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
+ delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
+
+ delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
+ delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
+
+
+/*
+Mmm... adjust neg tex deltas... will sometimes cause slight
+texture distortions
+ longest>>=16;
+ if(longest)
+ {
+ if(longest<0) longest=-longest;
+ if(delta_right_u<0)
+ delta_right_u-=delta_right_u/longest;
+ if(delta_right_v<0)
+ delta_right_v-=delta_right_v/longest;
+ }
+*/
+
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+__inline int RightSection_F4(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline int LeftSection_F4(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL NextRow_F4(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section > 0)
+ while(LeftSection_F4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+ }
+ else
+ {
+ left_x += delta_left_x;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section > 0)
+ while(RightSection_F4()<=0)
+ {
+ if(--right_section<=0) break;
+ }
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL SetupSections_F4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4)
+{
+ soft_vertex * v1, * v2, * v3, * v4;
+ int height,width,longest1,longest2;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+ if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
+ if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
+
+ height = v4->y - v1->y; if(height == 0) height =1;
+ width = (v4->x - v1->x)>>16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if(longest1 < 0) // 2 is right
+ {
+ if(longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ }
+ else
+ {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ }
+ else
+ {
+ if(longest2 < 0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while(LeftSection_F4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+
+ while(RightSection_F4()<=0)
+ {
+ if(--right_section <= 0) break;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v4->y-1,drawH);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+__inline int RightSection_FT4(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ right_u = v1->u;
+ right_v = v1->v;
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+ delta_right_u = (v2->u - v1->u) / height;
+ delta_right_v = (v2->v - v1->v) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline int LeftSection_FT4(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ left_u = v1->u;
+ left_v = v1->v;
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+ delta_left_u = (v2->u - v1->u) / height;
+ delta_left_v = (v2->v - v1->v) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL NextRow_FT4(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section > 0)
+ while(LeftSection_FT4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section > 0)
+ while(RightSection_FT4()<=0)
+ {
+ if(--right_section<=0) break;
+ }
+ }
+ else
+ {
+ right_x += delta_right_x;
+ right_u += delta_right_u;
+ right_v += delta_right_v;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL SetupSections_FT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ soft_vertex * v1, * v2, * v3, * v4;
+ int height,width,longest1,longest2;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->u=tx1<<16;v1->v=ty1<<16;
+
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->u=tx2<<16;v2->v=ty2<<16;
+
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->u=tx3<<16;v3->v=ty3<<16;
+
+ v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
+ v4->u=tx4<<16;v4->v=ty4<<16;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+ if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
+ if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
+
+ height = v4->y - v1->y; if(height == 0) height =1;
+ width = (v4->x - v1->x)>>16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if(longest1 < 0) // 2 is right
+ {
+ if(longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ }
+ else
+ {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ }
+ else
+ {
+ if(longest2 < 0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while(LeftSection_FT4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+
+ while(RightSection_FT4()<=0)
+ {
+ if(--right_section <= 0) break;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v4->y-1,drawH);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+__inline int RightSection_GT4(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ right_u = v1->u;
+ right_v = v1->v;
+ right_R = v1->R;
+ right_G = v1->G;
+ right_B = v1->B;
+
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+ delta_right_u = (v2->u - v1->u) / height;
+ delta_right_v = (v2->v - v1->v) / height;
+ delta_right_R = (v2->R - v1->R) / height;
+ delta_right_G = (v2->G - v1->G) / height;
+ delta_right_B = (v2->B - v1->B) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline int LeftSection_GT4(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ left_u = v1->u;
+ left_v = v1->v;
+ left_R = v1->R;
+ left_G = v1->G;
+ left_B = v1->B;
+
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+ delta_left_u = (v2->u - v1->u) / height;
+ delta_left_v = (v2->v - v1->v) / height;
+ delta_left_R = (v2->R - v1->R) / height;
+ delta_left_G = (v2->G - v1->G) / height;
+ delta_left_B = (v2->B - v1->B) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL NextRow_GT4(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section > 0)
+ while(LeftSection_GT4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section > 0)
+ while(RightSection_GT4()<=0)
+ {
+ if(--right_section<=0) break;
+ }
+ }
+ else
+ {
+ right_x += delta_right_x;
+ right_u += delta_right_u;
+ right_v += delta_right_v;
+ right_R += delta_right_R;
+ right_G += delta_right_G;
+ right_B += delta_right_B;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline BOOL SetupSections_GT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,int32_t rgb1,int32_t rgb2,int32_t rgb3,int32_t rgb4)
+{
+ soft_vertex * v1, * v2, * v3, * v4;
+ int height,width,longest1,longest2;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->u=tx1<<16;v1->v=ty1<<16;
+ v1->R=(rgb1) & 0x00ff0000;
+ v1->G=(rgb1<<8) & 0x00ff0000;
+ v1->B=(rgb1<<16) & 0x00ff0000;
+
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->u=tx2<<16;v2->v=ty2<<16;
+ v2->R=(rgb2) & 0x00ff0000;
+ v2->G=(rgb2<<8) & 0x00ff0000;
+ v2->B=(rgb2<<16) & 0x00ff0000;
+
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->u=tx3<<16;v3->v=ty3<<16;
+ v3->R=(rgb3) & 0x00ff0000;
+ v3->G=(rgb3<<8) & 0x00ff0000;
+ v3->B=(rgb3<<16) & 0x00ff0000;
+
+ v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
+ v4->u=tx4<<16;v4->v=ty4<<16;
+ v4->R=(rgb4) & 0x00ff0000;
+ v4->G=(rgb4<<8) & 0x00ff0000;
+ v4->B=(rgb4<<16) & 0x00ff0000;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+ if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
+ if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
+
+ height = v4->y - v1->y; if(height == 0) height =1;
+ width = (v4->x - v1->x)>>16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if(longest1 < 0) // 2 is right
+ {
+ if(longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ }
+ else
+ {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ }
+ else
+ {
+ if(longest2 < 0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while(LeftSection_GT4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+
+ while(RightSection_GT4()<=0)
+ {
+ if(--right_section <= 0) break;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v4->y-1,drawH);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+// POLY FUNCS
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 FLAT SHADED
+////////////////////////////////////////////////////////////////////////
+
+__inline void drawPoly3Fi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ unsigned short color;uint32_t lcolor;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_F(x1,y1,x2,y2,x3,y3)) return;
+
+ ymax=Ymax;
+
+ color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
+ lcolor=lSetMask|(((uint32_t)(color))<<16)|color;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_F()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ color |=sSetMask;
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
+ xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
+ }
+ if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
+
+ if(NextRow_F()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
+ xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
+ }
+ if(j==xmax)
+ GetShadeTransCol(&psxVuw[(i<<10)+j],color);
+
+ if(NextRow_F()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3F(int32_t rgb)
+{
+ drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
+}
+
+#ifdef POLYQUAD3FS
+
+void drawPoly4F_TRI(int32_t rgb)
+{
+ drawPoly3Fi(lx1,ly1,lx3,ly3,lx2,ly2,rgb);
+ drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4F(int32_t rgb)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ unsigned short color;uint32_t lcolor;
+
+ if(lx0>drawW && lx1>drawW && lx2>drawW && lx3>drawW) return;
+ if(ly0>drawH && ly1>drawH && ly2>drawH && ly3>drawH) return;
+ if(lx0<drawX && lx1<drawX && lx2<drawX && lx3<drawX) return;
+ if(ly0<drawY && ly1<drawY && ly2<drawY && ly3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_F4(lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_F4()) return;
+
+ color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
+ lcolor= lSetMask|(((uint32_t)(color))<<16)|color;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ color |=sSetMask;
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
+ xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
+ }
+ if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
+
+ if(NextRow_F4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
+ xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
+ }
+ if(j==xmax) GetShadeTransCol(&psxVuw[(i<<10)+j],color);
+
+ if(NextRow_F4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 F-SHADED TEX PAL 4
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,XAdjust;
+ int32_t clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,XAdjust;
+ int32_t clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1;
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,XAdjust;
+ int32_t clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
+ if(xmax>xmin) xmax--;
+
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ drawPoly3TEx4(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY);
+ drawPoly3TEx4(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int32_t num;
+ int32_t i,j=0,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX=0,posY=0,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+
+ }
+ if(NextRow_FT4()) return;
+ }
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+////////////////////////////////////////////////////////////////////////
+// POLY 3 F-SHADED TEX PAL 8
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
+ if(xmax>xmin) xmax--;
+
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ drawPoly3TEx8(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY);
+
+ drawPoly3TEx8(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3 F-SHADED TEX 15 BIT
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ drawPoly3TD(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4);
+ drawPoly3TD(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY)<<10)+TWin.Position.y0+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TD_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY)<<10)+TWin.Position.y0+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED
+////////////////////////////////////////////////////////////////////////
+
+__inline void drawPoly3Gi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb1, int32_t rgb2, int32_t rgb3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_G(x1,y1,x2,y2,x3,y3,rgb1,rgb2,rgb3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_G()) return;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && iDither!=2)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]),
+ ((((cR1+difR) <<7)&0x7c000000)|(((cG1+difG) << 2)&0x03e00000)|(((cB1+difB)>>3)&0x001f0000)|
+ (((cR1) >> 9)&0x7c00)|(((cG1) >> 14)&0x03e0)|(((cB1) >> 19)&0x001f))|lSetMask);
+
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ PUTLE16(&psxVuw[(i<<10)+j], (((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f))|sSetMask);
+ }
+ if(NextRow_G()) return;
+ }
+ return;
+ }
+
+#endif
+
+ if(iDither==2)
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ GetShadeTransCol_Dither(&psxVuw[(i<<10)+j],(cB1>>16),(cG1>>16),(cR1>>16));
+
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_G()) return;
+ }
+ else
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ GetShadeTransCol(&psxVuw[(i<<10)+j],((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f));
+
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_G()) return;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3G(int32_t rgb1, int32_t rgb2, int32_t rgb3)
+{
+ drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,rgb1,rgb2,rgb3);
+}
+
+// draw two g-shaded tris for right psx shading emulation
+
+void drawPoly4G(int32_t rgb1, int32_t rgb2, int32_t rgb3, int32_t rgb4)
+{
+ drawPoly3Gi(lx1,ly1,lx3,ly3,lx2,ly2,
+ rgb2,rgb4,rgb3);
+ drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,
+ rgb1,rgb2,rgb3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED TEX PAL4
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=((left_x) >> 16);
+ xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
+{
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=((left_x) >> 16);
+ xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=((left_x) >> 16);
+ xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: the psx is doing g-shaded quads as two g-shaded tris,
+// like the following func... sadly texturing is not 100%
+// correct that way, so small texture distortions can
+// happen...
+
+void drawPoly4TGEx4_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col3, int32_t col4)
+{
+ drawPoly3TGEx4_IL(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx4_IL(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col3, int32_t col4)
+{
+ drawPoly3TGEx4(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx4(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col4, int32_t col3)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col3, int32_t col4)
+{
+ drawPoly3TGEx4_TW(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+
+ drawPoly3TGEx4_TW(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED TEX PAL8
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ (((posX+difX)>>16))];
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
+{
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
+
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: two g-shaded tris: small texture distortions can happen
+
+void drawPoly4TGEx8_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col3, int32_t col4)
+{
+ drawPoly3TGEx8_IL(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx8_IL(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col3, int32_t col4)
+{
+ drawPoly3TGEx8(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx8(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+#endif
+
+void drawPoly4TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col4, int32_t col3)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1])|
+ ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[clutP+tC1]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col3, int32_t col4)
+{
+ drawPoly3TGEx8_TW(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx8_TW(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3 G-SHADED TEX 15 BIT
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,int32_t col1, int32_t col2, int32_t col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]),
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,int32_t col1, int32_t col2, int32_t col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY,difX2, difY2;
+ int32_t posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]),
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: two g-shaded tris: small texture distortions can happen
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col3, int32_t col4)
+{
+ drawPoly3TGD(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ col2,col4,col3);
+ drawPoly3TGD(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ col1,col2,col3);
+}
+
+#endif
+
+void drawPoly4TGD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col4, int32_t col3)
+{
+ int32_t num;
+ int32_t i,j,xmin,xmax,ymin,ymax;
+ int32_t cR1,cG1,cB1;
+ int32_t difR,difB,difG,difR2,difB2,difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT4()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]),
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ if(NextRow_GT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ if(iDither)
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col3, int32_t col4)
+{
+ drawPoly3TGD_TW(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ col2,col4,col3);
+ drawPoly3TGD_TW(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ col1,col2,col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+
+/*
+// no real rect test, but it does its job the way I need it
+__inline BOOL IsNoRect(void)
+{
+ if(lx0==lx1 && lx2==lx3) return FALSE;
+ if(lx0==lx2 && lx1==lx3) return FALSE;
+ if(lx0==lx3 && lx1==lx2) return FALSE;
+ return TRUE;
+}
+*/
+
+// real rect test
+__inline BOOL IsNoRect(void)
+{
+ if(!(dwActFixes&0x200)) return FALSE;
+
+ if(ly0==ly1)
+ {
+ if(lx1==lx3 && ly3==ly2 && lx2==lx0) return FALSE;
+ if(lx1==lx2 && ly2==ly3 && lx3==lx0) return FALSE;
+ return TRUE;
+ }
+
+ if(ly0==ly2)
+ {
+ if(lx2==lx3 && ly3==ly1 && lx1==lx0) return FALSE;
+ if(lx2==lx1 && ly1==ly3 && lx3==lx0) return FALSE;
+ return TRUE;
+ }
+
+ if(ly0==ly3)
+ {
+ if(lx3==lx2 && ly2==ly1 && lx1==lx0) return FALSE;
+ if(lx3==lx1 && ly1==ly2 && lx2==lx0) return FALSE;
+ return TRUE;
+ }
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3FT(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {
+ if(GlobalTextTP==0)
+ drawPoly3TEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ else
+ drawPoly3TEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ }
+
+ if(!bUsingTWin && !(dwActFixes&0x100))
+ {
+ switch(GlobalTextTP) // depending on texture mode
+ {
+ case 0:
+ drawPoly3TEx4(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly3TEx8(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly3TD(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+
+ switch(GlobalTextTP) // depending on texture mode
+ {
+ case 0:
+ drawPoly3TEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly3TEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly3TD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4FT(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {
+ if(GlobalTextTP==0)
+ drawPoly4TEx4_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ else
+ drawPoly4TEx8_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ }
+
+ if(!bUsingTWin)
+ {
+#ifdef POLYQUAD3GT
+ if(IsNoRect())
+ {
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly4TEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly4TD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+#endif
+
+ switch (GlobalTextTP)
+ {
+ case 0: // grandia investigations needed
+ drawPoly4TEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly4TEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly4TD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly4TEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly4TD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3GT(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {
+ if(GlobalTextTP==0)
+ drawPoly3TGEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
+ else
+ drawPoly3TGEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
+ return;
+ }
+
+ if(!bUsingTWin)
+ {
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly3TGEx4(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
+ return;
+ case 1:
+ drawPoly3TGEx8(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
+ return;
+ case 2:
+ drawPoly3TGD(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
+ return;
+ }
+ return;
+ }
+
+ switch(GlobalTextTP)
+ {
+ case 0:
+ drawPoly3TGEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
+ return;
+ case 1:
+ drawPoly3TGEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
+ return;
+ case 2:
+ drawPoly3TGD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4GT(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {
+ if(GlobalTextTP==0)
+ drawPoly4TGEx4_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ else
+ drawPoly4TGEx8_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ return;
+ }
+
+ if(!bUsingTWin)
+ {
+#ifdef POLYQUAD3GT
+ if(IsNoRect())
+ {
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TGEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+
+ return;
+ case 1:
+ drawPoly4TGEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ return;
+ case 2:
+ drawPoly4TGD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ return;
+ }
+ return;
+ }
+#endif
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TGEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+
+ return;
+ case 1:
+ drawPoly4TGEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ return;
+ case 2:
+ drawPoly4TGD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ return;
+ }
+ return;
+ }
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TGEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ return;
+ case 1:
+ drawPoly4TGEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
+ GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ return;
+ case 2:
+ drawPoly4TGD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// SPRITE FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSpriteTWin(unsigned char * baseAddr,int32_t w,int32_t h)
+{
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+ short sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3;
+ short tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3;
+
+ sx0=lx0;
+ sy0=ly0;
+
+ sx0=sx3=sx0+PSXDisplay.DrawOffset.x;
+ sx1=sx2=sx0+w;
+ sy0=sy1=sy0+PSXDisplay.DrawOffset.y;
+ sy2=sy3=sy0+h;
+
+ tx0=tx3=GETLE32(&gpuData[2])&0xff;
+ tx1=tx2=tx0+w;
+ ty0=ty1=(GETLE32(&gpuData[2])>>8)&0xff;
+ ty2=ty3=ty0+h;
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TEx4_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
+ tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3,
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly4TEx8_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
+ tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3,
+ ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly4TD_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
+ tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3);
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSpriteMirror(unsigned char * baseAddr,int32_t w,int32_t h)
+{
+ int32_t sprtY,sprtX,sprtW,sprtH,lXDir,lYDir;
+ int32_t clutY0,clutX0,clutP,textX0,textY0,sprtYa,sprCY,sprCX,sprA;
+ short tC;
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+ sprtY = ly0;
+ sprtX = lx0;
+ sprtH = h;
+ sprtW = w;
+ clutY0 = (GETLE32(&gpuData[2])>>22) & iGPUHeightMask;
+ clutX0 = (GETLE32(&gpuData[2])>>12) & 0x3f0;
+ clutP = (clutY0<<11) + (clutX0<<1);
+ textY0 = ((GETLE32(&gpuData[2])>>8) & 0x000000ff) + GlobalTextAddrY;
+ textX0 = (GETLE32(&gpuData[2]) & 0x000000ff);
+
+ sprtX+=PSXDisplay.DrawOffset.x;
+ sprtY+=PSXDisplay.DrawOffset.y;
+
+// while (sprtX>1023) sprtX-=1024;
+// while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES;
+
+ if(sprtX>drawW)
+ {
+// if((sprtX+sprtW)>1023) sprtX-=1024;
+// else return;
+ return;
+ }
+
+ if(sprtY>drawH)
+ {
+// if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
+// else return;
+ return;
+ }
+
+ if(sprtY<drawY)
+ {
+ if((sprtY+sprtH)<drawY) return;
+ sprtH-=(drawY-sprtY);
+ textY0+=(drawY-sprtY);
+ sprtY=drawY;
+ }
+
+ if(sprtX<drawX)
+ {
+ if((sprtX+sprtW)<drawX) return;
+ sprtW-=(drawX-sprtX);
+ textX0+=(drawX-sprtX);
+ sprtX=drawX;
+ }
+
+ if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1;
+ if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1;
+
+ if(usMirror&0x1000) lXDir=-1; else lXDir=1;
+ if(usMirror&0x2000) lYDir=-1; else lYDir=1;
+
+ switch (GlobalTextTP)
+ {
+ case 0: // texture is 4-bit
+
+ sprtW=sprtW/2;
+ textX0=(GlobalTextAddrX<<1)+(textX0>>1);
+ sprtYa=(sprtY<<10);
+ clutP=(clutY0<<10)+clutX0;
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ for (sprCX=0;sprCX<sprtW;sprCX++)
+ {
+ tC= psxVub[((textY0+(sprCY*lYDir))<<11) + textX0 +(sprCX*lXDir)];
+ sprA=sprtYa+(sprCY<<10)+sprtX + (sprCX<<1);
+ GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
+ GetTextureTransColG_SPR(&psxVuw[sprA+1],GETLE16(&psxVuw[clutP+(tC&0xf)]));
+ }
+ return;
+
+ case 1:
+
+ clutP>>=1;
+ for(sprCY=0;sprCY<sprtH;sprCY++)
+ for(sprCX=0;sprCX<sprtW;sprCX++)
+ {
+ tC = psxVub[((textY0+(sprCY*lYDir))<<11)+(GlobalTextAddrX<<1) + textX0 + (sprCX*lXDir)] & 0xff;
+ GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX + sprCX],psxVuw[clutP+tC]);
+ }
+ return;
+
+ case 2:
+
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ for (sprCX=0;sprCX<sprtW;sprCX++)
+ {
+ GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX+sprCX],
+ GETLE16(&psxVuw[((textY0+(sprCY*lYDir))<<10)+GlobalTextAddrX + textX0 +(sprCX*lXDir)]));
+ }
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSprite_IL(unsigned char * baseAddr,short w,short h,int32_t tx,int32_t ty)
+{
+ int32_t sprtY,sprtX,sprtW,sprtH,tdx,tdy;
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+
+ sprtY = ly0;
+ sprtX = lx0;
+ sprtH = h;
+ sprtW = w;
+
+ sprtX+=PSXDisplay.DrawOffset.x;
+ sprtY+=PSXDisplay.DrawOffset.y;
+
+ if(sprtX>drawW) return;
+ if(sprtY>drawH) return;
+
+ tdx=tx+sprtW;
+ tdy=ty+sprtH;
+
+ sprtW+=sprtX;
+ sprtH+=sprtY;
+
+ // Pete is too lazy to make a faster version ;)
+
+ if(GlobalTextTP==0)
+ drawPoly4TEx4_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY,
+ tx,ty, tx,tdy, tdx,tdy, tdx,ty,
+ (GETLE32(&gpuData[2])>>12) & 0x3f0, ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+
+
+ else
+ drawPoly4TEx8_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY,
+ tx,ty, tx,tdy, tdx,tdy, tdx,ty,
+ (GETLE32(&gpuData[2])>>12) & 0x3f0, ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSprite(unsigned char * baseAddr,short w,short h,int32_t tx,int32_t ty)
+{
+ int32_t sprtY,sprtX,sprtW,sprtH;
+ int32_t clutY0,clutX0,clutP,textX0,textY0,sprtYa,sprCY,sprCX,sprA;
+ short tC,tC2;
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+ unsigned char * pV;
+ BOOL bWT,bWS;
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {DrawSoftwareSprite_IL(baseAddr,w,h,tx,ty);return;}
+
+ sprtY = ly0;
+ sprtX = lx0;
+ sprtH = h;
+ sprtW = w;
+ clutY0 = (GETLE32(&gpuData[2])>>22) & iGPUHeightMask;
+ clutX0 = (GETLE32(&gpuData[2])>>12) & 0x3f0;
+
+ clutP = (clutY0<<11) + (clutX0<<1);
+
+ textY0 =ty+ GlobalTextAddrY;
+ textX0 =tx;
+
+ sprtX+=PSXDisplay.DrawOffset.x;
+ sprtY+=PSXDisplay.DrawOffset.y;
+
+ //while (sprtX>1023) sprtX-=1024;
+ //while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES;
+
+ if(sprtX>drawW)
+ {
+// if((sprtX+sprtW)>1023) sprtX-=1024;
+// else return;
+ return;
+ }
+
+ if(sprtY>drawH)
+ {
+// if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
+// else return;
+ return;
+ }
+
+ if(sprtY<drawY)
+ {
+ if((sprtY+sprtH)<drawY) return;
+ sprtH-=(drawY-sprtY);
+ textY0+=(drawY-sprtY);
+ sprtY=drawY;
+ }
+
+ if(sprtX<drawX)
+ {
+ if((sprtX+sprtW)<drawX) return;
+
+ sprtW-=(drawX-sprtX);
+ textX0+=(drawX-sprtX);
+ sprtX=drawX;
+ }
+
+ if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1;
+ if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1;
+
+
+ bWT=FALSE;
+ bWS=FALSE;
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+
+ if(textX0&1) {bWS=TRUE;sprtW--;}
+ if(sprtW&1) bWT=TRUE;
+
+ sprtW=sprtW>>1;
+ textX0=(GlobalTextAddrX<<1)+(textX0>>1)+(textY0<<11);
+ sprtYa=(sprtY<<10)+sprtX;
+ clutP=(clutY0<<10)+clutX0;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=sprtYa+(sprCY<<10);
+ pV=&psxVub[(sprCY<<11)+textX0];
+
+ if(bWS)
+ {
+ tC=*pV++;
+ GetTextureTransColG_S(&psxVuw[sprA++],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
+ }
+
+ for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2)
+ {
+ tC=*pV++;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
+ (((int32_t)GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]))<<16)|
+ GETLE16(&psxVuw[clutP+(tC&0x0f)]));
+ }
+
+ if(bWT)
+ {
+ tC=*pV;
+ GetTextureTransColG_S(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(tC&0x0f)]));
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=sprtYa+(sprCY<<10);
+ pV=&psxVub[(sprCY<<11)+textX0];
+
+ if(bWS)
+ {
+ tC=*pV++;
+ GetTextureTransColG_SPR(&psxVuw[sprA++],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
+ }
+
+ for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2)
+ {
+ tC=*pV++;
+
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
+ (((int32_t)GETLE16(&psxVuw[clutP+((tC>>4)&0xf)])<<16))|
+ GETLE16(&psxVuw[clutP+(tC&0x0f)]));
+ }
+
+ if(bWT)
+ {
+ tC=*pV;
+ GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(tC&0x0f)]));
+ }
+ }
+ return;
+
+ case 1:
+ clutP>>=1;sprtW--;
+ textX0+=(GlobalTextAddrX<<1) + (textY0<<11);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for(sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=((sprtY+sprCY)<<10)+sprtX;
+ pV=&psxVub[(sprCY<<11)+textX0];
+ for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
+ {
+ tC = *pV++;tC2 = *pV++;
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
+ (((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16)|
+ GETLE16(&psxVuw[clutP+tC]));
+ }
+ if(sprCX==sprtW)
+ GetTextureTransColG_S(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(*pV)]));
+ }
+ return;
+ }
+
+#endif
+
+ for(sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=((sprtY+sprCY)<<10)+sprtX;
+ pV=&psxVub[(sprCY<<11)+textX0];
+ for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
+ {
+ tC = *pV++;tC2 = *pV++;
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
+ (((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16)|
+ GETLE16(&psxVuw[clutP+tC]));
+ }
+ if(sprCX==sprtW)
+ GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(*pV)]));
+ }
+ return;
+
+ case 2:
+
+ textX0+=(GlobalTextAddrX) + (textY0<<10);
+ sprtW--;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=((sprtY+sprCY)<<10)+sprtX;
+
+ for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
+ (((int32_t)GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX +1]))<<16)|
+ GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
+ }
+ if(sprCX==sprtW)
+ GetTextureTransColG_S(&psxVuw[sprA],
+ GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
+
+ }
+ return;
+ }
+
+#endif
+
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=((sprtY+sprCY)<<10)+sprtX;
+
+ for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
+ {
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
+ (((int32_t)GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX +1]))<<16)|
+ GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
+ }
+ if(sprCX==sprtW)
+ GetTextureTransColG_SPR(&psxVuw[sprA],
+ GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
+
+ }
+ return;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+// LINE FUNCS
+////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int dx, dy, incrE, incrSE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx > 0)
+ {
+ dr = ((int32_t)r1 - (int32_t)r0) / dx;
+ dg = ((int32_t)g1 - (int32_t)g0) / dx;
+ db = ((int32_t)b1 - (int32_t)b0) / dx;
+ }
+ else
+ {
+ dr = ((int32_t)r1 - (int32_t)r0);
+ dg = ((int32_t)g1 - (int32_t)g0);
+ db = ((int32_t)b1 - (int32_t)b0);
+ }
+
+ d = 2*dy - dx; /* Initial value of d */
+ incrE = 2*dy; /* incr. used for move to E */
+ incrSE = 2*(dy - dx); /* incr. used for move to SE */
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ while(x0 < x1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrE; /* Choose E */
+ }
+ else
+ {
+ d = d + incrSE; /* Choose SE */
+ y0++;
+ }
+ x0++;
+
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_S_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int dx, dy, incrS, incrSE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dy > 0)
+ {
+ dr = ((int32_t)r1 - (int32_t)r0) / dy;
+ dg = ((int32_t)g1 - (int32_t)g0) / dy;
+ db = ((int32_t)b1 - (int32_t)b0) / dy;
+ }
+ else
+ {
+ dr = ((int32_t)r1 - (int32_t)r0);
+ dg = ((int32_t)g1 - (int32_t)g0);
+ db = ((int32_t)b1 - (int32_t)b0);
+ }
+
+ d = 2*dx - dy; /* Initial value of d */
+ incrS = 2*dx; /* incr. used for move to S */
+ incrSE = 2*(dx - dy); /* incr. used for move to SE */
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ while(y0 < y1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrS; /* Choose S */
+ }
+ else
+ {
+ d = d + incrSE; /* Choose SE */
+ x0++;
+ }
+ y0++;
+
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_N_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int dx, dy, incrN, incrNE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+
+ if (dy > 0)
+ {
+ dr = ((int32_t)r1 - (int32_t)r0) / dy;
+ dg = ((int32_t)g1 - (int32_t)g0) / dy;
+ db = ((int32_t)b1 - (int32_t)b0) / dy;
+ }
+ else
+ {
+ dr = ((int32_t)r1 - (int32_t)r0);
+ dg = ((int32_t)g1 - (int32_t)g0);
+ db = ((int32_t)b1 - (int32_t)b0);
+ }
+
+ d = 2*dx - dy; /* Initial value of d */
+ incrN = 2*dx; /* incr. used for move to N */
+ incrNE = 2*(dx - dy); /* incr. used for move to NE */
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ while(y0 > y1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrN; /* Choose N */
+ }
+ else
+ {
+ d = d + incrNE; /* Choose NE */
+ x0++;
+ }
+ y0--;
+
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int dx, dy, incrE, incrNE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+
+ if (dx > 0)
+ {
+ dr = ((int32_t)r1 - (int32_t)r0) / dx;
+ dg = ((int32_t)g1 - (int32_t)g0) / dx;
+ db = ((int32_t)b1 - (int32_t)b0) / dx;
+ }
+ else
+ {
+ dr = ((int32_t)r1 - (int32_t)r0);
+ dg = ((int32_t)g1 - (int32_t)g0);
+ db = ((int32_t)b1 - (int32_t)b0);
+ }
+
+ d = 2*dy - dx; /* Initial value of d */
+ incrE = 2*dy; /* incr. used for move to E */
+ incrNE = 2*(dy - dx); /* incr. used for move to NE */
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ while(x0 < x1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrE; /* Choose E */
+ }
+ else
+ {
+ d = d + incrNE; /* Choose NE */
+ y0--;
+ }
+ x0++;
+
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void VertLineShade(int x, int y0, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int y, dy;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dy = (y1 - y0);
+
+ if (dy > 0)
+ {
+ dr = ((int32_t)r1 - (int32_t)r0) / dy;
+ dg = ((int32_t)g1 - (int32_t)g0) / dy;
+ db = ((int32_t)b1 - (int32_t)b0) / dy;
+ }
+ else
+ {
+ dr = ((int32_t)r1 - (int32_t)r0);
+ dg = ((int32_t)g1 - (int32_t)g0);
+ db = ((int32_t)b1 - (int32_t)b0);
+ }
+
+ if (y0 < drawY)
+ {
+ r0+=dr*(drawY - y0);
+ g0+=dg*(drawY - y0);
+ b0+=db*(drawY - y0);
+ y0 = drawY;
+ }
+
+ if (y1 > drawH)
+ y1 = drawH;
+
+ for (y = y0; y <= y1; y++)
+ {
+ GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void HorzLineShade(int y, int x0, int x1, uint32_t rgb0, uint32_t rgb1)
+{
+ int x, dx;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = (x1 - x0);
+
+ if (dx > 0)
+ {
+ dr = ((int32_t)r1 - (int32_t)r0) / dx;
+ dg = ((int32_t)g1 - (int32_t)g0) / dx;
+ db = ((int32_t)b1 - (int32_t)b0) / dx;
+ }
+ else
+ {
+ dr = ((int32_t)r1 - (int32_t)r0);
+ dg = ((int32_t)g1 - (int32_t)g0);
+ db = ((int32_t)b1 - (int32_t)b0);
+ }
+
+ if (x0 < drawX)
+ {
+ r0+=dr*(drawX - x0);
+ g0+=dg*(drawX - x0);
+ b0+=db*(drawX - x0);
+ x0 = drawX;
+ }
+
+ if (x1 > drawW)
+ x1 = drawW;
+
+ for (x = x0; x <= x1; x++)
+ {
+ GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
+{
+ int dx, dy, incrE, incrSE, d, x, y;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ d = 2*dy - dx; /* Initial value of d */
+ incrE = 2*dy; /* incr. used for move to E */
+ incrSE = 2*(dy - dx); /* incr. used for move to SE */
+ x = x0;
+ y = y0;
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ while(x < x1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrE; /* Choose E */
+ x++;
+ }
+ else
+ {
+ d = d + incrSE; /* Choose SE */
+ x++;
+ y++;
+ }
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_S_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
+{
+ int dx, dy, incrS, incrSE, d, x, y;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ d = 2*dx - dy; /* Initial value of d */
+ incrS = 2*dx; /* incr. used for move to S */
+ incrSE = 2*(dx - dy); /* incr. used for move to SE */
+ x = x0;
+ y = y0;
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ while(y < y1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrS; /* Choose S */
+ y++;
+ }
+ else
+ {
+ d = d + incrSE; /* Choose SE */
+ x++;
+ y++;
+ }
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_N_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
+{
+ int dx, dy, incrN, incrNE, d, x, y;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+ d = 2*dx - dy; /* Initial value of d */
+ incrN = 2*dx; /* incr. used for move to N */
+ incrNE = 2*(dx - dy); /* incr. used for move to NE */
+ x = x0;
+ y = y0;
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ while(y > y1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrN; /* Choose N */
+ y--;
+ }
+ else
+ {
+ d = d + incrNE; /* Choose NE */
+ x++;
+ y--;
+ }
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
+{
+ int dx, dy, incrE, incrNE, d, x, y;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+ d = 2*dy - dx; /* Initial value of d */
+ incrE = 2*dy; /* incr. used for move to E */
+ incrNE = 2*(dy - dx); /* incr. used for move to NE */
+ x = x0;
+ y = y0;
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ while(x < x1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrE; /* Choose E */
+ x++;
+ }
+ else
+ {
+ d = d + incrNE; /* Choose NE */
+ x++;
+ y--;
+ }
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void VertLineFlat(int x, int y0, int y1, unsigned short colour)
+{
+ int y;
+
+ if (y0 < drawY)
+ y0 = drawY;
+
+ if (y1 > drawH)
+ y1 = drawH;
+
+ for (y = y0; y <= y1; y++)
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void HorzLineFlat(int y, int x0, int x1, unsigned short colour)
+{
+ int x;
+
+ if (x0 < drawX)
+ x0 = drawX;
+
+ if (x1 > drawW)
+ x1 = drawW;
+
+ for (x = x0; x <= x1; x++)
+ GetShadeTransCol(&psxVuw[(y << 10) + x], colour);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+/* Bresenham Line drawing function */
+void DrawSoftwareLineShade(int32_t rgb0, int32_t rgb1)
+{
+ short x0, y0, x1, y1, xt, yt;
+ int32_t rgbt;
+ double m, dy, dx;
+
+ if (lx0 > drawW && lx1 > drawW) return;
+ if (ly0 > drawH && ly1 > drawH) return;
+ if (lx0 < drawX && lx1 < drawX) return;
+ if (ly0 < drawY && ly1 < drawY) return;
+ if (drawY >= drawH) return;
+ if (drawX >= drawW) return;
+
+ x0 = lx0;
+ y0 = ly0;
+ x1 = lx1;
+ y1 = ly1;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx == 0)
+ {
+ if (dy > 0)
+ VertLineShade(x0, y0, y1, rgb0, rgb1);
+ else
+ VertLineShade(x0, y1, y0, rgb1, rgb0);
+ }
+ else
+ if (dy == 0)
+ {
+ if (dx > 0)
+ HorzLineShade(y0, x0, x1, rgb0, rgb1);
+ else
+ HorzLineShade(y0, x1, x0, rgb1, rgb0);
+ }
+ else
+ {
+ if (dx < 0)
+ {
+ xt = x0;
+ yt = y0;
+ rgbt = rgb0;
+ x0 = x1;
+ y0 = y1;
+ rgb0 = rgb1;
+ x1 = xt;
+ y1 = yt;
+ rgb1 = rgbt;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ }
+
+ m = dy / dx;
+
+ if (m >= 0)
+ {
+ if (m > 1)
+ Line_S_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ else
+ Line_E_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ }
+ else
+ if (m < -1)
+ Line_N_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ else
+ Line_E_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareLineFlat(int32_t rgb)
+{
+ short x0, y0, x1, y1, xt, yt;
+ double m, dy, dx;
+ unsigned short colour = 0;
+
+ if (lx0 > drawW && lx1 > drawW) return;
+ if (ly0 > drawH && ly1 > drawH) return;
+ if (lx0 < drawX && lx1 < drawX) return;
+ if (ly0 < drawY && ly1 < drawY) return;
+ if (drawY >= drawH) return;
+ if (drawX >= drawW) return;
+
+ colour = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb & 0x000000f8) >> 3);
+
+ x0 = lx0;
+ y0 = ly0;
+ x1 = lx1;
+ y1 = ly1;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx == 0)
+ {
+ if (dy == 0)
+ return; // Nothing to draw
+ else if (dy > 0)
+ VertLineFlat(x0, y0, y1, colour);
+ else
+ VertLineFlat(x0, y1, y0, colour);
+ }
+ else
+ if (dy == 0)
+ {
+ if (dx > 0)
+ HorzLineFlat(y0, x0, x1, colour);
+ else
+ HorzLineFlat(y0, x1, x0, colour);
+ }
+ else
+ {
+ if (dx < 0)
+ {
+ xt = x0;
+ yt = y0;
+ x0 = x1;
+ y0 = y1;
+ x1 = xt;
+ y1 = yt;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ }
+
+ m = dy/dx;
+
+ if (m >= 0)
+ {
+ if (m > 1)
+ Line_S_SE_Flat(x0, y0, x1, y1, colour);
+ else
+ Line_E_SE_Flat(x0, y0, x1, y1, colour);
+ }
+ else
+ if (m < -1)
+ Line_N_NE_Flat(x0, y0, x1, y1, colour);
+ else
+ Line_E_NE_Flat(x0, y0, x1, y1, colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
diff --git a/plugins/dfxvideo/soft.h b/plugins/dfxvideo/soft.h
new file mode 100644
index 0000000..f52d5c0
--- /dev/null
+++ b/plugins/dfxvideo/soft.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ soft.h - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _GPU_SOFT_H_
+#define _GPU_SOFT_H_
+
+void offsetPSXLine(void);
+void offsetPSX2(void);
+void offsetPSX3(void);
+void offsetPSX4(void);
+
+void FillSoftwareAreaTrans(short x0,short y0,short x1,short y1,unsigned short col);
+void FillSoftwareArea(short x0,short y0,short x1,short y1,unsigned short col);
+void drawPoly3G(int32_t rgb1, int32_t rgb2, int32_t rgb3);
+void drawPoly4G(int32_t rgb1, int32_t rgb2, int32_t rgb3, int32_t rgb4);
+void drawPoly3F(int32_t rgb);
+void drawPoly4F(int32_t rgb);
+void drawPoly4FT(unsigned char * baseAddr);
+void drawPoly4GT(unsigned char * baseAddr);
+void drawPoly3FT(unsigned char * baseAddr);
+void drawPoly3GT(unsigned char * baseAddr);
+void DrawSoftwareSprite(unsigned char * baseAddr,short w,short h,int32_t tx,int32_t ty);
+void DrawSoftwareSpriteTWin(unsigned char * baseAddr,int32_t w,int32_t h);
+void DrawSoftwareSpriteMirror(unsigned char * baseAddr,int32_t w,int32_t h);
+void DrawSoftwareLineShade(int32_t rgb0, int32_t rgb1);
+void DrawSoftwareLineFlat(int32_t rgb);
+
+#endif // _GPU_SOFT_H_
diff --git a/plugins/dfxvideo/swap.h b/plugins/dfxvideo/swap.h
new file mode 100644
index 0000000..3f7ac21
--- /dev/null
+++ b/plugins/dfxvideo/swap.h
@@ -0,0 +1,71 @@
+#include <stdint.h>
+
+// byteswappings
+
+#define SWAP16(x) ({ uint16_t y=(x); (((y)>>8 & 0xff) | ((y)<<8 & 0xff00)); })
+#define SWAP32(x) ({ uint32_t y=(x); (((y)>>24 & 0xfful) | ((y)>>8 & 0xff00ul) | ((y)<<8 & 0xff0000ul) | ((y)<<24 & 0xff000000ul)); })
+
+#ifdef __BIG_ENDIAN__
+
+// big endian config
+#define HOST2LE32(x) SWAP32(x)
+#define HOST2BE32(x) (x)
+#define LE2HOST32(x) SWAP32(x)
+#define BE2HOST32(x) (x)
+
+#define HOST2LE16(x) SWAP16(x)
+#define HOST2BE16(x) (x)
+#define LE2HOST16(x) SWAP16(x)
+#define BE2HOST16(x) (x)
+
+#else
+
+// little endian config
+#define HOST2LE32(x) (x)
+#define HOST2BE32(x) SWAP32(x)
+#define LE2HOST32(x) (x)
+#define BE2HOST32(x) SWAP32(x)
+
+#define HOST2LE16(x) (x)
+#define HOST2BE16(x) SWAP16(x)
+#define LE2HOST16(x) (x)
+#define BE2HOST16(x) SWAP16(x)
+
+#endif
+
+#define GETLEs16(X) ((int16_t)GETLE16((uint16_t *)X))
+#define GETLEs32(X) ((int16_t)GETLE32((uint16_t *)X))
+
+#if defined(__PPC__) && defined(__BIG_ENDIAN__)
+
+// GCC style
+static __inline__ uint16_t GETLE16(uint16_t *ptr) {
+ uint16_t ret; __asm__ ("lhbrx %0, 0, %1" : "=r" (ret) : "r" (ptr));
+ return ret;
+}
+static __inline__ uint32_t GETLE32(uint32_t *ptr) {
+ uint32_t ret;
+ __asm__ ("lwbrx %0, 0, %1" : "=r" (ret) : "r" (ptr));
+ return ret;
+}
+static __inline__ uint32_t GETLE16D(uint32_t *ptr) {
+ uint32_t ret;
+ __asm__ ("lwbrx %0, 0, %1\n"
+ "rlwinm %0, %0, 16, 0, 31" : "=r" (ret) : "r" (ptr));
+ return ret;
+}
+
+static __inline__ void PUTLE16(uint16_t *ptr, uint16_t val) {
+ __asm__ ("sthbrx %0, 0, %1" : : "r" (val), "r" (ptr) : "memory");
+}
+static __inline__ void PUTLE32(uint32_t *ptr, uint32_t val) {
+ __asm__ ("stwbrx %0, 0, %1" : : "r" (val), "r" (ptr) : "memory");
+}
+
+#else
+#define GETLE16(X) LE2HOST16(*(uint16_t *)X)
+#define GETLE32(X) LE2HOST32(*(uint32_t *)X)
+#define GETLE16D(X) ({uint32_t val = GETLE32(X); (val<<16 | val >> 16);})
+#define PUTLE16(X, Y) do{*((uint16_t *)X)=HOST2LE16((uint16_t)Y);}while(0)
+#define PUTLE32(X, Y) do{*((uint32_t *)X)=HOST2LE16((uint32_t)Y);}while(0)
+#endif
diff --git a/plugins/dfxvideo/zn.c b/plugins/dfxvideo/zn.c
new file mode 100644
index 0000000..ea8537b
--- /dev/null
+++ b/plugins/dfxvideo/zn.c
@@ -0,0 +1,255 @@
+/***************************************************************************
+ zn.c - description
+ -------------------
+ begin : Sat Jan 31 2004
+ copyright : (C) 2004 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_ZN
+
+#include "externals.h"
+
+// --------------------------------------------------- //
+// - psx gpu plugin interface prototypes-------------- //
+// --------------------------------------------------- //
+
+long GPUopen(unsigned long *disp, const char *CapText, const char *CfgFile);
+
+void CALLBACK GPUdisplayText(char * pText);
+void CALLBACK GPUdisplayFlags(uint32_t dwFlags);
+void CALLBACK GPUmakeSnapshot(void);
+long CALLBACK GPUinit();
+long CALLBACK GPUclose();
+long CALLBACK GPUshutdown();
+void CALLBACK GPUcursor(int iPlayer,int x,int y);
+void CALLBACK GPUupdateLace(void);
+uint32_t CALLBACK GPUreadStatus(void);
+void CALLBACK GPUwriteStatus(uint32_t gdata);
+void CALLBACK GPUreadDataMem(uint32_t * pMem, int iSize);
+uint32_t CALLBACK GPUreadData(void);
+void CALLBACK GPUwriteDataMem(uint32_t * pMem, int iSize);
+void CALLBACK GPUwriteData(uint32_t gdata);
+void CALLBACK GPUsetMode(uint32_t gdata);
+long CALLBACK GPUgetMode(void);
+long CALLBACK GPUdmaChain(uint32_t * baseAddrL, uint32_t addr);
+long CALLBACK GPUconfigure(void);
+void CALLBACK GPUabout(void);
+long CALLBACK GPUtest(void);
+long CALLBACK GPUfreeze(uint32_t ulGetFreezeData,void * pF);
+void CALLBACK GPUgetScreenPic(unsigned char * pMem);
+void CALLBACK GPUshowScreenPic(unsigned char * pMem);
+
+void CALLBACK GPUkeypressed(int keycode);
+
+
+// --------------------------------------------------- //
+// - zn gpu interface -------------------------------- //
+// --------------------------------------------------- //
+
+uint32_t dwGPUVersion=0;
+int iGPUHeight=512;
+int iGPUHeightMask=511;
+int GlobalTextIL=0;
+int iTileCheat=0;
+
+// --------------------------------------------------- //
+// --------------------------------------------------- //
+// --------------------------------------------------- //
+
+typedef struct GPUOTAG
+ {
+ uint32_t Version; // Version of structure - currently 1
+ long hWnd; // Window handle
+ uint32_t ScreenRotation; // 0 = 0CW, 1 = 90CW, 2 = 180CW, 3 = 270CW = 90CCW
+ uint32_t GPUVersion; // 0 = a, 1 = b, 2 = c
+ const char* GameName; // NULL terminated string
+ const char* CfgFile; // NULL terminated string
+ } GPUConfiguration_t;
+
+// --------------------------------------------------- //
+// --------------------------------------------------- //
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUdisplayFlags(uint32_t dwFlags)
+{
+ GPUdisplayFlags(dwFlags);
+}
+
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUmakeSnapshot(void)
+{
+ GPUmakeSnapshot();
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUinit()
+{ // we always set the vram size to 2MB, if the ZN interface is used
+ iGPUHeight=1024;
+ iGPUHeightMask=1023;
+
+ return GPUinit();
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUopen(void * vcfg)
+{
+ GPUConfiguration_t * cfg=(GPUConfiguration_t *)vcfg;
+ long lret;
+
+ if(!cfg) return -1;
+ if(cfg->Version!=1) return -1;
+
+ lret = GPUopen(&cfg->hWnd, cfg->GameName, cfg->CfgFile);
+
+
+/*
+ if(!lstrcmp(cfg->GameName,"kikaioh") ||
+ !lstrcmp(cfg->GameName,"sr2j") ||
+ !lstrcmp(cfg->GameName,"rvschool_a"))
+ iTileCheat=1;
+*/
+
+ // some ZN games seem to erase the cluts with a 'white' TileS... strange..
+ // I've added a cheat to avoid this issue. We can set it globally (for
+ // all ZiNc games) without much risk
+
+ iTileCheat=1;
+
+ dwGPUVersion=cfg->GPUVersion;
+
+ return lret;
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUclose()
+{
+ return GPUclose();
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUshutdown()
+{
+ return GPUshutdown();
+}
+
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUupdateLace(void)
+{
+ GPUupdateLace();
+}
+
+// --------------------------------------------------- //
+
+uint32_t CALLBACK ZN_GPUreadStatus(void)
+{
+ return GPUreadStatus();
+}
+
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUwriteStatus(uint32_t gdata)
+{
+ GPUwriteStatus(gdata);
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUdmaSliceOut(uint32_t *baseAddrL, uint32_t addr, uint32_t iSize)
+{
+ GPUreadDataMem(baseAddrL+addr,iSize);
+ return 0;
+}
+
+// --------------------------------------------------- //
+
+uint32_t CALLBACK ZN_GPUreadData(void)
+{
+ return GPUreadData();
+}
+
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUsetMode(uint32_t gdata)
+{
+ GPUsetMode(gdata);
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUgetMode(void)
+{
+ return GPUgetMode();
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUdmaSliceIn(uint32_t *baseAddrL, uint32_t addr, uint32_t iSize)
+{
+ GPUwriteDataMem(baseAddrL+addr,iSize);
+ return 0;
+}
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUwriteData(uint32_t gdata)
+{
+ GPUwriteDataMem(&gdata,1);
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUdmaChain(uint32_t * baseAddrL, uint32_t addr)
+{
+ return GPUdmaChain(baseAddrL,addr);
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUtest(void)
+{
+ return GPUtest();
+}
+
+// --------------------------------------------------- //
+
+long CALLBACK ZN_GPUfreeze(uint32_t ulGetFreezeData,void * pF)
+{
+ return GPUfreeze(ulGetFreezeData,pF);
+}
+
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUgetScreenPic(unsigned char * pMem)
+{
+ GPUgetScreenPic(pMem);
+}
+
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUshowScreenPic(unsigned char * pMem)
+{
+ GPUshowScreenPic(pMem);
+}
+
+// --------------------------------------------------- //
+
+void CALLBACK ZN_GPUkeypressed(int keycode)
+{
+ GPUkeypressed(keycode);
+}
+