Initial import from 013a1 cvs

This commit is contained in:
Jens Hemprich 2006-05-26 19:42:13 +00:00
parent c47833fc64
commit 61205ec045
94 changed files with 45975 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,148 @@
Compatibility:
Performance and rendering quality:
In general, MacGLide works best when used in the MacOS X Classic environment. In this case
it can use the MacOS X OpenGL driver to render better quality images, and offers a lot more
features (like anisotropic filtering, Full Scene Antialiasing, etc.).
In MacOS 9, the performance is a little bit better, but the rendering quality is not as good
as in the Classic environment.
Compatibility:
MacGLide has been tested with a lot of several games, and with several
hardware configurations. Below is a list of games and how they do with MacGLide.
Playable Games:
Carmageddon: Works just fine. There is just a small problem with ExposŽ and
the mouse pointer. To use the mouse, you must set the screen
resolution to your desktop size.
Carmageddon Splatpack: Works just fine. Set the resolution to the desktop resolution
to get the mouse pointer working correctly.
Carmageddon 2: Works fine except that in menus and the loading screen,
the colors of the background images are wrong. Otherwise
the game is fully playable.
Descent 1 & 2: Playable, but there are issues with switching from cockpit to map
view. The textures become corrupt after a few switches, or the screen
behind the cockpit becomes blank (to resolve this you can just switch
the view to rear and back)
Descent 3 Demo: Works fine, with great graphics. But I have just the demo, and no
twin-stick, so I just gave it a quick try.
Deus Ex: Works fine except the sunglasses of some characters are sometimes
white. The same goes for gun-smoke effects which are displayed
all the time (instead just when firing a gun). Sometimes, textured
landscape tiles show the wrong textures (or garbage).
DS9 - The Fallen: Some objects in the intro seem to have problems with transparency.
Otherwise the game looks great but I haven't tested it a lot.
Falcon 4.0: Works just fine. For maximum performance at 1600x1200, choose 800x600
in the game menu, and set Resolution=2 in the settings file.
Futurecop LAPD: Works fine except that in version 1.02, the pause screen is corrupt.
But you can stick with version 1.0.
Myth The Fallen Lords: Works fine except when you override the Glide resolution in V1.3
or below, the mouse pointer will not work correctly anymore.
Quake 3Dfx: Works fine.
Rune Demo: The Demo seems to work fine.
Tomb Raider 1 (Gold): Works fine. Please note, that the In-Game menu has a black background,
except for 640x480, where you can see the dimmed paused game.
I believe this is actually a game feature, so don't blame me without
screenshots made with 3dfx hardware.
Tomb Raider 2 (Gold): Works fine even with movies enabled with Version TR2 1.03. Earlier
versions of TR2 may not display everything as expected.
Tomb Raider 3: Works fine.
Unreal: Works fine.
Games with issues:
Diablo 2: In the video driver setup dialog, the 3dfx/Glide options is greyed out
and can't be selected. Probably needs 3DfxGlideLib3.x to run properly
in 3dfx mode. However, there's a MacOS X patch available.
Driver 3dfx: The main menu screen is missing. Besides that, the game doesn't run
in the MaxOS X classic environment (even with software rendering).
F-18 Korea: Hardly playable. Although the textures look correct now, there are
severe screen update problems in cockpit mode.
Waterrace: Needs 3DfxGlideLib3.x to run properly in 3dfx mode.
In general, MacGLide works best when used in the MacOS X Classic environment. In this case
it can use the MacOS X OpenGL driver to render better quality images, and offers a lot more
features (like anisotropic filtering, Full Scene Antialiasing, etc.).
In MacOS 9, the performance is a little bit better, but the rendering quality is not as good
as in the Classic environment.
Tested systems on MacOS X:
MacGLide runs on any system with an OpenGL capable graphics card.
So far, I've tested MacGLide myself with the following cards:
- NVidia GForce 2MX
- NVidia 4MX
- ATI Radeon 7500
- ATI Radeon 9000
- ATI Mobility Radeon 9200
With these cards, all supported games work as described above.
But other cards will likely work without problems, too.
Same systems with MacOS 9.22:
On MacOS 9, MacGLide doesn't run very well. The development of MacGLide
is focussed on features available through the Classic environemnt.
As a result, MacOS9 users have to live with the following inconveniences:
- Fog is missing
- Unreal doesn't work with mipmaps enabled.
- In Carmageddon, textured objects loose their texture adn become white shaded.
- The MacOS 9.22 OpenGL drivers doesn't support Antialiasing.
- Chromakeying mght not work (probably caused by non-working alpha test).
If you still want to play your games on MacOS 9.22, here's some problems
I have encountered on my machines:
NVidia GForce 2MX OpenGL 1.2.2 (MacOS 9.22):
- In Myth, most objects in the game are drawn in the wrong colors.
ATI Rage 128 OpenGL Engine Version 1.1.ATI-5.99 (MacOS 9.22):
- The display in Carmageddon starts to flicker when the race starts.
- The ATI OpenGL 1.1 driver returns 32 bit as the maximum Depth Buffer bits, causing
display errors. To get a correct display, the maximum number of depth buffer
bits must explicitely be set to 16 in the ini-file (DepthBufferBits=16).
- Tomb Raider Gold has still zbuffer problems, even with the changed settings.
- Unreal looks bad when mipmapping is enabled.
- In Myth, the bounding rectangle of most objects in the game ise drawn with the wrong colors
(seems to be a problem with the Alpha test not working)
If you have a graphic card not mentioned here, please let me know your experiences.
Regards, Jens

View File

@ -0,0 +1,72 @@
Configuration:
MacGLide stores its settings in the "MacGLide Settings" subfolder of the
Preferences Folder in the MacOS 9 System Folder. There can be settings for
each game, but normally you're just editing the default settings, which
apply to all games. The files are created when you run a game the first
time.
The most important settings:
Resolution=n Overrides the screen resolution
values from 1 to 8 are used to multiply the resolution requested by
the game.
Example: With Resolution=2 and the game requests 800x600, the
screen resolution will be actually 1600x1200.
Because the game still thinks it 800x600, you might
achive higher framerates for games that extensively
write to the framebuffer (for instance Falcon 4.0).
Greater values override the requested resolution with a fixed value:
Example: Resolution=1024 sets the screen resolution to 1024x768
regardless what the game requests (handy if you're using
a LCD with that resolution).
FullSceneAntiAliasing=n Sets the amount of samples to be used for antialiasing.
Values greater than 1 enable full scene antialiasing
(improves rendering quality a lot)
Example: FullSceneAntiAliasing=4 uses 4 samples to render a pixel. The
maximum value depends on the amount of VRAM of your video card
and the screen resolution.
So if your set the value too high, FSAA may cease to work. In
this case, you have either to decrease the screen resolution
or the FSAA value.
TextureSmoothing=n Improves rendering quality by enabling global texture
smoothing and mipmapping for all objects.
A value of 1 (default) enables texture smoothing, a value of 0 disables
it. When enabled, all textures (instead of just the ones chosen by the
game) are rendered smoothly (using the OpenGL linear filter). If
mipmaps are enabled (they are by default) all textures are also
mipmapped.
MonitorRefreshRate=n Overrides the vertical screen refesh rate.
Values from >=60 set the vertical screen refresh rate to n.
Example: MonitorRefreshRate=75 sets the vertical screen refresh rate to
75Hz. Some games doesn't allow to change the refresh rate, but you can
change it here.
All other default values are chosen for each game to provide the best quality/
compatibility, so it shouldn't be necessary to change them.
For other setings, see the hints at the top of the ini-file for details.
Memory usage:
In order to get a game running with MacGLide on a MacOS 9 system and to avoid
a sudden exit to the finder, you must raise its memory partition by
about 50000K. When started in the MacOS X classic environment, the memory
setting can be left as it as.

View File

@ -0,0 +1,18 @@
Installation:
With the Installer:
Just doubleclick the installer and follow the instructions. You'll get
a folder on the desktop with all the necessary readme files (since
you're reading this you've probably already done it) .
Installing from an archive:
To install, unstuff the archive (since you're reading this you've
probably already done it) and drag the file 3DfxGlideLib2.x onto your
your MacOS9 System folder. You will be asked if you want to place it
in the System Extensions folder. Answer Yes. Alternatively, you can
place it in the System Extensions Folder manually.

BIN
MacGLide/Final/MacGLide.vct Normal file

Binary file not shown.

61
MacGLide/Final/Readme.rtf Normal file
View File

@ -0,0 +1,61 @@
{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf380
{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica-Oblique;\f2\fswiss\fcharset77 Helvetica;
}
{\colortbl;\red255\green255\blue255;\red21\green6\blue255;\red17\green4\blue255;\red16\green0\blue255;
}
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker +}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid1}}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
\paperw11900\paperh16840\margl1440\margr1440\vieww11320\viewh11760\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\f0\b\fs28 \cf0 MacGLide 0.13 Readme
\f1\i\b0 \
\f2\i0\fs24 \
MacGLide is a shared library that emulates 3Dfx Voodoo Graphics hardware.\
It makes it possible to run games originally made for 3Dfx/Glide without\
the 3Dfx-hardware by translating Glide-function calls to OpenGL.\
The project has been started once as a port of the OpenGLide project but\
has undergone many enhancements since.\
\
The MacGLide project aims to preserve a part of Macintosh gaming history.\
Some of these games are no longer playable, or the user experience itself\
suffers because the image quality and/or detail level of the software\
renderer is lacking. Among these games are unique titles like Tomb Raider,\
Carmageddon and the Falcon 4 flight simulator. These games couldn't be\
played (or viewed) as intended by the developers but with either the\
original 3dfx hardware (which will someday cease to exist) or the software\
emulation provided by the MacGLide project.\
\
Thanks to OpenGL and the capabilities of todays graphics hardware MacGLide\
can spice up things a bit to give these old timers a second life.\
And with the graphics technology up to date in OS X, it's again possible\
to relive those moments of yesteryear with the old games we fell in love with.\
\
Main features:\
\
\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\ql\qnatural\pardirnatural
\ls1\ilvl0\cf0 + Play your old games out of the box.\
+ Benefit from todays graphics hardware to play in higher resolutions,\
smoother images and higher frame rates among others.\
+ Show your family and friends how you've wasted your time in the past :^)\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\cf0 \
MacGLide is supposed to work with any 3Dfx-enabled game, preferably in the\
Classic enviroment of MacOS X (10.1.5 or later) or (if you can still boot it)\
with MacOS 9.22.\
\
MacGLide is released under the Gnu Lesser Public License\
({\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/lgpl.html"}}{\fldrslt \cf2 http://www.gnu.org/licenses/lgpl.html}}).\
\
The latest version can be found at\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
{\field{\*\fldinst{HYPERLINK "http://sourceforge.net/projects/macglide/"}}{\fldrslt \cf3 http://sourceforge.net/projects/macglide/}}\
\
If you discover a bug in MacGLide, or have ideas for improvements,\
or just wanna let me know how it works for you, visit\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
{\field{\*\fldinst{HYPERLINK "http://sourceforge.net/projects/macglide/"}}{\fldrslt \cf4 http://sourceforge.net/projects/macglide/}} and let me know.\
\
Best regards, Jens\
}

44
MacGLide/Final/Readme.txt Normal file
View File

@ -0,0 +1,44 @@
MacGLide 0.11 Readme
MacGLide is a shared library that emulates 3Dfx Voodoo Graphics hardware.
It makes it possible to run games originally made for 3Dfx/Glide without
the hardware by translating Glide-function calls to OpenGL.
The project has been started once as a port of the OpenGLide project but
has undergone many enhancements since.
The MacGLide project aims to preserve a part of Macintosh gaming history.
Some of these games are no longer playable, or the user experience itself
suffers because the image quality and/or detail level of the software
renderer is lacking. Among these games are unique titles like Tomb Raider,
Carmageddon and the Falcon 4 flight simulator. These games couldn't be
played (or viewed) as intended by the developers but with either the
original 3dfx hardware (which will someday cease to exist) or the software
emulation provided by the MacGLide project.
Thanks to OpenGL and the capabilities of todays graphics hardware MacGLide
can spice up things a bit to give these old timers a second life.
And with the graphics technology up to date in OS X, it's again possible
to relive those moments of yesteryear with the old games we fell in love with.
Main features:
+ Play your old games out of the box.
+ Benefit from todays graphics hardware to play in higher resolutions,
smoother images and higher frame rates among others.
+ Show your family and friends how you've wasted your time in the past :^)
MacGLide is supposed to work with any 3dfx-enabled game, preferably in the
Classic enviroment of MacOS X (10.1.5 or later) or (if you can still boot
it) with MacOS 9.22.
MacGLide is released under the Gnu Lesser Public License
(http://www.gnu.org/licenses/lgpl.html).
The latest version can be found at
http://sourceforge.net/projects/macglide/
If you discover a bug in MacGLide, or have ideas for improvements,
or just wanna let me know how it works for you, visit
http://sourceforge.net/projects/macglide/ and let me know.
Regards, Jens

514
MacGLide/Final/lgpl.rtf Normal file
View File

@ -0,0 +1,514 @@
{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf230
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw11900\paperh16840\margl1440\margr1440\vieww8720\viewh13080\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\f0\fs36 \cf0 GNU LESSER GENERAL PUBLIC LICENSE\
\fs28 Version 2.1, February 1999\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\fs24 \cf0 \
Copyright (C) 1991, 1999 Free Software Foundation, Inc.\
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\
Everyone is permitted to copy and distribute verbatim copies\
of this license document, but changing it is not allowed.\
\
[This is the first released version of the Lesser GPL. It also counts\
as the successor of the GNU Library Public License, version 2, hence\
the version number 2.1.]\
\
Preamble\
\
The licenses for most software are designed to take away your\
freedom to share and change it. By contrast, the GNU General Public\
Licenses are intended to guarantee your freedom to share and change\
free software--to make sure the software is free for all its users.\
\
This license, the Lesser General Public License, applies to some\
specially designated software packages--typically libraries--of the\
Free Software Foundation and other authors who decide to use it. You\
can use it too, but we suggest you first think carefully about whether\
this license or the ordinary General Public License is the better\
strategy to use in any particular case, based on the explanations below.\
\
When we speak of free software, we are referring to freedom of use,\
not price. Our General Public Licenses are designed to make sure that\
you have the freedom to distribute copies of free software (and charge\
for this service if you wish); that you receive source code or can get\
it if you want it; that you can change the software and use pieces of\
it in new free programs; and that you are informed that you can do\
these things.\
\
To protect your rights, we need to make restrictions that forbid\
distributors to deny you these rights or to ask you to surrender these\
rights. These restrictions translate to certain responsibilities for\
you if you distribute copies of the library or if you modify it.\
\
For example, if you distribute copies of the library, whether gratis\
or for a fee, you must give the recipients all the rights that we gave\
you. You must make sure that they, too, receive or can get the source\
code. If you link other code with the library, you must provide\
complete object files to the recipients, so that they can relink them\
with the library after making changes to the library and recompiling\
it. And you must show them these terms so they know their rights.\
\
We protect your rights with a two-step method: (1) we copyright the\
library, and (2) we offer you this license, which gives you legal\
permission to copy, distribute and/or modify the library.\
\
To protect each distributor, we want to make it very clear that\
there is no warranty for the free library. Also, if the library is\
modified by someone else and passed on, the recipients should know\
that what they have is not the original version, so that the original\
author's reputation will not be affected by problems that might be\
introduced by others.\
\page \
Finally, software patents pose a constant threat to the existence of\
any free program. We wish to make sure that a company cannot\
effectively restrict the users of a free program by obtaining a\
restrictive license from a patent holder. Therefore, we insist that\
any patent license obtained for a version of the library must be\
consistent with the full freedom of use specified in this license.\
\
Most GNU software, including some libraries, is covered by the\
ordinary GNU General Public License. This license, the GNU Lesser\
General Public License, applies to certain designated libraries, and\
is quite different from the ordinary General Public License. We use\
this license for certain libraries in order to permit linking those\
libraries into non-free programs.\
\
When a program is linked with a library, whether statically or using\
a shared library, the combination of the two is legally speaking a\
combined work, a derivative of the original library. The ordinary\
General Public License therefore permits such linking only if the\
entire combination fits its criteria of freedom. The Lesser General\
Public License permits more lax criteria for linking other code with\
the library.\
\
We call this license the "Lesser" General Public License because it\
does Less to protect the user's freedom than the ordinary General\
Public License. It also provides other free software developers Less\
of an advantage over competing non-free programs. These disadvantages\
are the reason we use the ordinary General Public License for many\
libraries. However, the Lesser license provides advantages in certain\
special circumstances.\
\
For example, on rare occasions, there may be a special need to\
encourage the widest possible use of a certain library, so that it becomes\
a de-facto standard. To achieve this, non-free programs must be\
allowed to use the library. A more frequent case is that a free\
library does the same job as widely used non-free libraries. In this\
case, there is little to gain by limiting the free library to free\
software only, so we use the Lesser General Public License.\
\
In other cases, permission to use a particular library in non-free\
programs enables a greater number of people to use a large body of\
free software. For example, permission to use the GNU C Library in\
non-free programs enables many more people to use the whole GNU\
operating system, as well as its variant, the GNU/Linux operating\
system.\
\
Although the Lesser General Public License is Less protective of the\
users' freedom, it does ensure that the user of a program that is\
linked with the Library has the freedom and the wherewithal to run\
that program using a modified version of the Library.\
\
The precise terms and conditions for copying, distribution and\
modification follow. Pay close attention to the difference between a\
"work based on the library" and a "work that uses the library". The\
former contains code derived from the library, whereas the latter must\
be combined with the library in order to run.\
\page \
GNU LESSER GENERAL PUBLIC LICENSE\
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\
\
0. This License Agreement applies to any software library or other\
program which contains a notice placed by the copyright holder or\
other authorized party saying it may be distributed under the terms of\
this Lesser General Public License (also called "this License").\
Each licensee is addressed as "you".\
\
A "library" means a collection of software functions and/or data\
prepared so as to be conveniently linked with application programs\
(which use some of those functions and data) to form executables.\
\
The "Library", below, refers to any such software library or work\
which has been distributed under these terms. A "work based on the\
Library" means either the Library or any derivative work under\
copyright law: that is to say, a work containing the Library or a\
portion of it, either verbatim or with modifications and/or translated\
straightforwardly into another language. (Hereinafter, translation is\
included without limitation in the term "modification".)\
\
"Source code" for a work means the preferred form of the work for\
making modifications to it. For a library, complete source code means\
all the source code for all modules it contains, plus any associated\
interface definition files, plus the scripts used to control compilation\
and installation of the library.\
\
Activities other than copying, distribution and modification are not\
covered by this License; they are outside its scope. The act of\
running a program using the Library is not restricted, and output from\
such a program is covered only if its contents constitute a work based\
on the Library (independent of the use of the Library in a tool for\
writing it). Whether that is true depends on what the Library does\
and what the program that uses the Library does.\
\
1. You may copy and distribute verbatim copies of the Library's\
complete source code as you receive it, in any medium, provided that\
you conspicuously and appropriately publish on each copy an\
appropriate copyright notice and disclaimer of warranty; keep intact\
all the notices that refer to this License and to the absence of any\
warranty; and distribute a copy of this License along with the\
Library.\
\
You may charge a fee for the physical act of transferring a copy,\
and you may at your option offer warranty protection in exchange for a\
fee.\
\page \
2. You may modify your copy or copies of the Library or any portion\
of it, thus forming a work based on the Library, and copy and\
distribute such modifications or work under the terms of Section 1\
above, provided that you also meet all of these conditions:\
\
a) The modified work must itself be a software library.\
\
b) You must cause the files modified to carry prominent notices\
stating that you changed the files and the date of any change.\
\
c) You must cause the whole of the work to be licensed at no\
charge to all third parties under the terms of this License.\
\
d) If a facility in the modified Library refers to a function or a\
table of data to be supplied by an application program that uses\
the facility, other than as an argument passed when the facility\
is invoked, then you must make a good faith effort to ensure that,\
in the event an application does not supply such function or\
table, the facility still operates, and performs whatever part of\
its purpose remains meaningful.\
\
(For example, a function in a library to compute square roots has\
a purpose that is entirely well-defined independent of the\
application. Therefore, Subsection 2d requires that any\
application-supplied function or table used by this function must\
be optional: if the application does not supply it, the square\
root function must still compute square roots.)\
\
These requirements apply to the modified work as a whole. If\
identifiable sections of that work are not derived from the Library,\
and can be reasonably considered independent and separate works in\
themselves, then this License, and its terms, do not apply to those\
sections when you distribute them as separate works. But when you\
distribute the same sections as part of a whole which is a work based\
on the Library, the distribution of the whole must be on the terms of\
this License, whose permissions for other licensees extend to the\
entire whole, and thus to each and every part regardless of who wrote\
it.\
\
Thus, it is not the intent of this section to claim rights or contest\
your rights to work written entirely by you; rather, the intent is to\
exercise the right to control the distribution of derivative or\
collective works based on the Library.\
\
In addition, mere aggregation of another work not based on the Library\
with the Library (or with a work based on the Library) on a volume of\
a storage or distribution medium does not bring the other work under\
the scope of this License.\
\
3. You may opt to apply the terms of the ordinary GNU General Public\
License instead of this License to a given copy of the Library. To do\
this, you must alter all the notices that refer to this License, so\
that they refer to the ordinary GNU General Public License, version 2,\
instead of to this License. (If a newer version than version 2 of the\
ordinary GNU General Public License has appeared, then you can specify\
that version instead if you wish.) Do not make any other change in\
these notices.\
\page \
Once this change is made in a given copy, it is irreversible for\
that copy, so the ordinary GNU General Public License applies to all\
subsequent copies and derivative works made from that copy.\
\
This option is useful when you wish to copy part of the code of\
the Library into a program that is not a library.\
\
4. You may copy and distribute the Library (or a portion or\
derivative of it, under Section 2) in object code or executable form\
under the terms of Sections 1 and 2 above provided that you accompany\
it with the complete corresponding machine-readable source code, which\
must be distributed under the terms of Sections 1 and 2 above on a\
medium customarily used for software interchange.\
\
If distribution of object code is made by offering access to copy\
from a designated place, then offering equivalent access to copy the\
source code from the same place satisfies the requirement to\
distribute the source code, even though third parties are not\
compelled to copy the source along with the object code.\
\
5. A program that contains no derivative of any portion of the\
Library, but is designed to work with the Library by being compiled or\
linked with it, is called a "work that uses the Library". Such a\
work, in isolation, is not a derivative work of the Library, and\
therefore falls outside the scope of this License.\
\
However, linking a "work that uses the Library" with the Library\
creates an executable that is a derivative of the Library (because it\
contains portions of the Library), rather than a "work that uses the\
library". The executable is therefore covered by this License.\
Section 6 states terms for distribution of such executables.\
\
When a "work that uses the Library" uses material from a header file\
that is part of the Library, the object code for the work may be a\
derivative work of the Library even though the source code is not.\
Whether this is true is especially significant if the work can be\
linked without the Library, or if the work is itself a library. The\
threshold for this to be true is not precisely defined by law.\
\
If such an object file uses only numerical parameters, data\
structure layouts and accessors, and small macros and small inline\
functions (ten lines or less in length), then the use of the object\
file is unrestricted, regardless of whether it is legally a derivative\
work. (Executables containing this object code plus portions of the\
Library will still fall under Section 6.)\
\
Otherwise, if the work is a derivative of the Library, you may\
distribute the object code for the work under the terms of Section 6.\
Any executables containing that work also fall under Section 6,\
whether or not they are linked directly with the Library itself.\
\page \
6. As an exception to the Sections above, you may also combine or\
link a "work that uses the Library" with the Library to produce a\
work containing portions of the Library, and distribute that work\
under terms of your choice, provided that the terms permit\
modification of the work for the customer's own use and reverse\
engineering for debugging such modifications.\
\
You must give prominent notice with each copy of the work that the\
Library is used in it and that the Library and its use are covered by\
this License. You must supply a copy of this License. If the work\
during execution displays copyright notices, you must include the\
copyright notice for the Library among them, as well as a reference\
directing the user to the copy of this License. Also, you must do one\
of these things:\
\
a) Accompany the work with the complete corresponding\
machine-readable source code for the Library including whatever\
changes were used in the work (which must be distributed under\
Sections 1 and 2 above); and, if the work is an executable linked\
with the Library, with the complete machine-readable "work that\
uses the Library", as object code and/or source code, so that the\
user can modify the Library and then relink to produce a modified\
executable containing the modified Library. (It is understood\
that the user who changes the contents of definitions files in the\
Library will not necessarily be able to recompile the application\
to use the modified definitions.)\
\
b) Use a suitable shared library mechanism for linking with the\
Library. A suitable mechanism is one that (1) uses at run time a\
copy of the library already present on the user's computer system,\
rather than copying library functions into the executable, and (2)\
will operate properly with a modified version of the library, if\
the user installs one, as long as the modified version is\
interface-compatible with the version that the work was made with.\
\
c) Accompany the work with a written offer, valid for at\
least three years, to give the same user the materials\
specified in Subsection 6a, above, for a charge no more\
than the cost of performing this distribution.\
\
d) If distribution of the work is made by offering access to copy\
from a designated place, offer equivalent access to copy the above\
specified materials from the same place.\
\
e) Verify that the user has already received a copy of these\
materials or that you have already sent this user a copy.\
\
For an executable, the required form of the "work that uses the\
Library" must include any data and utility programs needed for\
reproducing the executable from it. However, as a special exception,\
the materials to be distributed need not include anything that is\
normally distributed (in either source or binary form) with the major\
components (compiler, kernel, and so on) of the operating system on\
which the executable runs, unless that component itself accompanies\
the executable.\
\
It may happen that this requirement contradicts the license\
restrictions of other proprietary libraries that do not normally\
accompany the operating system. Such a contradiction means you cannot\
use both them and the Library together in an executable that you\
distribute.\
\page \
7. You may place library facilities that are a work based on the\
Library side-by-side in a single library together with other library\
facilities not covered by this License, and distribute such a combined\
library, provided that the separate distribution of the work based on\
the Library and of the other library facilities is otherwise\
permitted, and provided that you do these two things:\
\
a) Accompany the combined library with a copy of the same work\
based on the Library, uncombined with any other library\
facilities. This must be distributed under the terms of the\
Sections above.\
\
b) Give prominent notice with the combined library of the fact\
that part of it is a work based on the Library, and explaining\
where to find the accompanying uncombined form of the same work.\
\
8. You may not copy, modify, sublicense, link with, or distribute\
the Library except as expressly provided under this License. Any\
attempt otherwise to copy, modify, sublicense, link with, or\
distribute the Library is void, and will automatically terminate your\
rights under this License. However, parties who have received copies,\
or rights, from you under this License will not have their licenses\
terminated so long as such parties remain in full compliance.\
\
9. You are not required to accept this License, since you have not\
signed it. However, nothing else grants you permission to modify or\
distribute the Library or its derivative works. These actions are\
prohibited by law if you do not accept this License. Therefore, by\
modifying or distributing the Library (or any work based on the\
Library), you indicate your acceptance of this License to do so, and\
all its terms and conditions for copying, distributing or modifying\
the Library or works based on it.\
\
10. Each time you redistribute the Library (or any work based on the\
Library), the recipient automatically receives a license from the\
original licensor to copy, distribute, link with or modify the Library\
subject to these terms and conditions. You may not impose any further\
restrictions on the recipients' exercise of the rights granted herein.\
You are not responsible for enforcing compliance by third parties with\
this License.\
\page \
11. If, as a consequence of a court judgment or allegation of patent\
infringement or for any other reason (not limited to patent issues),\
conditions are imposed on you (whether by court order, agreement or\
otherwise) that contradict the conditions of this License, they do not\
excuse you from the conditions of this License. If you cannot\
distribute so as to satisfy simultaneously your obligations under this\
License and any other pertinent obligations, then as a consequence you\
may not distribute the Library at all. For example, if a patent\
license would not permit royalty-free redistribution of the Library by\
all those who receive copies directly or indirectly through you, then\
the only way you could satisfy both it and this License would be to\
refrain entirely from distribution of the Library.\
\
If any portion of this section is held invalid or unenforceable under any\
particular circumstance, the balance of the section is intended to apply,\
and the section as a whole is intended to apply in other circumstances.\
\
It is not the purpose of this section to induce you to infringe any\
patents or other property right claims or to contest validity of any\
such claims; this section has the sole purpose of protecting the\
integrity of the free software distribution system which is\
implemented by public license practices. Many people have made\
generous contributions to the wide range of software distributed\
through that system in reliance on consistent application of that\
system; it is up to the author/donor to decide if he or she is willing\
to distribute software through any other system and a licensee cannot\
impose that choice.\
\
This section is intended to make thoroughly clear what is believed to\
be a consequence of the rest of this License.\
\
12. If the distribution and/or use of the Library is restricted in\
certain countries either by patents or by copyrighted interfaces, the\
original copyright holder who places the Library under this License may add\
an explicit geographical distribution limitation excluding those countries,\
so that distribution is permitted only in or among countries not thus\
excluded. In such case, this License incorporates the limitation as if\
written in the body of this License.\
\
13. The Free Software Foundation may publish revised and/or new\
versions of the Lesser General Public License from time to time.\
Such new versions will be similar in spirit to the present version,\
but may differ in detail to address new problems or concerns.\
\
Each version is given a distinguishing version number. If the Library\
specifies a version number of this License which applies to it and\
"any later version", you have the option of following the terms and\
conditions either of that version or of any later version published by\
the Free Software Foundation. If the Library does not specify a\
license version number, you may choose any version ever published by\
the Free Software Foundation.\
\page \
14. If you wish to incorporate parts of the Library into other free\
programs whose distribution conditions are incompatible with these,\
write to the author to ask for permission. For software which is\
copyrighted by the Free Software Foundation, write to the Free\
Software Foundation; we sometimes make exceptions for this. Our\
decision will be guided by the two goals of preserving the free status\
of all derivatives of our free software and of promoting the sharing\
and reuse of software generally.\
\
NO WARRANTY\
\
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY\
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\
\
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\
DAMAGES.\
\
END OF TERMS AND CONDITIONS\
\page \
How to Apply These Terms to Your New Libraries\
\
If you develop a new library, and you want it to be of the greatest\
possible use to the public, we recommend making it free software that\
everyone can redistribute and change. You can do so by permitting\
redistribution under these terms (or, alternatively, under the terms of the\
ordinary General Public License).\
\
To apply these terms, attach the following notices to the library. It is\
safest to attach them to the start of each source file to most effectively\
convey the exclusion of warranty; and each file should have at least the\
"copyright" line and a pointer to where the full notice is found.\
\
<one line to give the library's name and a brief idea of what it does.>\
Copyright (C) <year> <name of author>\
\
This library is free software; you can redistribute it and/or\
modify it under the terms of the GNU Lesser General Public\
License as published by the Free Software Foundation; either\
version 2.1 of the License, or (at your option) any later version.\
\
This library 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\
Lesser General Public License for more details.\
\
You should have received a copy of the GNU Lesser General Public\
License along with this library; if not, write to the Free Software\
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\
\
Also add information on how to contact you by electronic and paper mail.\
\
You should also get your employer (if you work as a programmer) or your\
school, if any, to sign a "copyright disclaimer" for the library, if\
necessary. Here is a sample; alter the names:\
\
Yoyodyne, Inc., hereby disclaims all copyright interest in the\
library `Frob' (a library for tweaking knobs) written by James Random Hacker.\
\
<signature of Ty Coon>, 1 April 1990\
Ty Coon, President of Vice\
\
That's all there is to it!\
\
\
}

504
MacGLide/Final/lgpl.txt Normal file
View File

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

0
MacGLide/Final/localized Normal file
View File

View File

@ -0,0 +1,48 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Glide application management
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GlideApplication.h"
GlideApplication s_GlideApplication;
GlideApplication::GlideApplication()
{
Init();
}
void GlideApplication::Init()
{
ProcessSerialNumber psn;
if (GetCurrentProcess(&psn) == noErr)
{
ProcessInfoRec info;
memset(&info, 0, sizeof(info));
info.processInfoLength = sizeof(info);
memset(&m_Name[0], 0, sizeof(m_Name));
info.processName = reinterpret_cast<unsigned char*>(&m_Name[0]);
GetProcessInformation(&psn, &info);
// Convert pascal to c-string
m_Name[m_Name[0] + 1] = 0x0;
// set application type
if (strstr((char*) &m_Name[1], "Tomb Raider III") ) m_Type = TombRaiderIII;
else if (strstr((char*) &m_Name[1], "Tomb Raider II Gold") ) m_Type = TombRaiderII;
else if (strstr((char*) &m_Name[1], "Tomb Raider II") ) m_Type = TombRaiderII;
else if (strstr((char*) &m_Name[1], "Tomb Raider I") ) m_Type = TombRaiderI;
else if (strstr((char*) &m_Name[1], "TR Unfinished Business") ) m_Type = TombRaiderI;
else if (strstr((char*) &m_Name[1], "Carmageddon 2") ) m_Type = Carmageddon2;
else if (strstr((char*) &m_Name[1], "Carmageddon 3dfx") ) m_Type = Carmageddon;
else if (strstr((char*) &m_Name[1], "Falcon 4.0") ) m_Type = Falcon40;
else if (strstr((char*) &m_Name[1], "F/A-18") ) m_Type = FA18;
else if (strstr((char*) &m_Name[1], "Future Cop") ) m_Type = FutureCop;
else if (strstr((char*) &m_Name[1], "Myth The Fallen Lords") ) m_Type = MythTFL;
else if (strstr((char*) &m_Name[1], "Quake 3Dfx") ) m_Type = Quake;
else m_Type = Generic;
}
}

View File

@ -0,0 +1,704 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Macintosh display
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Displays.h"
#include "GlideApplication.h"
#include "GlideDisplay.h"
// display manager related stuff
const unsigned int VideoGammaTableSize = sizeof(CMVideoCardGamma) + 256 * 2;
struct DisplayModeSpec
{
unsigned long HorizontalPixels_wanted;
unsigned long VerticalLines_wanted;
unsigned long RefreshRate_wanted;
unsigned long DisplayMode_wanted;
unsigned long HorizontalPixels;
unsigned long VerticalLines;
unsigned long RefreshRate;
unsigned long DisplayMode;
unsigned long ColorDepth;
GDHandle Device;
DisplayIDType DisplayID;
char VideoGammaTable[VideoGammaTableSize]; // Actually the CMVideoCardGamma table
bool Valid;
bool GammaValid;
};
// gamma related stuff
CMError DisplayManager_RememberGamma(DisplayModeSpec& display);
CMError DisplayManager_RestoreGamma(DisplayModeSpec& display);
CMError DisplayManager_SetGamma(DisplayModeSpec& display, FxFloat gamma);
bool DisplayManager_applyGamma();
CMError DisplayManager_SetGammaBlack(DisplayModeSpec& display);
// Usally games have a Glide resolution
DisplayModeSpec DesktopDisplay;
// a resolution for displaying In-Game graphics via passthrough
DisplayModeSpec PassthroughDisplay;
// and the desktop resolution
DisplayModeSpec GlideDisplay;
// Copy of the colorsync profile of the monitor we're using
CMProfileRef DesktopColorSyncProfile;
// Whether to restore the menubar
bool RestoreMenuBar;
bool DisplayManager_ColorSyncAvailable()
{
return (Ptr) CMCloseProfile != (Ptr) kUnresolvedCFragSymbolAddress &&
(Ptr) CMGetSystemProfile != (Ptr) kUnresolvedCFragSymbolAddress &&
(Ptr) CMProfileElementExists != (Ptr) kUnresolvedCFragSymbolAddress &&
(Ptr) CMGetProfileByAVID != (Ptr) kUnresolvedCFragSymbolAddress &&
(Ptr) CMSetProfileByAVID != (Ptr) kUnresolvedCFragSymbolAddress &&
(Ptr) CMGetGammaByAVID != (Ptr) kUnresolvedCFragSymbolAddress &&
(Ptr) CMSetGammaByAVID != (Ptr) kUnresolvedCFragSymbolAddress;
}
bool DisplayManager_applyGamma()
{
return DisplayManager_ColorSyncAvailable && DesktopDisplay.GammaValid && DesktopColorSyncProfile;
}
CMProfileRef DisplayManager_GetDesktopProfile()
{
CMProfileRef profile = NULL;
// F/A-18 exits here
CMError err = CMGetProfileByAVID(DesktopDisplay.DisplayID, &profile);
if (err == noErr)
{
bool gammatag_found = false;
// Check for gamma tag
err = CMProfileElementExists(profile, (unsigned long) cmVideoCardGammaTag, (unsigned char*) &gammatag_found);
if (gammatag_found == false)
{
GlideMsg("Display Manager Warning: Using CMGetSystemProfile() to retrieve desktop gamma table\n");
err = CMGetSystemProfile(&profile);
if (err == noErr)
{
// Check for gamma tag
err = CMProfileElementExists(profile, (unsigned long) cmVideoCardGammaTag, (unsigned char*) &gammatag_found);
if (err == noErr && gammatag_found == false)
{
GlideMsg("Display Manager Warning: Gamma correction has been disabled because the System profile doesn't contain a gamma table\n");
err = cmElementTagNotFound;
}
}
}
}
if (err != noErr)
{
GlideError("Display Manager error: Retrieving the Desktop gamma correction table failed with error %d\n", err);
if (profile)
{
CMCloseProfile(profile);
profile = NULL;
}
}
return profile;
}
void DisplayManager_Initialise()
{
memset(&DesktopDisplay, 0, sizeof(DisplayModeSpec));
memset(&PassthroughDisplay, 0, sizeof(DisplayModeSpec));
memset(&GlideDisplay, 0, sizeof(DisplayModeSpec));
// Get devices
DesktopDisplay.Device = GetMainDevice();
PassthroughDisplay.Device = GetMainDevice();
GlideDisplay.Device = GetMainDevice();
DesktopDisplay.GammaValid = false;
RestoreMenuBar = false;
DesktopColorSyncProfile = NULL;
if (DisplayManager_ColorSyncAvailable())
{
// Get AVids
OSErr err = DMGetDisplayIDByGDevice(DesktopDisplay.Device, &DesktopDisplay.DisplayID, true);
if (err == noErr)
{
err = DMGetDisplayIDByGDevice(PassthroughDisplay.Device, &PassthroughDisplay.DisplayID, true);
if (err == noErr)
{
err = DMGetDisplayIDByGDevice(GlideDisplay.Device, &GlideDisplay.DisplayID, true);
}
}
if (err != noErr)
{
GlideMsg("Error: Unable to determine display id - gamma correction disabled\n");
}
else
{
// Exits right at the start otherwise
if (s_GlideApplication.GetType() == GlideApplication::FA18)
{
DesktopDisplay.GammaValid = false;
}
else
{
CMProfileRef profile = DisplayManager_GetDesktopProfile();
if (profile)
{
err = CMCopyProfile(&DesktopColorSyncProfile, NULL, profile);
if (err == noErr)
{
// Finally remember the gamma correction
err = DisplayManager_RememberGamma(DesktopDisplay);
if (err == noErr)
{
DesktopDisplay.GammaValid = true;
}
}
CMCloseProfile(profile);
}
if (err != noErr)
{
GlideMsg("Error: Unable to get desktop colorsync profile - gamma correction disabled\n");
}
}
}
}
else
{
GlideMsg("Warning: ColorSync not installed or available - gamma correction disabled\n");
}
}
void DisplayManager_Cleanup()
{
// Release the temporary profile
if (DesktopColorSyncProfile) CMCloseProfile(DesktopColorSyncProfile);
}
extern "C"
{
pascal void DisplayModeForResolution(void* userData, DMListIndexType itemIndex, DMDisplayModeListEntryPtr displaymodeInfo)
{
DisplayModeSpec* d = static_cast<DisplayModeSpec*>(userData);
VDResolutionInfoRec* res = displaymodeInfo->displayModeResolutionInfo;
// Get the exact resolution, and try to pick the highest available (or exact) refresh rate available below the wanted one
if (res->csHorizontalPixels == d->HorizontalPixels_wanted
&& res->csVerticalLines == d->VerticalLines_wanted
&& (d->RefreshRate_wanted == 0
|| (d->RefreshRate_wanted >= (res->csRefreshRate / 65536) && d->RefreshRate <= (res->csRefreshRate / 65536)))
)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Considering matching display mode %d with resolution %dx%d@%dHz\n",
displaymodeInfo->displayModeResolutionInfo->csDisplayModeID,
res->csHorizontalPixels,
res->csVerticalLines,
res->csRefreshRate / 65536);
#endif
// Copy values
d->DisplayMode = displaymodeInfo->displayModeResolutionInfo->csDisplayModeID;
d->HorizontalPixels = res->csHorizontalPixels;
d->VerticalLines = res->csVerticalLines;
d->RefreshRate = res->csRefreshRate / 65536;
d->Valid = true;
}
// Get the next larger resolution, and try to pick the highest available (or exact) refresh rate available below the wanted one
else if (res->csHorizontalPixels >= d->HorizontalPixels_wanted
&& res->csVerticalLines >= d->VerticalLines_wanted
&& d->HorizontalPixels >= res->csHorizontalPixels
&& d->VerticalLines >= res->csVerticalLines
&& (d->RefreshRate_wanted == 0
|| (d->RefreshRate_wanted >= (res->csRefreshRate / 65536) && d->RefreshRate <= (res->csRefreshRate / 65536)))
)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Considering next larger display mode %d with resolution %dx%d@%dHz\n",
displaymodeInfo->displayModeResolutionInfo->csDisplayModeID,
res->csHorizontalPixels,
res->csVerticalLines,
res->csRefreshRate / 65536);
#endif
// Copy values
d->DisplayMode = displaymodeInfo->displayModeResolutionInfo->csDisplayModeID;
d->HorizontalPixels = res->csHorizontalPixels;
d->VerticalLines = res->csVerticalLines;
d->RefreshRate = res->csRefreshRate / 65536;
d->Valid = true;
}
else
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Found display mode %d with resolution %dx%d@%dHz\n",
displaymodeInfo->displayModeResolutionInfo->csDisplayModeID,
res->csHorizontalPixels,
res->csVerticalLines,
res->csRefreshRate / 65536);
#endif
}
}
pascal void ResolutionForDisplayMode(void* userData, DMListIndexType itemIndex, DMDisplayModeListEntryPtr displaymodeInfo)
{
DisplayModeSpec* d = static_cast<DisplayModeSpec*>(userData);
VDResolutionInfoRec* res = displaymodeInfo->displayModeResolutionInfo;
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Found display mode %d with resolution %dx%d@%dHz\n",
displaymodeInfo->displayModeResolutionInfo->csDisplayModeID,
res->csHorizontalPixels,
res->csVerticalLines,
res->csRefreshRate / 65536);
#endif
if (displaymodeInfo->displayModeResolutionInfo->csDisplayModeID == d->DisplayMode_wanted
// && spec.device == res->device
)
{
d->HorizontalPixels = res->csHorizontalPixels;
d->VerticalLines = res->csVerticalLines;
d->RefreshRate = res->csRefreshRate / 65536;
d->DisplayMode = displaymodeInfo->displayModeResolutionInfo->csDisplayModeID;
d->Valid = true;
}
}
}
OSErr DisplayManager_Query(DMDisplayModeListIteratorProcPtr iteratorproc, DisplayModeSpec& spec)
{
OSErr err = noErr;
DMDisplayModeListIteratorUPP MyDMDisplayModeListIteratorUPP;
MyDMDisplayModeListIteratorUPP = NewDMDisplayModeListIteratorUPP(iteratorproc);
// use display manager to change the resolution
spec.Device = DMGetFirstScreenDevice(dmOnlyActiveDisplays);
while (spec.Device != nil)
{
DisplayIDType displayID;
err = DMGetDisplayIDByGDevice(spec.Device, &displayID, true);
if (err == noErr)
{
DMListIndexType thePanelCount;
DMListType thePanelList;
err = DMNewDisplayModeList(displayID, NULL, NULL, &thePanelCount, &thePanelList);
if (err == noErr)
{
for (int i = 0; i < thePanelCount; i++)
{
err = DMGetIndexedDisplayModeFromList(thePanelList, i, NULL, MyDMDisplayModeListIteratorUPP, &spec);
if (err == noErr)
{
// search until the exact resolution with the exact display mode was found
if (spec.Valid && spec.RefreshRate == spec.RefreshRate_wanted) break;
}
}
DMDisposeList(thePanelList);
}
}
// At this point, we might have found a valid spec with the exact resolution,
// but with a refresh rate smaller than requested one, which is ok
// (For instance on LCD-iMacs, the refresh rate may be 0)
// -> Don't get the next screen device
if (spec.Valid) break;
// Get the next device in the list
spec.Device = DMGetNextScreenDevice(spec.Device, dmOnlyActiveDisplays);
}
DisposeDMDisplayModeListIteratorUPP(MyDMDisplayModeListIteratorUPP);
return err;
}
OSErr DisplayManager_SetGlideDisplay(unsigned int width, unsigned int height, unsigned int freq)
{
GlideDisplay.HorizontalPixels_wanted = width;
GlideDisplay.VerticalLines_wanted = height;
GlideDisplay.HorizontalPixels = 65535;
GlideDisplay.VerticalLines = 65535;
GlideDisplay.RefreshRate_wanted = freq;
GlideDisplay.ColorDepth = 32;
GlideDisplay.DisplayMode = 0;
GlideDisplay.RefreshRate = 0;
GlideDisplay.Valid = false;
GlideDisplay.GammaValid = true; // we're not remembering this one
Handle displayState = NULL;
OSErr err = DMBeginConfigureDisplays(&displayState);
if (err == noErr)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Searching for display resolution %dx%dx%d@%dHz\n",
GlideDisplay.HorizontalPixels_wanted, GlideDisplay.VerticalLines_wanted,
GlideDisplay.ColorDepth, GlideDisplay.RefreshRate_wanted);
#endif
err = DisplayManager_Query(&DisplayModeForResolution, GlideDisplay);
if (!GlideDisplay.Valid && err == noErr)
{
GlideMsg("Display Manager: Unable to find a valid display mode for Glide display\n");
err = kDMNotFoundErr;
}
else if (err == noErr)
{
err = DMSetDisplayMode(GlideDisplay.Device, GlideDisplay.DisplayMode, &GlideDisplay.ColorDepth, NULL, displayState);
}
DMEndConfigureDisplays(displayState);
}
if (err == noErr)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Using display mode %d with resolution %dx%dx%d@%dHz\n",
GlideDisplay.DisplayMode,
GlideDisplay.HorizontalPixels, GlideDisplay.VerticalLines,
GlideDisplay.ColorDepth, GlideDisplay.RefreshRate);
#endif
if (IsMenuBarVisible()) HideMenuBar();
}
else
{
GlideMsg("Display Manager: Error while setting Glide display to %dx%dx%d@%dHz: %d\n",
GlideDisplay.HorizontalPixels_wanted, GlideDisplay.VerticalLines_wanted,
GlideDisplay.ColorDepth, GlideDisplay.RefreshRate_wanted, err);
}
return err;
}
OSErr DisplayManager_RememberPassthroughDisplay()
{
#ifdef OGL_DEBUG
GlideMsg(OGL_LOG_SEPARATE);
#endif
// Invalidate any previous search
PassthroughDisplay.Valid = false;
PassthroughDisplay.GammaValid = false;
Handle displayState = NULL;
OSErr err = DMBeginConfigureDisplays(&displayState);
if (err == noErr)
{
// save the old desktop resolution
VDSwitchInfoRec switchinfo;
err = DMGetDisplayMode(PassthroughDisplay.Device, &switchinfo);
if (err == noErr)
{
PassthroughDisplay.DisplayMode_wanted = switchinfo.csData;
PassthroughDisplay.ColorDepth = switchinfo.csMode;
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Searching for passthrough display mode %d\n", PassthroughDisplay.DisplayMode_wanted);
#endif
// save previous display resolution
err = DisplayManager_Query(&ResolutionForDisplayMode, PassthroughDisplay);
if (!PassthroughDisplay.Valid && err == noErr)
{
GlideMsg("Display Manager: Unable to find the display resolution for the passthrough display\n");
err = kDMNotFoundErr;
}
}
DMEndConfigureDisplays(displayState);
}
if (err == noErr)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Remembering passthrough display mode %d with resolution %dx%dx%d@%dHz\n",
PassthroughDisplay.DisplayMode,
PassthroughDisplay.HorizontalPixels, PassthroughDisplay.VerticalLines,
PassthroughDisplay.ColorDepth, PassthroughDisplay.RefreshRate);
#endif
if (DisplayManager_RememberGamma(PassthroughDisplay) == noErr)
{
PassthroughDisplay.GammaValid = true;
}
// Remember menubar status
RestoreMenuBar = IsMenuBarVisible();
}
else
{
GlideMsg("Display Manager: Error while remembering passthrough display mode: %d\n", err);
}
return err;
}
OSErr DisplayManager_RememberDesktopDisplay()
{
#ifdef OGL_DEBUG
GlideMsg(OGL_LOG_SEPARATE);
#endif
// Invalidate any previous search
DesktopDisplay.Valid = false;
// save the old desktop resolution
Handle displayState = NULL;
OSErr err = DMBeginConfigureDisplays(&displayState);
if (err == noErr)
{
VDSwitchInfoRec switchinfo;
err = DMGetDisplayMode(DesktopDisplay.Device, &switchinfo);
if (err == noErr)
{
DesktopDisplay.DisplayMode_wanted = switchinfo.csData;
DesktopDisplay.ColorDepth = switchinfo.csMode;
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Searching for Desktop display mode %d\n", DesktopDisplay.DisplayMode_wanted);
#endif
// save previous display resolution
err = DisplayManager_Query(&ResolutionForDisplayMode, DesktopDisplay);
if (!DesktopDisplay.Valid && err == noErr)
{
GlideMsg("Display Manager: Unable to find the display resolution for the Desktop display\n");
err = kDMNotFoundErr;
}
}
DMEndConfigureDisplays(displayState);
// Desktop gamma already remembered in DisplayManager_Initialise()
}
if (err == noErr)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Remembering desktop display mode %d with resolution %dx%dx%d@%dHz\n",
DesktopDisplay.DisplayMode,
DesktopDisplay.HorizontalPixels, DesktopDisplay.VerticalLines,
DesktopDisplay.ColorDepth, DesktopDisplay.RefreshRate);
#endif
}
else
{
GlideMsg("Display Manager: Error while remembering desktop display mode: %d\n", err);
}
return err;
}
OSErr DisplayManager_RestoreGlideDisplay()
{
#ifdef OGL_DEBUG
GlideMsg(OGL_LOG_SEPARATE);
#endif
OSErr err = noErr;
if (GlideDisplay.Valid)
{
Handle displayState = NULL;
err = DMBeginConfigureDisplays(&displayState);
if (err == noErr)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Restoring Glide display mode %d with resolution %dx%dx%d@%dHz\n",
GlideDisplay.DisplayMode,
GlideDisplay.HorizontalPixels, GlideDisplay.VerticalLines,
GlideDisplay.ColorDepth, GlideDisplay.RefreshRate);
#endif
if (err == noErr)
{
err = DMSetDisplayMode(GlideDisplay.Device, GlideDisplay.DisplayMode, &GlideDisplay.ColorDepth, NULL, displayState);
}
DMEndConfigureDisplays(displayState);
}
}
else
{
GlideMsg("Display Manager: Glide display not restored\n");
}
if (err == noErr)
{
// Remember menubar status
RestoreMenuBar = IsMenuBarVisible();
if (RestoreMenuBar) HideMenuBar();
}
else
{
GlideMsg("Display Manager: Error while restoring Glide display mode: %d\n", err);
}
return noErr;
}
OSErr DisplayManager_RestorePassthroughDisplay()
{
#ifdef OGL_DEBUG
GlideMsg(OGL_LOG_SEPARATE);
#endif
OSErr err = noErr;
if (PassthroughDisplay.Valid)
{
Handle displayState = NULL;
err = DMBeginConfigureDisplays(&displayState);
if (err == noErr)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Restoring passthrough display mode %d with resolution %dx%dx%d@%dHz\n",
PassthroughDisplay.DisplayMode,
PassthroughDisplay.HorizontalPixels, PassthroughDisplay.VerticalLines,
PassthroughDisplay.ColorDepth, PassthroughDisplay.RefreshRate);
#endif
err = DMSetDisplayMode(PassthroughDisplay.Device, PassthroughDisplay.DisplayMode, &PassthroughDisplay.ColorDepth, NULL, displayState);
DMEndConfigureDisplays(displayState);
}
}
else
{
GlideMsg("Display Manager: Passthrough display not restored\n");
}
// Restore menubar and gamma
if (err == noErr)
{
if (RestoreMenuBar) ShowMenuBar();
if (PassthroughDisplay.GammaValid == true) DisplayManager_RestoreGamma(PassthroughDisplay);
}
else
{
GlideMsg("Display Manager: Error while restoring passthrough display mode: %d\n", err);
}
return err;
}
OSErr DisplayManager_RestoreDesktopDisplay()
{
#ifdef OGL_DEBUG
GlideMsg(OGL_LOG_SEPARATE);
#endif
OSErr err = noErr;
if (DesktopDisplay.Valid)
{
Handle displayState = NULL;
err = DMBeginConfigureDisplays(&displayState);
if (err == noErr)
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Restoring desktop display mode %d with resolution %dx%dx%d@%dHz\n",
DesktopDisplay.DisplayMode,
DesktopDisplay.HorizontalPixels, DesktopDisplay.VerticalLines,
DesktopDisplay.ColorDepth, DesktopDisplay.RefreshRate);
#endif
err = DMSetDisplayMode(DesktopDisplay.Device, DesktopDisplay.DisplayMode, &DesktopDisplay.ColorDepth, NULL, displayState);
DMEndConfigureDisplays(displayState);
}
}
else
{
#ifdef OGL_DEBUG
GlideMsg("Display Manager: Desktop display not restored\n");
#endif
}
if (err == noErr)
{
if (DisplayManager_applyGamma())
{
err = CMSetProfileByAVID(DesktopDisplay.DisplayID, DesktopColorSyncProfile);
}
}
if (err != noErr)
{
GlideMsg("Display Manager: Error while restoring desktop display mode: %d\n", err);
}
return err;
}
bool DisplayManager_GetDesktopDisplayResolution(unsigned long& width, unsigned long& height)
{
width = DesktopDisplay.HorizontalPixels;
height = DesktopDisplay.VerticalLines;
return DesktopDisplay.Valid;
}
bool DisplayManager_GetGlideDisplayResolution(unsigned long& width, unsigned long& height)
{
width = GlideDisplay.HorizontalPixels;
height = GlideDisplay.VerticalLines;
return GlideDisplay.Valid;
}
CMError DisplayManager_SetGamma(DisplayModeSpec& display, FxFloat gamma)
{
CMError err = noErr;
CMVideoCardGamma* gammatable = reinterpret_cast<CMVideoCardGamma*>(display.VideoGammaTable);
if (gammatable && DisplayManager_applyGamma())
{
gammatable->tagType = cmVideoCardGammaTableType;
gammatable->u.table.channels = 1;
const unsigned int entryCount = 256;
gammatable->u.table.entryCount = entryCount;
gammatable->u.table.entrySize = 2;
FxU16* gray = reinterpret_cast<FxU16*>(&gammatable->u.table.data);
FxFloat biased_gamma = gamma + InternalConfig.GammaBias;
// Valid values go from 0.0 to 20.0 according to Glide24pgm
biased_gamma = max(0.0f, biased_gamma);
biased_gamma = min(biased_gamma, 20.0f);
for (unsigned int i = 0; i < entryCount; i++)
{
gray[i] = pow(i / 255.0, 1.0 / biased_gamma) * 65535;
}
err = CMSetGammaByAVID(display.DisplayID, gammatable);
if (err != noErr)
{
GlideMsg("Error: DisplayManager_SetGamma() failed with error code %d\n", err);
}
}
return err;
}
void DisplayManager_SetGlideDisplayGamma(FxFloat gamma)
{
CMError err = DisplayManager_SetGamma(GlideDisplay, gamma);
}
CMError DisplayManager_RememberGamma(DisplayModeSpec& display)
{
CMError err = noErr;
CMVideoCardGamma* gammatable = reinterpret_cast<CMVideoCardGamma*>(display.VideoGammaTable);
if (gammatable && DisplayManager_applyGamma())
{
UInt32 size = VideoGammaTableSize;
err = CMGetGammaByAVID(display.DisplayID, gammatable, &size);
if (err != noErr)
{
GlideMsg("Error: DisplayManager_RememberGamma() failed with error code %d\n", err);
}
}
return err;
}
CMError DisplayManager_RestoreGamma(DisplayModeSpec& display)
{
CMError err = noErr;
CMVideoCardGamma* gammatable = reinterpret_cast<CMVideoCardGamma*>(display.VideoGammaTable);
if (display.GammaValid && gammatable && DisplayManager_applyGamma())
{
err = CMSetGammaByAVID(display.DisplayID, gammatable);
if (err != noErr)
{
GlideMsg("Error: DisplayManager_RestoreGamma() failed with error code %d\n", err);
}
}
return err;
}
void DisplayManager_RestorePassthroughDisplayGamma()
{
DisplayManager_RestoreGamma(PassthroughDisplay);
}
CMError DisplayManager_SetGammaBlack(DisplayModeSpec& display)
{
CMError err = noErr;
// Only change if the gamma can be restored
if (display.GammaValid && DisplayManager_applyGamma())
{
// We can savely use the Glide Display table, because it can be restored via SetGlideDisplayGamma()
CMVideoCardGamma* gammatable = reinterpret_cast<CMVideoCardGamma*>(GlideDisplay.VideoGammaTable);
gammatable->tagType = cmVideoCardGammaTableType;
gammatable->u.table.channels = 1;
const unsigned int entryCount = 256;
gammatable->u.table.entryCount = entryCount;
gammatable->u.table.entrySize = 2;
FxU16* gray = reinterpret_cast<FxU16*>(&gammatable->u.table.data);
memset(gray, 0, entryCount * gammatable->u.table.entrySize);
err = CMSetGammaByAVID(display.DisplayID, gammatable);
if (err != noErr)
{
GlideMsg("Error: DisplayManager_SetGammaBlack() failed with error code %d\n", err);
}
}
return err;
}
void DisplayManager_SetGlideDisplayGammaBlack()
{
DisplayManager_SetGammaBlack(GlideDisplay);
}
void DisplayManager_SetPassthroughDisplayGammaBlack()
{
DisplayManager_SetGammaBlack(PassthroughDisplay);
}
void DisplayManager_SetDesktopDisplayGammaBlack()
{
DisplayManager_SetGammaBlack(DesktopDisplay);
}

View File

@ -0,0 +1,241 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* OpenGLide Settings File
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GlideSettings_FSp.h"
char* s_SettingsFolderName = "XMacGLide Settings";
const char* s_DefaultSettingsFileName = "Defaults";
const char* s_LogFileName = "MacGLide.log";
OSType s_SettingsFileCreator = 0x54545854; // "ttxt"
OSType s_SettingsFileType = 0x54455854; // "TEXT"
OSType s_LogFileCreator = 0x54545854; // "ttxt"
OSType s_LogFileType = 0x54455854; // "TEXT"
GlideSettingsFSp::GlideSettingsFSp()
: m_vRefNumPrefsFolder(0)
, m_dirIDPrefsFolder(0)
, m_SettingsFileRefnum(0)
, m_LogFileRefnum(0)
{
}
GlideSettingsFSp::~GlideSettingsFSp(void)
{
if (m_FileBuffer) DisposePtr(m_FileBuffer);
FSClose(m_LogFileRefnum);
}
GlideSettings::IOErr GlideSettingsFSp::makeSettingsFolderFileSpec(const char* path, const char* filename, FSSpec* fsspec)
{
char buffer[StringBufferSize];
strcpy(&buffer[1], ":");
strcat(&buffer[1], path);
strcat(&buffer[1], ":");
strcat(&buffer[1], filename);
GlideSettings::IOErr err = FSMakeFSSpec(m_vRefNumPrefsFolder, m_dirIDPrefsFolder, PascalString(buffer), fsspec);
if (err == fnfErr) err = noErr;
return err;
}
GlideSettings::IOErr GlideSettingsFSp::init(const char* applicationname)
{
// Make the settings folder
GlideSettings::IOErr err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &m_vRefNumPrefsFolder, &m_dirIDPrefsFolder);
if (err == noErr)
{
FSSpec fsspec;
err = FSMakeFSSpec(m_vRefNumPrefsFolder, m_dirIDPrefsFolder, PascalString(s_SettingsFolderName), &fsspec);
if (err == fnfErr)
{
long dirID;
err = FSpDirCreate(&fsspec, smSystemScript, &dirID);
}
}
// Make references to various files
if (err == noErr)
{
err = makeSettingsFolderFileSpec(&s_SettingsFolderName[1], applicationname, &m_fsSettingsFile);
if (err == noErr)
{
err = makeSettingsFolderFileSpec(&s_SettingsFolderName[1], s_DefaultSettingsFileName, &m_fsDefaultSettingsFile);
if (err == noErr)
{
err = makeSettingsFolderFileSpec(&s_SettingsFolderName[1], s_LogFileName, &m_fsLogFile);
}
}
}
return err;
}
GlideSettings::IOErr GlideSettingsFSp::read_file(FSSpec* file, char** mem, long* size, short* refnum)
{
GlideSettings::IOErr err = FSpOpenDF(file, fsRdPerm, refnum);
if (err == noErr)
{
err = GetEOF(*refnum, size);
if (err == noErr)
{
*mem = new char[*size + 1];
(*mem)[*size] = 0x00;
err = FSRead(*refnum, size, *mem);
if (err == noErr)
{
err = FSClose(*refnum);
}
else
{
FSClose(*refnum);
}
}
}
return err;
}
GlideSettings::IOErr GlideSettingsFSp::read_defaults()
{
#ifdef OGL_DEBUG
GlideMsg("Reading default settings...\n");
#endif
return read_settings_from_file(&m_fsDefaultSettingsFile, &GlideSettings::create_defaults);
}
GlideSettings::IOErr GlideSettingsFSp::read()
{
#ifdef OGL_DEBUG
GlideMsg("Reading application specific settings...\n");
#endif
return read_settings_from_file(&m_fsSettingsFile, &GlideSettings::create);
}
GlideSettings::IOErr GlideSettingsFSp::read_settings_from_file(FSSpec* file, GlideSettingsFSp::IOErr (GlideSettings::*default_creator) ())
{
GlideSettings::IOErr err = read_file(file, &m_FileBuffer, &m_FileBufferSize, &m_SettingsFileRefnum);
if (err != noErr)
{
// create file with default settings
defaults();
err = (this->*default_creator)();
if (err == noErr)
{
err = save();
if (err == noErr)
{
// Now we have o load the file into memory to make the settings reader happy
err = read_file(file, &m_FileBuffer, &m_FileBufferSize, &m_SettingsFileRefnum);
}
}
}
return err;
}
GlideSettings::IOErr GlideSettingsFSp::create_defaults()
{
#ifdef OGL_DEBUG
GlideMsg("Creating new file with default settings...\n");
#endif
GlideSettings::IOErr err = FSpDelete(&m_fsDefaultSettingsFile);
err = FSpCreate(&m_fsDefaultSettingsFile, s_SettingsFileCreator, s_SettingsFileType, smSystemScript);
if (err == noErr || err == dupFNErr)
{
err = FSpOpenDF(&m_fsDefaultSettingsFile, fsWrPerm, &m_SettingsFileRefnum);
}
if (err == noErr)
{
#ifdef OGL_DEBUG
GlideMsg("Looking for obsolete 0.09 settings in app dir...\n");
#endif
ProcessSerialNumber psn;
if (GetCurrentProcess(&psn) == noErr)
{
ProcessInfoRec info;
memset(&info, 0, sizeof(info));
info.processInfoLength = sizeof(info);
FSSpec fsspec;
info.processAppSpec = &fsspec;
GlideSettings::IOErr err2 = GetProcessInformation(&psn, &info);
if (err2 == noErr)
{
const unsigned int number_of_old_files = 3;
char* old_files[number_of_old_files] =
{
"X:OpenGLid.INI",
"X:OpenGLid.LOG",
"X:OpenGLid.ERR"
};
for(unsigned long i = 0; i < number_of_old_files; i++)
{
err2 = HDelete(fsspec.vRefNum, fsspec.parID, PascalString(old_files[i]));
if (err2 == noErr) GlideMsg("Removed 0.09 %s in app dir\n", &(old_files[i])[2]);
}
}
}
}
return err;
}
GlideSettings::IOErr GlideSettingsFSp::create()
{
#ifdef OGL_DEBUG
GlideMsg("Creating new file with application specific settings...\n");
#endif
GlideSettings::IOErr err = FSpDelete(&m_fsSettingsFile);
err = FSpCreate(&m_fsSettingsFile, s_SettingsFileCreator, s_SettingsFileType, smSystemScript);
if (err == noErr || err == dupFNErr)
{
err = FSpOpenDF(&m_fsSettingsFile, fsWrPerm, &m_SettingsFileRefnum);
if (err == noErr)
{
// Enable using this file
UseApplicationSpecificSettings = true;
}
}
return err;
}
GlideSettings::IOErr GlideSettingsFSp::put_raw(const char* string)
{
long count = strlen(string);
GlideSettings::IOErr err = FSWrite(m_SettingsFileRefnum, &count, string);
return err;
}
GlideSettings::IOErr GlideSettingsFSp::close()
{
GlideSettings::IOErr err = FSClose(m_SettingsFileRefnum);
return err;
}
GlideSettings::IOErr GlideSettingsFSp::create_log()
{
GlideSettings::IOErr err = FSpDelete(&m_fsLogFile);
if (err == noErr || err == fnfErr)
{
err = FSpCreate(&m_fsLogFile, s_SettingsFileCreator, s_SettingsFileType, smSystemScript);
if (err == noErr)
{
err = FSpOpenDF(&m_fsLogFile, fsWrPerm, &m_LogFileRefnum);
}
}
return err;
}
GlideSettings::IOErr GlideSettingsFSp::write_log(const char* message)
{
long count = strlen(message);
IOErr err = FSWrite(m_LogFileRefnum, &count, message);
return err;
}
const unsigned char* GlideSettingsFSp::PascalString(char* string)
{
string[0] = static_cast<char>(strlen(&string[1]));
return reinterpret_cast<const unsigned char*>(string);
}

View File

@ -0,0 +1,42 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* OpenGLide Settings File
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
#include "GlideSettings.h"
class GlideSettingsFSp : public GlideSettings
{
public:
GlideSettingsFSp();
virtual ~GlideSettingsFSp(void);
public:
IOErr init(const char* application);
IOErr create_log();
IOErr write_log(const char* message);
protected:
IOErr create_defaults();
IOErr create();
IOErr read_defaults();
IOErr read();
IOErr put_raw(const char* string);
IOErr close();
const unsigned char* PascalString(char* string);
short m_vRefNumPrefsFolder;
long m_dirIDPrefsFolder;
FSSpec m_fsSettingsFile;
FSSpec m_fsDefaultSettingsFile;
short m_SettingsFileRefnum;
FSSpec m_fsLogFile;
short m_LogFileRefnum;
IOErr makeSettingsFolderFileSpec(const char* path, const char* filename, FSSpec* fsspec);
IOErr read_file(FSSpec* file, char** mem, long* size, short* refnum);
IOErr read_settings_from_file(FSSpec* file, IOErr (GlideSettings::*default_creator)());
};

449
MacGLide/Mac/MacGLide.cpp Normal file
View File

@ -0,0 +1,449 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Mac specific functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "FormatConversion.h"
#include "Glide.h"
#include "GlideApplication.h"
#include "GlideDisplay.h"
#include "GlideSettings.h"
#include "GLExtensions.h"
#include "GLRender.h"
#ifdef OGL_PROFILING
#include <profiler.h>
#endif
OSErr __macglide_initialize(struct CFragInitBlock* initBlkPtr)
{
OSErr err = __initialize((CFragInitBlock*) initBlkPtr);
if (err == noErr)
{
#ifdef OGL_PROFILING
err = ProfilerInit(collectSummary, bestTimeBase, 666, 666);
assert(err == noErr);
ProfilerSetStatus(1);
#endif
err = UserConfig.init(s_GlideApplication.GetName());
if (err == noErr)
{
if (!ClearAndGenerateLogFile())
{
GlideError("Unable to init log file: Error code %d", err);
}
else
{
InitMainVariables();
DisplayManager_Initialise();
err = DisplayManager_RememberDesktopDisplay();
GlideMsg(OGL_LOG_SEPARATE);
}
}
}
return err;
}
void __macglide_terminate()
{
#ifdef OGL_DEBUG
GlideMsg(OGL_LOG_SEPARATE);
#endif
grGlideShutdown();
OSErr err = DisplayManager_RestoreDesktopDisplay();
DisplayManager_Cleanup();
CloseLogFile();
if (Glide.ReadBuffer.Address)
{
FreeFrameBuffer(Glide.ReadBuffer.Address);
Glide.ReadBuffer.Address = NULL;
}
#ifdef OGL_PROFILING
char* filename = "XMacGLide Profiler stats";
filename[0] = strlen(&filename[1]);
err = ProfilerDump(reinterpret_cast<unsigned char*>(filename));
ProfilerTerm();
#endif
__terminate();
}
const char* OpenGLideProductName = "MacGLide";
// Allow allocation of memory at 16-byte boundaries to support altivec
void* AllocSysPtr16ByteAligned(long buffersize)
{
void* buffer = NewPtrSys(buffersize + 16);
if (buffer == NULL) return NULL;
unsigned long aligned_buffer = (reinterpret_cast<unsigned long>(buffer) + 16) & 0xfffffff0;
// remember the real location of the buffer
(reinterpret_cast<unsigned long*>(aligned_buffer))[-1] = reinterpret_cast<unsigned long>(buffer);
return reinterpret_cast<void*>(aligned_buffer);
}
void Free16ByteAligned(void* aligned_buffer)
{
DisposePtr((Ptr) (static_cast<unsigned long*>(aligned_buffer))[-1]);
}
void FatalErrorMessageBox(const char* message)
{
unsigned char buffer1[] = "XMacGLide has encountered an unrecoverable error and cannot continue. Excuse:";
buffer1[0] = strlen(reinterpret_cast<char*>(&buffer1[1]));
unsigned char buffer2[StringBufferSize + 1];
strncpy(reinterpret_cast<char*>(&buffer2[1]), message, StringBufferSize -1);
buffer2[0] = strlen(message);
buffer2[buffer2[0] + 1] = 0x0;
SInt16 itemhit;
StandardAlert(kAlertStopAlert, buffer1, buffer2, NULL, &itemhit);
}
char* _strtime(char* timebuf)
{
time_t systime;
struct tm *currtime;
systime = time(NULL);
currtime = localtime(&systime);
strftime(timebuf, 128, "%X", currtime);
return timebuf;
}
char* _strdate(char* timebuf)
{
time_t systime;
struct tm *currtime;
systime = time(NULL);
currtime = localtime(&systime);
strftime(timebuf, 128, "%x", currtime);
return timebuf;
}
//////////////////////////////////////////////////////////////
// Big endian conversion functions
//////////////////////////////////////////////////////////////
// Note about anisotropy and chromakeying:
// If anisotropy is enabled, some textured objects contain
// chromakey-colored pixels.
// This happens because chromakey pixels keep their color values,
// and only the alpha value is set to 0. If the texture is rendered
// with anisotropy enabled (also happened in the framebuffer emulation
// with linear texture filter), the chromakeyed pixels are somehow
// combined with a neighboring (non-chromakey colored) pixel.
// This seems to change the alpha value and as a result, the pixels
// pass the alpha test and are rendered.
// To minimise the resulting artefacts, the color of the chroma-keyed pixel
// is set to the color of the neighboring pixel.
// Used by MacGLide for lossy conversions
void Convert565Kto5551(const FxU32* Buffer1, FxU32 key, FxU32* Buffer2, FxU32 NumberOfPixels )
{
// Convert565Kto5551((unsigned long*) Src, (unsigned long*) Dst, NumberOfPixels);
// This functions processes 2 pixels at a time, there is no problem in
// passing odd numbers or a number less than 2 for the pixels, but
// the buffers should be large enough
FxU32 key1 = key & 0xffff;
FxU32 key2 = key << 16;
while ( NumberOfPixels > 0)
{
FxU32 src1 = *Buffer1 && 0xffff;
FxU32 dest;
if (key1 == src1)
{
dest = 0;
}
else
{
dest = src1;
}
FxU32 src2 = (*Buffer1 && 0xffff0000);
if (key2 != src2)
{
dest = dest | src2;
}
*Buffer2++ = ( (dest) & 0xFFC0FFC0 ) |
( ( (dest) & 0x001F001F ) << 1 ) |
0x00010001;
Buffer1++;
NumberOfPixels -= 2;
}
}
void Convert565Kto8888(const FxU16* src, FxU16 key, FxU32* dst, FxU32 pixels)
{
// Scan for first non-chromakey pixel
// in order to find to the starting value
// for the chromakey_replacement
const register FxU32 mask_pixel_r = 0x0000f800;
const register FxU32 mask_pixel_g = 0x000007e0;
const register FxU32 mask_pixel_b = 0x0000001f;
register FxU16 chromakey_replacement_565 = 0x0000;
for(const FxU16* p = src; p < (src + pixels); p++)
{
chromakey_replacement_565 = *p;
if (chromakey_replacement_565 != key) break;
}
register FxU32 rgb_mask_8888 = 0xffffff00;
register FxU32 chromakey_replacement_8888 = 0x00000000;
chromakey_replacement_8888 = (0x00000000 | // A
(chromakey_replacement_565 & mask_pixel_b) << 11 | // B
(chromakey_replacement_565 & mask_pixel_g) << 13 | // G
(chromakey_replacement_565 & mask_pixel_r) << 16); // R
// Start the conversion
register FxU16 pixel_565;
register FxU32 pixel_8888;
while (pixels)
{
pixel_565 = *src++;
if (pixel_565 == key)
{
// Minimise anisotropy artefacts
pixel_8888 = chromakey_replacement_8888;
}
else
{
pixel_8888 = (0x000000ff | // A
(pixel_565 & mask_pixel_b) << 11 | // B
(pixel_565 & mask_pixel_g) << 13 | // G
(pixel_565 & mask_pixel_r) << 16); // R
chromakey_replacement_8888 = pixel_8888 & rgb_mask_8888;
}
*dst++ = pixel_8888;
pixels--;
}
}
void ConvertA8toAP88(const FxU8 *Buffer1, FxU16 *Buffer2, FxU32 Pixels )
{
while ( Pixels )
{
*Buffer2 = ( ( ( *Buffer1 ) << 8 ) | ( *Buffer1 ) );
Buffer1++;
Buffer2++;
Pixels--;
}
}
void Convert8332to8888(const FxU16 *Buffer1, FxU32 *Buffer2, FxU32 Pixels )
{
FxU32 R, G, B, A;
for ( FxU32 i = Pixels; i > 0; i-- )
{
A = ( ( ( *Buffer1 ) >> 8 ) & 0xFF );
R = ( ( ( *Buffer1 ) >> 5 ) & 0x07 ) << 5;
G = ( ( ( *Buffer1 ) >> 2 ) & 0x07 ) << 5;
B = ( ( *Buffer1 ) & 0x03 ) << 6;
*Buffer2 = ( R << 24 ) | ( G << 16 ) | ( B << 8 ) | A;
Buffer1++;
Buffer2++;
}
}
void ConvertP8to8888(const FxU8 *Buffer1, FxU32 *Buffer2, FxU32 Pixels, FxU32 *palette )
{
while ( Pixels-- )
{
*Buffer2++ = palette[ *Buffer1++ ];
}
}
void ConvertP8Kto8888(const FxU8 *Buffer1, FxU32 Key, FxU32 *Buffer2, FxU32 Pixels, FxU32 *palette )
{
// Scan for first non-chromakey pixel
// in order to find to the starting value
// for the chromakey_replacement
register FxU32 chromakey_replacement = 0;
register FxU32 chromakey = Key;
register FxU32 alpha_mask = 0xffffff00;
for(const FxU8* b = Buffer1; b < (Buffer1 + Pixels); b++)
{
chromakey_replacement = (palette[*b] & alpha_mask);
if (chromakey_replacement != chromakey) break;
}
// Start the conversion
register FxU32 current_pixel = 0;
while ( Pixels-- )
{
current_pixel = palette[*Buffer1++];
if (current_pixel == chromakey)
{
*Buffer2 = chromakey_replacement;
}
else
{
*Buffer2 = current_pixel;
chromakey_replacement = current_pixel & alpha_mask;
}
Buffer2++;
}
}
void ConvertAI44toAP88(const FxU8 *Buffer1, FxU16 *Buffer2, FxU32 Pixels )
{
for ( FxU32 i = Pixels; i > 0; i-- )
{
*Buffer2 = ( ( ( ( *Buffer1 ) & 0xF0 ) << 8 ) | ( ( ( *Buffer1 ) & 0x0F ) << 4 ) );
Buffer2++;
Buffer1++;
}
}
void ConvertAP88to8888(const FxU16 *Buffer1, FxU32 *Buffer2, FxU32 Pixels, FxU32 *palette )
{
FxU32 RGB,
A;
for ( FxU32 i = Pixels; i > 0; i-- )
{
RGB = ( palette[ *Buffer1 & 0x00ff ] & 0xffffff00 );
A = *Buffer1 >> 8;
*Buffer2 = A | RGB;
Buffer1++;
Buffer2++;
}
}
void ConvertYIQto8888(const FxU8 *in, FxU32 *out, FxU32 Pixels, GuNccTable *ncc )
{
FxI32 R;
FxI32 G;
FxI32 B;
for ( FxU32 i = Pixels; i > 0; i-- )
{
R = ncc->yRGB[ *in >> 4 ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 0 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 0 ];
G = ncc->yRGB[ *in >> 4 ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 1 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 1 ];
B = ncc->yRGB[ *in >> 4 ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 2 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 2 ];
// Clamp values
R = ( ( R < 0 ) ? 0 : ( ( R > 255 ) ? 255 : R ) );
G = ( ( G < 0 ) ? 0 : ( ( G > 255 ) ? 255 : G ) );
B = ( ( B < 0 ) ? 0 : ( ( B > 255 ) ? 255 : B ) );
*out = ( (R << 24) | ( G << 16 ) | ( B << 8 ) | 0x000000ff );
in++;
out++;
}
}
void ConvertAYIQto8888(const FxU16 *in, FxU32 *out, FxU32 Pixels, GuNccTable *ncc)
{
FxI32 R;
FxI32 G;
FxI32 B;
for ( FxU32 i = Pixels; i > 0; i-- )
{
R = ncc->yRGB[ ( *in >> 4 ) & 0xf ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 0 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 0 ];
G = ncc->yRGB[ ( *in >> 4 ) & 0xf ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 1 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 1 ];
B = ncc->yRGB[ ( *in >> 4 ) & 0xf ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 2 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 2 ];
R = ( ( R < 0 ) ? 0 : ( ( R > 255 ) ? 255 : R ) );
G = ( ( G < 0 ) ? 0 : ( ( G > 255 ) ? 255 : G ) );
B = ( ( B < 0 ) ? 0 : ( ( B > 255 ) ? 255 : B ) );
*out = ( (R <<24) | ( G << 16 ) | ( B << 8 ) | ( /*0x000000ff &*/ ( *in >> 8 ) ) );
in++;
out++;
}
}
void SplitAP88(const FxU16 *ap88, FxU8 *index, FxU8 *alpha, FxU32 pixels )
{
for ( FxU32 i = pixels; i > 0; i-- )
{
*alpha++ = ( *ap88 >> 8 );
*index++ = ( *ap88++ & 0xff );
}
}
// Color conversion functions: The windows version converts colors to ARGB,
// whereas the mac version converts colors to RGBA (no extension needed)
void ConvertColor4B( GrColor_t GlideColor, FxU32 &C )
{
switch ( Glide.State.ColorFormat )
{
case GR_COLORFORMAT_ARGB: //0xAARRGGBB
C = ( ( GlideColor & 0x00ffffff ) << 8 ) |
( ( GlideColor & 0xff000000 ) >> 24 );
break;
case GR_COLORFORMAT_ABGR: //0xAABBGGRR
C = ( ( GlideColor & 0xff000000 ) >> 24 ) |
( ( GlideColor & 0x00ff0000 ) >> 8 ) |
( ( GlideColor & 0x0000ff00 ) << 8 ) |
( ( GlideColor & 0x000000ff ) << 24 );
break;
case GR_COLORFORMAT_RGBA: //0xRRGGBBAA
C = GlideColor;
break;
case GR_COLORFORMAT_BGRA: //0xBBGGRRAA
C = ( ( GlideColor & 0xFF000000 ) >> 24 ) |
( ( GlideColor & 0x0000ff00 ) << 16 ) |
( ( GlideColor & 0x0ff000ff ) );
break;
}
}
void Convert1555Kto8888(const FxU16* src, FxU16 key, FxU32* dst, FxU32 pixels)
{
// Scan for first non-chromakey pixel
// in order to find to the starting value
// for the chromakey_replacement
const register FxU32 mask_pixel_r = 0x00007c00;
const register FxU32 mask_pixel_g = 0x000003e0;
const register FxU32 mask_pixel_b = 0x0000001f;
const register FxU32 mask_pixel_a = 0x00008000;
register FxU16 chromakey_replacement_1555 = 0x0000;
register FxU16 chromakey = key & 0x7fff;
for(const FxU16* p = src; p < (src + pixels); p++)
{
chromakey_replacement_1555 = *p;
if (chromakey_replacement_1555 != chromakey) break;
}
register FxU32 rgb_mask_8888 = 0xffffff00;
register FxU32 chromakey_replacement_8888 = 0x00000000;
chromakey_replacement_8888 = (0x00000000 | // A
(chromakey_replacement_1555 & mask_pixel_b) << 11 | // B
(chromakey_replacement_1555 & mask_pixel_g) << 14 | // G
(chromakey_replacement_1555 & mask_pixel_r) << 17); // R
// Start the conversion
register FxU16 pixel_1555;
register FxU32 pixel_8888;
while (pixels)
{
pixel_1555 = *src++;
if ((pixel_1555 & 0x7fff) == chromakey)
{
// Minimise anisotropy artefacts
pixel_8888 = chromakey_replacement_8888;
}
else
{
pixel_8888 = (((pixel_1555 & mask_pixel_a) ? 0x000000ff : 0x00000080) | // A
(pixel_1555 & mask_pixel_b) << 11 | // B
(pixel_1555 & mask_pixel_g) << 14 | // G
(pixel_1555 & mask_pixel_r) << 17); // R
chromakey_replacement_8888 = pixel_8888 & rgb_mask_8888;
}
*dst++ = pixel_8888;
pixels--;
}
}

50
MacGLide/Mac/MacGLide.h Normal file
View File

@ -0,0 +1,50 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Shared Library entry points
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
// library entry points
#pragma export on
extern "C" OSErr __macglide_initialize(struct CFragInitBlock* initBlkPtr);
extern "C" void __macglide_terminate();
extern "C" OSErr __initialize(struct CFragInitBlock* initBlkPtr);
extern "C" void __terminate();
#pragma export off
// Not declared in MSL
char* _strtime(char* tmpbuf);
char* _strdate(char* tmpbuf);
// OpenGL extension data not available in MacOS 9 but
// provided by the MacOS X OpenGL driver in Classic
// GL_APPLE_client_storage
#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
// GL_ARB_multisample
// aglChoosePixelFormat
#define AGL_SAMPLE_BUFFERS_ARB 55
#define AGL_SAMPLES_ARB 56
// aglSetInteger
#define AGL_ATI_FSAA_LEVEL 510
// GL_NV_multisample_filter_hint
#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
// GL_ARB_texture_env_combine
#define GL_SUBTRACT_ARB 0x84E7
// GL_ATI_texture_env_combine3
#define GL_MODULATE_ADD_ATI 0x8744
// Swap limit
#define AGL_SWAP_LIMIT 203

View File

View File

@ -0,0 +1,261 @@
/*
File: Carbon Error Handler.c
Contains: SetupGL error handling
Written by: Geoff Stahl (ggs)
Copyright: Copyright © 1999-2001 Apple Computer, Inc., All Rights Reserved
Change History (most recent first):
<1> 1/19/01 ggs Initial re-add
<4> 1/24/00 ggs double check for latest
<4> 1/24/00 ggs double check for latest
<3> 12/18/99 ggs Fix headers
<2> 11/28/99 ggs Added verbose error flag
<1> 11/28/99 ggs Initial add. Split of just error handling functions. Need to
add more reporting examples
<1> 11/11/99 ggs Initial Add
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define kVerboseErrors
//#define kQuake3
// system includes ----------------------------------------------------------
#ifdef kQuake3
typedef int sysEventType_t; // FIXME...
#endif
#ifdef __APPLE_CC__
#include <Carbon/Carbon.h>
#else
#include <MacTypes.h>
#endif
#include <stdio.h>
// project includes ---------------------------------------------------------
#include "Carbon_SetupDSp.h"
#include "Carbon_Error_Handler.h"
#ifdef kQuake3
#include "../renderer/tr_local.h"
#include "mac_local.h"
#endif
// globals (internal/private) -----------------------------------------------
// prototypes (internal/private) --------------------------------------------
static void CStrToPStr (StringPtr outString, const char *inString);
// functions (internal/private) ---------------------------------------------
// Copy C string to Pascal string
static void CStrToPStr (StringPtr outString, const char *inString)
{
unsigned char x = 0;
do
*(((char*)outString) + x + 1) = *(inString + x++);
while ((*(inString + x) != 0) && (x < 256));
*((char*)outString) = (char) x;
}
#pragma mark -
// --------------------------------------------------------------------------
// central error reporting
void ReportErrorNum (char * strError, long numError)
{
GlideMsg(strError, "%s %ld (0x%lx)\n", strError, numError, numError);
/*
char errMsgCStr [256];
Str255 strErr = "\p";
// out as debug string
#ifdef kVerboseErrors
#ifdef kQuake3
ri.Printf( PRINT_ALL, errMsgCStr);
#else
// ensure we are faded in
if (gDSpStarted)
DSpContext_CustomFadeGammaIn (NULL, NULL, 0);
CStrToPStr (strErr, errMsgCStr);
DebugStr (strErr);
#endif // kQuake3
#endif // kVerboseErrors
*/
}
// --------------------------------------------------------------------------
void ReportError (char * strError)
{
GlideError(strError);
/*
char errMsgCStr [256];
Str255 strErr = "\p";
sprintf (errMsgCStr, "%s\n", strError);
// out as debug string
#ifdef kVerboseErrors
#ifdef kQuake3
ri.Printf( PRINT_ALL, errMsgCStr);
#else
// ensure we are faded in
if (gDSpStarted)
DSpContext_CustomFadeGammaIn (NULL, NULL, 0);
CStrToPStr (strErr, errMsgCStr);
DebugStr (strErr);
#endif // kQuake3
#endif // kVerboseErrors
*/
}
//-----------------------------------------------------------------------------------------------------------------------
OSStatus DSpReportError (OSStatus error)
{
switch (error)
{
case noErr:
break;
case kDSpNotInitializedErr:
ReportError ("DSp Error: Not initialized");
break;
case kDSpSystemSWTooOldErr:
ReportError ("DSp Error: system Software too old");
break;
case kDSpInvalidContextErr:
ReportError ("DSp Error: Invalid context");
break;
case kDSpInvalidAttributesErr:
ReportError ("DSp Error: Invalid attributes");
break;
case kDSpContextAlreadyReservedErr:
ReportError ("DSp Error: Context already reserved");
break;
case kDSpContextNotReservedErr:
ReportError ("DSp Error: Context not reserved");
break;
case kDSpContextNotFoundErr:
ReportError ("DSp Error: Context not found");
break;
case kDSpFrameRateNotReadyErr:
ReportError ("DSp Error: Frame rate not ready");
break;
case kDSpConfirmSwitchWarning:
// ReportError ("DSp Warning: Must confirm switch"); // removed since it is just a warning, add back for debugging
return 0; // don't want to fail on this warning
break;
case kDSpInternalErr:
ReportError ("DSp Error: Internal error");
break;
case kDSpStereoContextErr:
ReportError ("DSp Error: Stereo context");
break;
}
return error;
}
//-----------------------------------------------------------------------------------------------------------------------
// if error dump agl errors to debugger string, return error
OSStatus aglReportError (void)
{
GLenum err = aglGetError();
if (AGL_NO_ERROR != err)
{
GlideError("AGL-Error: %s\n", reinterpret_cast<const char *>(aglErrorString(err)));
}
// ensure we are returning an OSStatus noErr if no error condition
if (err == AGL_NO_ERROR)
return noErr;
else
return (OSStatus) err;
}
//-----------------------------------------------------------------------------------------------------------------------
// if error dump gl errors to debugger string, return error
/*
OSStatus glReportError (void)
{
GLenum err = glGetError();
switch (err)
{
case GL_NO_ERROR:
break;
case GL_INVALID_ENUM:
ReportError ("GL Error: Invalid enumeration");
break;
case GL_INVALID_VALUE:
ReportError ("GL Error: Invalid value");
break;
case GL_INVALID_OPERATION:
ReportError ("GL Error: Invalid operation");
break;
case GL_STACK_OVERFLOW:
ReportError ("GL Error: Stack overflow");
break;
case GL_STACK_UNDERFLOW:
ReportError ("GL Error: Stack underflow");
break;
case GL_OUT_OF_MEMORY:
ReportError ("GL Error: Out of memory");
break;
}
// ensure we are returning an OSStatus noErr if no error condition
if (err == GL_NO_ERROR)
return noErr;
else
return (OSStatus) err;
}
*/

View File

@ -0,0 +1,106 @@
/*
File: Carbon Error Handler.h
Contains: Functions to enable build and destory a GL fullscreen context
Written by: Geoff Stahl (ggs)
Copyright: Copyright © 1999 Apple Computer, Inc., All Rights Reserved
Change History (most recent first):
<1> 1/19/01 ggs Initial re-add
<3> 1/24/00 ggs added C++ support
<2> 12/18/99 ggs Fix headers
<1> 11/28/99 ggs Initial add. Split of just error handling functions. Need to
add more reporting examples
<1> 11/11/99 ggs Initial Add
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Usage notes:
// include control --------------------------------------------------
#ifndef Error_Handler_h
#define Error_Handler_h
// includes ---------------------------------------------------------
#ifdef __APPLE_CC__
#include <DrawSprocket/DrawSprocket.h>
#include <AGL/agl.h>
#else
#include <DrawSprocket.h>
#include <agl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
// structures (public) -----------------------------------------------
// public function declarations -------------------------------------
// Error reporter, can be set to report however the application desires
void ReportError (char * strError);
// Error with numeric code reporter, can be set to report however the application desires
void ReportErrorNum (char * strError, long numError);
// Handle reporting of DSp errors, error code is passed through
OSStatus DSpReportError (OSStatus error);
// Handle reporting of agl errors, error code is passed through
OSStatus aglReportError (void);
// Handle reporting of OpenGL errors, error code is passed through
//OSStatus glReportError (void);
#ifdef __cplusplus
}
#endif
#endif // Error_Handler_h

View File

@ -0,0 +1,925 @@
/*
File: SetupDSp.c
Contains: Functions to enable building and destorying a DSp fullscreen context
Written by: Geoff Stahl (ggs)
Copyright: Copyright © 1999 Apple Computer, Inc., All Rights Reserved
Change History (most recent first):
<3> 3/26/01 ggs Add DSp version check and other items for full screen on X
<2> 3/26/01 ggs Add new DSp functinality for Mac OS X
<1> 1/19/01 ggs Initial re-add
<7> 3/21/00 ggs Added windowed mode and clean up various implementation details
<6> 2/22/00 ggs fix fades
<5> 1/26/00 ggs Add fade code back in, ensure NULL pointer/context checks are in
<4> 1/24/00 ggs add new disclaimer, protection from NULL dispose, better
software renderer handling
<3> 12/18/99 ggs Fixed err use before init
<2> 12/18/99 ggs Fix headers
<1> 11/28/99 ggs Initial add. Split of just DSp handling functions. Added total
device RAM checks, better step downs using actual supported
resolutions. Need to add user verify for contexts that require
it, integration of this in context step down, and a freq bit
field.
<1> 11/11/99 ggs Initial Add
Disclaimer: You may incorporate this sample code into your applications without
restriction, though the sample code has been provided "AS IS" and the
responsibility for its operation is 100% yours. However, what you are
not permitted to do is to redistribute the source as "DSC Sample Code"
after having made changes. If you're going to re-distribute the source,
we require that you make it clear in the source that the code was
descended from Apple Sample Code, but that you've made changes.
*/
/* changes for OpenGLide for Macintosh
Change History (most recent first):
<1> 2/6/04 jenz Changed BuildResolutionList to list up all frequencies for each resolution
*/
// Usage notes:
// kUseFades enables gamma fades for activates and deactivates
#define kUseFades
// kUseRAMCheck enables estimated video card RAM checks
#define kUseRAMCheck
// system includes ----------------------------------------------------------
#ifdef __APPLE_CC__
#include <Carbon/Carbon.h>
#else
#include <events.h>
#include <sound.h>
#include <fp.h>
#endif
#include <string.h>
// project includes ---------------------------------------------------------
#include "Carbon_Error_Handler.h"
#include "Carbon_SetupDSp.h"
// globals (internal/private) -----------------------------------------------
enum
{
kMaxNumRes = 128, // max number of resolution slots
kMaxRefreshFreq = 120
};
Boolean gDSpStarted = false; // will never be true unless DSp is installed and start succeeds
Boolean gNeedFade = false;
// prototypes (internal/private) --------------------------------------------
DSpContextReference * ReserveUnusedDevices (GDHandle hGD);
OSStatus FreeUnusedDevices (GDHandle hGD, DSpContextReference ** ppContextRefUnused);
void BuildResolutionList (GDHandle hGD, Point * pResList, SInt32 * pFreqList);
OSStatus DoDeviceRAMCheck (pstructGLInfo pcontextInfo, Point * pResList, SInt32 * pFreqList, GLint depthSizeSupport);
Boolean DoContextStepDown (pstructGLInfo pcontextInfo, DSpContextAttributes * pContextAttributes, Point * pResList, SInt32 * pFreqList);
// functions (internal/private) ---------------------------------------------
// ReserveUnusedDevices
// reserves contexts on unused devices to vprevent their selection by DSp, returns list of these devices
DSpContextReference * ReserveUnusedDevices (GDHandle hGD)
{
DSpContextAttributes theContextAttributes;
DSpContextReference * pContextRefUnused = NULL;
GDHandle hDevice = DMGetFirstScreenDevice (true); // check number of screens
DisplayIDType displayID = 0;
short numDevices = 0, indexDevice = 0;
do
{
numDevices++;
hDevice = DMGetNextScreenDevice (hDevice, true);
}
while (hDevice);
numDevices--; // only count unused screens
if (numDevices)
{
pContextRefUnused = (DSpContextReference *) NewPtr ((long) sizeof (DSpContextReference) * numDevices);
hDevice = DMGetFirstScreenDevice (true); // check number of screens
do
{
if (hDevice != hGD) // if this device is not the one the user chose
{
if (noErr == DSpReportError (DMGetDisplayIDByGDevice (hDevice, &displayID, false)))
if (noErr == DSpReportError (DSpGetFirstContext (displayID, &pContextRefUnused [indexDevice]))) // get a context and
if (noErr == DSpReportError (DSpContext_GetAttributes (pContextRefUnused [indexDevice], &theContextAttributes))) // find attributes
DSpReportError (DSpContext_Reserve (pContextRefUnused [indexDevice], &theContextAttributes)); // reserve it
indexDevice++;
}
hDevice = DMGetNextScreenDevice (hDevice, true);
}
while (hDevice);
}
return pContextRefUnused;
}
// --------------------------------------------------------------------------
// FreeUnusedDevices
// frees screen that were previously reserved to prevent selection
OSStatus FreeUnusedDevices (GDHandle hGD, DSpContextReference ** ppContextRefUnused)
{
OSStatus err = noErr;
GDHandle hDevice = DMGetFirstScreenDevice (true); // check number of screens
short indexDevice = 0;
do
{
if (hDevice != hGD) // if this device is not the one the user chose
{
err = DSpContext_Release (*ppContextRefUnused [indexDevice]); // release it
DSpReportError (err);
indexDevice++;
}
hDevice = DMGetNextScreenDevice (hDevice, true);
}
while (hDevice);
if (*ppContextRefUnused)
DisposePtr ((Ptr) *ppContextRefUnused);
*ppContextRefUnused = NULL;
return err;
}
// --------------------------------------------------------------------------
// BuildResolutionList
// builds a list of supported resolutions and frequencies for GDevice
void BuildResolutionList (GDHandle hGD, Point * pResList, SInt32 * pFreqList)
{
DSpContextAttributes theContextAttributes;
DSpContextReference currContext;
OSStatus err;
DisplayIDType displayID = 0;
short i;
for (i = 0; i < kMaxNumRes; i++) // clear resolution list
{
pResList [i].h = 0x7FFF;
pResList [i].v = 0x7FFF;
pFreqList [i] = 0; // some context require certain frequencies find highest for each (not higher than 85
}
err = DMGetDisplayIDByGDevice (hGD, &displayID, true);
if (noErr != err)
ReportErrorNum ("DMGetDisplayIDByGDevice error", err);
else
{
if (noErr == DSpReportError (DSpGetFirstContext (displayID, &currContext)))
do
{
// insertion sort into resolution list
if (noErr == DSpReportError (DSpContext_GetAttributes (currContext, &theContextAttributes)))
{
Point pntTemp;
Boolean fDone = false;
short i = 0;
while ((i < kMaxNumRes) && (!fDone))
{
// Don't just look for the highest vertical refresh rate,
// get all refresh rates for a resolution
if ((theContextAttributes.displayWidth == pResList [i].h)
&& (theContextAttributes.displayHeight == pResList [i].v)
&& (theContextAttributes.frequency == pFreqList[i] )) //skip
{
// avoid zero frequency
if ((pFreqList [i] == 0) || ((theContextAttributes.frequency <= (kMaxRefreshFreq << 16))
&& (theContextAttributes.frequency > pFreqList [i])))
{
pFreqList [i] = theContextAttributes.frequency;
}
break;
}
if (theContextAttributes.displayWidth * theContextAttributes.displayHeight < pResList [i].h * pResList [i].v) //insert
{
pntTemp = pResList [i];
pResList [i].h = (short) theContextAttributes.displayWidth;
pResList [i].v = (short) theContextAttributes.displayHeight;
pFreqList [i] = theContextAttributes.frequency;
fDone = true;
}
i++;
}
// i points to next element to switch; finish array swaps (if
while ((i < kMaxNumRes) && (fDone))
{
Point pntSwitch = pResList [i];
pResList [i++] = pntTemp;
pntTemp = pntSwitch;
}
}
err = DSpGetNextContext (currContext, &currContext);
if (noErr != err)
{
if (kDSpContextNotFoundErr != err)
DSpReportError (err);
currContext = 0; // ensure we drop out
}
}
while (currContext);
else
ReportErrorNum ("DSpGetFirstContext error", err);
}
// zeroize unused elements
for (i = 0; i < kMaxNumRes; i++)
if ((pResList [i].h == 0x7FFF) || (pResList [i].v == 0x7FFF))
{
pResList [i].h = 0;
pResList [i].v = 0;
}
}
// --------------------------------------------------------------------------
// DoDeviceRAMCheck
// checks requested allocation against device RAM
// Note: may modify pcontextInfo
// this should be equal or less strigent than OpenGL actual allocation to avoid failing on valid drawables
OSStatus DoDeviceRAMCheck (pstructGLInfo pcontextInfo, Point * pResList, SInt32 * pFreqList, GLint depthSizeSupport)
{
float frontBufferFactor = 1.0f, backBufferFactor = 0.0f; // amount of screen(front) or request(back) sized buffers required, in bytes
Point pntFrontBuffer; // size of front buffer that wil be allocated
short i, indexFrontBuffer;
OSStatus err = noErr;
// must take into account the entire front buffer, so figure out what screen resolution we are really going to use
// find front buffer for request
i = 0;
while (((pResList [i].h < pcontextInfo->width) || (pResList [i].v < pcontextInfo->height)) &&
((pResList [i].h != 0) || (pResList [i].v != 0)) &&
(i < kMaxNumRes))
i++;
while (((pResList [i].h == pcontextInfo->width) || (pResList [i].v == pcontextInfo->height)) &&
((pResList [i].h != 0) || (pResList [i].v != 0)) &&
(i < kMaxNumRes) && pFreqList[i + 1] <= pcontextInfo->freq << 16)
i++;
// save front buffer sizes
pntFrontBuffer.h = pResList [i].h;
pntFrontBuffer.v = pResList [i].v;
// if we have a valid frequency for the context set it (to ensure a good selection
pcontextInfo->freq = pFreqList [i] >> 16;
indexFrontBuffer = i;
// front buffers required
if (16 == pcontextInfo->pixelDepth)
frontBufferFactor *= 2.0;
else if (32 == pcontextInfo->pixelDepth)
frontBufferFactor *= 4.0;
// back buffers required
backBufferFactor = 0.0f;
i = 0;
while (64 > i)
if (AGL_DOUBLEBUFFER == pcontextInfo->aglAttributes[i++])
{
if (16 == pcontextInfo->pixelDepth)
backBufferFactor = 2.0f;
else if (32 == pcontextInfo->pixelDepth)
backBufferFactor = 4.0f;
break;
}
i = 0;
while (64 > i)
if (AGL_DEPTH_SIZE == pcontextInfo->aglAttributes[i++])
{
long requestDepth = pcontextInfo->aglAttributes[i];
GLint bit = 0x00000001;
short currDepth = 0, prevDepth = 0;
// if (depthSizeSupport)
// {
do
{
if (bit & depthSizeSupport) // if the card supports the depth
{
prevDepth = currDepth;
switch (bit)
{
case AGL_1_BIT:
currDepth = 1;
break;
case AGL_2_BIT:
currDepth = 2;
break;
case AGL_3_BIT:
currDepth = 3;
break;
case AGL_4_BIT:
currDepth = 4;
break;
case AGL_5_BIT:
currDepth = 5;
break;
case AGL_6_BIT:
currDepth = 6;
break;
case AGL_8_BIT:
currDepth = 8;
break;
case AGL_10_BIT:
currDepth = 10;
break;
case AGL_12_BIT:
currDepth = 12;
break;
case AGL_16_BIT:
currDepth = 16;
break;
case AGL_24_BIT:
currDepth = 24;
break;
case AGL_32_BIT:
currDepth = 32;
break;
case AGL_48_BIT:
currDepth = 48;
break;
case AGL_64_BIT:
currDepth = 64;
break;
case AGL_96_BIT:
currDepth = 96;
break;
case AGL_128_BIT:
currDepth = 128;
break;
}
}
bit *= 2;
} while (!((requestDepth > prevDepth) && (requestDepth <= currDepth)) && (bit < AGL_128_BIT + 1));
// }
// else // no card depth support info
// currDepth = requestDepth; // we don't have card info thus assume we can support exact depth requested (may fail later but will always be equal or less stringent)
if ((AGL_128_BIT >= bit) && (0 != currDepth))
backBufferFactor += (float) currDepth / 8.0;
break;
}
// What we now have:
// pcontextInfo->width, height: request width and height
// pResList: sorted list of resolutions supported on this display
// pntFrontBuffer : size of front buffer that will currently be allocated
// indexFrontBuffer: position in array of current front buffer request
// frontBufferFactor: number of screen resolution size buffers that will be needed
// backBufferFactor: number of request size buffers that will be needed
// if we see zero VRAM here we must be looking at the software renderer thus this check is moot.
if (pcontextInfo->VRAM == 0)
{
// no changes required
return noErr;
}
// find a context size that can support our texture requirements in the current total VRAM
if ((pcontextInfo->VRAM - pcontextInfo->textureRAM) < (pntFrontBuffer.h * pntFrontBuffer.v * frontBufferFactor +
pcontextInfo->width * pcontextInfo->height * backBufferFactor))
{
if (pcontextInfo->fDepthMust && pcontextInfo->fSizeMust)
{
// cannot accomdate request
ReportError ("Not enough total VRAM for drawable and textures (depth buffer and pixel size must be as requested)");
return err;
}
else if (pcontextInfo->fSizeMust) // if we can adjust the size, try adjusting the
{
// try 16 bit if must size is true
if ((pcontextInfo->pixelDepth > 16) &&
(pcontextInfo->VRAM - pcontextInfo->textureRAM) > (pntFrontBuffer.h * pntFrontBuffer.v * frontBufferFactor / 2.0 +
pcontextInfo->width * pcontextInfo->height * (backBufferFactor - 2.0)))
pcontextInfo->pixelDepth = 16;
else
{
// cannot accomdate request
ReportError ("Not enough total VRAM for drawable and textures");
return err;
}
}
else // can adjust size and might be able to adjust depth
{ // make drawable fit
Boolean fFound = false;
// see if we can just adjust the pixel depth
if ((pcontextInfo->pixelDepth > 16) && // if we are requesting 32 bit
(!pcontextInfo->fDepthMust) && // if we can adjust the pixel depth
(pcontextInfo->VRAM - pcontextInfo->textureRAM) > (pntFrontBuffer.h * pntFrontBuffer.v * frontBufferFactor / 2.0 +
pcontextInfo->width * pcontextInfo->height * (backBufferFactor - 2.0)))
{
fFound = true;
pcontextInfo->pixelDepth = 16;
}
else // pixel depth alone wont do it
{
i = (short) (indexFrontBuffer - 1);
while (i >= 0)
{
//
if ((pcontextInfo->VRAM - pcontextInfo->textureRAM) > (pResList [i].h * pResList [i].v * frontBufferFactor +
pResList [i].h * pResList [i].v * backBufferFactor))
{
fFound = true;
pcontextInfo->width = pResList [i].h;
pcontextInfo->height = pResList [i].v;
pcontextInfo->freq = pFreqList [i] >> 16;
break;
}
else if ((pcontextInfo->pixelDepth > 16) && // if we are requesting 32 bit
(!pcontextInfo->fDepthMust) && // if we can adjust the pixel depth
(pcontextInfo->VRAM - pcontextInfo->textureRAM) > (pResList [i].h * pResList [i].v * frontBufferFactor / 2.0 +
pResList [i].h * pResList [i].v * (backBufferFactor - 2.0)))
{
fFound = true;
pcontextInfo->width = pResList [i].h;
pcontextInfo->height = pResList [i].v;
pcontextInfo->freq = pFreqList [i] >> 16;
pcontextInfo->pixelDepth = 16;
break;
}
i--;
}
// we tried the smallest screen size and still need to use less VRAM, adjust backbuffer to what is available
if ((!fFound) && (((pcontextInfo->VRAM - pcontextInfo->textureRAM) - pResList [0].h * pResList [0].v * frontBufferFactor) > 0))
{
float factor;
fFound = true;
factor = (float) sqrt((float) (pcontextInfo->width * pcontextInfo->height * backBufferFactor) /
(float) ((pcontextInfo->VRAM - pcontextInfo->textureRAM) - pResList [0].h * pResList [0].v * frontBufferFactor));
pcontextInfo->width /= factor;
pcontextInfo->height /= factor;
pcontextInfo->freq = pFreqList [0] >> 16;
}
}
if (!fFound)
{
// cannot accomdate request
ReportError ("Not enough total VRAM for drawable and textures");
return err;
}
}
}
return noErr;
}
// --------------------------------------------------------------------------
// DoContextStepDown
// steps down through frequencies, depths and sizes to try to find a valid context
// bounded by flags for SizeMust and DepthMust
// Note: may modify pcontextInfo
Boolean DoContextStepDown (pstructGLInfo pcontextInfo, DSpContextAttributes * pContextAttributes, Point * pResList, SInt32 * pFreqList)
{
// find current resolution
short i = 0;
while (((pResList [i].h <= pContextAttributes->displayWidth) || (pResList [i].v <= pContextAttributes->displayHeight)) &&
((pResList [i].h != 0) || (pResList [i].v != 0)) &&
(i < kMaxNumRes))
i++;
i--; // i points to index of current resolution
if (pcontextInfo->freq > 0)
{
// adjust index to (equal or less than) desired refresh rate
while (((pResList [i + 1].h <= pContextAttributes->displayWidth) || (pResList [i + 1].v <= pContextAttributes->displayHeight)) &&
((pResList [i + 1].h != 0) || (pResList [i + 1].v != 0)) &&
(i + 1 < kMaxNumRes) &&
(pFreqList[i + 1] >= pcontextInfo->freq << 16))
{
i++;
}
pcontextInfo->freq = pFreqList [i] >> 16;
}
if (pcontextInfo->fSizeMust) // adjust depth only
{
if (pcontextInfo->pixelDepth > 16) // also try pixel depth step down
{
pContextAttributes->displayBestDepth = 16;
pContextAttributes->backBufferBestDepth = 16;
}
else
return false; // no more options to try
}
else if (pcontextInfo->fDepthMust) // adjust size only
{
if (i > 0)
{
while ((pResList [i].h == pContextAttributes->displayWidth)
&& (pResList [i].v == pContextAttributes->displayHeight)
&& i > 0)
{
i--; // i was pointing at current resolution, now it is pointing at new resolution to try
}
// set new resolution
pContextAttributes->displayWidth = pResList [i].h;
pContextAttributes->displayHeight = pResList [i].v;
// find refresh rate equal or smaller
while ((pResList [i - 1].h == pContextAttributes->displayWidth)
&& (pResList [i - 1].v == pContextAttributes->displayHeight)
&& i > 0
&& pFreqList[i] > pcontextInfo->freq << 16)
{
i--;
}
// set new refresh rate
pcontextInfo->freq = pFreqList [i] >> 16;
}
else
return false;
}
else // adjust size and depth
{
if (pContextAttributes->displayBestDepth > 16)
{
pContextAttributes->displayBestDepth = 16;
pContextAttributes->backBufferBestDepth = 16;
}
else if (i > 0)
{
while ((pResList [i].h == pContextAttributes->displayWidth)
&& (pResList [i].v == pContextAttributes->displayHeight)
&& i > 0)
{
i--; // i was pointing at current resolution, now it is pointing at new resolution to try
}
// set new resolution
pContextAttributes->displayWidth = pResList [i].h;
pContextAttributes->displayHeight = pResList [i].v;
// find refresh rate equal or smaller
while ((pResList [i - 1].h == pContextAttributes->displayWidth)
&& (pResList [i - 1].v == pContextAttributes->displayHeight)
&& i > 0
&& pFreqList[i] > pcontextInfo->freq << 16)
{
i--;
}
// set new refresh rate
pcontextInfo->freq = pFreqList [i] >> 16;
// reset pixel depth
pContextAttributes->displayBestDepth = pcontextInfo->pixelDepth;
pContextAttributes->backBufferBestDepth = pcontextInfo->pixelDepth;
}
else
return false;
}
return true;
}
#pragma mark -
// functions (public) -------------------------------------------------------
// GetDSpVersion
// Gets the current version of DSp
NumVersion GetDSpVersion (void)
{
NumVersion versionDSp = { 0, 0, 0, 0 };
OSStatus err = noErr;
if (!gDSpStarted)
err = StartDSp ();
if (noErr == err)
versionDSp = DSpGetVersion ();
return versionDSp;
}
// --------------------------------------------------------------------------
// StartDSp
// handles starting up DrawSprocket
OSStatus StartDSp (void)
{
OSStatus err = noErr;
if (!gDSpStarted)
{
// check for DSp
if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpStartup)
{
ReportError ("DSp not installed");
return kDSpNotInitializedErr;
}
else
{
err = DSpReportError (DSpStartup()); // start DSp
if (noErr != err)
return err;
else
gDSpStarted = true;
}
}
return err;
}
// --------------------------------------------------------------------------
// ShutdownDSpContext
// shuts down DrawSprocket
void ShutdownDSp (void)
{
if (gDSpStarted)
{
DSpShutdown ();
gDSpStarted = false;
}
}
#pragma mark -
// --------------------------------------------------------------------------
// GetDSpDrawable
// Just returns the front buffer
// Inputs: *pdspContext
// pcontextInfo: request and requirements for cotext and drawable
// Outputs: returns CGrafPtr thaat is front buffer of context
// if error: will return NULL
CGrafPtr GetDSpDrawable (DSpContextReference dspContext)
{
CGrafPtr pCGraf = NULL;
if (noErr == DSpReportError (DSpContext_GetFrontBuffer (dspContext, &pCGraf)))
return pCGraf;
else
return NULL;
}
// --------------------------------------------------------------------------
// BuildDSpContext
// contextInfo and tries to allocate the corresponding DSp context
// Inputs: hGD: GDHandle to device to look at
// pcontextInfo: request and requirements for cotext and drawable
// Outputs: *pdspContext as allocated
// pcontextInfo: allocated parameters
// if fail to allocate: pdspContext will be NULL
// if error: will return error pdspContext will be NULL
OSStatus BuildDSpContext (DSpContextReference* pdspContext, GDHandle hGD, GLint depthSizeSupport, pstructGLInfo pcontextInfo)
{
DSpContextAttributes theContextAttributes, foundAttributes;
DSpContextReference * pContextRefUnused;
SInt32 aFreqList [kMaxNumRes];
Point aResList [kMaxNumRes]; // list for resolution information
OSStatus err = noErr;
*pdspContext = 0;
// check for DSp
if (noErr != StartDSp ())
{
ReportError ("DSp startup failed");
return noErr; // already reported
}
// reserve contexts on other screens to prevent their selection
pContextRefUnused = ReserveUnusedDevices (hGD);
// build resolution list
BuildResolutionList (hGD, aResList, aFreqList);
// handle default pixel depths
if (pcontextInfo->pixelDepth == 0) // default
{
pcontextInfo->pixelDepth = (**(**hGD).gdPMap).pixelSize;
if (pcontextInfo->pixelDepth < 16)
pcontextInfo->pixelDepth = 16;
}
#ifdef kUseRAMCheck
if (noErr != DoDeviceRAMCheck (pcontextInfo, aResList, aFreqList, depthSizeSupport))
return err;
#endif // kUseRAMCheck
// Note: DSp < 1.7.3 REQUIRES the back buffer attributes even if only one buffer is required
BlockZero (&theContextAttributes, sizeof (DSpContextAttributes));
// memset(&theContextAttributes, 0, sizeof (DSpContextAttributes));
theContextAttributes.displayWidth = pcontextInfo->width;
theContextAttributes.displayHeight = pcontextInfo->height;
theContextAttributes.displayBestDepth = pcontextInfo->pixelDepth;
theContextAttributes.backBufferBestDepth = pcontextInfo->pixelDepth;
do
{
theContextAttributes.frequency = pcontextInfo->freq * 0x10000;
theContextAttributes.colorNeeds = kDSpColorNeeds_Require;
theContextAttributes.displayDepthMask = kDSpDepthMask_All;
theContextAttributes.backBufferDepthMask = kDSpDepthMask_All;
theContextAttributes.pageCount = 1; // only the front buffer is needed
err = DSpFindBestContext(&theContextAttributes, pdspContext);
if (noErr != err) // if we had any errors, reset for next try
if (!DoContextStepDown (pcontextInfo, &theContextAttributes, aResList, aFreqList))
break; // have run out of options
} while (err == kDSpContextNotFoundErr);
// check find best context errors
if (kDSpContextNotFoundErr == err)
{
*pdspContext = 0;
return noErr;
}
else if (noErr != err)
{
DSpReportError (err);
*pdspContext = 0;
return err;
}
err = DSpReportError (DSpContext_GetAttributes (*pdspContext, &foundAttributes));
if (noErr != err)
{
*pdspContext = 0;
return err;
}
// reset width and height to full screen and handle our own centering
// HWA will not correctly center less than full screen size contexts
theContextAttributes.displayWidth = foundAttributes.displayWidth;
theContextAttributes.displayHeight = foundAttributes.displayHeight;
theContextAttributes.pageCount = 1; // only the front buffer is needed
theContextAttributes.contextOptions = 0 | kDSpContextOption_DontSyncVBL; // no page flipping and no VBL sync needed
err = DSpReportError (DSpContext_Reserve(*pdspContext, &theContextAttributes )); // reserve our context
if (noErr != err)
{
*pdspContext = 0;
return err;
}
if (gNeedFade == true)
{
DSpReportError (DSpContext_CustomFadeGammaOut (NULL, NULL, fadeTicks));
gNeedFade = false;
}
err = DSpReportError (DSpContext_SetState (*pdspContext, kDSpContextState_Active)); // activate our context
if (noErr != err)
{
DSpContext_Release (*pdspContext);
DSpReportError (DSpContext_CustomFadeGammaIn (NULL, NULL, fadeTicks));
*pdspContext = 0;
return err;
}
FreeUnusedDevices (hGD, &pContextRefUnused);
if (!pcontextInfo->fSizeMust) // if we got whatever was available
{
// reset inputs to what was allocated (constrain aspect ratio)
// unless we ask for smaller, then leave the same
if ((pcontextInfo->width > foundAttributes.displayWidth) || (pcontextInfo->height > foundAttributes.displayHeight))
{
float hFactor = (float) pcontextInfo->width / (float) foundAttributes.displayWidth;
float vFactor = (float) pcontextInfo->height / (float) foundAttributes.displayHeight;
if (hFactor > vFactor)
{
pcontextInfo->width = (short) foundAttributes.displayWidth;
pcontextInfo->height /= hFactor;
}
else
{
pcontextInfo->height = (short) foundAttributes.displayHeight;
pcontextInfo->width /= vFactor;
}
}
}
// else still use inputs to allocate drawable
pcontextInfo->freq = foundAttributes.frequency / 0x10000;
pcontextInfo->pixelDepth = foundAttributes.displayBestDepth;
return noErr;
}
//-----------------------------------------------------------------------------------------------------------------------
// Deactivates and dumps context
void DestroyDSpContext (DSpContextReference* pdspContext)
{
if (gDSpStarted)
{
if (*pdspContext)
{
DSpReportError (DSpContext_SetState(*pdspContext, kDSpContextState_Inactive));
DSpReportError (DSpContext_CustomFadeGammaIn (NULL, NULL, fadeTicks));
DSpReportError (DSpContext_Release (*pdspContext));
*pdspContext = NULL;
}
}
}
#pragma mark -
//-----------------------------------------------------------------------------------------------------------------------
OSStatus DSpContext_CustomFadeGammaIn (DSpContextReference inContext, const RGBColor *fadeColor, long fadeTicks)
{
OSStatus err = noErr;
#ifndef kUseFades
#pragma unused (inContext, fadeColor, fadeTicks)
#else
RGBColor inZeroIntensityColor;
UInt32 currTick;
UInt16 step = (UInt16) (800 / fadeTicks);
long x, percent = 0;
if (gDSpStarted)
{
if (fadeTicks == 0)
fadeTicks = 1;
if (fadeColor == NULL)
{
inZeroIntensityColor.red = 0x0000;
inZeroIntensityColor.green = 0x0000;
inZeroIntensityColor.blue = 0x0000;
}
else
inZeroIntensityColor = *fadeColor;
currTick = TickCount ();
for (x = 1; x <= fadeTicks; x++)
{
percent = step * x / 8;
err = DSpContext_FadeGamma(inContext, percent, &inZeroIntensityColor);
if (err != noErr)
break;
while (currTick >= TickCount ()) {}
// SystemTask ();
currTick = TickCount ();
}
if (err == noErr)
err = DSpContext_FadeGamma(inContext, 100, &inZeroIntensityColor);
}
#endif // kUseFades
return err;
}
//-----------------------------------------------------------------------------------------------------------------------
OSStatus DSpContext_CustomFadeGammaOut (DSpContextReference inContext, const RGBColor *fadeColor, long fadeTicks )
{
OSStatus err = noErr;
#ifndef kUseFades
#pragma unused (inContext, fadeColor, fadeTicks)
#else
RGBColor inZeroIntensityColor;
UInt32 currTick;
UInt16 step = (UInt16) (800 / fadeTicks);
long x, percent = 0;
if (gDSpStarted)
{
if (fadeTicks == 0)
fadeTicks = 1; // ensure we do not have zero fade time
if (fadeColor == NULL)
{
inZeroIntensityColor.red = 0x0000;
inZeroIntensityColor.green = 0x0000;
inZeroIntensityColor.blue = 0x0000;
}
else
inZeroIntensityColor = *fadeColor;
currTick = TickCount ();
for (x = fadeTicks - 1; x >= 0; x--)
{
percent = step * x / 8;
err = DSpContext_FadeGamma(inContext, percent, &inZeroIntensityColor);
if (err != noErr)
break;
while (currTick >= TickCount ()) {}
// SystemTask ();
currTick = TickCount ();
}
}
#endif // kUseFades
return err;
}

View File

@ -0,0 +1,110 @@
/*
File: SetupDSp.h
Contains: Functions to enable building and destorying a DSp fullscreen context
Written by: Geoff Stahl (ggs)
Copyright: Copyright © 1999 Apple Computer, Inc., All Rights Reserved
Change History (most recent first):
<2> 3/26/01 ggs Add DSp version check and other items for full screen on X
<1> 1/19/01 ggs Initial re-add
<4> 1/26/00 ggs Add fade code back in, ensure NULL pointer/context checks are in
<3> 1/24/00 ggs Add C++ support
<2> 12/18/99 ggs Fix headers
<1> 11/28/99 ggs Initial add. Split of just DSp handling functions. Added total
device RAM checks, better step downs using actual supported
resolutions. Need to add user verify for contexts that require
it, integration of this in context step down, and a freq bit
field.
<1> 11/11/99 ggs Initial Add
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Usage notes:
// include control --------------------------------------------------
#ifndef SetupDSp_h
#define SetupDSp_h
// includes ---------------------------------------------------------
#ifdef __APPLE_CC__
#include <DrawSprocket/DrawSprocket.h>
#else
#include <DrawSprocket.h>
#endif
#include "Carbon_SetupGL.h"
#ifdef __cplusplus
extern "C" {
#endif
// structures (public) -----------------------------------------------
enum { fadeTicks = 10 };
// public function declarations -------------------------------------
NumVersion GetDSpVersion (void);
OSStatus StartDSp (void);
void ShutdownDSp (void);
CGrafPtr GetDSpDrawable (DSpContextReference dspContext);
OSStatus BuildDSpContext (DSpContextReference* pdspContext, GDHandle hGD, GLint depthSizeSupport, pstructGLInfo pcontextInfo);
void DestroyDSpContext (DSpContextReference* pdspContext);
OSStatus DSpContext_CustomFadeGammaOut (DSpContextReference inContext, const RGBColor *fadeColor, long fadeTicks);
OSStatus DSpContext_CustomFadeGammaIn (DSpContextReference inContext, const RGBColor *fadeColor, long fadeTicks);
extern Boolean gDSpStarted;
extern Boolean gNeedFade;
#ifdef __cplusplus
}
#endif
#endif // SetupDSp_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
/*
File: SetupGL.h
Contains: Functions to enable build and destory a GL fullscreen context
Written by: Geoff Stahl (ggs)
Copyright: Copyright © 1999 Apple Computer, Inc., All Rights Reserved
Change History (most recent first):
<2> 3/26/01 ggs Add DSp version check and other items for full screen on X
<1> 1/19/01 ggs Initial re-add
<7> 3/21/00 ggs Added windowed mode and clean up various implementation details
<6> 1/26/00 ggs Add fade code back in, ensure NULL pointer/context/drawable
checks are in, add Preflight
<5> 1/24/00 ggs Added get device num and get gdhandle from point routines, add
support for compiling from C++
<4> 12/18/99 ggs Fix headers
<3> 11/28/99 ggs Split out DSp and error handling. Added texture memory
considerations, assume VRAM is required if other than zero
<3> 11/12/99 ggs add pixel format and freq return
<2> 11/12/99 ggs 1.0 Interface complete
<1> 11/11/99 ggs Initial Add
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Usage notes:
// include control --------------------------------------------------
#ifndef SetupGL_h
#define SetupGL_h
// includes ---------------------------------------------------------
#ifdef __APPLE_CC__
#include <DrawSprocket/DrawSprocket.h>
#include <AGL/agl.h>
#else
#include <DrawSprocket.h>
#include <agl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
// structures (public) -----------------------------------------------
// structure for creating a fullscreen context
struct structGLInfo // storage for setup info
{
SInt16 width; // input: width of drawable (screen width in full screen mode), return: actual width allocated
SInt16 height; // input: height of drawable (screen height in full screen mode), return: actual height allocated
Boolean fSizeMust; // input: dspContext must be requested display size (ignored in window mode)
// if fSizeMust display size will not be stepped down to try to find a match,
// if display is stepped down aspect ratio will be maintained for returned size
UInt32 pixelDepth; // input: requested pixel depth
Boolean fDepthMust; // input: pixel depth must be set (if false then current depth will be used if able)
Boolean fFullscreen; // input: use DSp to get fullscreen? (or find full screen renderer)
// if fFullscreen, will search for full screen renderers first then use DSp for others
// unless a device is specified, in which case we will try there first
Boolean fAcceleratedMust; // input: must renderer be accelerated?
GLint aglAttributes[64]; // input: pixel format attributes always required (reset to what was actually allocated)
SInt32 VRAM; // input: minimum VRAM; output: actual (if successful otherwise input)
SInt32 textureRAM; // input: amount of texture RAM required on card; output: same (used in allcoation to ensure enough texture
AGLPixelFormat fmt; // input: none; output pixel format...
SInt32 freq; // input: frequency request for display; output: actual
};
typedef struct structGLInfo structGLInfo;
typedef struct structGLInfo * pstructGLInfo;
// structure for creating a context from a window
struct structGLWindowInfo // storage for setup info
{
Boolean fAcceleratedMust; // input: must renderer be accelerated?
GLint aglAttributes[64]; // input: pixel format attributes always required (reset to what was actually allocated)
SInt32 VRAM; // input: minimum VRAM; output: actual (if successful otherwise input)
SInt32 textureRAM; // input: amount of texture RAM required on card; output: same (used in allcoation to ensure enough texture
AGLPixelFormat fmt; // input: none; output pixel format...
Boolean fDraggable; // input: is window going to be dragable,
// if so renderer check (accel, VRAM, textureRAM) will look at all renderers vice just the current one
// if window is not dragable renderer check will either check the single device or short
// circuit to software if window spans multiple devices
// software renderer is consider to have unlimited VRAM, unlimited textureRAM and to not be accelerated
};
typedef struct structGLWindowInfo structGLWindowInfo;
typedef struct structGLWindowInfo * pstructGLWindowInfo;
// public function declarations -------------------------------------
// Runtime check to see if we are running on Mac OS X
// Inputs: None
// Returns: 0 if < Mac OS X or version number of Mac OS X (10.0 for GM)
UInt32 CheckMacOSX (void);
// Checks for presense of OpenGL and DSp (if required)
// Inputs: checkFullscreen: true if one wants to run fullscreen (which requires DrwSprocket currently)
// Ouputs: true if OpenGL is installed (and DrawSprocket if checkFullscreen is true
Boolean PreflightGL (Boolean checkFullscreen);
// Takes device # and geometry request and tries to build best context and drawable
// If requested device does not work, will start at first device and walk down devices
// looking for first one that satisfies requirments
// Devices are numbered in order that DMGetFirstScreenDevice/DMGetNextScreenDevice returns,
// fullscreen devices are numbered after this, but they will be searched first if fFullscreen == true,
// they will not be searched in the non-fullscreen case
// Inputs: *pnumDevice: -1: main device, 0: any device, other #: attempt that device first, then any device
// *pcontextInfo: request and requirements for cotext and drawable
// Outputs: *paglDraw, *paglContext and *pdspContext as allocated
// *pnumDevice to device number in list that was used
// *pcontextInfo: allocated parameters
// If fail to build context: paglDraw, paglContext and pdspContext will be NULL
// If fatal error: will return error and paglDraw, paglContext and pdspContext will be NULL
// Note: Errors can be generated internally when a specific device fails, this is normal and these
// will not be returned is a subsequent device succeeds
OSStatus BuildGL (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext,
short* pnumDevice, pstructGLInfo pcontextInfo, AGLContext aglShareContext);
// Destroys drawable and context
// Ouputs: *paglDraw, *paglContext and *pdspContext should be 0 on exit
OSStatus DestroyGL (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext, pstructGLInfo pcontextInfo);
// same as above except that it takes a window as input and attempts to build requested conext on that
OSStatus BuildGLFromWindow (WindowPtr pWindow, AGLContext* paglContext, pstructGLWindowInfo pcontextInfo, AGLContext aglShareContext);
// same as above but destorys a context that was associated with an existing window, window is left intacted
OSStatus DestroyGLFromWindow (AGLContext* paglContext, pstructGLWindowInfo pcontextInfo);
// Special suspend function to ensure the the GL window is hidden
OSStatus SuspendFullScreenGL (AGLDrawable aglDraw, AGLContext aglContext);
// Special resume function to ensure the the GL window is shown
OSStatus ResumeFullScreenGL (AGLDrawable aglDraw, AGLContext aglContext);
// Pauses gl to allow toolbox drawing
OSStatus PauseGL (AGLContext aglContext);
// resumes gl to allow gl drawing
OSStatus ResumeGL (AGLContext aglContext);
short FindGDHandleFromRect (Rect * pRect, GDHandle * phgdOnThisDevice);
short FindGDHandleFromWindow (WindowPtr pWindow, GDHandle * phgdOnThisDevice);
// returns the number of the device that the rect is mostly is on (i.e., where it is numerically in the search order)
short FindDeviceNumFromRect (Rect * rect);
#ifdef __cplusplus
}
#endif
#endif // SetupGL_h

1
MacGLide/Mac/SetupGL/Read Me Executable file

File diff suppressed because one or more lines are too long

BIN
MacGLide/MacGLide Normal file

Binary file not shown.

View File

@ -0,0 +1,63 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Debug switches
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
//#define OGL_DEBUG
//#define OGL_PROFILING
//#define OGL_RENDER
//#define OPENGL_DEBUG
//#define OGL_DEBUG_COORDS
//#define OGL_ALL
//#define OGL_DONE
//#define OGL_PARTDONE
//#define OGL_NOTDONE
//#define OGL_COMBINE
//#define OGL_CRITICAL
//#define OGL_FRAMEBUFFER
//#define OGL_UTEX
//#define OGL_UTEX_MEM
//#define OGL_OPTIMISE_DEBUG
//#define OGL_DEBUG_GLIDE_COORDS
//#define OGL_DEBUG_OPENGL_COORDS
#ifdef OGL_DEBUG_COORDS
#define OGL_DEBUG_GLIDE_COORDS
#define OGL_DEBUG_OPENGL_COORDS
#endif
#ifdef OGL_RENDER
#define OGL_DONE
#define OGL_PARTDONE
#define OGL_NOTDONE
#define OGL_DEBUG
#define OGL_CRITICAL
#define OGL_COMBINE
#define OGL_FRAMEBUFFER
#endif
#ifdef OGL_ALL
#define OGL_DONE
#define OGL_PARTDONE
#define OGL_NOTDONE
#define OGL_DEBUG
#define OGL_CRITICAL
#define OPENGL_DEBUG
#define OGL_PROFILING
#define OGL_UTEX
#define OGL_COMBINE
#define OGL_FRAMEBUFFER
#define OGL_DEBUG_GLIDE_COORDS
#define OGL_DEBUG_OPENGL_COORDS
#endif
#define OGL_STOP_ON_GL_ERROR

View File

@ -0,0 +1,452 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* OpenGL Extensions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "FormatConversion.h"
void Convert565to8888( FxU16 *Buffer1, FxU32 *Buffer2, FxU32 Pixels )
{
while ( Pixels )
{
*Buffer2++ = 0xFF000000 | // A
( (*Buffer1) & 0x001F ) << 19 | // B
( (*Buffer1) & 0x07E0 ) << 5 | // G
( (*Buffer1++) & 0xF800 ) >> 8; // R
Pixels--;
}
}
void Convert565Kto8888( FxU16 *Buffer1, FxU16 key, FxU32 *Buffer2, FxU32 Pixels )
{
while ( Pixels )
{
*Buffer2++ = ( ( (*Buffer1) == key) ? 0x00000000 : 0xFF000000 ) | // A
( (*Buffer1) & 0x001F ) << 19 | // B
( (*Buffer1) & 0x07E0 ) << 5 | // G
( (*Buffer1++) & 0xF800 ) >> 8; // R
Pixels--;
}
}
// This functions processes 2 pixels at a time, there is no problem in
// passing odd numbers or a number less than 2 for the pixels, but
// the buffers should be large enough
void Convert565to5551( FxU32 *Buffer1, FxU32 *Buffer2, int Pixels )
{
while ( Pixels > 0 )
{
*Buffer2++ = ( (*Buffer1) & 0xFFC0FFC0 ) |
( ( (*Buffer1++) & 0x001F001F ) << 1 ) |
0x00010001;
Pixels -= 2;
}
}
// This functions processes 2 pixels at a time, there is no problem in
// passing odd numbers or a number less than 2 for the pixels, but
// the buffers should be large enough
void Convert5551to565( FxU32 *Buffer1, FxU32 *Buffer2, int Pixels )
{
while ( Pixels > 0 )
{
*Buffer2++ = ( (*Buffer1) & 0xFFC0FFC0 ) |
( ( (*Buffer1++) & 0x003E003E ) >> 1 );
Pixels -= 2;
}
}
// This functions processes 2 pixels at a time, there is no problem in
// passing odd numbers or a number less than 2 for the pixels, but
// the buffers should be large enough
void Convert4444to4444special( FxU32 *Buffer1, FxU32 *Buffer2, int Pixels )
{
while ( Pixels > 0 )
{
*Buffer2++ = ( ( (*Buffer1) & 0x0FFF0FFF ) << 4 )|
( ( (*Buffer1++) & 0xF000F000 ) >> 12 );
Pixels -= 2;
}
}
void Convert1555to5551( FxU32 *Buffer1, FxU32 *Buffer2, int Pixels )
{
while ( Pixels > 0 )
{
*Buffer2++ = ( ( (*Buffer1) & 0x7FFF7FFF ) << 1 )|
( ( (*Buffer1++) & 0x80008000 ) >> 15 );
Pixels -= 2;
}
}
unsigned __int64 Mask565_5551_1 = 0xFFC0FFC0FFC0FFC0;
unsigned __int64 Mask565_5551_2 = 0x001F001F001F001F;
unsigned __int64 Mask565_5551_3 = 0x0001000100010001;
// This functions processes 4 pixels at a time, there is no problem in
// passing odd numbers or a number less than 4 for the pixels, but
// the buffers should be large enough
void MMXConvert565to5551( void *Src, void *Dst, int NumberOfPixels )
{
__asm
{
mov ecx, NumberOfPixels
mov eax, Src
shl ecx, 1
mov edx, Dst
movq mm6, [Mask565_5551_3]
movq mm5, [Mask565_5551_2]
movq mm4, [Mask565_5551_1]
align 16
copying:
movq mm0, [eax + ecx]
movq mm1, mm6
movq mm2, mm0
pand mm0, mm5
pand mm2, mm4
psllq mm0, 1
por mm1, mm2
por mm0, mm1
movq [edx + ecx], mm0
sub ecx, 8
jg copying
EMMS
}
}
// This functions processes 4 pixels at a time, there is no problem in
// passing odd numbers or a number less than 4 for the pixels, but
// the buffers should be large enough
void MMXConvert565Kto5551( void *Src, FxU32 key, void *Dst, int NumberOfPixels )
{
__asm
{
mov ecx, NumberOfPixels
mov eax, Src
shl ecx, 1
mov edx, Dst
movq mm6, [Mask565_5551_3]
movq mm5, [Mask565_5551_2]
movq mm4, [Mask565_5551_1]
movd mm7, key
movq mm0, mm7
psllq mm0, 16
por mm7, mm0
movq mm0, mm7
psllq mm0, 32
por mm7, mm0
align 16
copying:
movq mm3, mm7
movq mm0, [eax + ecx]
movq mm1, mm6
movq mm2, mm0
// Comparing
pcmpeqw mm3, mm0
pand mm0, mm5
pand mm2, mm4
psllq mm0, 1
por mm1, mm2
por mm0, mm1
// Applying key
pandn mm3, mm0
movq [edx + ecx], mm3
sub ecx, 8
jg copying
EMMS
}
}
unsigned __int64 Mask5551_565_1 = 0xFFC0FFC0FFC0FFC0;
unsigned __int64 Mask5551_565_2 = 0x003E003E003E003E;
// This functions processes 4 pixels at a time, there is no problem in
// passing odd numbers or a number less than 4 for the pixels, but
// the buffers should be large enough
void MMXConvert5551to565( void *Src, void *Dst, int NumberOfPixels )
{
__asm
{
mov ecx, NumberOfPixels
mov eax, Src
shl ecx, 1
mov edx, Dst
movq mm5, [Mask5551_565_2]
movq mm4, [Mask5551_565_1]
align 16
copying:
movq mm0, [eax + ecx]
movq mm2, mm0
pand mm0, mm5
pand mm2, mm4
psrlq mm0, 1
por mm0, mm2
movq [edx + ecx], mm0
sub ecx, 8
jg copying
EMMS
}
}
unsigned __int64 Mask4444_1 = 0x0FFF0FFF0FFF0FFF;
unsigned __int64 Mask4444_2 = 0xF000F000F000F000;
// This functions processes 4 pixels at a time, there is no problem in
// passing odd numbers or a number less than 4 for the pixels, but
// the buffers should be large enough
void MMXConvert4444to4444special( void *Src, void *Dst, int NumberOfPixels )
{
__asm
{
mov ecx, NumberOfPixels
mov eax, Src
shl ecx, 1
mov edx, Dst
movq mm7, [Mask4444_2]
movq mm6, [Mask4444_1]
align 16
copying:
movq mm0, [eax + ecx]
movq mm1, mm0
pand mm0, mm6
pand mm1, mm7
psllq mm0, 4
psrlq mm1, 12
por mm0, mm1
movq [edx + ecx], mm0
sub ecx, 8
jg copying
EMMS
}
}
unsigned __int64 Mask5551_1 = 0x7FFF7FFF7FFF7FFF;
unsigned __int64 Mask5551_2 = 0x8000800080008000;
// This functions processes 4 pixels at a time, there is no problem in
// passing odd numbers or a number less than 4 for the pixels, but
// the buffers should be large enough
void MMXConvert1555to5551( void *Src, void *Dst, int NumberOfPixels )
{
__asm
{
mov ecx, NumberOfPixels
mov eax, Src
shl ecx, 1
mov edx, Dst
movq mm7, [Mask4444_2]
movq mm6, [Mask4444_1]
align 16
copying:
movq mm0, [eax + ecx]
movq mm1, mm0
pand mm0, mm6
pand mm1, mm7
psllq mm0, 1
psrlq mm1, 15
por mm0, mm1
movq [edx + ecx], mm0
sub ecx, 8
jg copying
EMMS
}
}
FxU8 Mask565A[8] = { 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF };
FxU8 Mask565B[8] = { 0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8 };
FxU8 Mask565G[8] = { 0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07 };
FxU8 Mask565R[8] = { 0x1F,0x00,0x1F,0x00,0x1F,0x00,0x1F,0x00 };
void MMXConvert565to8888( void *Src, void *Dst, FxU32 NumberOfPixels )
{
// FxU16 entered is ARGB
// Has to be ABGR
__asm
{
MOVQ MM7, [Mask565A]
mov ECX, NumberOfPixels
MOVQ MM6, [Mask565B]
mov EAX, Src
MOVQ MM5, [Mask565G]
MOVQ MM4, [Mask565R]
mov EDX, Dst
copying:
MOVQ MM0, [EAX]
add EAX, 8
MOVQ MM2, MM0
MOVQ MM1, MM0
PAND MM0, MM4 // Mask R
PAND MM2, MM6 // Mask B
PSLLW MM0, 11 // Shift R
PAND MM1, MM5 // Mask G
PSRLW MM2, 8 // Shift B
MOVQ MM3, MM1
PSLLW MM1, 13
POR MM0, MM2
PSRLW MM3, 3
POR MM1, MM3
POR MM1, MM7
MOVQ MM2, MM0
PUNPCKHBW MM0, MM1
PUNPCKLBW MM2, MM1
// Storing Unpacked
MOVQ [EDX], MM2
add EDX, 16
MOVQ [EDX-8], MM0
sub ECX, 4
jg copying
EMMS
}
}
void ConvertA8toAP88( FxU8 *Buffer1, FxU16 *Buffer2, FxU32 Pixels )
{
while ( Pixels )
{
*Buffer2 = ( ( ( *Buffer1 ) << 8 ) | ( *Buffer1 ) );
Buffer1++;
Buffer2++;
Pixels--;
}
}
void Convert8332to8888( FxU16 *Buffer1, FxU32 *Buffer2, FxU32 Pixels )
{
static FxU32 R,
G,
B,
A;
for ( FxU32 i = Pixels; i > 0; i-- )
{
A = ( ( ( *Buffer1 ) >> 8 ) & 0xFF );
R = ( ( ( *Buffer1 ) >> 5 ) & 0x07 ) << 5;
G = ( ( ( *Buffer1 ) >> 2 ) & 0x07 ) << 5;
B = ( ( *Buffer1 ) & 0x03 ) << 6;
*Buffer2 = ( A << 24 ) | ( B << 16 ) | ( G << 8 ) | R;
Buffer1++;
Buffer2++;
}
}
void ConvertP8to8888( FxU8 *Buffer1, FxU32 *Buffer2, FxU32 Pixels, FxU32 *palette )
{
while ( Pixels-- )
{
*Buffer2++ = palette[ *Buffer1++ ];
}
}
void ConvertAI44toAP88( FxU8 *Buffer1, FxU16 *Buffer2, FxU32 Pixels )
{
for ( FxU32 i = Pixels; i > 0; i-- )
{
*Buffer2 = ( ( ( ( *Buffer1 ) & 0xF0 ) << 8 ) | ( ( ( *Buffer1 ) & 0x0F ) << 4 ) );
Buffer2++;
Buffer1++;
}
}
void ConvertAP88to8888( FxU16 *Buffer1, FxU32 *Buffer2, FxU32 Pixels, FxU32 *palette )
{
FxU32 RGB,
A;
for ( FxU32 i = Pixels; i > 0; i-- )
{
RGB = ( palette[ *Buffer1 & 0x00FF ] & 0x00FFFFFF );
A = *Buffer1 >> 8;
*Buffer2 = ( A << 24 ) | RGB;
Buffer1++;
Buffer2++;
}
}
void ConvertYIQto8888( FxU8 *in, FxU32 *out, FxU32 Pixels, GuNccTable *ncc )
{
LONG R;
LONG G;
LONG B;
for ( FxU32 i = Pixels; i > 0; i-- )
{
R = ncc->yRGB[ *in >> 4 ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 0 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 0 ];
G = ncc->yRGB[ *in >> 4 ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 1 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 1 ];
B = ncc->yRGB[ *in >> 4 ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 2 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 2 ];
R = ( ( R < 0 ) ? 0 : ( ( R > 255 ) ? 255 : R ) );
G = ( ( G < 0 ) ? 0 : ( ( G > 255 ) ? 255 : G ) );
B = ( ( B < 0 ) ? 0 : ( ( B > 255 ) ? 255 : B ) );
*out = ( R | ( G << 8 ) | ( B << 16 ) | 0xff000000 );
in++;
out++;
}
}
void ConvertAYIQto8888( FxU16 *in, FxU32 *out, FxU32 Pixels, GuNccTable *ncc)
{
LONG R;
LONG G;
LONG B;
for ( FxU32 i = Pixels; i > 0; i-- )
{
R = ncc->yRGB[ ( *in >> 4 ) & 0xf ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 0 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 0 ];
G = ncc->yRGB[ ( *in >> 4 ) & 0xf ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 1 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 1 ];
B = ncc->yRGB[ ( *in >> 4 ) & 0xf ] + ncc->iRGB[ ( *in >> 2 ) & 0x3 ][ 2 ]
+ ncc->qRGB[ ( *in ) & 0x3 ][ 2 ];
R = ( ( R < 0 ) ? 0 : ( ( R > 255 ) ? 255 : R ) );
G = ( ( G < 0 ) ? 0 : ( ( G > 255 ) ? 255 : G ) );
B = ( ( B < 0 ) ? 0 : ( ( B > 255 ) ? 255 : B ) );
*out = ( R | ( G << 8 ) | ( B << 16 ) | ( 0xff000000 & ( *in << 16 ) ) );
in++;
out++;
}
}
void SplitAP88( FxU16 *ap88, FxU8 *index, FxU8 *alpha, FxU32 pixels )
{
for ( FxU32 i = pixels; i > 0; i-- )
{
*alpha++ = ( *ap88 >> 8 );
*index++ = ( *ap88++ & 0xff );
}
}

View File

@ -0,0 +1,46 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* format conversion functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef __FORMAT_CONVERSION_H__
#define __FORMAT_CONVERSION_H__
// Introduced by MacGLide (available for Big Endian only)
void Convert565Kto5551(const FxU32* Buffer1, FxU32 key, FxU32* Buffer2, FxU32 NumberOfPixels );
void ConvertP8Kto8888(const FxU8 *Buffer1, FxU32 Key, FxU32 *Buffer2, FxU32 Pixels, FxU32 *palette );
// Litte Endian OpenGLide functions implemented in FormatConversion.cpp
// (Obsolete functions are commented out)
void Convert565to8888(const FxU16 *Buffer1, FxU32 *Buffer2, FxU32 Pixels );
void Convert565Kto8888(const FxU16 *Buffer1, FxU16 key, FxU32 *Buffer2, FxU32 Pixels );
void Convert565to5551(const FxU32 *Buffer1, FxU32 *Buffer2, FxU32 Pixels );
void Convert5551to565(const FxU32 *Buffer1, FxU32 *Buffer2, FxU32 Pixels );
void Convert4444to4444special(const FxU32 *Buffer1, FxU32 *Buffer2, int Pixels );
void Convert1555to5551(const FxU32 *Buffer1, FxU32 *Buffer2, int Pixels );
/*
void MMXConvert1555to5551(const void *Src, void *Dst, int NumberOfPixels );
void MMXConvert565to5551(const void *Src, void *Dst, int NumberOfPixels );
void MMXConvert565Kto5551(const void *Src, FxU32 key, void *Dst, int NumberOfPixels );
void MMXConvert5551to565(const void *Src, void *Dst, int NumberOfPixels );
void MMXConvert565to8888(const void *Src, void *Dst, FxU32 NumberOfPixels );
void MMXConvert4444to4444special(const void *Src, void *Dst, int NumberOfPixels );
*/
void ConvertA8toAP88(const FxU8 *Buffer1, FxU16 *Buffer2, FxU32 Pixels );
void ConvertAI44toAP88(const FxU8 *Buffer1, FxU16 *Buffer2, FxU32 Pixels );
void Convert8332to8888(const FxU16 *Buffer1, FxU32 *Buffer2, FxU32 Pixels );
void ConvertP8to8888(const FxU8 *Buffer1, FxU32 *Buffer2, FxU32 Pixels, FxU32 *palette );
void ConvertAP88to8888(const FxU16 *Buffer1, FxU32 *Buffer2, FxU32 Pixels, FxU32 *palette );
void ConvertYIQto8888(const FxU8 *in, FxU32 *out, FxU32 Pixels, GuNccTable *ncc );
void ConvertAYIQto8888(const FxU16 *in, FxU32 *out, FxU32 Pixels, GuNccTable *ncc );
void SplitAP88(const FxU16 *ap88, FxU8 *index, FxU8 *alpha, FxU32 pixels );
void Convert1555Kto8888(const FxU16* Buffer1, FxU16 Key, FxU32* Buffer2, FxU32 Pixels);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* framebuffer emulation
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
class Framebuffer
{
public:
Framebuffer();
~Framebuffer();
/*
enum Format
{
None = -1,
USHORT_565 = GL_UNSIGNED_SHORT_5_6_5,
USHORT_5551_REV = GL_UNSIGNED_SHORT_1_5_5_5_REV,
UBYTE_8888
};
*/
static const int MaxTiles = 12;
struct tilesize {GLint y; GLint x[MaxTiles];};
public:
bool initialise_buffers(BufferStruct* framebuffer, BufferStruct* texbuffer, FxU32 width, FxU32 height, const tilesize* tilesizetable, bool use_client_storage);
bool initialise_buffers(BufferStruct* framebuffer, BufferStruct* texbuffer, FxU32 width, FxU32 height, FxU32 x_tile, FxU32 y_tile, bool use_client_storage);
void free_buffers();
void initialise_format(GrLfbWriteMode_t format);
bool begin_write();
bool end_write();
bool end_write(FxU32 alpha);
bool end_write(FxU32 alpha, GLfloat depth, bool pixelpipeline);
bool end_write_opaque();
protected:
void Clear();
bool draw(const tilesize* tilesizetable, bool pixelpipeline);
void set_gl_state(bool pixelpipeline);
void restore_gl_state(bool pixelpipeline);
inline bool createTextureData(FxU32* texbuffer, FxU32 x, FxU32 y, FxU32 x_step, FxU32 y_step);
inline bool Convert565Kto8888(FxU16* buffer1, FxU32* buffer2, register FxU32 width, register FxU32 height, register FxU32 stride);
inline bool Convert1555Kto8888(FxU16* buffer1, register FxU32* buffer2, FxU32 register width, register FxU32 height, register FxU32 stride);
inline bool ConvertARGB8888Kto8888(FxU32* buffer1, register FxU32* buffer2, FxU32 register width, register FxU32 height, register FxU32 stride);
static const int m_max_client_storage_textures = 256;
GLuint m_tex_name[m_max_client_storage_textures];
bool m_use_client_storage;
bool m_must_clear_buffer;
GrOriginLocation_t m_origin;
// GrLfbWriteMode_t m_writemode;
GLint m_glInternalFormat;
GLint m_glFormat;
GLint m_glType;
FxU16 m_ChromaKey;
bool m_format_valid;
BufferStruct* m_framebuffer;
BufferStruct* m_texbuffer;
// FxU16* m_framebuffer;
// void* m_texbuffer;
FxU32 m_width;
FxU32 m_height;
GLint m_x_step_start;
GLint m_y_step_start;
GLint m_x_step_start_opaque;
GLint m_y_step_start_opaque;
tilesize m_tilesizes[MaxTiles];
const tilesize* m_custom_tilesizes;
GLfloat m_glDepth;
FxU32 m_glAlpha;
// Pixelpipeline
bool m_bRestoreColorCombine;
bool m_bRestoreAlphaCombine;
};

View File

@ -0,0 +1,395 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Color and Alpha CombineEnv tables
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GLColorAlphaCombineEnvTables.h"
// Additional internal combine functions for reduced terms
// Some of them are really senceless because they're clamped
// to {0.0, 1.0} anyway but they have been defined for complecity.
#define GR_COMBINE_FUNCTION_OTHER 0x11
#define GR_COMBINE_FUNCTION_MINUS_LOCAL 0x12
#define GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL 0x13
#define GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL_ALPHA 0x14
#define GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL 0x15
#define GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x16
#define GR_COMBINE_FUNCTION_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x17
// GL equivalents for Glide color combine functions
const CombineFunction ColorCombineFunctionsEnvCombineARB[25] =
{
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x00 GR_COMBINE_FUNCTION_ZERO
{{{CF_Replace ,{CFARG_Local ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x01 GR_COMBINE_FUNCTION_LOCAL
{{{CF_Replace ,{CFARG_LocalAlpha,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x02 GR_COMBINE_FUNCTION_LOCAL_ALPHA
{{{CF_Modulate ,{CFARG_Factor ,CFARG_Other ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x03 GR_COMBINE_FUNCTION_SCALE_OTHER
{{{CF_Modulate ,{CFARG_Factor ,CFARG_Other ,CFARG_None }},{CF_Add ,{CFARG_Previous ,CFARG_Local ,CFARG_None}}}}, // 0x04 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
{{{CF_Modulate ,{CFARG_Factor ,CFARG_Other ,CFARG_None }},{CF_Add ,{CFARG_Previous ,CFARG_LocalAlpha,CFARG_None}}}}, // 0x05 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA
{{{CF_Substract,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Modulate ,{CFARG_Previous ,CFARG_Factor ,CFARG_None}}}}, // 0x06 GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL
{{{CF_Blend ,{CFARG_Other ,CFARG_Local ,CFARG_Factor}},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x07 GR_COMBINE_FUNCTION_BLEND
{{{CF_Substract,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Modulate ,{CFARG_Factor ,CFARG_Previous ,CFARG_None}}}}, // 0x08 GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA // not correct, needs CF_ModulateAdd
{{{CF_Modulate ,{CFARG_Factor ,CFARG_Local ,CFARG_None }},{CF_Substract ,{CFARG_Local ,CFARG_Previous ,CFARG_None}}}}, // 0x09 GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0a dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0b dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0c dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0d dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0e dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0f dummy
{{{CF_Modulate ,{CFARG_Factor ,CFARG_Local ,CFARG_None }},{CF_Substract ,{CFARG_LocalAlpha,CFARG_Previous ,CFARG_None}}}}, // 0x10 GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA
// Additional functions for reducing the above terms if factor == GR_COMBINE_FACTOR_ZERO
// Additional functions for reducing the above terms if factor == GR_COMBINE_FACTOR_ONE
{{{CF_Replace ,{CFARG_Other ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x011 GR_COMBINE_FUNCTION_OTHER
{{{CF_Substract,{CFARG_Constant ,CFARG_Constant ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Local ,CFARG_None}}}}, // 0x12 GR_COMBINE_FUNCTION_MINUS_LOCAL // clamped to 0.0
{{{CF_Add ,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x13 GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL
{{{CF_Add ,{CFARG_Other ,CFARG_LocalAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x14 GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL_ALPHA
{{{CF_Substract,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x15 GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL
{{{CF_Substract,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Add ,{CFARG_Previous ,CFARG_LocalAlpha,CFARG_None}}}}, // 0x16 GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA
{{{CF_Substract,{CFARG_LocalAlpha,CFARG_Local ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}} // 0x17 GR_COMBINE_FUNCTION_MINUS_LOCAL_ADD_LOCAL_ALPHA
};
const CombineFunction ColorCombineFunctionsEnvCombine3ATI[25] =
{
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x00 GR_COMBINE_FUNCTION_ZERO
{{{CF_Replace ,{CFARG_Local ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x01 GR_COMBINE_FUNCTION_LOCAL
{{{CF_Replace ,{CFARG_LocalAlpha,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x02 GR_COMBINE_FUNCTION_LOCAL_ALPHA
{{{CF_Modulate ,{CFARG_Factor ,CFARG_Other ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x03 GR_COMBINE_FUNCTION_SCALE_OTHER
{{{CF_ModulateAdd,{CFARG_Factor ,CFARG_Local ,CFARG_Other }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x04 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
{{{CF_ModulateAdd,{CFARG_Factor ,CFARG_LocalAlpha,CFARG_Other }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x05 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA
{{{CF_Substract ,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Modulate ,{CFARG_Previous ,CFARG_Factor ,CFARG_None}}}}, // 0x06 GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL
// {{{CF_Blend ,{CFARG_Other ,CFARG_Local ,CFARG_Factor}},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x07 GR_COMBINE_FUNCTION_BLEND // psychedelic colors on G5 with ATI9600XT
{{{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None }},{CF_Blend ,{CFARG_Other ,CFARG_Local ,CFARG_Factor}}}}, // 0x07 GR_COMBINE_FUNCTION_BLEND // works (don't ask me why)
{{{CF_Substract ,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_ModulateAdd,{CFARG_Factor ,CFARG_LocalAlpha,CFARG_Previous}}}}, // 0x08 GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA
{{{CF_Modulate ,{CFARG_Factor ,CFARG_Local ,CFARG_None }},{CF_Substract ,{CFARG_Local ,CFARG_Previous ,CFARG_None}}}}, // 0x09 GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0a dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0b dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0c dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0d dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0e dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0f dummy
{{{CF_Modulate ,{CFARG_Factor ,CFARG_Local ,CFARG_None }},{CF_Substract ,{CFARG_LocalAlpha,CFARG_Previous ,CFARG_None}}}}, // 0x10 GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA
// Additional functions for reducing the above terms if factor == GR_COMBINE_FACTOR_ZERO
// Additional functions for reducing the above terms if factor == GR_COMBINE_FACTOR_ONE
{{{CF_Replace ,{CFARG_Other ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x011 GR_COMBINE_FUNCTION_OTHER
{{{CF_Substract ,{CFARG_Zero ,CFARG_Local ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x12 GR_COMBINE_FUNCTION_MINUS_LOCAL // clamped to 0.0
{{{CF_Add ,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x13 GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL
{{{CF_Add ,{CFARG_Other ,CFARG_LocalAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x14 GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL_ALPHA
{{{CF_Substract ,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x15 GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL
{{{CF_Substract ,{CFARG_Other ,CFARG_Local ,CFARG_None }},{CF_Add ,{CFARG_Previous ,CFARG_LocalAlpha,CFARG_None}}}}, // 0x16 GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA
{{{CF_Substract ,{CFARG_LocalAlpha,CFARG_Local ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}} // 0x17 GR_COMBINE_FUNCTION_MINUS_LOCAL_ADD_LOCAL_ALPHA
};
// Mapping for reducing combine functions if factor == GR_COMBINE_FACTOR_ZERO
const CombineReduceTerm ColorCombineFunctionsFactorZero[0x11] =
{
/* GR_COMBINE_FUNCTION_ZERO */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_LOCAL */ {GR_COMBINE_FUNCTION_LOCAL},
/* GR_COMBINE_FUNCTION_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_OTHER */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL */ {GR_COMBINE_FUNCTION_LOCAL},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_BLEND */ {GR_COMBINE_FUNCTION_LOCAL},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL */ {GR_COMBINE_FUNCTION_LOCAL},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA}
};
// Mapping for reducing combine functions if factor == GR_COMBINE_FACTOR_ONE
const CombineReduceTerm ColorCombineFunctionsFactorOne[0x11] =
{
/* GR_COMBINE_FUNCTION_ZERO */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_LOCAL */ {GR_COMBINE_FUNCTION_LOCAL},
/* GR_COMBINE_FUNCTION_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_OTHER */ {GR_COMBINE_FUNCTION_OTHER},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL */ {GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL */ {GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL},
/* GR_COMBINE_FUNCTION_BLEND */ {GR_COMBINE_FUNCTION_OTHER},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_MINUS_LOCAL_ADD_LOCAL_ALPHA}
};
const CombineArgument ColorCombineFactors[14] =
{
{CFARG_Constant,GL_SRC_COLOR}, // 0x00 GR_COMBINE_FACTOR_ZERO
{CFARG_Local,0}, // 0x01 GR_COMBINE_FACTOR_LOCAL
{CFARG_OtherAlpha,0}, // 0x02 GR_COMBINE_FACTOR_OTHER_ALPHA
{CFARG_LocalAlpha,0}, // 0x03 GR_COMBINE_FACTOR_LOCAL_ALPHA
{CFARG_Texture,GL_SRC_ALPHA}, // 0x04 GR_COMBINE_FACTOR_TEXTURE_ALPHA GR_COMBINE_FACTOR_DETAIL_FACTOR
{CFARG_Texture,GL_SRC_COLOR}, // 0x05 GR_COMBINE_FACTOR_TEXTURE_RGB GR_COMBINE_FACTOR_LOD_FRACTION (unused)
{CFARG_Local,0}, // 0x06 placeholder
{CFARG_Local,0}, // 0x07 placeholder
{CFARG_Constant,GL_SRC_COLOR}, // 0x08 GR_COMBINE_FACTOR_ONE
{CFARG_Local,0}, // 0x09 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
{CFARG_OtherAlpha,0}, // 0x0a GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA
{CFARG_LocalAlpha,0}, // 0x0b GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA
{CFARG_Texture,GL_ONE_MINUS_SRC_ALPHA}, // 0x0c GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR
{CFARG_Texture,GL_ONE_MINUS_SRC_ALPHA} // 0x0d GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION (unused)
};
const CombineArgument ColorCombineFactorsInverted[14] =
{
{CFARG_Constant,GL_SRC_COLOR}, // 0x00 GR_COMBINE_FACTOR_ZERO
{CFARG_Local,0}, // 0x01 GR_COMBINE_FACTOR_LOCAL
{CFARG_OtherAlpha,0}, // 0x02 GR_COMBINE_FACTOR_OTHER_ALPHA
{CFARG_LocalAlpha,0}, // 0x03 GR_COMBINE_FACTOR_LOCAL_ALPHA
{CFARG_Texture,GL_ONE_MINUS_SRC_ALPHA}, // 0x04 GR_COMBINE_FACTOR_TEXTURE_ALPHA GR_COMBINE_FACTOR_DETAIL_FACTOR
{CFARG_Texture,GL_ONE_MINUS_SRC_COLOR}, // 0x05 GR_COMBINE_FACTOR_TEXTURE_RGB GR_COMBINE_FACTOR_LOD_FRACTION (unused)
{CFARG_Local,0}, // 0x06 placeholder
{CFARG_Local,0}, // 0x07 placeholder
{CFARG_Constant,GL_SRC_COLOR}, // 0x08 GR_COMBINE_FACTOR_ONE
{CFARG_Local,0}, // 0x09 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
{CFARG_OtherAlpha,0}, // 0x0a GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA
{CFARG_LocalAlpha,0}, // 0x0b GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA
{CFARG_Texture,GL_SRC_ALPHA}, // 0x0c GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR
{CFARG_Texture,GL_SRC_ALPHA} // 0x0d GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION (unused)
};
const CombineArgument ColorCombineLocals[4] =
{
{GL_PRIMARY_COLOR_EXT,GL_SRC_COLOR}, // 0x00 GR_COMBINE_LOCAL_ITERATED
{GL_CONSTANT_EXT,GL_SRC_COLOR}, // 0x01 GR_COMBINE_LOCAL_CONSTANT GR_COMBINE_LOCAL_NONE
{GL_CONSTANT_EXT,GL_SRC_COLOR}, // 0x02 unused
{GL_TEXTURE,GL_SRC_COLOR} // 0x03 GR_COMBINE_LOCAL_PIXELPIPELINE - needed to support the framebuffer
};
const CombineArgument ColorCombineOthers[4] =
{
{GL_PRIMARY_COLOR_EXT,GL_SRC_COLOR}, // 0x00 GR_COMBINE_OTHER_ITERATED
{GL_TEXTURE,GL_SRC_COLOR}, // 0x01 GR_COMBINE_OTHER_TEXTURE
{GL_CONSTANT_EXT,GL_SRC_COLOR}, // 0x02 GR_COMBINE_OTHER_CONSTANT GR_COMBINE_OTHER_NONE
{GL_TEXTURE,GL_SRC_COLOR} // 0x03 GR_COMBINE_OTHER_PIXELPIPELINE - needed to support the framebuffer
};
const CombineArgument ColorCombineOthersInverted[4] =
{
{GL_PRIMARY_COLOR_EXT,GL_SRC_COLOR}, // 0x00 GR_COMBINE_OTHER_ITERATED
{GL_TEXTURE,GL_ONE_MINUS_SRC_COLOR}, // 0x01 GR_COMBINE_OTHER_TEXTURE
{GL_CONSTANT_EXT,GL_SRC_COLOR}, // 0x02 GR_COMBINE_OTHER_CONSTANT GR_COMBINE_OTHER_NONE
{GL_TEXTURE,GL_SRC_COLOR} // 0x03 GR_COMBINE_OTHER_PIXELPIPELINE - needed to support the framebuffer
};
// GL equivalents for Glide alpha combine functions
const CombineFunction AlphaCombineFunctionsEnvCombineARB[25] =
{
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x00 GR_COMBINE_FUNCTION_ZERO
{{{CF_Replace ,{CFARG_LocalAlpha ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x01 GR_COMBINE_FUNCTION_LOCAL
{{{CF_Replace ,{CFARG_LocalAlpha ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x02 GR_COMBINE_FUNCTION_LOCAL_ALPHA
{{{CF_Modulate ,{CFARG_Factor ,CFARG_OtherAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x03 GR_COMBINE_FUNCTION_SCALE_OTHER
{{{CF_Modulate ,{CFARG_Factor ,CFARG_OtherAlpha,CFARG_None }},{CF_Add ,{CFARG_Previous ,CFARG_LocalAlpha ,CFARG_None}}}}, // 0x04 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
{{{CF_Modulate ,{CFARG_Factor ,CFARG_OtherAlpha,CFARG_None }},{CF_Add ,{CFARG_Previous ,CFARG_LocalAlpha ,CFARG_None}}}}, // 0x05 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA
{{{CF_Substract,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_Modulate ,{CFARG_Previous ,CFARG_Factor ,CFARG_None}}}}, // 0x06 GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL
{{{CF_Blend ,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_Factor }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x07 GR_COMBINE_FUNCTION_BLEND
{{{CF_Substract,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_Modulate ,{CFARG_Factor ,CFARG_Previous ,CFARG_None}}}}, // 0x08 GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA // not correct, needs CF_ModulateAdd
{{{CF_Modulate ,{CFARG_Factor ,CFARG_LocalAlpha,CFARG_None }},{CF_Substract ,{CFARG_LocalAlpha ,CFARG_Previous ,CFARG_None}}}}, // 0x09 GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0a dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0b dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0c dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0d dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0e dummy
{{{CF_Replace ,{CFARG_Constant ,CFARG_None ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_Constant ,CFARG_None}}}}, // 0x0f dummy
{{{CF_Modulate ,{CFARG_Factor ,CFARG_LocalAlpha,CFARG_None }},{CF_Substract ,{CFARG_LocalAlpha ,CFARG_Previous ,CFARG_None}}}}, // 0x10 GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA
// Additional functions for reducing the above terms if factor == GR_COMBINE_FACTOR_ZERO
// Additional functions for reducing the above terms if factor == GR_COMBINE_FACTOR_ONE
{{{CF_Replace ,{CFARG_OtherAlpha ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x011 GR_COMBINE_FUNCTION_OTHER
{{{CF_Substract,{CFARG_Constant ,CFARG_Constant ,CFARG_None }},{CF_Substract ,{CFARG_Previous ,CFARG_LocalAlpha,CFARG_None}}}}, // 0x12 GR_COMBINE_FUNCTION_MINUS_LOCAL
{{{CF_Add ,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x13 GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL
{{{CF_Add ,{CFARG_OtherAlpha ,CFARG_OtherAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x14 GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL_ALPHA
{{{CF_Substract,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x15 GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL
{{{CF_Replace ,{CFARG_OtherAlpha ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x16 GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA
{{{CF_Substract,{CFARG_LocalAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}} // 0x17 GR_COMBINE_FUNCTION_MINUS_LOCAL_ADD_LOCAL_ALPHA
};
// GL equivalents for Glide alpha combine functions
const CombineFunction AlphaCombineFunctionsEnvCombine3ATI[25] =
{
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x00 GR_COMBINE_FUNCTION_ZERO
{{{CF_Replace ,{CFARG_LocalAlpha,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x01 GR_COMBINE_FUNCTION_LOCAL
{{{CF_Replace ,{CFARG_LocalAlpha,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x02 GR_COMBINE_FUNCTION_LOCAL_ALPHA
{{{CF_Modulate ,{CFARG_Factor ,CFARG_OtherAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x03 GR_COMBINE_FUNCTION_SCALE_OTHER
{{{CF_ModulateAdd,{CFARG_Factor ,CFARG_LocalAlpha,CFARG_OtherAlpha}},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x04 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
{{{CF_ModulateAdd,{CFARG_Factor ,CFARG_LocalAlpha,CFARG_OtherAlpha}},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x05 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA
{{{CF_Substract ,{CFARG_OtherAlpha,CFARG_LocalAlpha,CFARG_None }},{CF_Modulate ,{CFARG_Previous ,CFARG_Factor ,CFARG_None}}}}, // 0x06 GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL
// {{{CF_Blend ,{CFARG_OtherAlpha,CFARG_LocalAlpha,CFARG_Factor }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x07 GR_COMBINE_FUNCTION_BLEND // psychedelic colors on G5 with ATI9600XT
{{{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None }},{CF_Blend ,{CFARG_OtherAlpha ,CFARG_LocalAlpha ,CFARG_Factor }}}}, // 0x07 GR_COMBINE_FUNCTION_BLEND // works (don't ask me why)
{{{CF_Substract ,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_ModulateAdd,{CFARG_Factor ,CFARG_LocalAlpha ,CFARG_Previous}}}}, // 0x08 GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA
{{{CF_Modulate ,{CFARG_Factor ,CFARG_LocalAlpha,CFARG_None }},{CF_Substract,{CFARG_LocalAlpha ,CFARG_Previous ,CFARG_None}}}}, // 0x09 GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0a dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0b dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0c dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0d dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0e dummy
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x0f dummy
{{{CF_Modulate ,{CFARG_Factor ,CFARG_LocalAlpha,CFARG_None }},{CF_Substract ,{CFARG_LocalAlpha ,CFARG_Previous ,CFARG_None}}}}, // 0x10 GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA
// Additional functions for reducing the above terms if factor == GR_COMBINE_FACTOR_ZERO
// Additional functions for reducing the above terms if factor == GR_COMBINE_FACTOR_ONE
{{{CF_Replace ,{CFARG_OtherAlpha ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x011 GR_COMBINE_FUNCTION_OTHER
{{{CF_Substract,{CFARG_Zero ,CFARG_LocalAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x12 GR_COMBINE_FUNCTION_MINUS_LOCAL
{{{CF_Add ,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x13 GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL
{{{CF_Add ,{CFARG_OtherAlpha ,CFARG_OtherAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x14 GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL_ALPHA
{{{CF_Substract,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}}, // 0x15 GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL
{{{CF_Substract,{CFARG_OtherAlpha ,CFARG_LocalAlpha,CFARG_None }},{CF_Add ,{CFARG_Previous ,CFARG_LocalAlpha,CFARG_None}}}}, // 0x16 GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA
{{{CF_Replace ,{CFARG_Zero ,CFARG_None ,CFARG_None }},{CF_Unused ,{CFARG_None ,CFARG_None ,CFARG_None}}}} // 0x17 GR_COMBINE_FUNCTION_MINUS_LOCAL_ADD_LOCAL_ALPHA
};
// Mapping for reducing combine functions if factor == GR_COMBINE_FACTOR_ZERO
const CombineReduceTerm AlphaCombineFunctionsFactorZero[0x11] =
{
/* GR_COMBINE_FUNCTION_ZERO */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_LOCAL */ {GR_COMBINE_FUNCTION_LOCAL},
/* GR_COMBINE_FUNCTION_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_OTHER */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL */ {GR_COMBINE_FUNCTION_LOCAL},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_BLEND */ {GR_COMBINE_FUNCTION_LOCAL},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL */ {GR_COMBINE_FUNCTION_LOCAL},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA}
};
// Mapping for reducing combine functions if factor == GR_COMBINE_FACTOR_ONE
const CombineReduceTerm AlphaCombineFunctionsFactorOne[0x11] =
{
/* GR_COMBINE_FUNCTION_ZERO */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_LOCAL */ {GR_COMBINE_FUNCTION_LOCAL},
/* GR_COMBINE_FUNCTION_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_OTHER */ {GR_COMBINE_FUNCTION_OTHER},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL */ {GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_OTHER_ADD_LOCAL_ALPHA},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL */ {GR_COMBINE_FUNCTION_OTHER_MINUS_LOCAL},
/* GR_COMBINE_FUNCTION_BLEND */ {GR_COMBINE_FUNCTION_OTHER},
/* GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_OTHER},
/* GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* dummy */ {GR_COMBINE_FUNCTION_ZERO},
/* GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA */ {GR_COMBINE_FUNCTION_ZERO}
};
const CombineArgument AlphaCombineFactors[14] =
{
{CFARG_Constant,GL_SRC_ALPHA}, // 0x00 GR_COMBINE_FACTOR_ZERO
{CFARG_LocalAlpha,0}, // 0x01 GR_COMBINE_FACTOR_LOCAL
{CFARG_OtherAlpha,0}, // 0x02 GR_COMBINE_FACTOR_OTHER_ALPHA
{CFARG_LocalAlpha,0}, // 0x03 GR_COMBINE_FACTOR_LOCAL_ALPHA
{CFARG_Texture,GL_SRC_ALPHA}, // 0x04 GR_COMBINE_FACTOR_TEXTURE_ALPHA GR_COMBINE_FACTOR_DETAIL_FACTOR
{CFARG_Texture,GL_SRC_COLOR}, // 0x05 GR_COMBINE_FACTOR_TEXTURE_RGB GR_COMBINE_FACTOR_LOD_FRACTION (unused)
{CFARG_LocalAlpha,0}, // 0x06 placeholder
{CFARG_LocalAlpha,0}, // 0x07 placeholder
{CFARG_Constant,GL_SRC_ALPHA}, // 0x08 GR_COMBINE_FACTOR_ONE
{CFARG_LocalAlpha,0}, // 0x09 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
{CFARG_OtherAlpha,0}, // 0x0a GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA
{CFARG_LocalAlpha,0}, // 0x0b GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA
{CFARG_Texture,GL_ONE_MINUS_SRC_ALPHA}, // 0x0c GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR
{CFARG_Texture,GL_ONE_MINUS_SRC_ALPHA} // 0x0d GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION (unused)
};
const CombineArgument AlphaCombineFactorsInverted[14] =
{
{CFARG_Constant,GL_SRC_ALPHA}, // 0x00 GR_COMBINE_FACTOR_ZERO
{CFARG_LocalAlpha,0}, // 0x01 GR_COMBINE_FACTOR_LOCAL
{CFARG_OtherAlpha,0}, // 0x02 GR_COMBINE_FACTOR_OTHER_ALPHA
{CFARG_LocalAlpha,0}, // 0x03 GR_COMBINE_FACTOR_LOCAL_ALPHA
{CFARG_Texture,GL_ONE_MINUS_SRC_ALPHA}, // 0x04 GR_COMBINE_FACTOR_TEXTURE_ALPHA GR_COMBINE_FACTOR_DETAIL_FACTOR
{CFARG_Texture,GL_ONE_MINUS_SRC_COLOR}, // 0x05 GR_COMBINE_FACTOR_TEXTURE_RGB GR_COMBINE_FACTOR_LOD_FRACTION (unused)
{CFARG_LocalAlpha,0}, // 0x06 placeholder
{CFARG_LocalAlpha,0}, // 0x07 placeholder
{CFARG_Constant,GL_SRC_ALPHA}, // 0x08 GR_COMBINE_FACTOR_ONE
{CFARG_LocalAlpha,0}, // 0x09 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
{CFARG_OtherAlpha,0}, // 0x0a GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA
{CFARG_LocalAlpha,0}, // 0x0b GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA
{CFARG_Texture,GL_SRC_ALPHA}, // 0x0c GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR
{CFARG_Texture,GL_SRC_ALPHA} // 0x0d GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION (unused)
};
const CombineArgument AlphaCombineLocals[4] =
{
{GL_PRIMARY_COLOR_EXT,GL_SRC_ALPHA}, // 0x00 GR_COMBINE_LOCAL_ITERATED
{GL_CONSTANT_EXT,GL_SRC_ALPHA}, // 0x01 GR_COMBINE_LOCAL_CONSTANT GR_COMBINE_LOCAL_NONE
{GL_PRIMARY_COLOR_EXT,GL_SRC_ALPHA}, // 0x02 GR_COMBINE_LOCAL_DEPTH
{GL_TEXTURE,GL_SRC_ALPHA} // 0x03 GR_COMBINE_LOCAL_PIXELPIPELINE - needed to support the framebuffer
};
const CombineArgument AlphaCombineOthers[4] =
{
{GL_PRIMARY_COLOR_EXT,GL_SRC_ALPHA}, // 0x00 GR_COMBINE_OTHER_ITERATED
{GL_TEXTURE,GL_SRC_ALPHA}, // 0x01 GR_COMBINE_OTHER_TEXTURE
{GL_CONSTANT_EXT,GL_SRC_ALPHA}, // 0x02 GR_COMBINE_OTHER_CONSTANT GR_COMBINE_OTHER_NONE
{GL_TEXTURE,GL_SRC_ALPHA} // 0x03 GR_COMBINE_OTHER_PIXELPIPELINE - needed to support the framebuffer
};
const CombineArgument AlphaCombineOthersInverted[4] =
{
{GL_PRIMARY_COLOR_EXT,GL_SRC_ALPHA}, // 0x00 GR_COMBINE_OTHER_ITERATED
{GL_TEXTURE,GL_ONE_MINUS_SRC_ALPHA}, // 0x01 GR_COMBINE_OTHER_TEXTURE
{GL_CONSTANT_EXT,GL_SRC_ALPHA}, // 0x02 GR_COMBINE_OTHER_CONSTANT GR_COMBINE_OTHER_NONE
{GL_TEXTURE,GL_SRC_ALPHA} // 0x03 GR_COMBINE_OTHER_PIXELPIPELINE - needed to support the framebuffer
};

View File

@ -0,0 +1,84 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Color and Alpha CombineEnv tables
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
enum CombineFunctionValue
{
CF_Unused = 0,
CF_Replace = GL_REPLACE,
CF_Modulate = GL_MODULATE,
CF_Add = GL_ADD,
CF_Substract = GL_SUBTRACT_ARB,
CF_Blend = GL_INTERPOLATE_EXT,
CF_ModulateAdd = GL_MODULATE_ADD_ATI
};
struct CombineArgument
{
GLint Source;
GLint Operand;
};
enum CombineFunctionColorAlphaArg
{
CFARG_Local = 0,
CFARG_Other = 1,
CFARG_LocalAlpha = 2,
CFARG_OtherAlpha = 3,
CFARG_Factor = 4,
CFARG_None = 5,
CFARG_Constant = GL_CONSTANT_EXT,
CFARG_Previous = GL_PREVIOUS_EXT,
CFARG_Texture = GL_TEXTURE,
CFARG_PrimaryColor = GL_PRIMARY_COLOR_EXT,
CFARG_Zero = GL_ZERO,
CFARG_One = GL_ONE
};
struct CombineFunctionGLTextureUnit
{
CombineFunctionValue Function;
CombineFunctionColorAlphaArg CombineArg[3];
};
struct CombineFunction
{
CombineFunctionGLTextureUnit ColorAlphaUnit[2];
};
struct CombineReduceTerm
{
GrCombineFunction_t ReducedTerm;
};
extern const CombineFunction ColorCombineFunctionsEnvCombineARB[25];
extern const CombineFunction ColorCombineFunctionsEnvCombine3ATI[25];
extern const CombineReduceTerm ColorCombineFunctionsFactorZero[0x11];
extern const CombineReduceTerm ColorCombineFunctionsFactorOne[0x11];
extern const CombineFunction AlphaCombineFunctionsEnvCombineARB[25];
extern const CombineFunction AlphaCombineFunctionsEnvCombine3ATI[25];
extern const CombineReduceTerm AlphaCombineFunctionsFactorZero[0x11];
extern const CombineReduceTerm AlphaCombineFunctionsFactorOne[0x11];
extern const CombineArgument ColorCombineFactors[14];
extern const CombineArgument AlphaCombineFactors[14];
extern const CombineArgument ColorCombineFactorsInverted[14];
extern const CombineArgument AlphaCombineFactorsInverted[14];
extern const CombineArgument ColorCombineLocals[4];
extern const CombineArgument ColorCombineOthers[4];
extern const CombineArgument ColorCombineLocalsInverted[4];
extern const CombineArgument ColorCombineOthersInverted[4];
extern const CombineArgument AlphaCombineLocals[4];
extern const CombineArgument AlphaCombineOthers[4];
extern const CombineArgument AlphaCombineLocalsInverted[4];
extern const CombineArgument AlphaCombineOthersInverted[4];
#define GR_COMBINE_LOCAL_PIXELPIPELINE 0x03
#define GR_COMBINE_OTHER_PIXELPIPELINE 0x03

View File

@ -0,0 +1,653 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* OpenGL Extensions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Glide.h"
#include "GlideSettings.h"
#include "GLColorAlphaCombineEnvTables.h"
#include "GLextensions.h"
#include "GLRender.h"
#include "GLutil.h"
#include <agl.h>
enum enExtensionType
{
OGL_EXT_UNUSED = 0,
OGL_EXT_REQUIRED,
OGL_EXT_DESIRED
};
struct stExtensionSupport
{
char * name;
enExtensionType type;
bool * userVar;
bool * internalVar;
};
// Running in Classic ?
#ifdef OPENGLIDE_HOST_MAC
bool RunningInClassic = false;
#endif
// It is important that dummyExtVariable retains the value true, so
// we pass dummyExtVariable2 in places where the value may be altered.
bool dummyExtVariable = true;
bool dummyExtVariable2 = true;
// Env Combine fog data
static GLuint fogtexturename = 0;
static FxU8* fogalpharamp = NULL;
static GLint dummytexture = 0x00000000;
stExtensionSupport glNecessaryExt[] =
{
// new
{ "GL_EXT_abgr", OGL_EXT_REQUIRED, &dummyExtVariable, &dummyExtVariable2 },
{ "GL_EXT_bgra", OGL_EXT_REQUIRED, &dummyExtVariable, &dummyExtVariable2 },
{ "GL_EXT_secondary_color", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_secondary_color },
{ "GL_ARB_multitexture", OGL_EXT_DESIRED, &UserConfig.ARB_multitexture, &InternalConfig.ARB_multitexture },
{ "GL_ARB_texture_env_add", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_texture_env_add },
{ "GL_ARB_texture_env_combine", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_texture_env_combine },
{ "GL_ATI_texture_env_combine3", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.ATI_texture_env_combine3 },
{ "GL_EXT_texture_lod_bias", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_texture_lod_bias },
{ "GL_SGIS_generate_mipmap", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_SGIS_generate_mipmap },
{ "GL_SGIS_texture_edge_clamp", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_SGIS_texture_edge_clamp },
{ "GL_EXT_paletted_texture", OGL_EXT_DESIRED, &UserConfig.EXT_paletted_texture, &InternalConfig.EXT_paletted_texture },
{ "GL_APPLE_packed_pixels", OGL_EXT_REQUIRED, &dummyExtVariable, &dummyExtVariable2 },
{ "GL_APPLE_client_storage", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_Client_Storage },
{ "GL_EXT_compiled_vertex_array", OGL_EXT_DESIRED, &UserConfig.EXT_compiled_vertex_array,&InternalConfig.EXT_compiled_vertex_array },
#ifdef OPENGLIDE_SYSTEM_HAS_FOGCOORD
{ "GL_EXT_fog_coord", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_fog_coord },
#endif
#ifdef OPENGLIDE_SYSTEM_HAS_BLENDFUNC_SEPERATE
{ "GL_EXT_blend_func_separate", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_blend_func_separate },
#endif
{ "GL_EXT_texture_filter_anisotropic",OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.EXT_texture_filter_anisotropic },
{ "GL_ARB_multisample", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.ARB_multisample },
{ "GL_NV_multisample_filter_hint", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.NV_multisample_filter_hint },
{ "GL_EXT_clip_volume_hint", OGL_EXT_DESIRED, &UserConfig.EXT_clip_volume_hint, &InternalConfig.EXT_clip_volume_hint },
{ "GL_APPLE_transform_hint", OGL_EXT_DESIRED, &dummyExtVariable, &InternalConfig.APPLE_transform_hint },
{ "", OGL_EXT_UNUSED, &dummyExtVariable, &dummyExtVariable2 }
};
// check to see if Extension is Supported
// code by Mark J. Kilgard of NVidia modified by Fabio Barros
bool OGLIsExtensionSupported( const char * extension )
{
const char * extensions;
const char * start;
char * where,
* terminator;
where = (char *) strchr( extension, ' ' );
if ( where || ( *extension == '\0' ) )
{
return false;
}
extensions = (char*)glGetString( GL_EXTENSIONS );
start = extensions;
if ( *start == '\0' )
{
GlideError( "No OpenGL extension supported, using all emulated.\n" );
return false;
}
while ( true )
{
where = (char *)strstr( start, extension );
if ( !where )
{
break;
}
terminator = where + strlen( extension );
if ( ( where == start ) || ( *( where - 1 ) == ' ' ) )
{
if ( ( *terminator == ' ' ) || ( *terminator == '\0' ) )
{
return true;
}
}
start = terminator;
}
// fix for Rage 128 OpenGL Engine 1.1.ATI-5.99
// (See apple techote TN2014)
if (strcmp(extension, "GL_APPLE_packed_pixels") == 0)
{
return OGLIsExtensionSupported("GL_APPLE_packed_pixel");
}
// fix for Rage 128 OpenGL Engine 1.1.ATI-5.99
// support for GL_EXT_texture_env_combine
else if (strcmp(extension, "GL_ARB_texture_env_combine") == 0)
{
return OGLIsExtensionSupported("GL_EXT_texture_env_combine");
}
// also support the older GL_EXT_texture_env_add
else if (strcmp(extension, "GL_ARB_texture_env_add") == 0)
{
return OGLIsExtensionSupported("GL_EXT_texture_env_add");
}
else
{
return false;
}
}
void ValidateUserConfig( void )
{
glReportErrors("ValidateUserConfig");
// Copy config
InternalConfig = UserConfig;
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg( "** OpenGL Information **\n" );
const unsigned char* renderer = glGetString( GL_RENDERER );
if (renderer == NULL || strlen(reinterpret_cast<const char*>(renderer)) == 0)
{
GlideError("The OpenGL driver failed to report its version/vendor/renderer.\nThis may be caused by beta drivers located in thge game directory.\nThese drivers should be deleted.\n");
}
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg( "Vendor: %s\n", glGetString( GL_VENDOR ) );
GlideMsg( "Renderer: %s\n", glGetString( GL_RENDERER ) );
GlideMsg( "Version: %s\n", glGetString( GL_VERSION ) );
// Extension string is too long for the temp buffer, so we don't use GlideMsg()
UserConfig.write_log("Available Extensions: ");
UserConfig.write_log(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
UserConfig.write_log("\n");
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg( "OpenGL Extensions:\n" );
GlideMsg( OGL_LOG_SEPARATE );
int index = 0;
while ( strlen( glNecessaryExt[ index ].name ) > 0 )
{
*glNecessaryExt[ index ].internalVar = false;
switch ( glNecessaryExt[ index ].type )
{
case OGL_EXT_REQUIRED:
if ( ! OGLIsExtensionSupported( glNecessaryExt[ index ].name ) )
{
char buffer[StringBufferSize];
sprintf(buffer, "Severe Problem: OpenGL %s extension is required for %s!",
glNecessaryExt[ index ].name, OpenGLideProductName);
GlideError(buffer);
}
break;
case OGL_EXT_DESIRED:
if ( ! OGLIsExtensionSupported( glNecessaryExt[ index ].name ) )
{
char buffer[StringBufferSize];
sprintf(buffer, "Note: OpenGL %s extension is not supported, emulating behavior.\n",
glNecessaryExt[ index ].name );
GlideMsg(buffer);
}
else
{
if ( *glNecessaryExt[ index ].userVar )
{
*glNecessaryExt[ index ].internalVar = true;
GlideMsg( "Extension %s is present and ENABLED\n", glNecessaryExt[ index ].name );
}
else
{
char buffer[StringBufferSize];
sprintf(buffer, "Note: OpenGL %s extension is supported but disabled by user\n",
glNecessaryExt[ index ].name );
GlideMsg(buffer);
}
}
break;
case OGL_EXT_UNUSED:
break;
}
++index;
}
GlideMsg( OGL_LOG_SEPARATE );
GLExtensions( );
// Rendering quality seems to be better when this is left enabled for depth buffer size < 24 bits only
// (Try spinning around at the portal in the first level of Tomb Raider Gold)
GLint depthbufferbits;
glGetIntegerv(GL_DEPTH_BITS, &depthbufferbits);
glReportError();
if (depthbufferbits >= 24 && InternalConfig.PrecisionFix == 1)
{
GlideMsg("Actual number of depthbuffer bits is %d - precision fix can safely be disabled\n", depthbufferbits);
InternalConfig.PrecisionFix = 0;
}
}
void GLExtensions(void)
{
glReportErrors("GLExtensions");
float one = 1.0f;
#ifdef OPENGLIDE_HOST_MAC
RunningInClassic = strstr(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)), "GL_EXT_fog_coord") != NULL;
#endif
// query the actual buffer size
GLint size;
glGetIntegerv(GL_DEPTH_BITS, &size);
GlideMsg("Depthbuffer size = %d\n", size);
if (UserConfig.GapFix & OpenGLideGapFixFlag_Enabled)
{
glGetIntegerv(GL_STENCIL_BITS, &size);
GlideMsg("Stencilbuffer size = %d\n", size);
}
GLint MaxAnisotropyLevel;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &MaxAnisotropyLevel);
GlideMsg("Maximum level of anisotropy = %d\n", MaxAnisotropyLevel);
if (InternalConfig.EXT_texture_filter_anisotropic)
{
GLint MaxAnisotropyLevel;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &MaxAnisotropyLevel);
if (UserConfig.AnisotropylLevel > MaxAnisotropyLevel)
{
InternalConfig.AnisotropylLevel = MaxAnisotropyLevel;
}
else
{
InternalConfig.AnisotropylLevel = UserConfig.AnisotropylLevel;
}
}
else
{
InternalConfig.AnisotropylLevel = 1;
}
if (InternalConfig.ARB_multisample == false)
{
InternalConfig.FullSceneAntiAliasing = 0;
}
else if (InternalConfig.FullSceneAntiAliasing > 0)
{
// Thanks to Frank Condello <developerNOSPAM@NOSPAMchaoticbox.com> for posting this trick at
// http://support.realsoftware.com/listarchives/realbasic-games/2004-09/msg00273.html
aglSetInteger(pWindowInfo->aglContext, AGL_ATI_FSAA_LEVEL, reinterpret_cast<const long*>(&InternalConfig.FullSceneAntiAliasing));
GLenum err = aglGetError();
if (AGL_NO_ERROR != err)
{
GlideError("Couldn't set ATI FSAA level: %s\n", reinterpret_cast<const char *>(aglErrorString(err)));
}
// Initially enable multisampling
glEnable(GL_MULTISAMPLE_ARB);
glReportError();
}
if (InternalConfig.FullSceneAntiAliasing > 0
&& InternalConfig.NV_multisample_filter_hint)
{
glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
glReportError();
}
#ifdef OPENGLIDE_SYSTEM_HAS_FOGCOORD
if (InternalConfig.EXT_fog_coord == false && InternalConfig.FogMode > OpenGLideFogEmulation_EnvCombine)
{
InternalConfig.FogMode = OpenGLideFogEmulation_EnvCombine;
}
#endif
// FogCoord extension not supported on MacOS9
#ifdef OPENGLIDE_SYSTEM_DOESN_T_HAVE_FOGCOORD
if (InternalConfig.FogMode > OpenGLideFogEmulation_EnvCombine)
{
InternalConfig.FogMode = OpenGLideFogEmulation_EnvCombine;
}
#endif
// check for other extensions needed by fog emulation
if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine
&& InternalConfig.EXT_texture_env_combine == false)
{
GlideMsg( "Enhanced fog emulation disabled because GL_ARB_texture_env_combine is missing or disabled\n");
InternalConfig.FogMode = OpenGLideFogEmulation_Simple;
}
else if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine
&& InternalConfig.ARB_multitexture == false)
{
GlideMsg( "Enhanced fog emulation disabled because GL_ARB_multitexture is missing or disabled\n");
InternalConfig.FogMode = OpenGLideFogEmulation_Simple;
}
// Setup texture units
if (InternalConfig.GlideTextureUnits > 1)
{
GlideMsg( "Only one texure unit is currently supported. Additional units are ignored.\n");
}
if (InternalConfig.ARB_multitexture)
{
GLint number_of_texture_units = 1;
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &number_of_texture_units);
GlideMsg("MultiTexture Units = %x\n", number_of_texture_units);
if (InternalConfig.ColorAlphaRenderMode >= OpenGLideColorAlphaRenderMode_Unknown)
{
InternalConfig.ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_Automatic;
}
if (InternalConfig.ColorAlphaRenderMode > OpenGLideColorAlphaRenderMode_Simple
&& InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine
&& number_of_texture_units <= 2)
{
GlideMsg( "Coloralpha render mode reset to simple in favour of enhanced fog emulation\n");
InternalConfig.ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_Simple;
}
// Setup coloralpha texture units
OpenGL.ColorAlphaUnit1 = GL_TEXTURE0_ARB;
if ((number_of_texture_units > 2 && InternalConfig.EXT_texture_env_combine
|| number_of_texture_units == 2 && InternalConfig.FogMode != OpenGLideFogEmulation_EnvCombine)
&& (InternalConfig.ColorAlphaRenderMode == OpenGLideColorAlphaRenderMode_Automatic
|| InternalConfig.ColorAlphaRenderMode > OpenGLideColorAlphaRenderMode_Simple))
{
OpenGL.ColorAlphaUnit2 = GL_TEXTURE1_ARB;
OpenGL.FogTextureUnit = GL_TEXTURE2_ARB;
// All texture units are enabled all the time
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glActiveTextureARB(OpenGL.ColorAlphaUnit2);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glReportError();
// Secondary color not neded in the enhanced color alpha rendering model
InternalConfig.EXT_secondary_color = false;
if (InternalConfig.ColorAlphaRenderMode == OpenGLideColorAlphaRenderMode_Automatic)
{
if (InternalConfig.ATI_texture_env_combine3)
{
// With GL_ATI_texture_env_combine3, more combine functions can be modeled as
// exactly as the original combine functions. They can also be rendered more
// often with one texture unit, which leaves more space for correct rendering
// of textures that use both chromakeying and alpha blending together.
InternalConfig.ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_EnvCombine3_ATI;
OpenGL.ColorCombineFunctions = ColorCombineFunctionsEnvCombine3ATI;
OpenGL.AlphaCombineFunctions = AlphaCombineFunctionsEnvCombine3ATI;
}
else if (InternalConfig.EXT_texture_env_combine)
{
// Standard setup, works with most graphics cards and provides accurate
// results in most cases
InternalConfig.ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_EnvCombine_ARB;
OpenGL.ColorCombineFunctions = ColorCombineFunctionsEnvCombineARB;
OpenGL.AlphaCombineFunctions = AlphaCombineFunctionsEnvCombineARB;
}
}
if (InternalConfig.ColorAlphaRenderMode == OpenGLideColorAlphaRenderMode_EnvCombine3_ATI)
{
OpenGL.ColorCombineFunctions = ColorCombineFunctionsEnvCombine3ATI;
OpenGL.AlphaCombineFunctions = AlphaCombineFunctionsEnvCombine3ATI;
}
else if (InternalConfig.ColorAlphaRenderMode == OpenGLideColorAlphaRenderMode_EnvCombine_ARB)
{
OpenGL.ColorCombineFunctions = ColorCombineFunctionsEnvCombineARB;
OpenGL.AlphaCombineFunctions = AlphaCombineFunctionsEnvCombineARB;
}
}
else
{
OpenGL.ColorAlphaUnit2 = 0;
OpenGL.FogTextureUnit = number_of_texture_units > 2 ? GL_TEXTURE2_ARB : GL_TEXTURE1_ARB;
InternalConfig.ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_Simple;
}
}
else
{
OpenGL.ColorAlphaUnit1 = GL_TEXTURE0_ARB;
OpenGL.ColorAlphaUnit2 = 0;
OpenGL.FogTextureUnit = 0;
InternalConfig.ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_Simple;
}
// Print out coloralpha render mode
char* coloralpharendermodename;
switch (InternalConfig.ColorAlphaRenderMode)
{
case OpenGLideColorAlphaRenderMode_Simple:
coloralpharendermodename = "MultiTextureSimple";
break;
case OpenGLideColorAlphaRenderMode_EnvCombine_ARB:
coloralpharendermodename = "EnvironmentCombineARB";
break;
case OpenGLideColorAlphaRenderMode_EnvCombine3_ATI:
coloralpharendermodename = "EnvironmentCombine3ATI";
break;
default:
assert(false);
break;
}
GlideMsg( "Coloralpha rendermode = %s\n", coloralpharendermodename);
if (OpenGL.FogTextureUnit == 0 && InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine)
{
InternalConfig.FogMode = OpenGLideFogEmulation_Simple;
}
if (InternalConfig.EXT_secondary_color && OpenGL.ColorAlphaUnit2 == 0)
{
glEnable(GL_COLOR_SUM_EXT);
glReportError();
}
if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine)
{
fogalpharamp = static_cast<unsigned char*> (AllocBuffer(256, 1));
if (fogalpharamp)
{
for(unsigned int i = 0; i < 256; i++)
{
fogalpharamp[i] = 255 - i;
}
}
else
{
InternalConfig.FogMode = OpenGLideFogEmulation_Simple;
}
}
if (OpenGL.ColorAlphaUnit2 || InternalConfig.FogMode != OpenGLideFogEmulation_EnvCombine)
{
glGenTextures(1, &OpenGL.DummyTextureName);
glPrioritizeTextures(1, &OpenGL.DummyTextureName, &one);
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
glBindTexture(GL_TEXTURE_2D, OpenGL.DummyTextureName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, InternalConfig.EXT_SGIS_texture_edge_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP); // GL_REPEAT would cause randomly
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, InternalConfig.EXT_SGIS_texture_edge_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP); // fogged triangles in the foreground
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (InternalConfig.AnisotropylLevel >= 2)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
}
glTexImage2D(GL_TEXTURE_2D, 0, 4, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &dummytexture);
glReportError();
}
#ifdef OPENGLIDE_SYSTEM_HAS_FOGCOORD
if (InternalConfig.FogMode == OpenGLideFogEmulation_FogCoord)
{
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
glFogf(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, 0.0f);
glFogf(GL_FOG_END, 1.0f);
glReportError();
}
else
#endif
if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine)
{
GrFog_t fogtable[GR_FOG_TABLE_SIZE];
guFogGenerateLinear(fogtable, 0.0f, 1.0f);
grFogTable(fogtable);
GlideMsg( "Using env-combine fog emulation\n");
// Setup fog texture unit
glActiveTextureARB(OpenGL.FogTextureUnit);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
// The color part is used for the fog function (see RenderUpdateState.cpp)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
// The alpha is not blended with the fog alpha because this
// would also fog otherwise invisible parts of the texture
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
glGenTextures(1, &fogtexturename);
glPrioritizeTextures(1, &fogtexturename, &one);
glBindTexture(GL_TEXTURE_2D, fogtexturename);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, InternalConfig.EXT_SGIS_texture_edge_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP); // GL_REPEAT would cause randomly
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, InternalConfig.EXT_SGIS_texture_edge_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP); // fogged triangles in the foreground
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (InternalConfig.AnisotropylLevel >= 2)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 256, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, fogalpharamp);
glReportError();
}
else if (InternalConfig.FogMode == OpenGLideFogEmulation_Simple)
{
// Provide a reasonable default for application that use fog,
// but don't set the fog table (like Carmageddon)
// Adjusted to camageddon Main Street Track (compared with Race Track Preview image)
// and to Coastal Carnage Track so that objects become colored right after they pop up
// when popup distance option is far (fog is set to black in this level)
// This doesn't seem to work with MacOS9 OpenGL drivers (beasue of version < 1.3 ?).
// The whole scene is too dark. However, it works well in the Classic environment
// (which actually uses the OpenGL driver provided by MacOS X)
// When the fog table is not set as below, the whole scene seems to be a little to dark,
// whereas when it's set, the foreground looks as brighht as in the software rendrerer.
GrFog_t fogtable[GR_FOG_TABLE_SIZE];
// The values below come from comparing screenshots between GeForce 2mx
// (MacOS X OpenGL 1.3 driver) and the software renderer version of Carmageddon
guFogGenerateLinear(fogtable, 0.9985f, 1.0f);
grFogTable(fogtable);
GlideMsg( "Using simple fog emulation\n");
}
else
{
InternalConfig.FogMode = OpenGLideFogEmulation_None;
// These default values must be provied even if fog is
// disabled or the shadows in Carmageddon Splatpack,
// Meltdown Alley level will have the fog color
// (occures on MacOS 9, Nvidia OpenGL 1.22)
glFogf( GL_FOG_MODE, GL_LINEAR );
glReportError();
glFogf( GL_FOG_START, 1.0f );
glReportError();
glFogf( GL_FOG_END, 0.0f );
glReportError();
glDisable(GL_FOG);
GlideMsg( "Fog emulation disabled\n");
}
if (InternalConfig.FogMode != OpenGLideFogEmulation_EnvCombine && OpenGL.DummyTextureName && OpenGL.FogTextureUnit)
{
// Setup fog texture unit as inverter (for inverting the color alpha output)
glActiveTextureARB(OpenGL.FogTextureUnit);
glBindTexture(GL_TEXTURE_2D, OpenGL.DummyTextureName);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
glReportError();
OpenGL.FogTextureUnitEnabledState = true;
}
else
{
OpenGL.FogTextureUnitEnabledState = false;
}
// End of texture unit setup
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
if (InternalConfig.EXT_paletted_texture)
{
GlideMsg( "Using Palette Extension\n" );
}
#ifdef OPENGLIDE_HOST_MAC
if (InternalConfig.EXT_compiled_vertex_array)
{
// Compiled vertex array crashes on MacOS9 (at least on my system)
// so if anybody who would like to investigate this...
if (!RunningInClassic)
{
InternalConfig.EXT_compiled_vertex_array = false;
GlideMsg( "Compiled vertex arrays have been disabled (works in Classic only)\n" );
}
}
#endif
if (InternalConfig.TextureSmoothing)
{
OpenGL.MinFilterMode = InternalConfig.Mipmapping ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
OpenGL.MagFilterMode = GL_LINEAR;
}
if (InternalConfig.EXT_clip_volume_hint)
{
GlideMsg("Using clip volume hint\n");
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
OpenGL.ClipVerticesEnabledState = false;
}
if (InternalConfig.APPLE_transform_hint)
{
GlideMsg("Using apple transform hint\n");
glHint(GL_TRANSFORM_HINT_APPLE, GL_NICEST);
}
if (InternalConfig.EXT_SGIS_generate_mipmap)
{
GlideMsg("Using SGIS mipmap generation hint\n");
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
}
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
}
void GLExtensionsCleanup()
{
// cleanup fog texture
if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine)
{
if (fogalpharamp)
{
FreeBuffer(fogalpharamp);
glReportErrors("RenderFree");
glDeleteTextures(1, &fogtexturename);
glReportError();
}
}
if (OpenGL.DummyTextureName)
{
glDeleteTextures(1, &OpenGL.DummyTextureName);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,159 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Render Header
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef __GLRENDER_H__
#define __GLRENDER_H__
//**************************************************************
// Defines
//**************************************************************
#define MAXTRIANGLES 500
//**************************************************************
// Structs
//**************************************************************
struct GlVertex
{
GLfloat x, y, z;
GLfloat s, t, q, oow;
GLfloat r, g, b, a;
GLfloat r2, g2, b2, a2;
GLfloat f;
};
struct Triangle
{
GlVertex a, b, c;
};
struct ColorStruct
{
GLfloat r, g, b, a;
};
struct TColorStruct
{
GLfloat ar, ag, ab, aa;
GLfloat br, bg, bb, ba;
GLfloat cr, cg, cb, ca;
};
struct TVertexStruct
{
GLfloat ax, ay, az, aw;
GLfloat bx, by, bz, bw;
GLfloat cx, cy, cz, cw;
};
struct TTextureStruct
{
GLfloat as, at, aq, aoow;
GLfloat bs, bt, bq, boow;
GLfloat cs, ct, cq, coow;
};
struct TFogStruct
{
GLfloat af;
GLfloat bf;
GLfloat cf;
};
struct RenderStruct
{
TColorStruct *TColor;
TColorStruct *TColor2;
TVertexStruct *TVertex;
TTextureStruct *TTexture;
TFogStruct *TFog;
long NumberOfTriangles;
bool UseEnvCombineFog;
bool BufferLocked;
FxU32 BufferLockedStart;
FxU32 BufferStart;
#ifdef OGL_DEBUG
float MinX, MinY, MinZ, MinW;
float MaxX, MaxY, MaxZ, MaxW;
float MinS, MinT, MaxS, MaxT;
float MinR, MinG, MinB, MinA;
float MaxR, MaxG, MaxB, MaxA;
float MaxF, MinF;
unsigned long FrameTriangles, MaxTriangles, MaxSequencedTriangles;
unsigned long OverallTriangles, OverallRenderTriangleCalls;
unsigned long OverallLines;
unsigned long OverallPoints;
unsigned long OverallQuads;
unsigned long OverallPolygons;
#endif
};
typedef float (*ALPHAFACTORFUNCPROC)( float LocalAlpha, float OtherAlpha );
typedef void (*COLORFACTORFUNCPROC)( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
typedef void (*COLORFUNCTIONPROC)( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
//**************************************************************
// Function Prototypes
//**************************************************************
// Main Render functions
void RenderInitialize( void );
void RenderFree( void );
void RenderAddTriangle( const GrVertex *a, const GrVertex *b, const GrVertex *c, bool unsnap );
void RenderAddLine( const GrVertex *a, const GrVertex *b, bool unsnap );
void RenderAddPoint( const GrVertex *a, bool unsnap );
void RenderDrawTriangles( void );
extern RenderStruct OGLRender;
void RenderInitialize( void );
void RenderFree( void );
// Main Render variables
// extern RenderStruct OGLRender;
extern ALPHAFACTORFUNCPROC AlphaFactorFunc;
extern COLORFACTORFUNCPROC ColorFactor3Func;
extern COLORFUNCTIONPROC ColorFunctionFunc;
// Prototypes for the color combining
float AlphaFactorZero( float LocalAlpha, float OtherAlpha );
float AlphaFactorLocal( float LocalAlpha, float OtherAlpha );
float AlphaFactorOther( float LocalAlpha, float OtherAlpha );
float AlphaFactorOneMinusLocal( float LocalAlpha, float OtherAlpha );
float AlphaFactorOneMinusOther( float LocalAlpha, float OtherAlpha );
float AlphaFactorOne( float LocalAlpha, float OtherAlpha );
void ColorFactor3Zero( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
void ColorFactor3Local( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
void ColorFactor3LocalAlpha( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
void ColorFactor3OneMinusLocal( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
void ColorFactor3OneMinusLocalAlpha( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
void ColorFactor3OtherAlpha( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
void ColorFactor3OneMinusOtherAlpha( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
void ColorFactor3One( TColorStruct *Result, const TColorStruct *ColorComponent, const TColorStruct *OtherAlpha );
void ColorFunctionZero( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionLocal( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionLocalAlpha( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionScaleOther( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionScaleOtherAddLocal( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionScaleOtherAddLocalAlpha( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionScaleOtherMinusLocal( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionScaleOtherMinusLocalAddLocal( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionScaleOtherMinusLocalAddLocalAlpha( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionMinusLocalAddLocal( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
void ColorFunctionMinusLocalAddLocalAlpha( TColorStruct * pC, TColorStruct * pC2, const TColorStruct * Local, const TColorStruct * Other );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* updates the GL state before rendering vertices
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GlOgl.h"
#include "GlideApplication.h"
extern bool s_bUpdateTextureState;
extern bool s_bUpdateFogModeState;
extern bool s_bUpdateFogColorState;
extern bool s_bUpdateBlendState;
extern bool s_bUpdateChromaKeyAndAlphaState;
extern bool s_bUpdateColorCombineState;
extern bool s_bUpdateAlphaCombineState;
extern bool s_bUpdateColorInvertState;
extern bool s_bUpdateAlphaInvertState;
extern bool s_bUpdateConstantColorValueState;
extern bool s_bUpdateConstantColorValue4State;
extern bool s_bForceChromaKeyAndAlphaStateUpdate;
// Forward declarations for inline functions
// (Deferred inlining)
inline void SetChromaKeyAndAlphaState();
inline void SetAlphaCombineState();
inline void ForceChromaKeyAndAlphaStateUpdate()
{
s_bForceChromaKeyAndAlphaStateUpdate = true;
}
inline void SetColorTextureState()
{
if ((Glide.COther &&
(Glide.State.ColorCombineOther == GR_COMBINE_OTHER_TEXTURE)
&& (Glide.State.TextureCombineCFunction != GR_COMBINE_FUNCTION_ZERO))
|| ((Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_TEXTURE_ALPHA)
|| (Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA)
|| (Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_TEXTURE_RGB)))
{
OpenGL.ColorTexture = true;
}
else
{
OpenGL.ColorTexture = false;
}
#ifdef OPENGL_DEBUG
GlideMsg( "OpenGL.ColorTexture = %d\n", OpenGL.ColorTexture);
#endif
}
inline void SetAlphaTextureState()
{
if (OpenGL.ColorAlphaUnit2)
{
if (( Glide.AOther &&
(Glide.State.AlphaOther == GR_COMBINE_OTHER_TEXTURE)
&& (Glide.State.TextureCombineAFunction != GR_COMBINE_FUNCTION_ZERO))
|| ((Glide.State.AlphaFactor == GR_COMBINE_FACTOR_TEXTURE_ALPHA)
|| (Glide.State.AlphaFactor == GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA)
|| (Glide.State.AlphaFactor == GR_COMBINE_FACTOR_TEXTURE_RGB)))
{
OpenGL.AlphaTexture = true;
}
else
{
OpenGL.AlphaTexture = false;
}
}
else
{
if ( Glide.AOther && ( Glide.State.AlphaOther == GR_COMBINE_OTHER_TEXTURE ) )
{
OpenGL.AlphaTexture = true;
}
else
{
OpenGL.AlphaTexture = false;
}
}
#ifdef OPENGL_DEBUG
GlideMsg( "OpenGL.AlphaTexture = %d\n", OpenGL.AlphaTexture);
#endif
}
inline void SetTextureState()
{
s_bUpdateTextureState = true;
bool opengl_texture = (OpenGL.ColorTexture || (OpenGL.Blend && OpenGL.AlphaTexture))
&& Glide.State.TexSource.StartAddress != GR_NULL_MIPMAP_HANDLE;
OpenGL.Texture = opengl_texture;
// When the texture state changes, chromakeying is also affected
SetChromaKeyAndAlphaState();
#ifdef OPENGL_DEBUG
GlideMsg( "OpenGL.Texture = %d\n", OpenGL.Texture);
#endif
}
inline void SetBlendState()
{
s_bUpdateBlendState = true;
#ifdef OPENGL_DEBUG
GlideMsg( "OpenGL.Blend = %d\n", OpenGL.Blend);
#endif
}
inline void SetFogModeState()
{
s_bUpdateFogModeState = true;
#ifdef OPENGL_DEBUG
GlideMsg( "OpenGL.Fog = %d\n", OpenGL.Fog);
#endif
}
inline void SetFogColorState()
{
s_bUpdateFogColorState = true;
}
inline void SetChromaKeyAndAlphaState()
{
s_bUpdateChromaKeyAndAlphaState = true;
#ifdef OPENGL_DEBUG
GlideMsg( "OpenGL.ChromaKey = %d\n", OpenGL.ChromaKey);
#endif
if (OpenGL.ColorAlphaUnit2)
{
// Need to change alpha combine because the alpha channel
// in non-blended chromakey textures is a special case
SetAlphaCombineState();
}
}
inline void SetColorCombineState()
{
s_bUpdateColorCombineState = true;
}
inline void SetAlphaCombineState()
{
s_bUpdateAlphaCombineState = true;
}
inline void SetColorInvertState()
{
s_bUpdateColorInvertState = true;
SetFogModeState();
#ifdef OPENGL_DEBUG
GlideMsg( "Glide.State.ColorCombineInvert = %d\n", Glide.State.ColorCombineInvert);
#endif
}
inline void SetAlphaInvertState()
{
s_bUpdateAlphaInvertState = true;
SetFogModeState();
#ifdef OPENGL_DEBUG
GlideMsg( "Glide.State.AlphaInvert = %d\n", Glide.State.AlphaInvert);
#endif
}
inline void SetConstantColorValueState()
{
s_bUpdateConstantColorValueState = true;
}
inline void SetConstantColorValue4State()
{
s_bUpdateConstantColorValue4State = true;
}
// Also called from FrameBuffer class
extern void SetClipVerticesState_Update(bool clip_vertices);
// Needs to be called before adding a triangle, line or point
inline void SetClipVerticesState(bool clip)
{
bool clip_vertices = clip || OpenGL.Clipping;
// Triggers very seldomly (because grDrawXXXWithClip() is used very seldom)
// As a result this method is designed for cause the least cost when not being triggered
if (clip_vertices != OpenGL.ClipVerticesEnabledState)
{
SetClipVerticesState_Update(clip_vertices);
}
}
extern void RenderUpdateState();

View File

@ -0,0 +1,475 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Utility File
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Glide.h"
#include "GlideDisplay.h"
#include "GlideSettings.h"
#include "GLExtensions.h"
#include "GLUtil.h"
#include "PGTexture.h"
OSStatus aglReportWarning(void)
{
GLenum err = aglGetError();
if (AGL_NO_ERROR != err)
{
GlideMsg("AGL-Error: %s\n", reinterpret_cast<const char *>(aglErrorString(err)));
}
// ensure we are returning an OSStatus noErr if no error condition
if (err == AGL_NO_ERROR)
return noErr;
else
return (OSStatus) err;
}
// Gobals for initialising the display
WindowPtr pGLWindow = NULL;
structWindowInfoPtr pWindowInfo = NULL;
short SetAGLAttributes(GLint* aglAttributes, short index)
{
// The maximun depth buffer size will be requested
// by choosing AGL_MAXIMUM_POLICY
if (UserConfig.DepthBufferBits < 0) UserConfig.DepthBufferBits = 0;
if (UserConfig.DepthBufferBits > 32) UserConfig.DepthBufferBits = 32;
GLint depthbufferbits = UserConfig.DepthBufferBits;
// 0 triggers the maximun number of available depth
// buffer bits to be used but at least 16
if (depthbufferbits == 0)
{
depthbufferbits = 16;
}
aglAttributes[index++] = AGL_RGBA;
aglAttributes[index++] = AGL_ALPHA_SIZE;
aglAttributes[index++] = 0; // Alpha not supported on Glide Cards with depth buffering
aglAttributes[index++] = AGL_DOUBLEBUFFER;
// ARB_multisample doesn't seem to work in Classic,
// but maybe someone wants to port this to Carbon...
/*
if (UserConfig.FullSceneAntiAliasing > 0)
{
aglAttributes[index++] = AGL_SAMPLE_BUFFERS_ARB;
aglAttributes[index++] = 1;
aglAttributes[index++] = AGL_SAMPLES_ARB;
aglAttributes[index++] = UserConfig.FullSceneAntiAliasing > 0;
}
*/
aglAttributes[index++] = AGL_NO_RECOVERY;
if (UserConfig.DepthBufferBits == 0) aglAttributes[index++] = AGL_MAXIMUM_POLICY;
aglAttributes[index++] = AGL_DEPTH_SIZE;
aglAttributes[index++] = depthbufferbits;
if (UserConfig.DisplayMode == OpenGLideDisplayMode_aglSetFullScreen)
{
aglAttributes[index++] = AGL_FULLSCREEN;
}
if (UserConfig.GapFix & OpenGLideGapFixFlag_Enabled)
{
aglAttributes[index++] = AGL_STENCIL_SIZE;
aglAttributes[index++] = AGL_2_BIT;
}
aglAttributes[index] = AGL_NONE;
return index;
}
// This function can only use settings from UserConfig,
// as it's called before InternalConfig
bool InitialiseOpenGLWindow(FxU32 hwnd, int x, int y, FxU32 width, FxU32 height )
{
glReportErrors("InitialiseOpenGLWindow");
// Adjust the origin if the selected display resolution
// is greater than the OpenGL resolution
unsigned long display_width = 0;
unsigned long display_height = 0;
OpenGL.OriginX = 0;
OpenGL.OriginY = 0;
Rect rectWin = {y, x , height, width};
// Change the screen resolution?
if (UserConfig.DisplayMode == OpenGLideDisplayMode_DisplayManager ||
UserConfig.DisplayMode == OpenGLideDisplayMode_aglSetFullScreen)
{
OSErr err = DisplayManager_RememberPassthroughDisplay();
if (err == noErr)
{
// Avoid flicker during screen resolution switching
#ifndef OGL_DEBUG
DisplayManager_SetPassthroughDisplayGammaBlack();
#endif
long freq = UserConfig.MonitorRefreshRate;
// sort out illegal values
if (freq < 60) freq = 0;
// check whether to use the refresh rate requested by the Glide application
if (freq == 0) freq = OpenGL.Refresh;
// Allows to play Falcon 4.0 in True Color and to play Tomb Raider Gold 1+2 with movies enabled.
// However, Tomb Raider II < 1.03 has problems displaying Lara and other in-game objects.
err = DisplayManager_SetGlideDisplay(width, height, freq);
if (err != noErr)
{
if (width < 640)
{
// Not all displays support all Glide resolutions,
// for instance the LCD-iMacs don't support 512x384
GlideMsg("Error: Resolution %dx%d@%dHz not found. Trying double resolution %dx%d@%dHz.\n", width, height, freq, width << 1, height << 1, freq);
// Restore gamma first
err = DisplayManager_SetGlideDisplay(width << 1, height << 1, freq);
if (err == noErr)
{
width = width << 1;
height = height << 1;
OpenGL.WindowWidth = width;
OpenGL.WindowHeight = height;
}
}
}
}
if (err != noErr)
{
// If changing the screensize failed (for instance
// when the calling app checks for available resolutions)
// the gamma correction table must be restored or
// we may end up with a black screen
DisplayManager_RestorePassthroughDisplayGamma();
return false;
}
if (DisplayManager_GetGlideDisplayResolution(display_width, display_height))
{
// Position the viewport in the middle of the screen
OpenGL.OriginX = (display_width - width) / 2;
OpenGL.OriginY = (display_height - height) / 2;
rectWin.right = display_width;
rectWin.bottom = display_height;
}
}
else
{
if (DisplayManager_GetDesktopDisplayResolution(display_width, display_height))
{
// Position the window in the middle of the screen
rectWin.left = (display_width - width) / 2;
rectWin.top = (display_height - height) / 2;
}
else
{
rectWin.left = 40;
rectWin.top = 60;
}
rectWin.right = rectWin.left + width;
rectWin.bottom = rectWin.top + height;
}
// build window
pWindowInfo = (structWindowInfoPtr) NewPtrSysClear (sizeof (structWindowInfo));
OSStatus err = CreateNewWindow(kDocumentWindowClass, kWindowNoAttributes, &rectWin, &pGLWindow);
if (pGLWindow)
{
ShowWindow (pGLWindow);
SetPortWindowPort (pGLWindow);
pWindowInfo->glInfo.fDraggable = false;
pWindowInfo->glInfo.fmt = 0;
pWindowInfo->glInfo.fAcceleratedMust = true;
pWindowInfo->glInfo.VRAM = 0;
pWindowInfo->glInfo.textureRAM = 0;
SetAGLAttributes(pWindowInfo->glInfo.aglAttributes, 0);
BuildGLFromWindow(pGLWindow, &pWindowInfo->aglContext, &pWindowInfo->glInfo, NULL);
if (pWindowInfo->aglContext)
{
// This does not work reliably
/*
if (UserConfig.DisplayMode == OpenGLideDisplayMode_aglSetFullScreen)
{
long freq = UserConfig.MonitorRefreshRate;
// sort out illegal values
if (freq < 60) freq = 0;
// check whether to use the refresh rate requested by the Glide application
if (freq == 0) freq = OpenGL.Refresh;
// aglSetDrawable(pWindowInfo->aglContext, (AGLDrawable) NULL);
if (aglSetFullScreen(pWindowInfo->aglContext, width, height, freq, 0))
{
if (aglSetCurrentContext(pWindowInfo->aglContext))
{
aglUpdateContext(pWindowInfo->aglContext);
}
else
{
aglReportWarning();
GlideError("aglSetCurrentContext() after aglSetFullScreen() failed\n");
// shutdown full screen
aglSetCurrentContext(pWindowInfo->aglContext);
aglReportError();
aglSetDrawable(pWindowInfo->aglContext, (AGLDrawable) GetWindowPort(pGLWindow));
aglReportError();
aglUpdateContext(pWindowInfo->aglContext);
aglReportError();
}
}
else
{
aglReportWarning();
GlideError("aglSetFullScreen() failed\n");
// shutdown full screen
aglSetCurrentContext(pWindowInfo->aglContext);
aglReportError();
aglSetDrawable(pWindowInfo->aglContext, (AGLDrawable) GetWindowPort(pGLWindow));
aglReportError();
aglUpdateContext(pWindowInfo->aglContext);
aglReportError();
}
}
else
{
if (aglSetCurrentContext(pWindowInfo->aglContext))
{
aglUpdateContext(pWindowInfo->aglContext);
aglReportError();
}
else
{
aglReportWarning();
GlideError("aglSetCurrentContext() failed\n");
}
}
*/
// Keep renderers in memory
aglConfigure(AGL_RETAIN_RENDERERS, GL_TRUE);
aglReportWarning();
// And minimise cache size
aglConfigure(AGL_FORMAT_CACHE_SIZE, 1);
aglReportWarning();
// Don't render ahead
bool runningInClassic = strstr(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)), "GL_EXT_fog_coord") != NULL;
if (runningInClassic)
{
aglEnable(pWindowInfo->aglContext, AGL_SWAP_LIMIT);
aglReportWarning();
}
}
else
{
aglReportWarning();
DestroyGLFromWindow(&pWindowInfo->aglContext, &pWindowInfo->glInfo);
GlideError("couldn't create agl context");
return false;
}
}
else
{
GlideError("Couldn't create window");
}
// clear color buffer to black to minimmise white screen flash on resolution change
// and white top/bottoms when displaying widescreen movies on 4/3 screens
glDrawBuffer(GL_BACK);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
GLint swap = 0;
aglSetInteger(pWindowInfo->aglContext, AGL_SWAP_INTERVAL, &swap);
aglSwapBuffers(pWindowInfo->aglContext);
aglReportError();
if (UserConfig.GapFix & OpenGLideGapFixFlag_Enabled)
{
glEnable(GL_STENCIL_TEST);
glStencilMask(0x03);
glClearStencil(0x00);
glStencilFunc(GL_ALWAYS, 0x02, 0x03);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glReportError();
}
// The gamma correction value is restored in grSstWinOpen()
// so we don't have to do anything here
return true;
}
void FinaliseOpenGLWindow(void)
{
s_Framebuffer.Cleanup();
if (UserConfig.DisplayMode == OpenGLideDisplayMode_DisplayManager ||
UserConfig.DisplayMode == OpenGLideDisplayMode_aglSetFullScreen)
{
#ifndef OGL_DEBUG
DisplayManager_SetGlideDisplayGammaBlack();
#endif
}
if (pWindowInfo)
{
// DeleteFontGL (pWindowInfo->fontList);
// must clean up failure to do so will result in an Unmapped Memory Exception
DestroyGLFromWindow(&pWindowInfo->aglContext, &pWindowInfo->glInfo);
DisposePtr ((Ptr) pWindowInfo);
pWindowInfo = NULL;
}
if (pGLWindow)
{
DisposeWindow (pGLWindow);
pGLWindow = NULL;
}
// Cleanup display manager?
if (UserConfig.DisplayMode == OpenGLideDisplayMode_DisplayManager ||
UserConfig.DisplayMode == OpenGLideDisplayMode_aglSetFullScreen)
{
DisplayManager_RestorePassthroughDisplay();
}
}
void HideOpenGLWindow()
{
if (UserConfig.DisplayMode == OpenGLideDisplayMode_DisplayManager ||
UserConfig.DisplayMode == OpenGLideDisplayMode_aglSetFullScreen)
{
#ifndef OGL_DEBUG
DisplayManager_SetGlideDisplayGammaBlack();
#endif
}
// Hide window by moving it offscreen, allowing some extra offset to hide the bar
MoveWindow(pGLWindow, OpenGL.WindowWidth + 64, OpenGL.WindowHeight + 64, FALSE);
// Actually HideWIndow() should be working, but it blacks out
// the Movies in Tomb Raider Gold
// HideWindow(pGLWindow);
aglUpdateContext(pWindowInfo->aglContext);
aglReportError();
if (UserConfig.DisplayMode == OpenGLideDisplayMode_DisplayManager ||
UserConfig.DisplayMode == OpenGLideDisplayMode_aglSetFullScreen)
{
DisplayManager_RestorePassthroughDisplay();
aglUpdateContext(pWindowInfo->aglContext);
aglReportError();
}
}
void RestoreOpenGLWindow()
{
// Change the screen resolution?
if (UserConfig.DisplayMode == OpenGLideDisplayMode_DisplayManager ||
UserConfig.DisplayMode == OpenGLideDisplayMode_aglSetFullScreen)
{
OSErr err = DisplayManager_RememberPassthroughDisplay();
if (err == noErr)
{
// Avoid flicker during screen resolution switching
#ifndef OGL_DEBUG
DisplayManager_SetPassthroughDisplayGammaBlack();
#endif
}
}
DisplayManager_RestoreGlideDisplay();
// 0,0 is only correct in fullscreen modes where the OpenGL window matches the
// Glide screen resolution.
MoveWindow(pGLWindow, 0, 0, FALSE);
// Actually HideWIndow() should be working, but it blacks out the
// Movies in Tomb Raider Gold
// ShowWindow(pGLWindow);
aglUpdateContext(pWindowInfo->aglContext);
aglReportError();
SelectWindow(pGLWindow);
aglUpdateContext(pWindowInfo->aglContext);
aglReportError();
// @todo: Sometimes textures in Descent look wierd
// Clearing the textues shouldn't be necessary,
// so updating the context might not be enough.
// to restore the textures (they look wierd after showing he window)
// Textures->Clear();
DisplayManager_SetGlideDisplayGamma(Glide.State.Gamma);
}
void ConvertColorB( GrColor_t GlideColor, FxU8 &R, FxU8 &G, FxU8 &B, FxU8 &A )
{
switch ( Glide.State.ColorFormat )
{
case GR_COLORFORMAT_ARGB: //0xAARRGGBB
A = (FxU8)( ( GlideColor & 0xFF000000 ) >> 24 );
R = (FxU8)( ( GlideColor & 0x00FF0000 ) >> 16 );
G = (FxU8)( ( GlideColor & 0x0000FF00 ) >> 8 );
B = (FxU8)( ( GlideColor & 0x000000FF ) );
break;
case GR_COLORFORMAT_ABGR: //0xAABBGGRR
A = (FxU8)( ( GlideColor & 0xFF000000 ) >> 24 );
B = (FxU8)( ( GlideColor & 0x00FF0000 ) >> 16 );
G = (FxU8)( ( GlideColor & 0x0000FF00 ) >> 8 );
R = (FxU8)( ( GlideColor & 0x000000FF ) );
break;
case GR_COLORFORMAT_RGBA: //0xRRGGBBAA
R = (FxU8)( ( GlideColor & 0xFF000000 ) >> 24 );
G = (FxU8)( ( GlideColor & 0x00FF0000 ) >> 16 );
B = (FxU8)( ( GlideColor & 0x0000FF00 ) >> 8 );
A = (FxU8)( ( GlideColor & 0x000000FF ) );
break;
case GR_COLORFORMAT_BGRA: //0xBBGGRRAA
B = (FxU8)( ( GlideColor & 0xFF000000 ) >> 24 );
G = (FxU8)( ( GlideColor & 0x00FF0000 ) >> 16 );
R = (FxU8)( ( GlideColor & 0x0000FF00 ) >> 8 );
A = (FxU8)( ( GlideColor & 0x000000FF ) );
break;
}
}
GrColor_t ConvertConstantColor( float R, float G, float B, float A )
{
GrColor_t r = (GrColor_t) R;
GrColor_t g = (GrColor_t) G;
GrColor_t b = (GrColor_t) B;
GrColor_t a = (GrColor_t) A;
switch ( Glide.State.ColorFormat )
{
case GR_COLORFORMAT_ARGB: //0xAARRGGBB
return ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | b;
case GR_COLORFORMAT_ABGR: //0xAABBGGRR
return ( a << 24 ) | ( b << 16 ) | ( g << 8 ) | r;
case GR_COLORFORMAT_RGBA: //0xRRGGBBAA
return ( r << 24 ) | ( g << 16 ) | ( b << 8 ) | a;
case GR_COLORFORMAT_BGRA: //0xBBGGRRAA
return ( b << 24 ) | ( g << 16 ) | ( r << 8 ) | a;
}
return 0;
}
void ConvertColorF( GrColor_t GlideColor, float &R, float &G, float &B, float &A )
{
switch ( Glide.State.ColorFormat )
{
case GR_COLORFORMAT_ARGB: //0xAARRGGBB
A = (float)( ( GlideColor & 0xFF000000 ) >> 24 ) * D1OVER255;
R = (float)( ( GlideColor & 0x00FF0000 ) >> 16 ) * D1OVER255;
G = (float)( ( GlideColor & 0x0000FF00 ) >> 8 ) * D1OVER255;
B = (float)( ( GlideColor & 0x000000FF ) ) * D1OVER255;
break;
case GR_COLORFORMAT_ABGR: //0xAABBGGRR
A = (float)( ( GlideColor & 0xFF000000 ) >> 24 ) * D1OVER255;
B = (float)( ( GlideColor & 0x00FF0000 ) >> 16 ) * D1OVER255;
G = (float)( ( GlideColor & 0x0000FF00 ) >> 8 ) * D1OVER255;
R = (float)( ( GlideColor & 0x000000FF ) ) * D1OVER255;
break;
case GR_COLORFORMAT_RGBA: //0xRRGGBBAA
R = (float)( ( GlideColor & 0xFF000000 ) >> 24 ) * D1OVER255;
G = (float)( ( GlideColor & 0x00FF0000 ) >> 16 ) * D1OVER255;
B = (float)( ( GlideColor & 0x0000FF00 ) >> 8 ) * D1OVER255;
A = (float)( ( GlideColor & 0x000000FF ) ) * D1OVER255;
break;
case GR_COLORFORMAT_BGRA: //0xBBGGRRAA
B = (float)( ( GlideColor & 0xFF000000 ) >> 24 ) * D1OVER255;
G = (float)( ( GlideColor & 0x00FF0000 ) >> 16 ) * D1OVER255;
R = (float)( ( GlideColor & 0x0000FF00 ) >> 8 ) * D1OVER255;
A = (float)( ( GlideColor & 0x000000FF ) ) * D1OVER255;
break;
}
}

View File

@ -0,0 +1,43 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* OpenGL Utility File
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Carbon_SetupGL.h"
#include "Carbon_SetupDSP.h"
#include "Carbon_Error_Handler.h"
#include <agl.h>
struct structWindowInfo
{
structGLWindowInfo glInfo;
AGLContext aglContext;
GLuint fontList;
char strContext [256];
};
typedef struct structWindowInfo structWindowInfo;
typedef struct structWindowInfo* structWindowInfoPtr;
extern WindowPtr pGLWindow;
extern structWindowInfoPtr pWindowInfo;
OSStatus aglReportWarning(void);
// General opengl utility functions
bool InitialiseOpenGLWindow( FxU32 hwnd, int x, int y, FxU32 width, FxU32 height );
void FinaliseOpenGLWindow( void );
void HideOpenGLWindow();
void RestoreOpenGLWindow();
void ConvertColor4B( GrColor_t GlideColor, FxU32 &C );
void ConvertColorB( GrColor_t GlideColor, FxU8 &R, FxU8 &G, FxU8 &B, FxU8 &A );
void ConvertColorF( GrColor_t GlideColor, float &R, float &G, float &B, float &A );
GrColor_t ConvertConstantColor( float R, float G, float B, float A );

228
MacGLide/OpenGLide/GlOgl.h Normal file
View File

@ -0,0 +1,228 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Main Header
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef __GLOGL_H__
#define __GLOGL_H__
// #define __WIN32__
#include "sdk2_glide.h"
/*
#define RDTSC(v) __asm _emit 0x0f \
__asm _emit 0x31 \
__asm mov FxU32 ptr v, eax \
__asm mov FxU32 ptr v+4, edx
*/
#define RDTSC(v)
#define OGL_LOG_SEPARATE "--------------------------------------------------------\n"
#define OGL_MIN_FRAME_BUFFER 2
#define OGL_MAX_FRAME_BUFFER 16
#define OGL_MIN_TEXTURE_BUFFER 2
#define OGL_MAX_TEXTURE_BUFFER 32
#define OPENGLFOGTABLESIZE 64 * 1024
#define D1OVER255 0.003921568627451f // 1 / 255
#define D1OVER65536 0.0000152587890625f // 1 / 65536
#define D1OVER65535 0.000015259021896696421759365224689097f // 1 / 65535
#define D1OVER256 0.00390625f // 1 / 256
#define D2OVER256 0.0078125f // 2 / 256
#define D4OVER256 0.015625f // 4 / 256
#define D8OVER256 0.03125f // 8 / 256
#define WBUFFERNEAR -1.0f
#define WBUFFERFAR 0.0f
#define ZBUFFERNEAR 0.0f
#define ZBUFFERFAR -1.0f
// Class declarations
struct BufferStruct
{
bool Lock;
GrLock_t Type;
GrLfbWriteMode_t WriteMode;
GrBuffer_t Buffer;
FxBool PixelPipeline;
FxU16 *Address;
};
struct TexSourceStruct
{
FxU32 StartAddress;
FxU32 EvenOdd;
GrTexInfo Info;
};
union OGLByteColor
{
struct
{
FxU8 B;
FxU8 G;
FxU8 R;
FxU8 A;
};
FxU32 C;
};
struct CombineFunction;
struct CombineArgument;
struct GlideState
{
GrBuffer_t RenderBuffer;
GrDepthBufferMode_t DepthBufferMode;
GrCmpFnc_t DepthFunction;
FxBool DepthBufferWritting;
FxI16 DepthBiasLevel;
GrDitherMode_t DitherMode;
GrColor_t ChromakeyValue;
GrChromakeyMode_t ChromaKeyMode;
GrAlpha_t AlphaReferenceValue;
GrCmpFnc_t AlphaTestFunction;
FxBool AlphaMask;
FxBool ColorMask;
GrColor_t ConstantColorValue;
GrColor_t FogColorValue;
GrFogMode_t FogMode;
GrCullMode_t CullMode;
GrTextureClampMode_t SClampMode;
GrTextureClampMode_t TClampMode;
GrTextureFilterMode_t MinFilterMode;
GrTextureFilterMode_t MagFilterMode;
GrMipMapMode_t MipMapMode;
FxBool LodBlend;
GrCombineFunction_t ColorCombineFunction;
GrCombineFactor_t ColorCombineFactor;
GrCombineLocal_t ColorCombineLocal;
GrCombineOther_t ColorCombineOther;
FxBool ColorCombineInvert;
GrCombineFunction_t AlphaFunction;
GrCombineFactor_t AlphaFactor;
GrCombineLocal_t AlphaLocal;
GrCombineOther_t AlphaOther;
FxBool AlphaInvert;
GrCombineFunction_t TextureCombineCFunction;
GrCombineFactor_t TextureCombineCFactor;
GrCombineFunction_t TextureCombineAFunction;
GrCombineFactor_t TextureCombineAFactor;
FxBool TextureCombineRGBInvert;
FxBool TextureCombineAInvert;
GrOriginLocation_t OriginInformation;
TexSourceStruct TexSource;
GrAlphaBlendFnc_t AlphaBlendRgbSf;
GrAlphaBlendFnc_t AlphaBlendRgbDf;
GrAlphaBlendFnc_t AlphaBlendAlphaSf;
GrAlphaBlendFnc_t AlphaBlendAlphaDf;
FxU32 ClipMinX;
FxU32 ClipMaxX;
FxU32 ClipMinY;
FxU32 ClipMaxY;
GrColorFormat_t ColorFormat;
FxU32 STWHint;
FxBool VRetrace;
FxFloat LodBias;
bool Delta0Mode;
FxFloat Delta0ModeColor[4];
FxFloat Gamma;
};
struct GlideStruct
{
int ActiveVoodoo;
// Frame Buffer Stuff
int WindowWidth;
int WindowHeight;
int WindowTotalPixels;
GrScreenResolution_t Resolution;
GrScreenRefresh_t Refresh;
int NumBuffers;
int AuxBuffers;
// States and Constants
FxU8 FogTable[ GR_FOG_TABLE_SIZE + 1 ];
FxU32 TexMemoryMaxPosition;
bool CLocal;
bool COther;
bool ALocal;
bool AOther;
GlideState State;
BufferStruct TempBuffer;
BufferStruct FrameBuffer;
BufferStruct ReadBuffer;
FxU32 TextureMemory;
};
struct OpenGLStruct
{
bool GlideInit;
bool WinOpen;
unsigned long WindowWidth;
unsigned long WindowHeight;
FxU32 OriginX;
FxU32 OriginY;
FxU32 ClipMinX;
FxU32 ClipMaxX;
FxU32 ClipMinY;
FxU32 ClipMaxY;
GLfloat Gamma;
GLfloat AlphaReferenceValue;
GLenum AlphaTestFunction;
GLboolean DepthBufferWritting;
GLfloat DepthBiasLevel;
GLenum DepthFunction;
int DepthBufferType;
GLenum RenderBuffer;
GLenum SClampMode;
GLenum TClampMode;
GLenum MinFilterMode;
GLenum MagFilterMode;
GLenum SrcBlend;
GLenum DstBlend;
GLenum SrcAlphaBlend;
GLenum DstAlphaBlend;
GLuint Refresh;
GLfloat ConstantColor[4];
GLfloat Delta0Color[4];
GLfloat AlphaColor[4];
GLfloat ZNear;
GLfloat ZFar;
GLint ColorAlphaUnit1;
GLint ColorAlphaUnit2;
bool ColorAlphaUnitColorEnabledState[2];
bool ColorAlphaUnitAlphaEnabledState[2];
GLuint DummyTextureName;
GLint FogTextureUnit;
bool FogTextureUnitEnabledState;
GLfloat FogColor[4];
OGLByteColor ChromaColor;
bool Fog;
bool ColorTexture;
bool AlphaTexture;
bool Blend;
bool Texture;
bool ChromaKey;
bool Clipping;
bool ClipVerticesEnabledState;
int MultiTextureTMUs;
const CombineFunction* ColorCombineFunctions;
const CombineFunction* AlphaCombineFunctions;
const CombineArgument* ColorCombineArguments[5];
const CombineArgument* AlphaCombineArguments[5];
FxU32 WaitSignal;
FxU8 FogTable[OPENGLFOGTABLESIZE];
};
#endif

View File

@ -0,0 +1,21 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* OpenGL Extensions Header
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef __GLEXTENSIONS__
#define __GLEXTENSIONS__
void ValidateUserConfig();
void GLExtensions( );
void GLExtensionsCleanup();
bool OGLIsExtensionSupported(const char* extension);
#endif

View File

@ -0,0 +1,475 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Main File
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Glide.h"
#include "GlideApplication.h"
#include "GlideDisplay.h"
#include "GlideFramebuffer.h"
#include "GlideSettings.h"
#include "GLextensions.h"
#include "GLUtil.h"
#include "PGTexture.h"
#include "PGUTexture.h"
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Version numbers ///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
const char* OpenGLideVersion = "0.13a1";
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
// Structs
GlideStruct Glide;
OpenGLStruct OpenGL;
GlideSettingsImpl UserConfig;
GlideSettingsImpl InternalConfig;
PGTexture* Textures = NULL;
PGUTexture UTextures;
GlideFramebuffer s_Framebuffer;
// Number of Errors
unsigned long NumberOfErrors;
OSErr InitMainVariables(void)
{
OpenGL.WinOpen = false;
OpenGL.GlideInit = false;
NumberOfErrors = 0;
OSErr err = UserConfig.load();
if (err == noErr)
{
// The following values must be updated right away, because the client application
// might call grSstQueryHardware() before opening a window
if ((UserConfig.TextureMemorySize >= OGL_MIN_TEXTURE_BUFFER) &&
(UserConfig.TextureMemorySize <= OGL_MAX_TEXTURE_BUFFER))
{
UserConfig.TextureMemorySize = UserConfig.TextureMemorySize;
}
if ((UserConfig.FrameBufferMemorySize >= OGL_MIN_FRAME_BUFFER) &&
(UserConfig.FrameBufferMemorySize <= OGL_MAX_FRAME_BUFFER))
{
UserConfig.FrameBufferMemorySize = UserConfig.FrameBufferMemorySize;
}
if (UserConfig.BoardType < OpenGLideBoardType_Voodoo)
{
UserConfig.BoardType = OpenGLideBoardType_Voodoo;
}
else if (UserConfig.BoardType > OpenGLideBoardType_Voodoo2)
{
UserConfig.BoardType = OpenGLideBoardType_Voodoo2;
}
if (UserConfig.GlideTextureUnits < 1)
{
UserConfig.GlideTextureUnits = 1;
}
else if (UserConfig.GlideTextureUnits > 3)
{
UserConfig.GlideTextureUnits = 3;
}
// Apply mandatory application dependent settings/patches
GlideApplication::Type application = s_GlideApplication.GetType();
switch (application)
{
case GlideApplication::Quake:
{
// Quake would not display anything without fixing the memory
unsigned int megabytes = 4;
if (UserConfig.FrameBufferMemorySize > megabytes)
{
UserConfig.FrameBufferMemorySize = megabytes;
GlideMsg("Decreased frmaebuffer memory size to %d megabytes to make Quake 3Dfx happy\n");
}
}
break;
}
// Apply optional game specific settings
if (UserConfig.AutoEnableGameSpecificSettings)
{
bool texturesmoothing = false;
bool subtextures = false;
bool gapfix = false;
switch(application)
{
case GlideApplication::Carmageddon:
texturesmoothing = true;
break;
case GlideApplication::MythTFL:
texturesmoothing = true;
break;
case GlideApplication::Falcon40:
texturesmoothing = true;
break;
case GlideApplication::TombRaiderI:
texturesmoothing = true;
subtextures = true;
gapfix = true;
break;
case GlideApplication::TombRaiderII:
// subtextures = true; // works but slow
gapfix = true;
break;
default:
break;
}
if (texturesmoothing || subtextures || gapfix)
{
GlideMsg("Auto-enabling game specific settings for %s:\n", s_GlideApplication.GetName());
}
// Suppress artefacts in main menu
if (texturesmoothing)
{
UserConfig.TextureSmoothing = true;
GlideMsg("TextureSmoothing enabled\n");
}
if (subtextures)
{
UserConfig.GenerateSubTextures = 8; // Good for TR1 and TR2
GlideMsg("Subtexture generation enabled\n");
}
if (gapfix)
{
UserConfig.GapFix = static_cast<OpenGLideGapFixFlags>(UserConfig.GapFix | (OpenGLideGapFixFlag_Enabled));
GlideMsg("GapFix enabled\n");
}
}
}
if (err != noErr) GlideError("Failed to load user config file: Error code %d", err);
return err;
}
bool InitWindow(FxU32 hwnd)
{
if (InitialiseOpenGLWindow(hwnd, 0, 0, OpenGL.WindowWidth, OpenGL.WindowHeight) == false)
{
return FXFALSE;
}
// Initialise some basic OpenGL() settings
InitOpenGL();
// Continue initialising OpenGL with processing
// the user config and setup OpenGL extensions
ValidateUserConfig();
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg( "Configuration:\n");
GlideMsg( OGL_LOG_SEPARATE );
char sEnabled[] = "enabled";
char sDisabled[] = "disabled";
const char* boardnames[4] = {"Voodoo", "Voodoo Rush", "AT3D", "Voodoo 2"};
GlideMsg( "Board type = %s\n", boardnames[InternalConfig.BoardType]);
GlideMsg( "Number of Texture Units = %d\n", InternalConfig.GlideTextureUnits );
GlideMsg( "Texture Memory Size = %d Mb\n", InternalConfig.TextureMemorySize );
GlideMsg( "Frame Buffer Memory Size = %d Mb\n", InternalConfig.FrameBufferMemorySize );
GlideMsg( "Display method = %d\n", InternalConfig.DisplayMode);
// display resolution
GlideMsg("Display resolution = %dx%d\n", OpenGL.WindowWidth, OpenGL.WindowHeight);
if (InternalConfig.MonitorRefreshRate > 0)
{
GlideMsg( "Monitor Refresh Rate = %d\n", InternalConfig.MonitorRefreshRate );
}
GlideMsg("Mipmapping %s\n", InternalConfig.Mipmapping ? sEnabled : sDisabled );
if (InternalConfig.AnisotropylLevel >= 2 && InternalConfig.EXT_texture_filter_anisotropic)
{
GlideMsg("Selected level of anisotropy = %d\n", InternalConfig.AnisotropylLevel);
}
else
{
GlideMsg("Anisotropic texture filtering disabled\n");
}
if (InternalConfig.FullSceneAntiAliasing == 0)
{
GlideMsg("FullSceneAntiAliasing disabled\n");
}
else
{
GlideMsg("FullSceneAntiAliasing enabled, using %d samples\n", InternalConfig.FullSceneAntiAliasing);
}
GlideMsg("TextureSmoothing = %s\n", InternalConfig.TextureSmoothing ? sEnabled : sDisabled );
GlideMsg("Precision Fix = %s\n", InternalConfig.PrecisionFix ? sEnabled : sDisabled );
bool gapfix_enabled = InternalConfig.GapFix & OpenGLideGapFixFlag_Enabled;
GlideMsg("GapFix = %s\n", gapfix_enabled ? sEnabled : sDisabled);
if (gapfix_enabled)
{
GlideMsg(" Debug = %s\n", InternalConfig.GapFix & OpenGLideGapFixFlag_Debug ? sEnabled : sDisabled);
GlideMsg(" IncircleFilterOr = %s\n", InternalConfig.GapFix & OpenGLideGapFixFlag_IncircleOr ? sEnabled : sDisabled);
GlideMsg(" IncircleFilterAnd = %s\n", InternalConfig.GapFix & OpenGLideGapFixFlag_IncircleAnd ? sEnabled : sDisabled);
GlideMsg(" IncircleFilterSecondRadius = %s\n", InternalConfig.GapFix & OpenGLideGapFixFlag_IncircleSecondRadius ? sEnabled : sDisabled);
GlideMsg("VertexLengthFilterSecondRadius = %s\n", InternalConfig.GapFix & OpenGLideGapFixFlag_VertexLengthSecondRadius ? sEnabled : sDisabled);
GlideMsg(" 1st radius = %g\n", InternalConfig.GapFixParam1);
if (InternalConfig.GapFix & OpenGLideGapFixFlag_VertexLengthSecondRadius)
{
GlideMsg(" Vertex Length = %g\n", InternalConfig.GapFixParam2);
}
else
{
GlideMsg(" triangle isoscelesness= %g\n", InternalConfig.GapFixParam2);
}
if ((InternalConfig.GapFix & OpenGLideGapFixFlag_IncircleSecondRadius) || (InternalConfig.GapFix & OpenGLideGapFixFlag_VertexLengthSecondRadius))
{
GlideMsg(" 2nd radius = %g\n", InternalConfig.GapFixParam3);
}
if (InternalConfig.GapFix & OpenGLideGapFixFlag_DepthFactor)
{
GlideMsg(" Depth Factor = %g\n", InternalConfig.GapFixDepthFactor);
}
}
GlideMsg("Generate subtextures = %s", InternalConfig.GenerateSubTextures ? sEnabled : sDisabled );
if (InternalConfig.GenerateSubTextures) GlideMsg(" (gridsize = %d)", InternalConfig.GenerateSubTextures);
GlideMsg("\n");
GlideMsg("Framebuffer overlays = %s\n", InternalConfig.EnableFrameBufferOverlays ? sEnabled : sDisabled );
GlideMsg("Framebuffer underlays = %s\n", InternalConfig.EnableFrameBufferUnderlays ? sEnabled : sDisabled );
if (InternalConfig.FramebufferIgnoreUnlock) GlideMsg( "Ignore buffer unlocks = %s\n", InternalConfig.FramebufferIgnoreUnlock ? sEnabled : sDisabled);
if (InternalConfig.PedanticFrameBufferEmulation) GlideMsg( "Pedantic Framebuffer emulation = %s\n", InternalConfig.PedanticFrameBufferEmulation ? sEnabled : sDisabled);
GlideMsg(OGL_LOG_SEPARATE);
#ifdef OGL_DEBUG
GlideMsg("GlideState size = %d\n", sizeof(GlideState));
GlideMsg("GrState size = %d\n", sizeof(GrState));
GlideMsg(OGL_LOG_SEPARATE);
#endif
GlideMsg("** Glide Calls **\n" );
GlideMsg(OGL_LOG_SEPARATE);
return true;
}
void* AllocFrameBuffer(long buffersize, long buffertypesize)
{
void* buffer = AllocSysPtr16ByteAligned(buffersize * buffertypesize);
if (buffer == NULL)
{
GlideError("Could NOT allocate sufficient memory for framebuffer... Sorry.");
exit( -1 );
}
return buffer;
}
void FreeFrameBuffer(void* buffer)
{
Free16ByteAligned(buffer);
}
void* AllocBuffer(long buffersize, long buffertypesize)
{
void* buffer = AllocSysPtr16ByteAligned(buffersize * buffertypesize);
if (buffer == NULL)
{
GlideError("Could NOT allocate sufficient memory for buffer... Sorry.");
exit( -1 );
}
return buffer;
}
void FreeBuffer(void* buffer)
{
Free16ByteAligned(buffer);
}
void* AllocObject(long buffersize)
{
// Causes classic to crash
void* buffer = AllocSysPtr16ByteAligned(buffersize);
if (buffer == NULL)
{
GlideError("Could NOT allocate sufficient memory for object... Sorry.");
exit( -1 );
}
return buffer;
}
void FreeObject(void* buffer)
{
Free16ByteAligned(buffer);
}
// error handling
#ifdef OPENGL_DEBUG
OSStatus glReportError_impl (const char* __glide_functionname)
{
char* errortext = NULL;
GLenum err = glGetError();
switch (err)
{
case GL_NO_ERROR:
break;
case GL_INVALID_ENUM:
errortext = "Invalid enumeration";
break;
case GL_INVALID_VALUE:
errortext ="Invalid value";
break;
case GL_INVALID_OPERATION:
errortext = "Invalid operation";
break;
case GL_STACK_OVERFLOW:
errortext = "Stack overflow";
break;
case GL_STACK_UNDERFLOW:
errortext = "Stack underflow";
break;
case GL_OUT_OF_MEMORY:
errortext = "Out of memory";
break;
default:
errortext = "Unknown error code";
break;
}
if (errortext)
{
GlideMsg ("Function %s, GL Error: %s\n", __glide_functionname, errortext);
}
// ensure we are returning an OSStatus noErr if no error condition
if (err == GL_NO_ERROR)
return noErr;
else
return (OSStatus) err;
}
#endif
#if defined(OPTIMISE_OPENGL_STATE_CHANGES) || defined(OGL_DEBUG) || defined(OPENGL_DEBUG)
bool VerifyActiveTextureUnit_impl(GLint x, const char* functionname)
{
glReportErrors("VerifyActiveTextureUnit_impl");
GLint y;
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &y);
glReportError();
bool bVerified = x == y;
if (!bVerified)
{
GlideMsg("Warning: %s() active texture unit is GL_TEXTURE%d_ARB, but should be GL_TEXTURE%d_ARB\n", functionname, y - GL_TEXTURE0_ARB, x - GL_TEXTURE0_ARB);
}
return bVerified;
}
#endif
#if defined(OPTIMISE_OPENGL_STATE_CHANGES) || defined(OGL_DEBUG) || defined(OPENGL_DEBUG)
bool VerifyTextureEnabledState_impl(const char* functionname)
{
glReportErrors("VerifyActiveTextureUnit_impl");
// emember state
GLint current;
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &current);
glReportError();
bool bVerified = true;
if (OpenGL.ColorAlphaUnit2)
{
for(long unit_index = 1; unit_index >= 0; unit_index--)
{
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
bool bState = glIsEnabled(GL_TEXTURE_2D);
if (bState != (OpenGL.ColorAlphaUnitColorEnabledState[unit_index] ||
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index]))
{
GlideMsg("Warning: texture unit GL_TEXTURE%d_ARB is %s in %s()\n", OpenGL.ColorAlphaUnit1 + unit_index - GL_TEXTURE0_ARB, bState ? "enabled" : "disabled", functionname);
bVerified = false;
}
glReportError();
}
}
// Restore previous state
glActiveTextureARB(current);
return bVerified;
}
#endif
//*************************************************
//* Initializes OpenGL
//*************************************************
void InitOpenGL( void )
{
OpenGL.ZNear = ZBUFFERNEAR;
OpenGL.ZFar = ZBUFFERFAR;
OpenGL.ClipMinX = 0;
OpenGL.ClipMinY = 0;
OpenGL.ClipMaxX = OpenGL.WindowWidth;
OpenGL.ClipMaxY = OpenGL.WindowHeight;
// Glide texture data is aligned at 8 byte boundaries
int alignment = 8;
glPixelStorei( GL_PACK_ALIGNMENT, alignment);
glPixelStorei( GL_UNPACK_ALIGNMENT, alignment);
}
void GlideMsg(const char* message, ... )
{
va_list(args);
va_start(args, message);
char buffer[StringBufferSize];
vsnprintf(buffer, StringBufferSize, message, args);
UserConfig.write_log(buffer);
va_end(args);
}
void GlideError(const char *message, ... )
{
va_list(args);
va_start(args, message);
char buffer[StringBufferSize];
NumberOfErrors++;
vsnprintf(buffer, StringBufferSize, message, args);
GlideMsg(buffer);
va_end(args);
grGlideShutdown();
if (UserConfig.DisplayMode == OpenGLideDisplayMode_DisplayManager)
{
DisplayManager_RestoreDesktopDisplay();
}
FatalErrorMessageBox(buffer);
exit(0);
}
bool ClearAndGenerateLogFile( void )
{
UserConfig.create_log();
char buffer[32];
GlideMsg(OGL_LOG_SEPARATE );
GlideMsg("%s Log File\n", OpenGLideProductName);
GlideMsg(OGL_LOG_SEPARATE );
GlideMsg("***** %s %s *****\n", OpenGLideProductName, OpenGLideVersion);
GlideMsg(OGL_LOG_SEPARATE );
_strdate(buffer);
GlideMsg("Date: %s\n", buffer);
_strtime(buffer);
GlideMsg("Time: %s\n", buffer);
GlideMsg("Application: %s\n", s_GlideApplication.GetName());
return true;
}
void CloseLogFile( void )
{
char tmpbuf[ 128 ];
GlideMsg( OGL_LOG_SEPARATE );
_strtime( tmpbuf );
GlideMsg( "Time: %s\n", tmpbuf );
GlideMsg( OGL_LOG_SEPARATE );
}

142
MacGLide/OpenGLide/Glide.h Normal file
View File

@ -0,0 +1,142 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Shared Library entry points
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
#include "GlideFramebuffer.h"
#include "GlideSettings_FSp.h"
typedef GlideSettingsFSp GlideSettingsImpl;
#ifdef OPENGLIDE_HOST_MAC
#include "MacGlide.h"
#endif
// Pointer to version string
extern const char* OpenGLideVersion;
// Product name of the library
extern const char* OpenGLideProductName;
// extern double ClockFreq;
extern GlideStruct Glide; // Glide Internal
extern OpenGLStruct OpenGL; // OpenGL equivalents
extern GlideSettingsImpl UserConfig;
extern GlideSettingsImpl InternalConfig;
// GLide
OSErr InitMainVariables();
bool InitWindow( FxU32 hwnd );
void InitOpenGL( void );
bool ClearAndGenerateLogFile( void );
void CloseLogFile( void );
// Memory management
void* AllocFrameBuffer(long buffersize, long buffertypesize);
void FreeFrameBuffer(void* address);
void* AllocBuffer(long buffersize, long buffertypesize);
void FreeBuffer(void* address);
void* AllocObject(long buffersize);
void FreeObject(void* buffer);
// Platform specific
void* AllocSysPtr16ByteAligned(long buffersize);
void Free16ByteAligned(void* aligned_buffer);
// framebuffer emulation
extern GlideFramebuffer s_Framebuffer;
// endianess
inline void swaplong(void* l)
{
unsigned char* v = reinterpret_cast<unsigned char*>(l);
unsigned char n[4];
n[0] = v[3]; n[1] = v[2]; n[2] = v[1]; n[3] = v[0];
*reinterpret_cast<unsigned long*>(l) = *reinterpret_cast<unsigned long*>(n);
}
inline void swapshort(void* s)
{
unsigned char* v = reinterpret_cast<unsigned char*>(s);
unsigned char n[2];
n[0] = v[1]; n[1] = v[0];
*reinterpret_cast<unsigned short*>(s) = *reinterpret_cast<unsigned short*>(n);
}
inline void swaplong(void* d, const void* l)
{
const unsigned char* v = reinterpret_cast<const unsigned char*>(l);
unsigned char n[4];
n[0] = v[3]; n[1] = v[2]; n[2] = v[1]; n[3] = v[0];
*reinterpret_cast<unsigned long*>(d) = *reinterpret_cast<unsigned long*>(n);
}
inline void swapshort(void* d, const void* s)
{
const unsigned char* v = reinterpret_cast<const unsigned char*>(s);
unsigned char n[2];
n[0] = v[1]; n[1] = v[0];
*reinterpret_cast<unsigned short*>(d) = *reinterpret_cast<unsigned short*>(n);
}
#define max(X,Y) ( (X) > (Y) ? (X) : (Y) )
#define min(X,Y) ( (X) < (Y) ? (X) : (Y) )
// size of temporary buffers for string processing
const int StringBufferSize = 256;
void GlideMsg(const char *message, ...);
void GlideError(const char *message, ...);
extern void FatalErrorMessageBox(const char* message);
// error handling and debugging
#ifdef OPENGL_DEBUG
OSStatus glReportError_impl(const char* __glide_functionname);
#ifdef OGL_STOP_ON_GL_ERROR
#define glReportError() assert(GL_NO_ERROR == glReportError_impl(__glide_functionname));
#else
#define glReportError() glReportError_impl(__glide_functionname);
#endif
#define glReportErrors(name) const char* __glide_functionname = name
#else
#define glReportError()
#define glReportErrors(name)
#endif
// Optimising the code
#ifdef OPTIMISE_GLIDE_STATE_CHANGES
#define CHECK_STATE_CHANGED(x) if (x) return
#else
#define CHECK_STATE_CHANGED(x)
#endif
// Veryfying state
#if defined(OPTIMISE_OPENGL_STATE_CHANGES) && defined(OPENGL_DEBUG)
bool VerifyActiveTextureUnit_impl(GLint x, const char* functionname);
#ifdef OGL_STOP_ON_GL_ERROR
#define VERIFY_ACTIVE_TEXTURE_UNIT(x) assert(VerifyActiveTextureUnit_impl(x, __glide_functionname));
#else
#define VERIFY_ACTIVE_TEXTURE_UNIT(x) VerifyActiveTextureUnit_impl(x, __glide_functionname);
#endif
#else
#define VERIFY_ACTIVE_TEXTURE_UNIT(x)
#endif
#if defined(OPTIMISE_OPENGL_STATE_CHANGES) && defined(OPENGL_DEBUG)
bool VerifyTextureEnabledState_impl(const char* functionname);
#ifdef OGL_STOP_ON_GL_ERROR
#define VERIFY_TEXTURE_ENABLED_STATE() assert(VerifyTextureEnabledState_impl(__glide_functionname));
#else
#define VERIFY_TEXTURE_ENABLED_STATE() VerifyTextureEnabledState_impl(__glide_functionname);
#endif
#else
#define VERIFY_TEXTURE_ENABLED_STATE()
#endif

View File

@ -0,0 +1,39 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Glide application management
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
class GlideApplication
{
public:
GlideApplication();
enum Type
{
Generic,
Carmageddon,
Carmageddon2,
FA18,
Falcon40,
FutureCop,
MythTFL,
Quake,
TombRaiderI,
TombRaiderII,
TombRaiderIII
};
const char* GetName() const {return &m_Name[1];};
inline const Type GetType() const {return m_Type;};
protected:
void Init();
char m_Name[33];
Type m_Type;
};
extern GlideApplication s_GlideApplication;

View File

@ -0,0 +1,28 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Macintosh display
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
void DisplayManager_Initialise();
void DisplayManager_Cleanup();
OSErr DisplayManager_SetGlideDisplay(unsigned int width, unsigned int height, unsigned int freq);
OSErr DisplayManager_RememberPassthroughDisplay();
OSErr DisplayManager_RememberDesktopDisplay();
OSErr DisplayManager_RestoreGlideDisplay();
OSErr DisplayManager_RestorePassthroughDisplay();
OSErr DisplayManager_RestoreDesktopDisplay();
bool DisplayManager_GetDesktopDisplayResolution(unsigned long& width, unsigned long& height);
bool DisplayManager_GetGlideDisplayResolution(unsigned long& width, unsigned long& height);
// gamma related functions
void DisplayManager_SetGlideDisplayGamma(FxFloat gamma);
void DisplayManager_SetGlideDisplayGammaBlack();
void DisplayManager_SetPassthroughDisplayGammaBlack();
void DisplayManager_RestorePassthroughDisplayGamma();
void DisplayManager_SetDesktopDisplayGammaBlack();

View File

@ -0,0 +1,542 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Glide framebuffer emulation
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "driversrc_declarations.h"
#include "GlideApplication.h"
#include "GlideFramebuffer.h"
#include "GlideSettings.h"
// Optimised framebuffer tile layout for Carmageddon: Minimise calls to glTexImage2D
// Note: Carmageddon uses only the glide resolution 640x480.
// The sum of the first column must be 480 (vertical resolution)
// The sum of each row must be 640 (horizontal resolution)
// This does not apply to drawing the underlay
// (Underlays are drawn with max tile sizes because they're usally used to draw backgrounds)
const Framebuffer::tilesize GlideFramebuffer::tilesize_table_carmageddon[11] =
{
{ 64, {128,128, 8,128,128, 64, 32, 16, 8,0,0}},
{ 64, {128,128,128,128, 64, 64, 0, 0, 0,0,0,0}},
{ 32, {128,128,128,128,128, 0, 0, 0, 0,0,0,0}},
{ 32, {128,128,128,128,128, 0, 0, 0, 0,0,0,0}},
{ 32, {128,128,128,128,128, 0, 0, 0, 0,0,0,0}},
{ 32, {128,128,128,128,128, 0, 0, 0, 0,0,0,0}},
{ 32, {128,128,128,128,128, 0, 0, 0, 0,0,0,0}},
{ 32, {128,128,128,128,128, 0, 0, 0, 0,0,0,0}},
{ 32, {128,128,128,128,128, 0, 0, 0, 0,0,0,0}},
{ 64, { 8,128,256,128, 32, 8, 64, 16, 0,0,0,0}},
{ 64, { 8,128,256,128, 32, 8, 64, 16, 0,0,0,0}}
};
GlideFramebuffer::GlideFramebuffer()
: m_write_opaque(false)
, m_must_write(false)
, m_renderbuffer_changed(false)
, m_renderbuffer_changed_for_read(false)
, m_depth(0.0f)
, m_alpha(0x000000ff)
, m_chromakeyvalue_changed(false)
, m_chromakeyvalue_new(0x0)
, m_bufferclearcalls(0)
{
}
GlideFramebuffer::~GlideFramebuffer()
{
}
void GlideFramebuffer::initialise(BufferStruct* framebuffer, BufferStruct* texbuffer)
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::initialise(---, ---)\n");
#endif
m_grLfbLockWriteMode[0] = GR_LFBWRITEMODE_UNUSED;
m_grLfbLockWriteMode[1] = GR_LFBWRITEMODE_UNUSED;
m_grLfbLockWriteMode[2] = GR_LFBWRITEMODE_UNUSED;
m_grLfbLockWriteMode[3] = GR_LFBWRITEMODE_UNUSED;
m_grLfbLockWriteMode[4] = GR_LFBWRITEMODE_UNUSED;
m_grLfbLockWriteMode[5] = GR_LFBWRITEMODE_UNUSED;
GlideApplication::Type application = s_GlideApplication.GetType();
if (application == GlideApplication::Carmageddon && Glide.WindowWidth == 640 && Glide.WindowHeight == 480)
{
initialise_buffers( framebuffer, texbuffer,
Glide.WindowWidth, Glide.WindowHeight,
tilesize_table_carmageddon, InternalConfig.EXT_Client_Storage);
}
else
{
initialise_buffers( framebuffer, texbuffer,
Glide.WindowWidth, Glide.WindowHeight,
128, 128, InternalConfig.EXT_Client_Storage);
}
framebuffer->WriteMode = GR_LFBWRITEMODE_UNUSED;
texbuffer->WriteMode = GR_LFBWRITEMODE_UNUSED;
}
void GlideFramebuffer::OnBufferLockStartWrite(GrLock_t dwType, GrBuffer_t dwBuffer, GrLfbWriteMode_t dwWriteMode, GrOriginLocation_t dwOrigin, FxBool bPixelPipeline)
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnBufferLockStartWrite(%d)\n", dwOrigin);
#endif
// Finish current write if buffer properties are about to change
if (m_must_write &&
(m_framebuffer->WriteMode != dwWriteMode ||
m_framebuffer->PixelPipeline != bPixelPipeline ||
m_origin != dwOrigin ||
(m_chromakeyvalue_changed && bPixelPipeline)))
{
// @todo: If the condition would trigger the frame buffer write
// in Falcon 4.0 (which it doesn't), parts of the cockpit overlay
// would appear twice or at unexpected places. This suggests there
// might be a bug in here (in conjunction with clipping??).
// Also be careful regarding performance issues.
WriteFrameBuffer(m_framebuffer->PixelPipeline);
m_must_write = false;
}
// Change format?
if (m_framebuffer->WriteMode != dwWriteMode)
{
if (dwWriteMode == GR_LFBWRITEMODE_565 ||
dwWriteMode == GR_LFBWRITEMODE_1555 ||
dwWriteMode == GR_LFBWRITEMODE_888)
{
initialise_format(dwWriteMode);
}
// The chromakey value is not flagged as changed here,
// because the initialise_format() function just changes
// the current value, not the new one
}
// Apply new values
m_grLfbLockWriteMode[m_framebuffer->Buffer] = dwWriteMode;
m_framebuffer->Lock = true;
m_framebuffer->Type = dwType;
m_framebuffer->WriteMode = dwWriteMode;
m_framebuffer->Buffer = dwBuffer;
m_framebuffer->PixelPipeline = bPixelPipeline;
m_origin = dwOrigin;
// Update chromakeyvalue for pixel pipeline
if (m_chromakeyvalue_changed && m_framebuffer->PixelPipeline)
{
// Apply changes to the frame buffer
m_ChromaKey = m_chromakeyvalue_new;
m_chromakeyvalue_changed = false;
m_must_clear_buffer = true;
begin_write();
}
else if (m_must_write == false)
{
// If we don't have to flush the framebuffer, then no write
// operation is in progress and we must start a new one
// (and clear the buffer if necessary)
begin_write();
}
m_must_write = true;
}
void GlideFramebuffer::OnBufferUnlockEndWrite(GrBuffer_t dwBuffer)
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnBufferUnlockEndWrite(%d)\n", dwBuffer);
#endif
// continuing to write into the framebuffer is toggeled by not setting back
// the buffer write mode flag. As a result, we don't have to query for the
// FramebufferIgnoreUnlock elsewhere (only if we want to defer drawing).
if (!InternalConfig.FramebufferIgnoreUnlock)
{
// reset buffer write mode to indicate the buffer is no more in use
m_grLfbLockWriteMode[dwBuffer] = GR_LFBWRITEMODE_UNUSED;
}
// When the pixel pipeline is enabled, the buffer must be written right away,
// in order to avoid commands like grColorCombine() etc. changing the
// pixel pipeline state before the buffer will eventtually be written out.
if (m_framebuffer->PixelPipeline)
{
WriteFrameBuffer(true);
// This write is finished
m_must_write = false;
}
// If the pixelpipeline is disabled, writing the frame buffer is defered
// until the next call to OnRenderDrawTriangles() or OnBeforeBufferSwap()
// m_must_write is not set to "true" here because it has already been set
// in OnBufferLockStartWrite()
}
/*
void GlideFramebuffer::OnBufferNumPending()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnBufferNumPending()\n");
#endif
// Defer writing the frame buffer until the next call to
// OnRenderDrawTriangles() or OnBeforeBufferSwap().
// Only the back buffer is checked as front and backbuffer locks
// share the same Glide buffer.
if (BackBufferIsLocked())
{
// Update: This should be obsolete as the
// flag is set in OnAfterBufferSwap()
// m_must_write = true;
}
}
*/
/*
void GlideFramebuffer::OnSetIdle()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnSetIdle()\n");
#endif
// Defer writing the frame buffer until the next call to
// OnRenderDrawTriangles() or OnBeforeBufferSwap().
// Only the back buffer is checked as front and backbuffer locks
// share the same Glide buffer.
if (BackBufferIsLocked())
{
// Disabled in favour of better frame rates
// Uncomment if PedanticFrameBufferEmulation
// reveals otherwise unrendered graphics
// Update: This should be obsolete as the
// flag is set in OnAfterBufferSwap()
// m_must_write = true;
}
}
*/
void GlideFramebuffer::OnClipWindow()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnClipWindow()\n");
#endif
// When the clip window changes, and the pixel pipeline is enabled
// and the clip window applies to framebuffer writes, so the current
// contents of the frame buffer must be rendered.
// @todo: This must be reconsidered because it triggers all the time
if (m_framebuffer->PixelPipeline)
{
WriteFrameBuffer(true);
// Keep writing as the frame buffer may still be locked
m_must_write = m_framebuffer->Lock;
// @todo: Think this is obsolete as the case is catched by OnChromaKeyValueChanged()
if (m_chromakeyvalue_changed)
{
m_ChromaKey = m_chromakeyvalue_new;
m_chromakeyvalue_changed = false;
// Fill the framebuffer with the new chromakey value
m_must_clear_buffer = true;
}
if (m_must_write)
{
begin_write();
}
}
}
void GlideFramebuffer::OnBeforeBufferClear()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnBufferClear()\n");
#endif
// Render Carma retro mirror
if (s_GlideApplication.GetType() == GlideApplication::Carmageddon &&
!InternalConfig.PedanticFrameBufferEmulation)
{
// ignore solid colored backgrounds (happens in some levels)
if (Glide.State.ColorMask == false)
{
m_bufferclearcalls++;
if (m_bufferclearcalls == 2)
{
// Trigger write in order to render cockpit layer before the retro mirror 3D-view
#ifdef OGL_FRAMEBUFFER
GlideMsg( "Triggering write in order to render cockpit layer before the retro mirror 3D-view\n");
#endif
m_must_write = true;
}
else if (m_write_opaque == false)
{
// This is be needed to render the 3D-View in the map screen
// in levels without a background texture. In these levels, the
// background of the 3d_View is cleared by writing a fog colored
// rectangle to the framebuffer, and this data must be rendered
// before the 3D-View (or it will be deleted before buffer swap)
#ifdef OGL_FRAMEBUFFER
GlideMsg( "Triggering write in order to make 3D-View in map mode visible\n");
#endif
m_must_write = true;
}
else if (m_framebuffer->Address[Glide.WindowTotalPixels >> 1] == m_ChromaKey)
{
// In Carmageddon, an opaque background is written to the frame buffer
// as the background for the Car Damage screen. By peeking just one pixel
// the framebuffer opaque render call can be avoided whilst in race mode.
// This triggers in levels with a background texture.
#ifdef OGL_FRAMEBUFFER
GlideMsg( "Detected background texture - skipping framebuffer underlay write\n");
#endif
m_write_opaque = false;
m_must_write = false;
}
}
else
{
// In levels without background texture, the background is cleared with
// grBufferClear() during the race, and we can skip writing the underlays
#ifdef OGL_FRAMEBUFFER
GlideMsg( "Detected opaque background - Skipping framebuffer underlay write in order to improve frame rate\n");
#endif
m_write_opaque = false;
m_must_write = false;
}
}
}
void GlideFramebuffer::OnLfbReadRegion()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnLfbReadRegion()\n");
#endif
if (s_GlideApplication.GetType() == GlideApplication::Carmageddon)
{
#ifdef OPENGL_DEBUG
GlideMsg("Framebuffer unlocks will be ignored from now on in order to display the framebuffer's content\n");
#endif
// Carmageddon unlocks the write buffer when moving the cursor
// in Movie mode, causing its contents not being displayed anymore.
// To avoid this, we must ignore the unlock.
InternalConfig.FramebufferIgnoreUnlock = true;
}
}
void GlideFramebuffer::OnRenderDrawTriangles()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnRenderDrawTriangles()\n");
#endif
// determine whether to write the underlays
if (m_write_opaque && m_must_write)
{
if (InternalConfig.EnableFrameBufferUnderlays)
{
// write underlays
end_write_opaque();
}
else
{
// clear the buffer in order to prevent drawing the underlays
// as an overlay in a subsequent write
m_must_clear_buffer = true;
}
}
else if (InternalConfig.PedanticFrameBufferEmulation || m_must_write)
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
}
// Need to start a new write
if (InternalConfig.PedanticFrameBufferEmulation)
{
if (m_chromakeyvalue_changed && m_framebuffer->PixelPipeline)
{
m_ChromaKey = m_chromakeyvalue_new;
m_chromakeyvalue_changed = false;
// Fill the framebuffer with the new chromakey value
m_must_clear_buffer = true;
}
begin_write();
}
else
{
m_must_write = false;
}
// Once a triangle has been drawn, the framebuffer
// data must be considered as overlay graphics
m_write_opaque = false;
}
void GlideFramebuffer::OnBeforeBufferSwap()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnBeforeBufferSwap()\n");
#endif
// apply the framebuffer changes?
if (InternalConfig.EnableFrameBufferOverlays)
{
// There's no check against the underlay flag here, because if no triangles
// have been drawn, then the display is rendered via the frame buffer only,
// and in that case, there's no such thing like under- and overlay.
if (m_write_opaque && m_must_write && !m_renderbuffer_changed)
{
end_write_opaque();
}
else if (m_must_write)
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
}
else if (BackBufferIsLocked())
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
}
m_must_write = false;
// optionally render the 3Dfx powerfield logo overlay on top of the frame
if (InternalConfig.ShamelessPlug)
{
// @todo: For apps that lock the frame buffer accross buffer swaps
// (for instance Carmageddon) the current state must be saved...
_grShamelessPlug();
if (m_must_write)
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
}
// ... and restored after rendering the shameless plug
}
}
else
{
m_must_clear_buffer = true;
}
m_must_write = false;
}
void GlideFramebuffer::OnAfterBufferSwap()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnAfterBufferSwap()\n");
#endif
m_must_write = BackBufferIsLocked() || m_framebuffer->Lock;
m_write_opaque = true;
m_renderbuffer_changed = false;
m_renderbuffer_changed_for_read = true;
m_bufferclearcalls = 0;
begin_write();
}
void GlideFramebuffer::WriteFrameBuffer(bool pixelpipeline)
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::WriteFrameBuffer(%d)\n", pixelpipeline);
#endif
// apply the framebuffer changes?
if (InternalConfig.EnableFrameBufferOverlays)
{
// Only the back buffer is supported because games like Carmageddon
// temporarily lock and unlock the front buffer while holding the lock
// to the back buffer. Becasue he current implementation of the framebuffer
// emulation doesn't support locks to multiple buffers, data is written to
// the current buffer (which is usally the back buffer).
if (pixelpipeline)
{
end_write(m_alpha, m_depth, pixelpipeline);
}
else
{
end_write();
}
}
else
{
m_must_clear_buffer = true;
}
}
void GlideFramebuffer::Cleanup()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::Cleanup()\n");
#endif
free_buffers();
}
void GlideFramebuffer::CopyFrameBuffer(FxU16* targetbuffer)
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::CopyFrameBuffer( 0x%x)\n", targetbuffer);
#endif
FxU16 chromakey = m_ChromaKey;
FxU16* framebuffer = m_framebuffer->Address;
FxU32 count = m_width * m_height;
for (FxU16* end = framebuffer + count; framebuffer < end; framebuffer++, targetbuffer++)
{
FxU16 pixel = *framebuffer;
if (pixel != chromakey) *targetbuffer = pixel;
}
}
FxU16 GlideFramebuffer::GetChromaKeyValue16(GrColor_t chromakeyvalue)
{
FxU16 chromakeyvalue16;
if (m_framebuffer->WriteMode == GR_LFBWRITEMODE_565)
{
chromakeyvalue16 = static_cast<FxU16>((chromakeyvalue & 0x00F80000) >> 8 |
(chromakeyvalue & 0x0000FC00) >> 5 |
(chromakeyvalue & 0x000000F8) >> 3);
}
else
{
chromakeyvalue16 = 0x0;
}
return chromakeyvalue16;
}
void GlideFramebuffer::OnChromaKeyValueChanged()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::OnChromaKeyColorChanged()\n");
#endif
FxU16 chromakeyvalue = GetChromaKeyValue16(Glide.State.ChromakeyValue);
m_chromakeyvalue_changed = m_ChromaKey != chromakeyvalue;
m_chromakeyvalue_new = chromakeyvalue;
if (m_must_write)
{
if (m_chromakeyvalue_changed && m_framebuffer->PixelPipeline)
{
// Flush the current contents of the framebuffer
WriteFrameBuffer(m_framebuffer->PixelPipeline);
m_ChromaKey = m_chromakeyvalue_new;
m_chromakeyvalue_changed = false;
// Fill the framebuffer with the new chromakey value
m_must_clear_buffer = true;
begin_write();
}
}
}
void GlideFramebuffer::SetAlpha(FxU32 alpha)
{
if (m_must_write && m_framebuffer->PixelPipeline & m_alpha != alpha)
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
}
m_alpha = alpha;
};
void GlideFramebuffer::SetDepth(GLfloat depth)
{
if (m_must_write && m_framebuffer->PixelPipeline && m_depth != depth)
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
}
m_depth = depth;
};

View File

@ -0,0 +1,60 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Glide framebuffer emulation
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
#include "Framebuffer.h"
#define GR_LFBWRITEMODE_UNUSED (GR_LFBWRITEMODE_ANY -1)
class GlideFramebuffer : protected Framebuffer
{
public:
GlideFramebuffer();
~GlideFramebuffer();
protected:
bool m_write_opaque;
bool m_must_write;
bool m_renderbuffer_changed;
bool m_renderbuffer_changed_for_read;
GLfloat m_depth;
FxU32 m_alpha;
bool m_chromakeyvalue_changed;
FxU16 m_chromakeyvalue_new;
GrLfbWriteMode_t m_grLfbLockWriteMode[6];
unsigned int m_bufferclearcalls;
static const tilesize tilesize_table_carmageddon[11];
public:
void initialise(BufferStruct* framebuffer, BufferStruct* texbuffer);
void OnBufferLockStartWrite(GrLock_t dwType, GrBuffer_t dwBuffer, GrLfbWriteMode_t dwWriteMode, GrOriginLocation_t dwOrigin, FxBool bPixelPipeline);
void OnBufferUnlockEndWrite(GrBuffer_t dwBuffer);
// void OnBufferNumPending();
void OnBeforeBufferClear();
void OnLfbReadRegion();
void OnRenderDrawTriangles();
void OnBeforeBufferSwap();
void OnAfterBufferSwap();
// void OnSetIdle();
void OnClipWindow();
void OnChromaKeyValueChanged();
void Cleanup();
void SetAlpha(FxU32 alpha);
void SetDepth(GLfloat depth);
FxU16 GetChromaKeyValue16(GrColor_t chromakeyvalue);
inline void SetRenderBufferChanged() {m_renderbuffer_changed = m_renderbuffer_changed_for_read = true;};
inline bool GetRenderBufferChanged() const {return m_renderbuffer_changed;};
inline bool GetRenderBufferChangedForRead() const {return m_renderbuffer_changed_for_read;};
inline void ResetRenderBufferChangedForRead() {m_renderbuffer_changed_for_read = false;};
void CopyFrameBuffer(FxU16* targetbuffer);
inline FxU16 GetChromaKeyValue() {return m_ChromaKey;};
protected:
void WriteFrameBuffer(bool pixelpipline);
inline bool BackBufferIsLocked() {return m_grLfbLockWriteMode[GR_BUFFER_BACKBUFFER] != GR_LFBWRITEMODE_UNUSED;};
};

View File

@ -0,0 +1,615 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* OpenGLide Settings File
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GlOgl.h"
#include "GlideSettings.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Version numbers ///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
const char* GlideSettings::OpenGLidePreferencesVersion = "0.13";
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
GlideSettings::GlideSettings()
: m_FileBuffer(NULL)
, m_FileBufferSize(0)
{
defaults();
}
GlideSettings::~GlideSettings(void)
{
}
bool GlideSettings::get(const char* setting, const char** value)
{
static char buffer[StringBufferSize];
buffer[0] = 0x0;
bool found = false;
const char* v = m_FileBuffer;
while(!found && v)
{
v = strstr(v, setting);
if (v)
{
int s = strlen(setting);
// At the beginning of the line or tabbed and followed by '='
if (v[-1] < 0x20 && v[s] == '=')
{
// found, point to begin of setting
v = v + s + 1;
// copy til end of line
sscanf(v, "%255s", buffer);
found = true;
}
}
}
*value = buffer;
if (!found)
{
GlideMsg("Setting '%s' not found, using default value\n", setting);
}
return found;
}
bool GlideSettings::get(const char* setting, unsigned long* value)
{
const char* v;
if (get(setting, &v))
{
*value = atol(v);
return true;
}
else
{
// keep default value
return false;
}
}
bool GlideSettings::get(const char* setting, float* value)
{
const char* v;
if (get(setting, &v))
{
*value = atof(v);
return true;
}
else
{
// keep default value
return false;
}
}
bool GlideSettings::get(const char* setting, bool* value)
{
const char* v;
if (get(setting, &v))
{
*value = atol(v) != 0;
return true;
}
else
{
// keep default value
return false;
}
}
void GlideSettings::defaults()
{
#ifdef OGL_DEBUG
GlideMsg("Initialising to internal default settings...\n");
#endif
// These are the default values that will end up in a new configuration file.
// OpenGL extensions that can be disabled via the config file must be set to
// true in order to become enabled in ValidateUserConfig()
Resolution = 1;
MonitorRefreshRate = 0;
DepthBufferBits = 0;
FullSceneAntiAliasing = 0;
GammaBias = -0.3f;
TextureSmoothing = false;
DisplayMode = OpenGLideDisplayMode_DisplayManager;
#ifdef OPENGLIDE_SYSTEM_HAS_FOGCOORD
FogMode = OpenGLideFogEmulation_FogCoord;
#else
FogMode = OpenGLideFogEmulation_EnvCombine;
#endif
ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_Automatic;
PrecisionFix = 1;
/*
// Not bad
GapFix = static_cast<OpenGLideGapFixFlags>(OpenGLideGapFixFlag_Enabled |
OpenGLideGapFixFlag_IncircleOr |
OpenGLideGapFixFlag_DepthFactor);
GapFixParam1 = 3.0f;
GapFixParam2 = 10.0f;
GapFixParam3 = 3.0f;
GapFixDepthFactor = 3.3f;
*/
/*
// But this one is better
GapFix = static_cast<OpenGLideGapFixFlags>(OpenGLideGapFixFlag_Enabled |
OpenGLideGapFixFlag_VertexLengthSecondRadius |
OpenGLideGapFixFlag_DepthFactor);
GapFixParam1 = 3.0f;
GapFixParam2 = 25.0f;
GapFixParam3 = 0.9f;
GapFixDepthFactor = 3.3f;
*/
// @todo: Let's make this even more better
GapFix = static_cast<OpenGLideGapFixFlags>(/*OpenGLideGapFixFlag_Enabled |*/
OpenGLideGapFixFlag_VertexLengthSecondRadius |
OpenGLideGapFixFlag_DepthFactor);
GapFixParam1 = 3.0f;
GapFixParam2 = 25.0f;
GapFixParam3 = 0.9f;
GapFixDepthFactor = 3.3f;
GenerateSubTextures = 0;
Mipmapping = true;
AnisotropylLevel = 16;
IgnorePaletteChange = false;
ARB_multitexture = true;
EXT_paletted_texture = true;
EXT_texture_env_add = true;
EXT_texture_env_combine = true;
ATI_texture_env_combine3 = true;
#ifdef OPENGLIDE_SYSTEM_HAS_FOGCOORD
EXT_fog_coord = true;
#endif
#ifdef OPENGLIDE_SYSTEM_HAS_BLENDFUNC_SEPERATE
EXT_blend_func_separate = true;
#endif
EXT_texture_lod_bias = true;
EXT_secondary_color = true;
EXT_SGIS_generate_mipmap = true;
EXT_SGIS_texture_edge_clamp = true;
EXT_Client_Storage = true;
EXT_compiled_vertex_array = true;
EXT_texture_filter_anisotropic = true;
ARB_multisample = true;
NV_multisample_filter_hint = true;
EXT_clip_volume_hint = true;
APPLE_transform_hint = true;
TextureMemorySize = 16;
FrameBufferMemorySize = 8;
EnableFrameBufferOverlays = true;
EnableFrameBufferUnderlays = true;
FramebufferIgnoreUnlock = false;
PedanticFrameBufferEmulation = false;
BoardType = static_cast<OpenGLideBoardType>(GR_SSTTYPE_VOODOO);
GlideTextureUnits = 0;
NoSplash = false;
ShamelessPlug = false;
UseApplicationSpecificSettings = false;
AutoEnableGameSpecificSettings = true;
}
GlideSettings::IOErr GlideSettings::read_settings()
{
#ifdef OGL_DEBUG
GlideMsg("Reading values...\n");
#endif
GlideSettings::IOErr err = noErr;
unsigned long value;
get("DisplayMode", &value);
DisplayMode = static_cast<OpenGLideDisplayMode>(value);
get("Resolution", &Resolution);
get("MonitorRefreshRate", &MonitorRefreshRate);
get("DepthBufferBits", &DepthBufferBits);
get("Mipmapping", &Mipmapping);
get("AnisotropylLevel", &AnisotropylLevel);
get("FullSceneAntiAliasing", &FullSceneAntiAliasing);
get("GammaBias", &GammaBias);
get("TextureSmoothing", &TextureSmoothing);
get("FogMode", &value);
FogMode = static_cast<OpenGLideFogEmulation>(value);
get("ColorAlphaRenderMode", &value);
ColorAlphaRenderMode = static_cast<OpenGLideColorAlphaRenderMode>(value);
get("EnablePrecisionFix", &PrecisionFix);
get("GapFix", &value);
GapFix = static_cast<OpenGLideGapFixFlags>(value);
get("GapFixParam1", &GapFixParam1);
get("GapFixParam2", &GapFixParam2);
get("GapFixParam3", &GapFixParam3);
get("GapFixDepthFactor", &GapFixDepthFactor);
get("GenerateSubTextures", &GenerateSubTextures);
get("IgnorePaletteChange", &IgnorePaletteChange);
get("TextureMemorySize", &TextureMemorySize);
get("FrameBufferMemorySize", &FrameBufferMemorySize);
get("EnableFrameBufferOverlays", &EnableFrameBufferOverlays);
get("EnableFrameBufferUnderlays", &EnableFrameBufferUnderlays);
get("FramebufferIgnoreUnlock", &FramebufferIgnoreUnlock);
get("PedanticFrameBufferEmulation", &PedanticFrameBufferEmulation);
get("CompiledVertexArray", &EXT_compiled_vertex_array);
get("EnableMultiTextureEXT", &ARB_multitexture);
get("EnablePaletteEXT", &EXT_paletted_texture);
get("EXT_clip_volume_hint", &EXT_clip_volume_hint);
get("BoardType", &value);
BoardType = static_cast<OpenGLideBoardType>(value);
get("GlideTextureUnits", &GlideTextureUnits);
get("NoSplash", &NoSplash);
get("ShamelessPlug", &ShamelessPlug);
get("UseApplicationSpecificSettings", &UseApplicationSpecificSettings);
get("AutoEnableGameSpecificSettings", &AutoEnableGameSpecificSettings);
return err;
}
GlideSettings::IOErr GlideSettings::load()
{
#ifdef OGL_DEBUG
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg("Loading settings from preferences directory...\n");
#endif
const char* prefs_version = OpenGLidePreferencesVersion;
GlideSettings::IOErr err = read_defaults();
if (err == noErr)
{
const char* version_complaint = "Unable to read version information from %s settings - using default values\n";
const char* version;
bool success = get("Version", &version);
if (success)
{
GlideMsg("Settings file version = %s\n", version);
}
if (success && strcmp(version, prefs_version) == 0)
{
err = read_settings();
}
else if (!success)
{
GlideMsg(version_complaint, "default");
}
else
{
GlideMsg("Configuration outdated - Creating new default settings %s...\n", prefs_version);
defaults();
err = create_defaults();
if (err == noErr)
{
err = save();
}
}
if (err == noErr)
{
if (UseApplicationSpecificSettings)
{
err = read();
if (err == noErr)
{
success = get("Version", &version);
if (success && strcmp(version, prefs_version) == 0)
{
bool use_app_specific_settings = false;
success = get("UseApplicationSpecificSettings", &use_app_specific_settings);
if (use_app_specific_settings)
{
err = read_settings();
}
}
else if (!success)
{
GlideMsg(version_complaint, "application specific");
}
else
{
GlideMsg("Configuration outdated - Creating new application specific settings %s...\n", prefs_version);
defaults();
err = create();
if (err == noErr)
{
err = save();
}
}
}
}
}
// if (!success) err = fnfErr;
}
return err;
}
GlideSettings::IOErr GlideSettings::save()
{
#ifdef OGL_DEBUG
GlideMsg("Saving...\n");
#endif
put("Configuration File for MacGLide");
put();
put();
put("Current version number of the settings file:" );
put("Version", OpenGLidePreferencesVersion);
put();
put("Enable to apply application specific settings:");
put("UseApplicationSpecificSettings", UseApplicationSpecificSettings);
put();
put("Video settings");
put();
put("Fullscreen display:");
put("0 for windowed mode, 1 for fullscreen display");
put("DisplayMode", static_cast<unsigned long>(DisplayMode));
put();
put("Display resolution:");
put("1-8: Multiplier for Glide resolution as requested by the");
put("game/application. Any value equal or greater than 512:");
put("fixed x resolution (y is computed for a 4/3 aspect ratio)");
put("Resolution", Resolution);
put();
put("Refresh rate of the monitor:");
put("0 to use the Glide refresh rate as requested by the game/");
put("application. Any other value equal or greater than 60(Hz):");
put("Use fixed refresh rate");
put("MonitorRefreshRate", MonitorRefreshRate);
put();
put("Gamma bias value for the Glide display:");
put("Most games adjust the gamma correction of the display.");
put("For certain monitors and LCD display the resulting gamma");
put("correction might be too bright (probably because the");
put("3Dfx-Hardware was never supposed to work with LCD displays).");
put("Although most games provide a way to adjust the gamma");
put("correction via their configuration dialog, it might be");
put("necessary to set a reasonable default bias value.");
put("Reasonable bias values are -1.0 to 1.0.");
put("GammaBias", GammaBias);
put();
put("Mip-Mapping: 0 to disable, 1 to enable mipmapped textures");
put("Mipmapping", Mipmapping);
put();
put("Anisotropic filtering:");
put("0 or 1 to disable, 2, 4, 8, 16 to specify the quality");
put("level of anisotropic filtering");
put("AnisotropylLevel", AnisotropylLevel);
put();
put("Fullscene antialiasing:");
put("0 to disable, any other value to set number of samples to use");
put("for antialiasing (currently this works with ATI cards only)");
put("FullSceneAntiAliasing", FullSceneAntiAliasing);
put();
put();
put("Game specific settings (usually set automatically per application");
put();
put("Enable game specific settings automatically:");
put("0 to disable, 1 to automatically certain enable game specific settings");
put("The settings in this section don't work with all games. To avoid");
put("problems, these settings are usually set individually for each game.");
put("AutoEnableGameSpecificSettings", AutoEnableGameSpecificSettings);
put();
put("Texture smoothing:");
put("0 to disable, 1 to enable texture filtering. Overrides Glide");
put("texture filter settings in order to suppress blocky pixels.");
put("Some games don't like these filter settings to be changed, for");
put("instance horizontal and vertical gaps may appear in texture-based");
put("menu screens");
put("TextureSmoothing", TextureSmoothing);
put();
put("Texture artefact optimisation for Tomb Raider 1 & 2:");
put("Tomb Raider joins a number of texture images within a");
put("larger texture object. In conjunction with ansisotropic");
put("filtering and mipmapping this cause artefacts at the");
put("edges of single tiles/triangles.");
put("0 to disable, n (power of 2) to place each texture image");
put("into a seperate OpenGL texture object. The value determines");
put("the grid points and the minimal size of the generated");
put("OpenGL textures.");
put("GenerateSubTextures", GenerateSubTextures);
put();
put("Vertex gapfix optimisation for Tomb Raider 1 & 2:");
put("Reduces gaps between tiles in the tomb raider series");
put("(best observed in TR1, but TR2 is also affected)");
put("A combination of the following values:");
put("1=Enable, 2=Debug, 4=DepthFactor, 16=IncircleOr,");
put("32=IncircleAnd, 64=IncircleSecondRadius,");
put("128=VertexLengthSecondRadius");
put("GapFix", static_cast<unsigned long>(GapFix));
put();
put("Minimum pixel incircle of a triangle for applying the gapfix");
put("GapFixParam1", GapFixParam1);
put();
put("Minimum value of the isoscelesness or the maximum vertex");
put("length of a triangle for applying the gapfix");
put("(an isosceles triangle has a value of 10)");
put("GapFixParam2", GapFixParam2);
put();
put("Second minimum incircle of a triangle for applying the gapfix,");
put(" this one is independent from the isoscelesness/vertex length");
put("GapFixParam3", GapFixParam3);
put();
put("Multiplies the incircles/isoscelesness with the vertex depth to");
put("allow applying the gapfix to smaller triangles in the background");
put("GapFixDepthFactor", GapFixDepthFactor);
put();
put();
put("Various settings that affect the rendering quality.");
put();
put("Fog emulation method:");
put("0 to disable, 1 for simple, 2 for complete fog emulation");
put("FogMode", static_cast<unsigned long>(FogMode));
put();
put("The renderer to be used to emulate the Glide color and alpha");
put("combine unit. 0 for automatic selection, 1 for simple (0.10),");
put("2 for enhanced, and 3 for enhanced ATI optimised emulation");
put("ColorAlphaRenderMode", static_cast<unsigned long>(ColorAlphaRenderMode));
put();
put("Number of bits to use for the depth buffer:");
put("0: automatic (attempts to use the largest possible value)");
put("16, 24, 32: use the specified number of bits for the depth buffer");
put("DepthBufferBits", DepthBufferBits);
put();
put("Depth precision fix: attempts to avoid depth precision");
put("problems on graphic cards with only 16bit-zbuffer depth");
put("0 = always off, 1 = automatic, 2 = always on");
put("EnablePrecisionFix", PrecisionFix);
put();
put();
put("Various debug settings");
put();
put("IgnorePaletteChange", IgnorePaletteChange);
put("EnableFrameBufferOverlays", EnableFrameBufferOverlays);
put("EnableFrameBufferUnderlays", EnableFrameBufferUnderlays);
put("FramebufferIgnoreUnlock", FramebufferIgnoreUnlock);
put("PedanticFrameBufferEmulation", PedanticFrameBufferEmulation);
put("CompiledVertexArray", EXT_compiled_vertex_array);
put("EnableMultiTextureEXT", ARB_multitexture);
put("EnablePaletteEXT", EXT_paletted_texture);
put("EXT_clip_volume_hint", EXT_clip_volume_hint);
put();
put();
put("Glide hardware settings");
put();
putv("Texture Memory goes from %d to %d", OGL_MIN_TEXTURE_BUFFER, OGL_MAX_TEXTURE_BUFFER);
put("TextureMemorySize", TextureMemorySize);
put();
putv("Frame Buffer Memory goes from %d to %d", OGL_MIN_FRAME_BUFFER, OGL_MAX_FRAME_BUFFER);
put("FrameBufferMemorySize", FrameBufferMemorySize);
put();
put("The hardware we're pretending to be emulating");
put("(This has no effect on the emulation, but games may change");
put("their behaviour/features depending on this setting)");
put("0 = Voodoo, 1 = SST-96, 2 = AT3D, 3 = Voodoo 2");
put("BoardType", static_cast<unsigned long>(BoardType));
put();
put("The number of emulated Glide texture units (TMUs)");
put("0 = as many as possible, 1-3 number of emulated TMUs");
put("GlideTextureUnits", GlideTextureUnits);
put();
put("0 to display the cool splash animation on startup,");
put("or 1 to supress the annoying splash animation");
put("NoSplash", NoSplash);
put();
put("Shows the 3Dfx logo in the lower right corner of the screen");
put("ShamelessPlug", ShamelessPlug);
GlideSettings::IOErr err = close();
return err;
}
GlideSettings::IOErr GlideSettings::put()
{
return put_raw("\n");
}
GlideSettings::IOErr GlideSettings::put(const char* string)
{
GlideSettings::IOErr err = put_raw("# ");
if (err == noErr)
{
err = put_raw(string);
if (err == noErr)
{
put();
}
}
return err;
}
GlideSettings::IOErr GlideSettings::putv(const char* format, ...)
{
va_list(args);
va_start(args, format);
char buffer[StringBufferSize];
vsnprintf(buffer, StringBufferSize, format, args );
GlideSettings::IOErr err = put(buffer);
va_end(args);
return err;
}
GlideSettings::IOErr GlideSettings::put(unsigned long value)
{
GlideSettings::IOErr err = noErr;
char buffer[StringBufferSize];
if (snprintf(buffer, StringBufferSize, "%d", value) > 0)
{
err = put_raw(buffer);
}
return err;
}
GlideSettings::IOErr GlideSettings::put(const char* setting, const char* value)
{
GlideSettings::IOErr err = put_raw(setting);
if (err == noErr)
{
err = put_raw("=");
if (err == noErr)
{
err = put_raw(value);
if (err == noErr)
{
err = put_raw("\n");
}
}
}
return err;
}
GlideSettings::IOErr GlideSettings::put(const char* setting, unsigned long value)
{
GlideSettings::IOErr err = put_raw(setting);
if (err == noErr)
{
err = put_raw("=");
if (err == noErr)
{
char buffer[StringBufferSize];
if (snprintf(buffer, StringBufferSize, "%d", value) > 0)
{
err = put_raw(buffer);
}
if (err == noErr)
{
err = put_raw("\n");
}
}
}
return err;
}
GlideSettings::IOErr GlideSettings::put(const char* setting, float value)
{
GlideSettings::IOErr err = put_raw(setting);
if (err == noErr)
{
err = put_raw("=");
if (err == noErr)
{
char buffer[StringBufferSize];
if (snprintf(buffer, StringBufferSize, "%g", value) > 0)
{
err = put_raw(buffer);
}
if (err == noErr)
{
err = put_raw("\n");
}
}
}
return err;
}
GlideSettings::IOErr GlideSettings::put(const char* setting, bool value)
{
return put(setting, value ? "1" : "0");
}

View File

@ -0,0 +1,156 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* OpenGLide Settings File
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
#include "sdk2_glide.h"
enum OpenGLideDisplayMode
{
OpenGLideDisplayMode_Window = 0,
OpenGLideDisplayMode_DisplayManager = 1,
OpenGLideDisplayMode_aglSetFullScreen = 2
};
enum OpenGLideFogEmulation
{
OpenGLideFogEmulation_None = 0,
OpenGLideFogEmulation_Simple = 1,
OpenGLideFogEmulation_EnvCombine = 2
#ifdef OPENGLIDE_SYSTEM_HAS_FOGCOORD
,
OpenGLideFogEmulation_FogCoord = 3
#endif
};
enum OpenGLideColorAlphaRenderMode
{
OpenGLideColorAlphaRenderMode_Automatic = 0,
OpenGLideColorAlphaRenderMode_Simple = 1,
OpenGLideColorAlphaRenderMode_EnvCombine_ARB = 2,
OpenGLideColorAlphaRenderMode_EnvCombine3_ATI = 3,
OpenGLideColorAlphaRenderMode_Unknown = 4
};
enum OpenGLideBoardType
{
OpenGLideBoardType_Voodoo = GR_SSTTYPE_VOODOO,
OpenGLideBoardType_VoodooRush = GR_SSTTYPE_SST96,
OpenGLideBoardType_AT3D = GR_SSTTYPE_AT3D,
OpenGLideBoardType_Voodoo2 = GR_SSTTYPE_Voodoo2
};
enum OpenGLideGapFixFlags
{
OpenGLideGapFixFlag_Disabled = 0x00,
OpenGLideGapFixFlag_Enabled = 0x01,
OpenGLideGapFixFlag_Debug = 0x02,
OpenGLideGapFixFlag_DepthFactor = 0x04,
OpenGLideGapFixFlag_IncircleOr = 0x10,
OpenGLideGapFixFlag_IncircleAnd = 0x20,
OpenGLideGapFixFlag_IncircleSecondRadius = 0x40,
OpenGLideGapFixFlag_VertexLengthSecondRadius = 0x80
};
struct ConfigStruct
{
OpenGLideDisplayMode DisplayMode;
unsigned long Resolution;
unsigned long MonitorRefreshRate;
unsigned long DepthBufferBits;
unsigned long FullSceneAntiAliasing;
float GammaBias;
bool TextureSmoothing;
OpenGLideFogEmulation FogMode;
OpenGLideColorAlphaRenderMode ColorAlphaRenderMode;
unsigned long PrecisionFix;
OpenGLideGapFixFlags GapFix;
float GapFixParam1;
float GapFixParam2;
float GapFixParam3;
float GapFixDepthFactor;
unsigned long GenerateSubTextures;
unsigned long TextureMemorySize;
unsigned long FrameBufferMemorySize;
unsigned long AnisotropylLevel;
bool Mipmapping;
bool IgnorePaletteChange;
bool EXT_secondary_color;
bool ARB_multitexture;
bool EXT_texture_env_add;
bool EXT_texture_env_combine;
bool ATI_texture_env_combine3;
bool EXT_texture_lod_bias;
bool EXT_paletted_texture;
bool EXT_SGIS_generate_mipmap;
bool EXT_SGIS_texture_edge_clamp;
bool EXT_Client_Storage;
bool EXT_compiled_vertex_array;
#ifdef OPENGLIDE_SYSTEM_HAS_FOGCOORD
bool EXT_fog_coord;
#endif
#ifdef OPENGLIDE_SYSTEM_HAS_BLENDFUNC_SEPERATE
bool EXT_blend_func_separate;
#endif
bool EXT_texture_filter_anisotropic;
bool ARB_multisample;
bool NV_multisample_filter_hint;
bool EXT_clip_volume_hint;
bool APPLE_transform_hint;
bool EnableFrameBufferOverlays;
bool EnableFrameBufferUnderlays;
bool FramebufferIgnoreUnlock;
bool PedanticFrameBufferEmulation;
OpenGLideBoardType BoardType;
unsigned long GlideTextureUnits;
bool NoSplash;
bool ShamelessPlug;
bool UseApplicationSpecificSettings;
bool AutoEnableGameSpecificSettings;
};
class GlideSettings : public ConfigStruct
{
protected:
static const char* OpenGLidePreferencesVersion;
public:
GlideSettings();
virtual ~GlideSettings(void);
public:
typedef int IOErr;
virtual IOErr init(const char* application)=0;
IOErr load();
IOErr save();
virtual IOErr create_log()=0;
virtual IOErr write_log(const char* message)=0;
virtual IOErr create_defaults()=0;
virtual IOErr create()=0;
protected:
void defaults();
virtual IOErr read_defaults()=0;
virtual IOErr read()=0;
IOErr read_settings();
bool get(const char* setting, const char** value);
bool get(const char* setting, unsigned long* value);
bool get(const char* setting, float* value);
bool get(const char* setting, bool* value);
virtual IOErr put_raw(const char* string)=0;
virtual IOErr close()=0;
IOErr put();
IOErr put(const char* string);
IOErr putv(const char* format, ...);
IOErr put(unsigned long value);
IOErr put(const char* setting, const char* value);
IOErr put(const char* setting, unsigned long value);
IOErr put(const char* setting, float value);
IOErr put(const char* setting, bool value);
char* m_FileBuffer;
long m_FileBufferSize;
};

View File

@ -0,0 +1,77 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* OpenGLide Settings File
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GlideSettings_iostream.h"
GlideSettingsIOStream::GlideSettingsIOStream()
{
}
GlideSettingsIOStream::~GlideSettingsIOStream(void)
{
if (m_FileBuffer) delete(m_FileBuffer);
}
GlideSettings::IOErr GlideSettingsIOStream::init(const char* applicationname)
{
return -1;
}
GlideSettings::IOErr GlideSettingsIOStream::read_defaults()
{
#ifdef OGL_DEBUG
GlideMsg("Reading default settings...\n");
#endif
return -1;
}
GlideSettings::IOErr GlideSettingsIOStream::read()
{
#ifdef OGL_DEBUG
GlideMsg("Reading application specific settings...\n");
#endif
return -1;
}
GlideSettings::IOErr GlideSettingsIOStream::create_defaults()
{
#ifdef OGL_DEBUG
GlideMsg("Creating new file with default settings...\n");
#endif
return -1;
}
GlideSettings::IOErr GlideSettingsIOStream::create()
{
#ifdef OGL_DEBUG
GlideMsg("Creating new file with application specific settings...\n");
#endif
return -1;
}
GlideSettings::IOErr GlideSettingsIOStream::put_raw(const char* string)
{
return -1;
}
GlideSettings::IOErr GlideSettingsIOStream::close()
{
return -1;
}
GlideSettings::IOErr GlideSettingsIOStream::create_log()
{
return -1;
}
GlideSettings::IOErr GlideSettingsIOStream::write_log(const char* message)
{
return -1;
}

View File

@ -0,0 +1,31 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* OpenGLide Settings File
//*
//* OpenGLide is OpenSource under LGPL license
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
#include "GlideSettings.h"
class GlideSettingsIOStream : public GlideSettings
{
public:
GlideSettingsIOStream();
virtual ~GlideSettingsIOStream(void);
public:
IOErr init(const char* application);
IOErr create_log();
IOErr write_log(const char* message);
protected:
IOErr create_defaults();
IOErr create();
IOErr read_defaults();
IOErr read();
IOErr put_raw(const char* string);
IOErr close();
};

View File

@ -0,0 +1,543 @@
#include "GLRender.h"
#include "OGLTables.h"
const OGLColorTable colorCombineTable[ 14 ][ 17 ] =
{
{ // GR_COMBINE_FACTOR_ZERO 0x0
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3Zero, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3Zero, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, false, false, false, ColorFactor3Zero, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, false, false, false, ColorFactor3Zero, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, false, true, false, ColorFactor3Zero, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ false, false, false, false, ColorFactor3Zero, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, false, false, false, ColorFactor3Zero, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ false, false, true, false, ColorFactor3Zero, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, false, ColorFactor3Zero, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xf
{ false, false, true, false, ColorFactor3Zero, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_LOCAL 0x1
{ false, false, false, false, ColorFactor3Local, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3Local, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3Local, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ true, true, false, false, ColorFactor3Local, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, false, ColorFactor3Local, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, true, false, ColorFactor3Local, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, false, ColorFactor3Local, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, false, ColorFactor3Local, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3Local, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, false, ColorFactor3Local, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3Local, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3Local, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3Local, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3Local, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3Local, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3Local, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3Local, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_OTHER_ALPHA 0x2
{ false, false, false, false, ColorFactor3OtherAlpha, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3OtherAlpha, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3OtherAlpha, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, false, true, ColorFactor3OtherAlpha, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, true, ColorFactor3OtherAlpha, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, true, ColorFactor3OtherAlpha, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, true, ColorFactor3OtherAlpha, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, true, ColorFactor3OtherAlpha, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, true, ColorFactor3OtherAlpha, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, true, ColorFactor3OtherAlpha, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3OtherAlpha, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3OtherAlpha, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3OtherAlpha, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3OtherAlpha, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3OtherAlpha, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3OtherAlpha, ColorFunctionZero }, // 0xf
{ true, false, true, true, ColorFactor3OtherAlpha, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_LOCAL_ALPHA 0x3
{ false, false, false, false, ColorFactor3LocalAlpha, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3LocalAlpha, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3LocalAlpha, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, true, false, ColorFactor3LocalAlpha, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, true, false, ColorFactor3LocalAlpha, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, false, ColorFactor3LocalAlpha, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, true, false, ColorFactor3LocalAlpha, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, true, false, ColorFactor3LocalAlpha, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3LocalAlpha, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, true, false, ColorFactor3LocalAlpha, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3LocalAlpha, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3LocalAlpha, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3LocalAlpha, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3LocalAlpha, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3LocalAlpha, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3LocalAlpha, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3LocalAlpha, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_TEXTURE_ALPHA 0x4
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3One, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3One, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, false, false, ColorFactor3One, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, false, ColorFactor3One, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, false, ColorFactor3One, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3One, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_TEXTURE_RGB 0x5
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3One, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3One, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, false, false, ColorFactor3One, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, false, ColorFactor3One, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, false, ColorFactor3One, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3One, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // 6
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xf
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // 7
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero }, // 0xf
{ false, false, false, false, ColorFactor3Zero, ColorFunctionZero } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE 0x8
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3One, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3One, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, false, false, ColorFactor3One, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, false, ColorFactor3One, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, false, ColorFactor3One, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3One, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_LOCAL 0x9
{ false, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3OneMinusLocal, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ true, true, false, false, ColorFactor3OneMinusLocal, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, false, ColorFactor3OneMinusLocal, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, true, false, ColorFactor3OneMinusLocal, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, false, ColorFactor3OneMinusLocal, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, false, ColorFactor3OneMinusLocal, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3OneMinusLocal, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3OneMinusLocal, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3OneMinusLocal, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA 0xa
{ false, false, false, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, false, true, ColorFactor3OneMinusOtherAlpha, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, true, ColorFactor3OneMinusOtherAlpha, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, true, ColorFactor3OneMinusOtherAlpha, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, true, ColorFactor3OneMinusOtherAlpha, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, true, ColorFactor3OneMinusOtherAlpha, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, true, ColorFactor3OneMinusOtherAlpha, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, true, ColorFactor3OneMinusOtherAlpha, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3OneMinusOtherAlpha, ColorFunctionZero }, // 0xf
{ true, false, true, true, ColorFactor3OneMinusOtherAlpha, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA 0xb
{ false, false, false, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3OneMinusLocalAlpha, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA 0xc
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3One, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3One, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, false, false, ColorFactor3One, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, false, ColorFactor3One, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, false, ColorFactor3One, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3One, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION 0xd
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, false, false, ColorFactor3One, ColorFunctionLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, true, false, ColorFactor3One, ColorFunctionLocalAlpha }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, false, false, ColorFactor3One, ColorFunctionScaleOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, true, true, false, ColorFactor3One, ColorFunctionScaleOtherAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, false, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, true, false, ColorFactor3One, ColorFunctionScaleOtherMinusLocalAddLocalAlpha }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, false, false, ColorFactor3One, ColorFunctionMinusLocalAddLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xa
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xb
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xc
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xd
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xe
{ false, false, false, false, ColorFactor3One, ColorFunctionZero }, // 0xf
{ true, false, true, false, ColorFactor3One, ColorFunctionMinusLocalAddLocalAlpha } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
}
};
const OGLAlphaTable alphaCombineTable[ 14 ][ 17 ] =
{
{ // GR_COMBINE_FACTOR_ZERO 0x0
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorZero }, // 0xa
{ false, false, AlphaFactorZero }, // 0xb
{ false, false, AlphaFactorZero }, // 0xc
{ false, false, AlphaFactorZero }, // 0xd
{ false, false, AlphaFactorZero }, // 0xe
{ false, false, AlphaFactorZero }, // 0xf
{ true, false, AlphaFactorZero } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_LOCAL 0x1
{ false, false, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorLocal }, // 0xa
{ false, false, AlphaFactorLocal }, // 0xb
{ false, false, AlphaFactorLocal }, // 0xc
{ false, false, AlphaFactorLocal }, // 0xd
{ false, false, AlphaFactorLocal }, // 0xe
{ false, false, AlphaFactorLocal }, // 0xf
{ true, false, AlphaFactorLocal } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_OTHER_ALPHA 0x2
{ false, false, AlphaFactorOther }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOther }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOther }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, AlphaFactorOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, true, AlphaFactorOther }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOther }, // 0xa
{ false, false, AlphaFactorOther }, // 0xb
{ false, false, AlphaFactorOther }, // 0xc
{ false, false, AlphaFactorOther }, // 0xd
{ false, false, AlphaFactorOther }, // 0xe
{ false, false, AlphaFactorOther }, // 0xf
{ true, true, AlphaFactorOther } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_LOCAL_ALPHA 0x3
{ false, false, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorLocal }, // 0xa
{ false, false, AlphaFactorLocal }, // 0xb
{ false, false, AlphaFactorLocal }, // 0xc
{ false, false, AlphaFactorLocal }, // 0xd
{ false, false, AlphaFactorLocal }, // 0xe
{ false, false, AlphaFactorLocal }, // 0xf
{ true, false, AlphaFactorLocal } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_TEXTURE_ALPHA 0x4
{ false, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOne }, // 0xa
{ false, false, AlphaFactorOne }, // 0xb
{ false, false, AlphaFactorOne }, // 0xc
{ false, false, AlphaFactorOne }, // 0xd
{ false, false, AlphaFactorOne }, // 0xe
{ false, false, AlphaFactorOne }, // 0xf
{ true, false, AlphaFactorOne } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_TEXTURE_RGB 0x5
{ false, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOne }, // 0xa
{ false, false, AlphaFactorOne }, // 0xb
{ false, false, AlphaFactorOne }, // 0xc
{ false, false, AlphaFactorOne }, // 0xd
{ false, false, AlphaFactorOne }, // 0xe
{ false, false, AlphaFactorOne }, // 0xf
{ true, false, AlphaFactorOne } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // 6
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorZero }, // 0xa
{ false, false, AlphaFactorZero }, // 0xb
{ false, false, AlphaFactorZero }, // 0xc
{ false, false, AlphaFactorZero }, // 0xd
{ false, false, AlphaFactorZero }, // 0xe
{ false, false, AlphaFactorZero }, // 0xf
{ false, false, AlphaFactorZero } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // 7
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ false, false, AlphaFactorZero }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorZero }, // 0xa
{ false, false, AlphaFactorZero }, // 0xb
{ false, false, AlphaFactorZero }, // 0xc
{ false, false, AlphaFactorZero }, // 0xd
{ false, false, AlphaFactorZero }, // 0xe
{ false, false, AlphaFactorZero }, // 0xf
{ false, false, AlphaFactorZero } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE 0x8
{ false, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOne }, // 0xa
{ false, false, AlphaFactorOne }, // 0xb
{ false, false, AlphaFactorOne }, // 0xc
{ false, false, AlphaFactorOne }, // 0xd
{ false, false, AlphaFactorOne }, // 0xe
{ false, false, AlphaFactorOne }, // 0xf
{ true, false, AlphaFactorOne } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_LOCAL 0x9
{ false, false, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOneMinusLocal }, // 0xa
{ false, false, AlphaFactorOneMinusLocal }, // 0xb
{ false, false, AlphaFactorOneMinusLocal }, // 0xc
{ false, false, AlphaFactorOneMinusLocal }, // 0xd
{ false, false, AlphaFactorOneMinusLocal }, // 0xe
{ false, false, AlphaFactorOneMinusLocal }, // 0xf
{ true, false, AlphaFactorOneMinusLocal } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA 0xa
{ false, false, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, true, AlphaFactorOneMinusOther }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOneMinusOther }, // 0xa
{ false, false, AlphaFactorOneMinusOther }, // 0xb
{ false, false, AlphaFactorOneMinusOther }, // 0xc
{ false, false, AlphaFactorOneMinusOther }, // 0xd
{ false, false, AlphaFactorOneMinusOther }, // 0xe
{ false, false, AlphaFactorOneMinusOther }, // 0xf
{ true, true, AlphaFactorOneMinusOther } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA 0xb
{ false, false, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorOneMinusLocal }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOneMinusLocal }, // 0xa
{ false, false, AlphaFactorOneMinusLocal }, // 0xb
{ false, false, AlphaFactorOneMinusLocal }, // 0xc
{ false, false, AlphaFactorOneMinusLocal }, // 0xd
{ false, false, AlphaFactorOneMinusLocal }, // 0xe
{ false, false, AlphaFactorOneMinusLocal }, // 0xf
{ true, false, AlphaFactorOneMinusLocal } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA 0xc
{ false, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOne }, // 0xa
{ false, false, AlphaFactorOne }, // 0xb
{ false, false, AlphaFactorOne }, // 0xc
{ false, false, AlphaFactorOne }, // 0xd
{ false, false, AlphaFactorOne }, // 0xe
{ false, false, AlphaFactorOne }, // 0xf
{ true, false, AlphaFactorOne } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
},
{ // GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION 0xd
{ false, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_ZERO 0x0
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL 0x1
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
{ false, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
{ true, true, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
{ true, false, AlphaFactorOne }, // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
{ false, false, AlphaFactorOne }, // 0xa
{ false, false, AlphaFactorOne }, // 0xb
{ false, false, AlphaFactorOne }, // 0xc
{ false, false, AlphaFactorOne }, // 0xd
{ false, false, AlphaFactorOne }, // 0xe
{ false, false, AlphaFactorOne }, // 0xf
{ true, false, AlphaFactorOne } // GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
}
};

View File

@ -0,0 +1,39 @@
#include "OGLTables.h"
const FxU32 intStartEnd[ GR_FOG_TABLE_SIZE + 1 ] =
{
1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 6, 8, 9, 11, 13, 16, 19, 22, 26, 32, 38, 45, 53,
64, 76, 90, 107, 128, 152, 181, 215, 256, 304, 362, 430, 512, 608, 724, 861,
1024, 1217, 1448, 1722, 2048, 2435, 2896, 3444, 4096, 4870, 5792, 6888, 8192,
9741, 11585, 13777, 16384, 19483, 23170, 27554, 32768, 38967, 46340, 55108, 65536
};
const FxU32 intEndMinusStart[ GR_FOG_TABLE_SIZE ] =
{
0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 2, 2, 3, 3, 3, 4, 6, 6, 7, 8, 11, 12, 14,
17, 21, 24, 29, 34, 41, 48, 58, 68, 82, 96, 116, 137, 163, 193, 231, 274, 326,
387, 461, 548, 652, 774, 922, 1096, 1304, 1549, 1844, 2192, 2607, 3099, 3687,
4384, 5214, 6199, 7373, 8768, 10428
};
const float tableIndexToW[ GR_FOG_TABLE_SIZE ] =
{
1.000000f, 1.142857f, 1.333333f, 1.600000f,
2.000000f, 2.285714f, 2.666667f, 3.200000f,
4.000000f, 4.571429f, 5.333333f, 6.400000f,
8.000000f, 9.142858f, 10.666667f, 12.800000f,
16.000000f, 18.285715f, 21.333334f, 25.600000f,
32.000000f, 36.571430f, 42.666668f, 51.200001f,
64.000000f, 73.142860f, 85.333336f, 102.400002f,
128.000000f, 146.285721f, 170.666672f, 204.800003f,
256.000000f, 292.571442f, 341.333344f, 409.600006f,
512.000000f, 585.142883f, 682.666687f, 819.200012f,
1024.000000f, 1170.285767f, 1365.333374f, 1638.400024f,
2048.000000f, 2340.571533f, 2730.666748f, 3276.800049f,
4096.000000f, 4681.143066f, 5461.333496f, 6553.600098f,
8192.000000f, 9362.286133f, 10922.666992f, 13107.200195f,
16384.000000f, 18724.572266f, 21845.333984f, 26214.400391f,
32768.000000f, 37449.144531f, 43690.667969f, 52428.800781f
};

View File

@ -0,0 +1,36 @@
#include "OGLTables.h"
const OGLWindow windowDimensions[ 16 ] =
{
{ 320, 200 }, // GR_RESOLUTION_320x200
{ 320, 240 }, // GR_RESOLUTION_320x240
{ 400, 256 }, // GR_RESOLUTION_400x256
{ 512, 384 }, // GR_RESOLUTION_512x384
{ 640, 200 }, // GR_RESOLUTION_640x200
{ 640, 350 }, // GR_RESOLUTION_640x350
{ 640, 400 }, // GR_RESOLUTION_640x400
{ 640, 480 }, // GR_RESOLUTION_640x480
{ 800, 600 }, // GR_RESOLUTION_800x600
{ 960, 720 }, // GR_RESOLUTION_960x720
{ 856, 480 }, // GR_RESOLUTION_856x480:
{ 512, 256 }, // GR_RESOLUTION_512x256:
{ 1024, 768 }, // GR_RESOLUTION_1024x768:
{ 1280, 1024 }, // GR_RESOLUTION_1280x1024:
{ 1600, 1200 }, // GR_RESOLUTION_1600x1200:
{ 400, 300 } // GR_RESOLUTION_400x300:
};
const int windowRefresh[ 9 ] =
{
60, // GR_REFRESH_60Hz
70, // GR_REFRESH_70Hz
72, // GR_REFRESH_72Hz
75, // GR_REFRESH_75Hz
80, // GR_REFRESH_80Hz
90, // GR_REFRESH_90Hz
100, // GR_REFRESH_100Hz
85, // GR_REFRESH_85Hz
120 // GR_REFRESH_120Hz
};

View File

@ -0,0 +1,63 @@
#ifndef __OGL_TABLES_H__
#define __OGL_TABLES_H__
#include "glogl.h"
#include "GLRender.h"
typedef struct
{
float h;
float w;
} OGLAspect;
typedef struct
{
int width;
int height;
} OGLWindow;
typedef struct
{
int width;
int height;
int numPixels;
} OGLTexInfo;
typedef struct
{
bool local;
bool other;
ALPHAFACTORFUNCPROC func;
} OGLAlphaTable;
typedef struct
{
bool local;
bool other;
bool alocal;
bool aother;
COLORFACTORFUNCPROC factorfunc;
COLORFUNCTIONPROC func;
} OGLColorTable;
// OGLTextureTables.cpp
extern const OGLAspect texAspects[ 7 ];
extern const OGLTexInfo texInfo[ 7 ][ 9 ];
extern const FxU32 nSquareLod[ 2 ][ 7 ][ 9 ];
extern const FxU32 nSquareTexLod[ 2 ][ 7 ][ 9 ][ 9 ];
// OGLColorAlphaTables.cpp
extern const OGLAlphaTable alphaCombineTable[ 14 ][ 17 ];
extern const OGLColorTable colorCombineTable[ 14 ][ 17 ];
// OGLFogTables.cpp
extern const FxU32 intStartEnd[ GR_FOG_TABLE_SIZE + 1 ];
extern const FxU32 intEndMinusStart[ GR_FOG_TABLE_SIZE ];
extern const float tableIndexToW[ GR_FOG_TABLE_SIZE ];
// OGLMiscTables.cpp
extern const OGLWindow windowDimensions[ 16 ];
extern const int windowRefresh[ 9 ];
#endif

View File

@ -0,0 +1,239 @@
#include "OGLTables.h"
const OGLAspect texAspects[ 7 ] =
{
{ D8OVER256, D1OVER256 }, // GR_ASPECT_8x1
{ D4OVER256, D1OVER256 }, // GR_ASPECT_4x1
{ D2OVER256, D1OVER256 }, // GR_ASPECT_2x1
{ D1OVER256, D1OVER256 }, // GR_ASPECT_1x1
{ D1OVER256, D2OVER256 }, // GR_ASPECT_1x2
{ D1OVER256, D4OVER256 }, // GR_ASPECT_1x4
{ D1OVER256, D8OVER256 } // GR_ASPECT_1x8
};
const OGLTexInfo texInfo[ 7 ][ 9 ] =
{
{ // GR_ASPECT_8x1
{ 256, 32, 8192 }, { 128, 16, 2048 }, { 64, 8, 512 },
{ 32, 4, 128 }, { 16, 2, 32 }, { 8, 1, 8 },
{ 4, 1, 4 }, { 2, 1, 2 }, { 1, 1, 1 }
},
{ // GR_ASPECT_4x1
{ 256, 64, 16384 }, { 128, 32, 4096 }, { 64, 16, 1024 },
{ 32, 8, 256 }, { 16, 4, 64 }, { 8, 2, 16 },
{ 4, 1, 4 }, { 2, 1, 2 }, { 1, 1, 1 }
},
{ // GR_ASPECT_2x1
{ 256, 128, 32768 }, { 128, 64, 8192 }, { 64, 32, 2048 },
{ 32, 16, 512 }, { 16, 8, 128 }, { 8, 4, 32 },
{ 4, 2, 8 }, { 2, 1, 2 }, { 1, 1, 1 }
},
{ // GR_ASPECT_1x1
{ 256, 256, 65536 }, { 128, 128, 16384 }, { 64, 64, 4096 },
{ 32, 32, 1024 }, { 16, 16, 256 }, { 8, 8, 64 },
{ 4, 4, 16 }, { 2, 2, 4 }, { 1, 1, 1 }
},
{ // GR_ASPECT_1x2
{ 128, 256, 32768 }, { 64, 128, 8192 }, { 32, 64, 2048 },
{ 16, 32, 512 }, { 8, 16, 128 }, { 4, 8, 32 },
{ 2, 4, 8 }, { 1, 2, 2 }, { 1, 1, 1 }
},
{ // GR_ASPECT_1x4
{ 64, 256, 16384 }, { 32, 128, 4096 }, { 16, 64, 1024 },
{ 8, 32, 256 }, { 4, 16, 64 }, { 2, 8, 16 },
{ 1, 4, 4 }, { 1, 2, 2 }, { 1, 1, 1 }
},
{ // GR_ASPECT_1x8
{ 32, 256, 8192 }, { 16, 128, 2048 }, { 8, 64, 512 },
{ 4, 32, 128 }, { 2, 16, 32 }, { 1, 8, 8 },
{ 1, 4, 4 }, { 1, 2, 2 }, { 1, 1, 1 }
}
};
const FxU32 nSquareLod[ 2 ][ 7 ][ 9 ] =
{
{
{ 8192, 2048, 512, 128, 32, 8, 2, 1, 1 },
{ 16384, 4096, 1024, 256, 64, 16, 4, 1, 1 },
{ 32768, 8192, 2048, 512, 128, 32, 8, 2, 1 },
{ 65536, 16384, 4096, 1024, 256, 64, 16, 4, 1 },
{ 32768, 8192, 2048, 512, 128, 32, 8, 2, 1 },
{ 16384, 4096, 1024, 256, 64, 16, 4, 1, 1 },
{ 8192, 2048, 512, 128, 32, 8, 2, 1, 1 }
},
{
{ 16384, 4096, 1024, 256, 64, 16, 4, 1, 1 },
{ 32768, 8192, 2048, 512, 128, 32, 8, 2, 1 },
{ 65536, 16384, 4096, 1024, 256, 64, 16, 4, 1 },
{ 131072, 32768, 8192, 2048, 512, 128, 32, 8, 2 },
{ 65536, 16384, 4096, 1024, 256, 64, 16, 4, 1 },
{ 32768, 8192, 2048, 512, 128, 32, 8, 2, 1 },
{ 16384, 4096, 1024, 256, 64, 16, 4, 1, 1 }
}
};
// Necessary memory for textures
// Big table to minimize calculation
const FxU32 nSquareTexLod[ 2 ][ 7 ][ 9 ][ 9 ] = // Tex type, aspect, largelod, smalllod
{
{ // Dual byte Textures
{ // GR_ASPECT_8x1
{ 16384, 20480, 21504, 21760, 21824, 21840, 21848, 21848, 21848 },
{ 0, 4096, 5120, 5376, 5440, 5456, 5464, 5464, 5464 },
{ 0, 0, 1024, 1280, 1344, 1360, 1368, 1368, 1368 },
{ 0, 0, 0, 256, 320, 336, 344, 344, 344 },
{ 0, 0, 0, 0, 64, 80, 88, 88, 88 },
{ 0, 0, 0, 0, 0, 16, 24, 24, 24 },
{ 0, 0, 0, 0, 0, 0, 8, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_4x1
{ 32768, 40960, 43008, 43520, 43648, 43680, 43688, 43696, 43696 },
{ 0, 8192, 10240, 10752, 10880, 10912, 10920, 10928, 10928 },
{ 0, 0, 2048, 2560, 2688, 2720, 2728, 2736, 2736 },
{ 0, 0, 0, 512, 640, 672, 680, 688, 688 },
{ 0, 0, 0, 0, 128, 160, 168, 176, 176 },
{ 0, 0, 0, 0, 0, 32, 40, 48, 48 },
{ 0, 0, 0, 0, 0, 0, 8, 16, 16 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_2x1
{ 65536, 81920, 86016, 87040, 87296, 87360, 87376, 87384, 87384 },
{ 0, 16384, 20480, 21504, 21760, 21824, 21840, 21848, 21848 },
{ 0, 0, 4096, 5120, 5376, 5440, 5456, 5464, 5464 },
{ 0, 0, 0, 1024, 1280, 1344, 1360, 1368, 1368 },
{ 0, 0, 0, 0, 256, 320, 336, 344, 344 },
{ 0, 0, 0, 0, 0, 64, 80, 88, 88 },
{ 0, 0, 0, 0, 0, 0, 16, 24, 24 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_1x1
{ 131072, 163840, 172032, 174080, 174592, 174720, 174752, 174760, 174768 },
{ 0, 32768, 40960, 43008, 43520, 43648, 43680, 43688, 43696 },
{ 0, 0, 8192, 10240, 10752, 10880, 10912, 10920, 10928 },
{ 0, 0, 0, 2048, 2560, 2688, 2720, 2728, 2736 },
{ 0, 0, 0, 0, 512, 640, 672, 680, 688 },
{ 0, 0, 0, 0, 0, 128, 160, 168, 176 },
{ 0, 0, 0, 0, 0, 0, 32, 40, 48 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 16 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_1x2
{ 65536, 81920, 86016, 87040, 87296, 87360, 87376, 87384, 87384 },
{ 0, 16384, 20480, 21504, 21760, 21824, 21840, 21848, 21848 },
{ 0, 0, 4096, 5120, 5376, 5440, 5456, 5464, 5464 },
{ 0, 0, 0, 1024, 1280, 1344, 1360, 1368, 1368 },
{ 0, 0, 0, 0, 256, 320, 336, 344, 344 },
{ 0, 0, 0, 0, 0, 64, 80, 88, 88 },
{ 0, 0, 0, 0, 0, 0, 16, 24, 24 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_1x4
{ 32768, 40960, 43008, 43520, 43648, 43680, 43688, 43696, 43696 },
{ 0, 8192, 10240, 10752, 10880, 10912, 10920, 10928, 10928 },
{ 0, 0, 2048, 2560, 2688, 2720, 2728, 2736, 2736 },
{ 0, 0, 0, 512, 640, 672, 680, 688, 688 },
{ 0, 0, 0, 0, 128, 160, 168, 176, 176 },
{ 0, 0, 0, 0, 0, 32, 40, 48, 48 },
{ 0, 0, 0, 0, 0, 0, 8, 16, 16 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_1x8
{ 16384, 20480, 21504, 21760, 21824, 21840, 21848, 21848, 21848 },
{ 0, 4096, 5120, 5376, 5440, 5456, 5464, 5464, 5464 },
{ 0, 0, 1024, 1280, 1344, 1360, 1368, 1368, 1368 },
{ 0, 0, 0, 256, 320, 336, 344, 344, 344 },
{ 0, 0, 0, 0, 64, 80, 88, 88, 88 },
{ 0, 0, 0, 0, 0, 16, 24, 24, 24 },
{ 0, 0, 0, 0, 0, 0, 8, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
}
},
{ // Single byte Textures
{ // GR_ASPECT_8x1
{ 8192, 10240, 10752, 10880, 10912, 10920, 10928, 10928, 10928 },
{ 0, 2048, 2560, 2688, 2720, 2728, 2736, 2736, 2736 },
{ 0, 0, 512, 640, 672, 680, 688, 688, 688 },
{ 0, 0, 0, 128, 160, 168, 176, 176, 176 },
{ 0, 0, 0, 0, 32, 40, 48, 48, 48 },
{ 0, 0, 0, 0, 0, 8, 16, 16, 16 },
{ 0, 0, 0, 0, 0, 0, 8, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_4x1
{ 16384, 20480, 21504, 21760, 21824, 21840, 21848, 21848, 21848 },
{ 0, 4096, 5120, 5376, 5440, 5456, 5464, 5464, 5464 },
{ 0, 0, 1024, 1280, 1344, 1360, 1368, 1368, 1368 },
{ 0, 0, 0, 256, 320, 336, 344, 344, 344 },
{ 0, 0, 0, 0, 64, 80, 88, 88, 88 },
{ 0, 0, 0, 0, 0, 16, 24, 24, 24 },
{ 0, 0, 0, 0, 0, 0, 8, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_2x1
{ 32768, 40960, 43008, 43520, 43648, 43680, 43688, 43696, 43696 },
{ 0, 8192, 10240, 10752, 10880, 10912, 10920, 10928, 10928 },
{ 0, 0, 2048, 2560, 2688, 2720, 2728, 2736, 2736 },
{ 0, 0, 0, 512, 640, 672, 680, 688, 688 },
{ 0, 0, 0, 0, 128, 160, 168, 176, 176 },
{ 0, 0, 0, 0, 0, 32, 40, 48, 48 },
{ 0, 0, 0, 0, 0, 0, 8, 16, 16 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_1x1
{ 65536, 81920, 86016, 87040, 87296, 87360, 87376, 87384, 87384 },
{ 0, 16384, 20480, 21504, 21760, 21824, 21840, 21848, 21848 },
{ 0, 0, 4096, 5120, 5376, 5440, 5456, 5464, 5464 },
{ 0, 0, 0, 1024, 1280, 1344, 1360, 1368, 1368 },
{ 0, 0, 0, 0, 256, 320, 336, 344, 344 },
{ 0, 0, 0, 0, 0, 64, 80, 88, 88 },
{ 0, 0, 0, 0, 0, 0, 16, 24, 24 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_1x2
{ 32768, 40960, 43008, 43520, 43648, 43680, 43688, 43696, 43696 },
{ 0, 8192, 10240, 10752, 10880, 10912, 10920, 10928, 10928 },
{ 0, 0, 2048, 2560, 2688, 2720, 2728, 2736, 2736 },
{ 0, 0, 0, 512, 640, 672, 680, 688, 688 },
{ 0, 0, 0, 0, 128, 160, 168, 176, 176 },
{ 0, 0, 0, 0, 0, 32, 40, 48, 48 },
{ 0, 0, 0, 0, 0, 0, 8, 16, 16 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_1x4
{ 16384, 20480, 21504, 21760, 21824, 21840, 21848, 21848, 21848 },
{ 0, 4096, 5120, 5376, 5440, 5456, 5464, 5464, 5464 },
{ 0, 0, 1024, 1280, 1344, 1360, 1368, 1368, 1368 },
{ 0, 0, 0, 256, 320, 336, 344, 344, 344 },
{ 0, 0, 0, 0, 64, 80, 88, 88, 88 },
{ 0, 0, 0, 0, 0, 16, 24, 24, 24 },
{ 0, 0, 0, 0, 0, 0, 8, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
},
{ // GR_ASPECT_1x8
{ 8192, 10240, 10752, 10880, 10912, 10920, 10928, 10928, 10928 },
{ 0, 2048, 2560, 2688, 2720, 2728, 2736, 2736, 2736 },
{ 0, 0, 512, 640, 672, 680, 688, 688, 688 },
{ 0, 0, 0, 128, 160, 168, 176, 176, 176 },
{ 0, 0, 0, 0, 32, 40, 48, 48, 48 },
{ 0, 0, 0, 0, 0, 8, 16, 16, 16 },
{ 0, 0, 0, 0, 0, 0, 8, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 8, 8 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 8 },
}
}
};

View File

@ -0,0 +1,57 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* Optimise switches
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
// Check if the Glide state really changes before executing a function.
// The idea behind this is to avoid unnecessary calls to RenderDrawTriangles().
// As a result, the necessary call to RenderDrawTriangles() can render more
// triangles at once.
//
// Most called functions (by analysing Falcon4.0):
// - grAlphaBlendFunction
// - grAlphaCombine
// - grAlphaTestFunction
// - grAlphaTestReferenceValue
// - grChromakeyMode
// - grChromakeyValue
// - grConstantColorValue
// - grConstantColorValue4
// - grClipWindow
// - grColorCombine
// - grDepthBufferMode
// - grDitherMode
// - grFogMode
// - grTexClampMode
// - grTexCombine
// - grTexFilterMode
// - grTexMipMapMode
// - guTexSource
//
// Would need support but are not yet implemented
// - grTexDetailControl
// - grHints
//
// The following function names appear in the logs on each call,
// but just call other functions which are already state-optimised.
// - guTexCombineFunction
// - guColorCombineFunction
//
// Optimises Glide calls with parameters that wouldn't change the Glide state
// (by placing the CHECK_STATE_CHANGED macro at the beginning of a function)
#define OPTIMISE_GLIDE_STATE_CHANGES
// Optimises internal function calls that wouldn't result
// in a change of the OpenGL state
#define OPTIMISE_OPENGL_STATE_CHANGES
// Retrieve TexDB records via a lookup table half the size of the texture memory.
#define OPTIMISE_TEXTURE_LOOKUP

View File

@ -0,0 +1,927 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* implementation of the PGTexture class
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "FormatConversion.h"
#include "Glide.h"
#include "GlideApplication.h"
#include "GlideSettings.h"
#include "Glextensions.h"
#include "GLRender.h"
#include "OGLTables.h"
#include "PGTexture.h"
void PGTexture::genPaletteMipmaps( FxU32 width, FxU32 height, const FxU8 *data )
{
FxU8 buf[ 128 * 128 ];
FxU32 mmwidth;
FxU32 mmheight;
FxU32 lod;
FxU32 skip;
mmwidth = width;
mmheight = height;
lod = 0;
skip = 1;
while ( ( mmwidth > 1 ) || ( mmheight > 1 ) )
{
FxU32 x,
y;
mmwidth = mmwidth > 1 ? mmwidth / 2 : 1;
mmheight = mmheight > 1 ? mmheight / 2 : 1;
lod += 1;
skip *= 2;
for ( y = 0; y < mmheight; y++ )
{
const FxU8* in;
FxU8* out;
in = data + width * y * skip;
out = buf + mmwidth * y;
for ( x = 0; x < mmwidth; x++ )
{
out[ x ] = in[ x * skip ];
}
}
glTexImage2D( GL_TEXTURE_2D, lod, GL_COLOR_INDEX8_EXT, mmwidth, mmheight, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buf );
}
}
PGTexture::PGTexture( int mem_size )
{
m_db = new TexDB( mem_size );
m_palette_dirty = true;
m_valid = false;
m_chromakey_mode = GR_CHROMAKEY_DISABLE;
m_tex_memory_size = mem_size;
m_memory = (FxU8*) AllocBuffer(mem_size, sizeof(FxU8));
m_tex_temp = reinterpret_cast<FxU32*>(AllocBuffer(256 * 256, sizeof(FxU32)));
m_ncc_select = GR_NCCTABLE_NCC0;
#ifdef OGL_DEBUG
Num_565_Tex = 0;
Num_565_Chromakey_Tex = 0;
Num_1555_Tex = 0;
Num_1555_Chromakey_Tex = 0;
Num_4444_Tex = 0;
Num_4444_Chromakey_Tex = 0;
Num_332_Tex = 0;
Num_8332_Tex = 0;
Num_Alpha_Tex = 0;
Num_AlphaIntensity88_Tex = 0;
Num_AlphaIntensity44_Tex = 0;
Num_AlphaPalette_Tex = 0;
Num_Palette_Tex = 0;
Num_Palette_Chromakey_Tex = 0;
Num_Intensity_Tex = 0;
Num_YIQ_Tex = 0;
Num_AYIQ_Tex = 0;
Num_Other_Tex = 0;
#endif
}
PGTexture::~PGTexture( void )
{
FreeBuffer(m_memory);
FreeBuffer(m_tex_temp);
delete m_db;
}
void PGTexture::DownloadMipMap( FxU32 startAddress, FxU32 evenOdd, const GrTexInfo *info )
{
const FxU32 mip_size = MipMapMemRequired( info->smallLod,
info->aspectRatio,
info->format );
const FxU32 mip_offset = startAddress + TextureMemRequired( evenOdd, info );
if ( mip_offset <= m_tex_memory_size )
{
memcpy( m_memory + mip_offset - mip_size, info->data, mip_size );
}
// Any texture based on memory crossing this range
// is now out of date
m_db->WipeRange( startAddress, mip_offset, 0 );
#ifdef OGL_DEBUG
if ( info->smallLod == info->largeLod )
{
switch ( info->format )
{
case GR_TEXFMT_RGB_332: Num_332_Tex++; break;
case GR_TEXFMT_YIQ_422: Num_YIQ_Tex++; break;
case GR_TEXFMT_ALPHA_8: Num_Alpha_Tex++; break;
case GR_TEXFMT_INTENSITY_8: Num_Intensity_Tex++; break;
case GR_TEXFMT_ALPHA_INTENSITY_44: Num_AlphaIntensity44_Tex++; break;
case GR_TEXFMT_P_8: m_chromakey_mode
? Num_Palette_Chromakey_Tex++
: Num_Palette_Tex++;
break;
case GR_TEXFMT_ARGB_8332: Num_8332_Tex++; break;
case GR_TEXFMT_AYIQ_8422: Num_AYIQ_Tex++; break;
case GR_TEXFMT_RGB_565: m_chromakey_mode
? Num_565_Chromakey_Tex++
: Num_565_Tex++;
break;
case GR_TEXFMT_ARGB_1555: m_chromakey_mode
? Num_1555_Chromakey_Tex++
: Num_1555_Tex++;
break;
case GR_TEXFMT_ARGB_4444: m_chromakey_mode
? Num_4444_Chromakey_Tex++
: Num_4444_Tex++;
break;
case GR_TEXFMT_ALPHA_INTENSITY_88: Num_AlphaIntensity88_Tex++; break;
case GR_TEXFMT_AP_88: Num_AlphaPalette_Tex++; break;
case GR_TEXFMT_RSVD0:
case GR_TEXFMT_RSVD1:
case GR_TEXFMT_RSVD2:
default: Num_Other_Tex++; break;
}
}
#endif
}
void PGTexture::DownloadMipMapLevel(FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
void *data)
{
GrTexInfo info;
info.smallLod = thisLod;
info.largeLod = largeLod;
info.aspectRatio = aspectRatio;
info.format = format;
info.data = data;
DownloadMipMap(startAddress, evenOdd, &info);
}
void PGTexture::DownloadMipMapLevelPartial(FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
void *data,
int start,
int end)
{
GrTexInfo info;
info.smallLod = thisLod;
info.largeLod = largeLod;
info.aspectRatio = aspectRatio;
info.format = format;
info.data = data;
const FxU32 mip_size = MipMapMemRequired(info.smallLod, info.aspectRatio, info.format);
// instead of forwarding evenOdd, GR_MIPMAPLEVELMASK_BOTH might also be appropriate
const FxU32 mip_offset = startAddress + TextureMemRequired(evenOdd, &info);
// Choose the rows to copy (only largeLod is supported)
TexValues texVals;
GetTexValues(&texVals);
const FxU32 texel_size = info.format >= GR_TEXFMT_16BIT ? 2 : 1;
const FxU32 startRow = texVals.width * texel_size * start;
const FxU32 rows = texVals.width * texel_size * (end - start);
if ( mip_offset <= m_tex_memory_size )
{
memcpy(m_memory + mip_offset - mip_size + startRow, info.data, rows);
}
// Any texture based on memory crossing this range
// is now out of date
m_db->WipeRange(startAddress, mip_offset, 0);
}
void PGTexture::Source( FxU32 startAddress, FxU32 evenOdd, const GrTexInfo *info )
{
m_startAddress = startAddress;
m_evenOdd = evenOdd;
m_info = *info;
m_wAspect = texAspects[ info->aspectRatio ].w;
m_hAspect = texAspects[ info->aspectRatio ].h;
m_valid = ( ( startAddress + TextureMemRequired( evenOdd, info ) ) <= m_tex_memory_size );
}
void PGTexture::DownloadMipmapsToOpenGL(GLint compnum, GLint compformat, GLenum comptype, const void* texdata, TexValues& t, bool build_mipmaps)
{
glReportErrors("DownloadMipmapsToOpenGL");
glTexImage2D(GL_TEXTURE_2D, t.lod, compnum, t.width, t.height, 0, compformat, comptype, texdata);
if (InternalConfig.Mipmapping && build_mipmaps)
{
gluBuild2DMipmaps(GL_TEXTURE_2D, compnum, t.width, t.height, compformat, comptype, texdata);
}
glReportError();
}
inline void ncc_convert_FxI9_2_FxI16(FxI16* ncc_xRGB)
{
if (*ncc_xRGB & 0x100)
*ncc_xRGB |= 0xff00;
}
void PGTexture::DownloadTable( GrTexTable_t type, const FxU32 *data, int first, int count )
{
if ( type == GR_TEXTABLE_PALETTE )
{
for ( int i = count - 1; i >= 0; i-- )
{
// Convert palette entry from ARGB to RGBA
const FxU32& src = data[ i ];
m_palette[ first + i ] = ((src & 0x00ffffff) << 8) | // RGB
((src & 0xff000000) >> 24); // A
}
m_palette_dirty = true;
}
else
{
// GR_TEXTABLE_NCC0 or GR_TEXTABLE_NCC1
GuNccTable *ncc = &(m_ncc[ type ]);
memcpy( ncc, data, sizeof( GuNccTable ) );
for (int i = 0; i < 4; i++ )
{
ncc_convert_FxI9_2_FxI16(&ncc->iRGB[ i ][ 0 ]);
ncc_convert_FxI9_2_FxI16(&ncc->iRGB[ i ][ 1 ]);
ncc_convert_FxI9_2_FxI16(&ncc->iRGB[ i ][ 2 ]);
ncc_convert_FxI9_2_FxI16(&ncc->qRGB[ i ][ 0 ]);
ncc_convert_FxI9_2_FxI16(&ncc->qRGB[ i ][ 1 ]);
ncc_convert_FxI9_2_FxI16(&ncc->qRGB[ i ][ 2 ]);
}
}
}
bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_triangles)
{
glReportErrors("PGTexture::MakeReady");
if( ! m_valid )
{
return false;
}
FxU32 test_hash = 0;
FxU32 wipe_hash = 0;
bool palette_changed = false;
bool use_mipmap_ext = InternalConfig.Mipmapping && InternalConfig.EXT_SGIS_generate_mipmap;
bool use_two_textures = false;
bool* pal_change_ptr = NULL;
const FxU8* data = m_memory + m_startAddress;
FxU32 size = TextureMemRequired(m_evenOdd, &m_info);
TexValues texVals;
GetTexValues(&texVals);
switch (m_info.format)
{
case GR_TEXFMT_P_8:
ApplyKeyToPalette();
// todo: Would work with anisotropic filtering if chromakeying was disabled
if (InternalConfig.EXT_paletted_texture && InternalConfig.AnisotropylLevel < 2)
{
//
// OpenGL's mipmap generation doesn't seem
// to handle paletted textures.
//
use_mipmap_ext = false;
pal_change_ptr = &palette_changed;
}
else
{
wipe_hash = m_palette_hash;
}
test_hash = m_palette_hash;
break;
case GR_TEXFMT_AP_88:
ApplyKeyToPalette();
if (InternalConfig.EXT_paletted_texture && InternalConfig.ARB_multitexture)
{
use_mipmap_ext = false;
pal_change_ptr = &palette_changed;
// Two textures can only be used with the simple coloralpha engine
// and if there are enough texture units left to support fog
use_two_textures = (OpenGL.ColorAlphaUnit2 == 0) && (OpenGL.FogTextureUnit >= GL_TEXTURE1_ARB);
}
else
{
wipe_hash = m_palette_hash;
}
test_hash = m_palette_hash;
break;
}
// Look if we already have an OpenGL texture to match this
TexDB::Record* texture_record;
SubTexCoord_t subtexcoords_struct;
const bool generate_sub_textures = InternalConfig.GenerateSubTextures &&
OpenGL.SClampMode != GL_REPEAT &&
OpenGL.TClampMode != GL_REPEAT;
SubTexCoord_t* subtexcoords = generate_sub_textures ? &subtexcoords_struct : NULL;
if (subtexcoords)
{
assert(number_of_triangles == 1);
GLfloat min;
GLfloat max;
const unsigned int grid_snap = 0xffffffff - (InternalConfig.GenerateSubTextures -1);
// Get Glide pixel coordinates (prepared in RenderAddTriangle())
const GLfloat as = tex_coords->as;
const GLfloat bs = tex_coords->bs;
const GLfloat cs = tex_coords->cs;
max = as;
min = bs;
if (max < min)
{
max = bs;
min = as;
}
if (max < cs)
{
max = cs;
}
else if (min > cs)
{
min = cs;
}
subtexcoords->smin = min;
subtexcoords->smax = max;
subtexcoords->left = min;
// snap to grid to allow using the left/top values as keys for caching
subtexcoords->left &= grid_snap; // snap to 8 pixel grid
subtexcoords->smin = subtexcoords->left;
// same for t
const GLfloat at = tex_coords->at;
const GLfloat bt = tex_coords->bt;
const GLfloat ct = tex_coords->ct;
max = at;
min = bt;
if (max < min)
{
max = bt;
min = at;
}
if (max < ct)
{
max = ct;
}
else if (min > ct)
{
min = ct;
}
subtexcoords->tmin = min;
subtexcoords->tmax = max;
subtexcoords->top = min;
subtexcoords->top &= grid_snap; // snap to 8 pixel grid
subtexcoords->tmin = subtexcoords->top;
// Calculate width and height of the texture
subtexcoords->width = subtexcoords->smax - subtexcoords->left;
subtexcoords->height = subtexcoords->tmax - subtexcoords->top;
subtexcoords->texImageWidth = max(InternalConfig.GenerateSubTextures, PowerOfTwoCeiling(subtexcoords->width));
subtexcoords->texImageHeight = max(InternalConfig.GenerateSubTextures, PowerOfTwoCeiling(subtexcoords->height));
texture_record = texture_record = m_db->Find(m_startAddress, &m_info, test_hash, pal_change_ptr, subtexcoords);
// At this point the subtexcoord texsize might have been updated (by Find())
// Calculate texture coordinates for rendering the subtexture
// 1. scale a->s to texture pixel s-space: as = a->tmuvtx[ 0 ].sow / atmuoow;
// 2. shift as to origin: as_s = as - subtexcoords.smin;
// 3. scale as_s to opengl texture space as_s *= wAspect / subtexcoords.width;
// 4. scale as_s to opengl subtexture space: * subtexcoords.width / subtexcoords.texImageWidth
// 5. undo dividing by atmoow and scale with maxoow to fit texture edge into object edges
// tex_coords->aoow is actually maxoow * aoow what is what we want
const GLfloat s_factor = 1.0f / subtexcoords->texImageWidth;
tex_coords->as = (as - subtexcoords->smin) * s_factor * tex_coords->aoow;
tex_coords->bs = (bs - subtexcoords->smin) * s_factor * tex_coords->boow;
tex_coords->cs = (cs - subtexcoords->smin) * s_factor * tex_coords->coow;
const GLfloat t_factor = 1.0f / subtexcoords->texImageHeight;
tex_coords->at = (at - subtexcoords->tmin) * t_factor * tex_coords->aoow;
tex_coords->bt = (bt - subtexcoords->tmin) * t_factor * tex_coords->boow;
tex_coords->ct = (ct - subtexcoords->tmin) * t_factor * tex_coords->coow;
#ifdef OGL_UTEX
GlideMsg("glTexCoords(%g,%g)-(%g,%g)-(%g,%g), ",
tex_coords->as,
tex_coords->at,
tex_coords->bs,
tex_coords->bt,
tex_coords->cs,
tex_coords->ct);
GlideMsg("Subtex: min/max(%g,%g)-(%g,%g),",
subtexcoords->smin,
subtexcoords->smax,
subtexcoords->tmin,
subtexcoords->tmax);
GlideMsg(" w/h(%g,%g), texture(%d,%d)-(%d,%d)\n",
subtexcoords->width,
subtexcoords->height,
subtexcoords->left,
subtexcoords->top,
subtexcoords->texImageWidth,
subtexcoords->texImageHeight);
#endif
}
else
{
texture_record = texture_record = m_db->Find(m_startAddress, &m_info, test_hash, pal_change_ptr, NULL);
}
#ifdef OGL_DEBUG
if (InternalConfig.EXT_paletted_texture == false && palette_changed)
{
GlideMsg("Performance Warning: PGTexture palette change for 0x%x causes texture regeneration\n", m_startAddress);
}
#endif
const bool enable_coloralpha_texture_unit_1 = OpenGL.ColorAlphaUnit2 == NULL ||
OpenGL.ColorAlphaUnitColorEnabledState[0] ||
OpenGL.ColorAlphaUnitAlphaEnabledState[0];
const bool enable_coloralpha_texture_unit_2 = OpenGL.ColorAlphaUnitColorEnabledState[1] ||
OpenGL.ColorAlphaUnitAlphaEnabledState[1];
if (texture_record)
{
if (palette_changed && InternalConfig.EXT_paletted_texture)
{
glColorTable(GL_TEXTURE_2D, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_palette);
glReportError();
}
GLint texnum2;
if (OpenGL.ColorAlphaUnit2 && enable_coloralpha_texture_unit_2)
{
texnum2 = texture_record->texNum;
}
else if (use_two_textures)
{
texnum2 = texture_record->tex2Num;
}
else
{
texnum2 = 0;
}
if (texnum2)
{
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + 1);
glBindTexture(GL_TEXTURE_2D, texnum2);
// Only needed if the two textures are different
if (use_two_textures)
{
if (texture_record->SClampMode != OpenGL.SClampMode)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texture_record->SClampMode);
}
if (texture_record->TClampMode != OpenGL.TClampMode)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture_record->TClampMode);
}
if (InternalConfig.TextureSmoothing == false)
{
if (texture_record->MinFilterMode != OpenGL.MinFilterMode)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_record->MinFilterMode);
}
if (texture_record->MagFilterMode != OpenGL.MagFilterMode)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texture_record->MagFilterMode);
}
}
}
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
glReportError();
}
if (enable_coloralpha_texture_unit_1)
{
glBindTexture(GL_TEXTURE_2D, texture_record->texNum);
if (texture_record->SClampMode != OpenGL.SClampMode)
{
texture_record->SClampMode = OpenGL.SClampMode;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, OpenGL.SClampMode);
}
if (texture_record->TClampMode != OpenGL.TClampMode)
{
texture_record->TClampMode = OpenGL.TClampMode;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, OpenGL.TClampMode);
}
if (InternalConfig.TextureSmoothing == false)
{
if (texture_record->MinFilterMode != OpenGL.MinFilterMode)
{
texture_record->MinFilterMode = OpenGL.MinFilterMode;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OpenGL.MinFilterMode);
}
if (texture_record->MagFilterMode != OpenGL.MagFilterMode)
{
texture_record->MagFilterMode = OpenGL.MagFilterMode;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OpenGL.MagFilterMode);
}
}
glReportError();
}
}
else
{
// Any existing textures crossing this memory range
// is unlikely to be used, so remove the OpenGL version
// of them
if (wipe_hash)
{
// If we don't have GL_PALETTE_EXT, the texture must be rebuilt
// after the palette has changed. Any existing textures must be deleted.
// This is because Find() above was looking for a texture with
// the current palette hash and might not have found it, although
// a texture with a different palette exists.
// @todo: Find doesn't return handles to TexDB records, so we have
// to search again every time a paletted texture is used -> optimise.
if (subtexcoords)
{
// Fall back to non-subtexture behaviour and just
// wipe the range if the texture doesn't exist at all
if (m_db->Find(m_startAddress, &m_info, test_hash, pal_change_ptr, NULL) == NULL)
{
m_db->WipeRange(m_startAddress, m_startAddress + size, wipe_hash);
}
}
}
else
{
// Nothing needs to be done because if it's not a paletted texture,
// the range has been wiped while downloading the texture
// m_db->WipeRange( m_startAddress, m_startAddress + size, wipe_hash);
}
// Add the new texture to the data base
TexDB::TextureMode texturemode = subtexcoords ? (use_two_textures ? TexDB::SubTextureTwo : TexDB::SubTextureOne) : (use_two_textures ? TexDB::Two : TexDB::One);
texture_record = m_db->Add(m_startAddress, m_startAddress + size, &m_info, test_hash, texturemode, subtexcoords);
texture_record->SClampMode = OpenGL.SClampMode;
texture_record->TClampMode = OpenGL.TClampMode;
texture_record->MinFilterMode = OpenGL.MinFilterMode;
texture_record->MagFilterMode = OpenGL.MagFilterMode;
glBindTexture( GL_TEXTURE_2D, texture_record->texNum);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, OpenGL.SClampMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, OpenGL.TClampMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OpenGL.MinFilterMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OpenGL.MagFilterMode);
// Texture artefact fix for TR2
// This would solve remaining issues with texture artefacts caused by filtering,
// but degrades the overall image quality too much
/*
bool fix_subtexture_artefacts = false;
if (subtexcoords)
{
// While TR1 uses subtextures with power-of-2 sizes only (as far as I know),
// some TR2 textures don't fit into this scheme, and thus still produces artefacts
// (for instance the joins in Lara's hair and butler james clothes)
const GLfloat epsilon = 0.75;
if (subtexcoords->width / static_cast<GLfloat>(subtexcoords->texImageWidth) <= epsilon ||
subtexcoords->height / static_cast<GLfloat>(subtexcoords->texImageHeight) <= epsilon)
{
// The artefacts can be fixed by applying neither mipmapping nor anisotropic filtering
fix_subtexture_artefacts = true;
}
}
// These are constant parameters and don't change between calls
const unsigned long anisotropy_level = fix_subtexture_artefacts ? 1 : InternalConfig.AnisotropylLevel;
const bool enable_mipmaps = fix_subtexture_artefacts ? false : InternalConfig.Mipmapping;
*/
const unsigned long anisotropy_level = InternalConfig.AnisotropylLevel;
const bool enable_mipmaps = InternalConfig.Mipmapping;
// Write only if enabled in config
if(InternalConfig.AnisotropylLevel > 1)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy_level);
}
if(use_mipmap_ext)
{
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, enable_mipmaps);
}
GLint texnum2;
if (OpenGL.ColorAlphaUnit2 && enable_coloralpha_texture_unit_2)
{
texnum2 = texture_record->texNum;
}
else if (use_two_textures)
{
texnum2 = texture_record->tex2Num;
}
else
{
texnum2 = 0;
}
if (texnum2)
{
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + 1);
glBindTexture(GL_TEXTURE_2D, texnum2);
// Only needed if the two textures are different
if (use_two_textures)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, OpenGL.SClampMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, OpenGL.TClampMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OpenGL.MinFilterMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OpenGL.MagFilterMode);
if(InternalConfig.AnisotropylLevel > 1)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy_level);
}
if (use_mipmap_ext)
{
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, enable_mipmaps);
}
}
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
}
glReportError();
if (subtexcoords)
{
/*
// Don't generate mipmaps in DownloadMipmapsToOpenGL()
if (fix_subtexture_artefacts)
{
// Pretend to have mipmap ext in order to
// avoid generating mipmaps without mipmap ext
use_mipmap_ext = true;
glBindTexture(GL_TEXTURE_2D, OpenGL.DummyTextureName);
}
*/
glPixelStorei(GL_UNPACK_SKIP_PIXELS, subtexcoords->left);
glPixelStorei(GL_UNPACK_SKIP_ROWS, subtexcoords->top);
glPixelStorei(GL_UNPACK_ROW_LENGTH, texVals.width);
// Must update texVals.width, texVals.height to new texture size
texVals.width = subtexcoords->texImageWidth;
texVals.height = subtexcoords->texImageHeight;
}
switch ( m_info.format )
{
case GR_TEXFMT_RGB_565:
if ( m_chromakey_mode )
{
// Read about anisotropy and chromakey issues in macFormatConversions.cpp
Convert565Kto8888((FxU16*)data, m_chromakey_value_565, m_tex_temp, texVals.nPixels);
DownloadMipmapsToOpenGL(4, GL_RGBA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
}
else
{
DownloadMipmapsToOpenGL(3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data, texVals, !use_mipmap_ext);
}
break;
case GR_TEXFMT_ARGB_4444:
DownloadMipmapsToOpenGL(4, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV, data, texVals, !use_mipmap_ext);
break;
case GR_TEXFMT_ARGB_1555:
if (m_chromakey_mode)
{
// Read about anisotropy and chromakey issues in macFormatConversions.cpp
Convert1555Kto8888((FxU16*) data, m_chromakey_value_1555, m_tex_temp, texVals.nPixels);
DownloadMipmapsToOpenGL(4, GL_RGBA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
}
else
{
DownloadMipmapsToOpenGL(4, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, data, texVals, !use_mipmap_ext);
}
break;
case GR_TEXFMT_P_8:
// Read about anisotropy and chromakey issues in macFormatConversions.cpp
if ( InternalConfig.EXT_paletted_texture && InternalConfig.AnisotropylLevel < 2)
{
glColorTable(GL_TEXTURE_2D, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_palette);
glTexImage2D( GL_TEXTURE_2D, texVals.lod, GL_COLOR_INDEX8_EXT,
texVals.width, texVals.height, 0,
GL_COLOR_INDEX, GL_UNSIGNED_BYTE, data );
if (InternalConfig.Mipmapping && !use_mipmap_ext)
{
genPaletteMipmaps(texVals.width, texVals.height, data);
}
glReportError();
}
else
{
if (InternalConfig.AnisotropylLevel >= 2)
{
// minimise anisotropy artefacts
ConvertP8Kto8888(data, m_chromakey_value_8888, m_tex_temp, texVals.nPixels, m_palette);
DownloadMipmapsToOpenGL(4, GL_RGBA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
}
else
{
ConvertP8to8888(data, m_tex_temp, texVals.nPixels, m_palette);
DownloadMipmapsToOpenGL(4, GL_RGBA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
}
}
break;
case GR_TEXFMT_AP_88:
if ( use_two_textures )
{
FxU32 *tex_temp2 = m_tex_temp + 256 * 128;
glColorTable(GL_TEXTURE_2D, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_palette);
SplitAP88( (FxU16 *)data, (FxU8 *)m_tex_temp, (FxU8 *)tex_temp2, texVals.nPixels );
glTexImage2D( GL_TEXTURE_2D, texVals.lod, GL_COLOR_INDEX8_EXT,
texVals.width, texVals.height, 0,
GL_COLOR_INDEX, GL_UNSIGNED_BYTE, m_tex_temp );
if (InternalConfig.Mipmapping && !use_mipmap_ext)
{
genPaletteMipmaps( texVals.width, texVals.height, (FxU8 *)m_tex_temp );
}
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + 1);
DownloadMipmapsToOpenGL( GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, tex_temp2, texVals, !use_mipmap_ext);
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
glReportError();
}
else
{
ConvertAP88to8888( (FxU16*)data, m_tex_temp, texVals.nPixels, m_palette );
DownloadMipmapsToOpenGL(4, GL_RGBA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
}
break;
case GR_TEXFMT_ALPHA_8:
ConvertA8toAP88( (FxU8*)data, (FxU16*)m_tex_temp, texVals.nPixels );
DownloadMipmapsToOpenGL( 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
// @todo: The statement below breaks the overlay texts in Myth TFL.
// As a result ,this optimsation has been undone for now
// DownloadMipmapsToOpenGL(1, GL_ALPHA, GL_UNSIGNED_BYTE, data, texVals, !use_mipmap_ext);
break;
case GR_TEXFMT_ALPHA_INTENSITY_88:
DownloadMipmapsToOpenGL(2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data, texVals, !use_mipmap_ext);
break;
case GR_TEXFMT_INTENSITY_8:
DownloadMipmapsToOpenGL(1, GL_LUMINANCE, GL_UNSIGNED_BYTE, data, texVals, !use_mipmap_ext);
break;
case GR_TEXFMT_ALPHA_INTENSITY_44:
// @todo: untested
// DownloadMipmapsToOpenGL(GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data, &texVals);
// @todo: untested
ConvertAI44toAP88((FxU8*)data, (FxU16*)m_tex_temp, texVals.nPixels);
DownloadMipmapsToOpenGL(2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
/*
ConvertAI44toAP88( (FxU8*)data, (FxU16*)m_tex_temp, texVals.nPixels );
glTexImage2D( GL_TEXTURE_2D, texVals.lod, 2, texVals.width, texVals.height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, m_tex_temp );
if (InternalConfig.Mipmapping && !use_mipmap_ext)
{
gluBuild2DMipmaps( GL_TEXTURE_2D, 2, texVals.width, texVals.height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, m_tex_temp );
}
glReportError();
*/
break;
case GR_TEXFMT_8BIT: //GR_TEXFMT_RGB_332
DownloadMipmapsToOpenGL(3, GL_RGB, GL_UNSIGNED_BYTE_3_3_2_EXT, data, texVals, !use_mipmap_ext);
break;
case GR_TEXFMT_16BIT: //GR_TEXFMT_ARGB_8332:
Convert8332to8888( (FxU16*)data, m_tex_temp, texVals.nPixels );
DownloadMipmapsToOpenGL(4, GL_RGBA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
break;
case GR_TEXFMT_YIQ_422:
ConvertYIQto8888( (FxU8*)data, m_tex_temp, texVals.nPixels, &(m_ncc[m_ncc_select]) );
// @todo: Should just be RGB in order to apply constant color per default, shouldn't it?
DownloadMipmapsToOpenGL(4, GL_RGBA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
break;
case GR_TEXFMT_AYIQ_8422:
ConvertAYIQto8888( (FxU16*)data, m_tex_temp, texVals.nPixels, &(m_ncc[m_ncc_select]) );
DownloadMipmapsToOpenGL(4, GL_RGBA, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
break;
case GR_TEXFMT_RSVD0:
case GR_TEXFMT_RSVD1:
case GR_TEXFMT_RSVD2:
default:
GlideMsg("Error: grTexDownloadMipMapLevel - Unsupported format(%d)\n", m_info.format);
memset( m_tex_temp, 255, texVals.nPixels * 2 );
DownloadMipmapsToOpenGL(1, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_tex_temp, texVals, !use_mipmap_ext);
break;
}
if (subtexcoords)
{
// restore values
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
}
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
return use_two_textures;
}
FxU32 PGTexture::LodOffset( FxU32 evenOdd, const GrTexInfo *info )
{
FxU32 total = 0;
GrLOD_t i;
for( i = info->largeLod; i < info->smallLod; i++ )
{
total += MipMapMemRequired( i, info->aspectRatio, info->format );
}
total = ( total + 7 ) & ~7;
return total;
}
FxU32 PGTexture::TextureMemRequired( FxU32 evenOdd, const GrTexInfo *info )
{
//
// If the format is one of these:
// GR_TEXFMT_RGB_332, GR_TEXFMT_YIQ_422, GR_TEXFMT_ALPHA_8
// GR_TEXFMT_INTENSITY_8, GR_TEXFMT_ALPHA_INTENSITY_44, GR_TEXFMT_P_8
// Reduces the size by 2
//
return nSquareTexLod[ info->format < GR_TEXFMT_16BIT ][ info->aspectRatio ][ info->largeLod ][ info->smallLod ];
}
FxU32 PGTexture::MipMapMemRequired( GrLOD_t lod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format )
{
//
// If the format is one of these:
// GR_TEXFMT_RGB_332, GR_TEXFMT_YIQ_422, GR_TEXFMT_ALPHA_8
// GR_TEXFMT_INTENSITY_8, GR_TEXFMT_ALPHA_INTENSITY_44, GR_TEXFMT_P_8
// Reduces the size by 2
//
return nSquareLod[ format >= GR_TEXFMT_16BIT ][ aspectRatio ][ lod ];
}
void PGTexture::GetTexValues( TexValues * tval ) const
{
tval->width = texInfo[ m_info.aspectRatio ][ m_info.largeLod ].width;
tval->height = texInfo[ m_info.aspectRatio ][ m_info.largeLod ].height;
tval->nPixels = texInfo[ m_info.aspectRatio ][ m_info.largeLod ].numPixels;
tval->lod = 0;
}
void PGTexture::Clear( void )
{
m_db->Clear( );
}
void PGTexture::ChromakeyValue( GrColor_t value )
{
m_chromakey_value_8888 = (value & 0xffffff00); // RGB, Alpha ommited
m_chromakey_value_565 = (FxU16) (( value & 0xF8000000 ) >> 16 |
( value & 0x00FC0000 ) >> 13 |
( value & 0x0000F800 ) >> 11 );
m_chromakey_value_1555 = (FxU16) (( value & 0xf8000000 ) >> 17 |
( value & 0x00f80000 ) >> 14 |
( value & 0x0000f800 ) >> 11 );
m_palette_dirty = true;
}
void PGTexture::ChromakeyMode( GrChromakeyMode_t mode )
{
m_chromakey_mode = mode;
m_palette_dirty = true;
}
void PGTexture::ApplyKeyToPalette( void )
{
FxU32 hash;
int i;
if ( m_palette_dirty )
{
hash = 0;
{
for ( i = 0; i < 256; i++ )
{
if ( ( m_chromakey_mode )
&& ( ( m_palette[i] & 0xffffff00 ) == m_chromakey_value_8888))
{
m_palette[i] &= 0xffffff00;
}
else
{
m_palette[i] |= 0x000000ff;
}
hash = ( ( hash << 5 ) | ( hash >> 27 ) );
hash += ( InternalConfig.IgnorePaletteChange
? ( m_palette[ i ] & 0x000000ff )
: m_palette[ i ]);
}
}
m_palette_hash = hash;
m_palette_dirty = false;
}
}
void PGTexture::NCCTable( GrNCCTable_t tab )
{
switch ( tab )
{
case GR_NCCTABLE_NCC0:
case GR_NCCTABLE_NCC1:
m_ncc_select = tab;
}
}
FxU32 PGTexture::GetMemorySize( void ) const
{
return m_tex_memory_size;
}
unsigned int PGTexture::PowerOfTwoCeiling(unsigned int x)
{
for(unsigned int potc= 1; potc < 0x0fffffff; potc <<= 1)
{
if (potc >= x) return potc;
}
return 0;
}

View File

@ -0,0 +1,124 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* PGTexture Class Definition
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef __PGTEXTURE_H__
#define __PGTEXTURE_H__
#include "TexDB.h"
struct TTextureStruct;
class PGTexture
{
struct TexValues
{
GrLOD_t lod;
FxU32 width;
FxU32 height;
FxU32 nPixels;
};
unsigned int PowerOfTwoCeiling(unsigned int x);
public:
void NCCTable( GrNCCTable_t tab );
static FxU32 LodOffset( FxU32 evenOdd, const GrTexInfo *info );
static FxU32 MipMapMemRequired( GrLOD_t lod, GrAspectRatio_t aspectRatio,
GrTextureFormat_t format );
static FxU32 TextureMemRequired( FxU32 evenOdd, const GrTexInfo *info );
static void genPaletteMipmaps( FxU32 width, FxU32 height, const FxU8 *data );
void ChromakeyMode( GrChromakeyMode_t mode );
void ChromakeyValue( GrColor_t value );
inline float GetHAspect() const
{
return m_hAspect;
}
inline float GetWAspect() const
{
return m_wAspect;
}
inline const GrTexInfo* GetCurrentTexInfo() const
{
return &m_info;
}
void Clear();
bool MakeReady(TTextureStruct* tex_coords = NULL, unsigned long number_of_triangles = 0);
void DownloadTable( GrTexTable_t type, const FxU32 *data, int first, int count );
void Source( FxU32 startAddress, FxU32 evenOdd, const GrTexInfo *info );
void DownloadMipMap( FxU32 startAddress, FxU32 evenOdd, const GrTexInfo *info );
void DownloadMipMapLevel(FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
void *data);
void DownloadMipMapLevelPartial(FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
void *data,
int start,
int end);
FxU32 GetMemorySize( void ) const;
PGTexture( int mem_size );
virtual ~PGTexture();
#ifdef OGL_DEBUG
int Num_565_Tex;
int Num_565_Chromakey_Tex;
int Num_1555_Tex;
int Num_1555_Chromakey_Tex;
int Num_4444_Tex;
int Num_4444_Chromakey_Tex;
int Num_332_Tex;
int Num_8332_Tex;
int Num_Alpha_Tex;
int Num_AlphaIntensity88_Tex;
int Num_AlphaIntensity44_Tex;
int Num_AlphaPalette_Tex;
int Num_Palette_Tex;
int Num_Palette_Chromakey_Tex;
int Num_Intensity_Tex;
int Num_YIQ_Tex;
int Num_AYIQ_Tex;
int Num_Other_Tex;
#endif
private:
void ApplyKeyToPalette( void );
void GetTexValues( TexValues *tval ) const;
void DownloadMipmapsToOpenGL(GLint compnum, GLint compformat, GLenum comptype, const void* texdata, TexValues& t, bool build_mipmaps);
FxU32 m_tex_memory_size;
bool m_palette_dirty;
FxU32 m_palette_hash;
TexDB * m_db;
GrChromakeyMode_t m_chromakey_mode;
FxU32 m_chromakey_value_8888;
FxU16 m_chromakey_value_565;
FxU16 m_chromakey_value_1555;
float m_wAspect;
float m_hAspect;
FxU32* m_tex_temp;
bool m_valid;
FxU8 * m_memory;
FxU32 m_startAddress;
FxU32 m_evenOdd;
GrTexInfo m_info;
FxU32 m_palette[ 256 ];
GrNCCTable_t m_ncc_select;
GuNccTable m_ncc[2];
};
extern PGTexture *Textures;
#endif

View File

@ -0,0 +1,222 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* implementation of the PGUexture class
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "PGTexture.h"
#include "PGUTexture.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
PGUTexture::PGUTexture( void )
{
for ( int i = 0; i < MAX_MM; i++ )
{
mm_info[ i ].valid = false;
}
m_free_mem = 0;
m_free_id = 0;
m_current_id = GR_NULL_MIPMAP_HANDLE;
}
PGUTexture::~PGUTexture( void )
{
}
GrMipMapId_t PGUTexture::AllocateMemory( GrChipID_t tmu, FxU8 odd_even_mask,
int width, int height,
GrTextureFormat_t fmt, GrMipMapMode_t mm_mode,
GrLOD_t smallest_lod, GrLOD_t largest_lod,
GrAspectRatio_t aspect,
GrTextureClampMode_t s_clamp_mode,
GrTextureClampMode_t t_clamp_mode,
GrTextureFilterMode_t minfilter_mode,
GrTextureFilterMode_t magfilter_mode,
float lod_bias, FxBool trilinear )
{
FxU32 size = 0;
GrLOD_t lod;
for ( lod = largest_lod; lod <= smallest_lod; lod++ )
{
size += PGTexture::MipMapMemRequired( lod, aspect, fmt );
}
size = ((size + 7) & ~7);
#ifdef OGL_UTEX
GlideMsg( "Allocate id = %d size = %d\n", m_free_id, size );
#endif
if ( ( m_free_id >= MAX_MM ) ||
( ( m_free_mem + size ) >= Textures->GetMemorySize( ) ) )
{
#ifdef OGL_UTEX
GlideMsg("Allocation failed\n");
#endif
return GR_NULL_MIPMAP_HANDLE;
}
mm_info[ m_free_id ].tmu = tmu;
mm_info[ m_free_id ].odd_even_mask = odd_even_mask;
mm_info[ m_free_id ].width = width;
mm_info[ m_free_id ].height = height;
mm_info[ m_free_id ].format = fmt;
mm_info[ m_free_id ].mipmap_mode = mm_mode;
mm_info[ m_free_id ].lod_min = smallest_lod;
mm_info[ m_free_id ].lod_max = largest_lod;
mm_info[ m_free_id ].aspect_ratio = aspect;
mm_info[ m_free_id ].s_clamp_mode = s_clamp_mode;
mm_info[ m_free_id ].t_clamp_mode = t_clamp_mode;
mm_info[ m_free_id ].minfilter_mode = minfilter_mode;
mm_info[ m_free_id ].magfilter_mode = magfilter_mode;
mm_info[ m_free_id ].lod_bias = lod_bias;
mm_info[ m_free_id ].trilinear = trilinear;
mm_info[ m_free_id ].valid = FXTRUE;
mm_start[ m_free_id ] = m_free_mem;
m_free_mem += size;
return m_free_id++;
}
void PGUTexture::DownloadMipMap( GrMipMapId_t mmid, const void *src, const GuNccTable *table )
{
#ifdef OGL_UTEX
GlideMsg("Download id = %d ", mmid);
#endif
if ( ( mmid >=0 ) && ( mmid < MAX_MM ) && ( mm_info[ mmid ].valid ) )
{
GrTexInfo info;
info.aspectRatio = mm_info[ mmid ].aspect_ratio;
info.format = mm_info[ mmid ].format;
info.largeLod = mm_info[ mmid ].lod_max;
info.smallLod = mm_info[ mmid ].lod_min;
info.data = (void *)src;
if (info.format == GR_TEXFMT_YIQ_422 ||
info.format == GR_TEXFMT_AYIQ_8422)
{
memcpy(&mm_info[ mmid ].ncc_table, table, sizeof(GuNccTable));
}
#ifdef OGL_UTEX
{
FxU32 size = 0;
for ( GrLOD_t lod = info.largeLod; lod <= info.smallLod; lod++ )
{
size += PGTexture::MipMapMemRequired( lod, info.aspectRatio, info.format );
}
GlideMsg( "size = %d\n", size );
}
#endif
grTexDownloadMipMap( mm_info[mmid].tmu, mm_start[ mmid ], mm_info[ mmid ].odd_even_mask, &info );
}
#ifdef OGL_UTEX
else
{
GlideMsg( "failed\n" );
}
#endif
}
void PGUTexture::DownloadMipMapLevel( GrMipMapId_t mmid, GrLOD_t lod, const void **src )
{
#ifdef OGL_NOTDONE
GlideMsg("PGUTexture::DownloadMipMapLevel(...)\n");
#endif
}
void PGUTexture::MemReset( void )
{
#ifdef OGL_UTEX
GlideMsg("Reset\n");
#endif
for ( int i = 0; i < MAX_MM; i++ )
{
mm_info[ i ].valid = false;
}
m_free_mem = 0;
m_free_id = 0;
m_current_id = GR_NULL_MIPMAP_HANDLE;
}
void PGUTexture::Source( GrMipMapId_t id )
{
if ( ( id >=0 ) && ( id < MAX_MM ) && ( mm_info[ id ].valid ) )
{
GrTexInfo info;
info.aspectRatio = mm_info[ id ].aspect_ratio;
info.format = mm_info[ id ].format;
info.largeLod = mm_info[ id ].lod_max;
info.smallLod = mm_info[ id ].lod_min;
int tmu = mm_info[ id ].tmu;
grTexSource( tmu, mm_start[ id ], mm_info[ id ].odd_even_mask, &info );
grTexFilterMode( tmu, mm_info[ id ].minfilter_mode, mm_info[ id ].magfilter_mode );
grTexMipMapMode( tmu, mm_info[ id ].mipmap_mode, mm_info[ id ].trilinear );
grTexClampMode( tmu, mm_info[ id ].s_clamp_mode, mm_info[ id ].t_clamp_mode );
grTexLodBiasValue( tmu, mm_info[ id ].lod_bias );
// Download the ncc table
// @todo: the linux driver utilises both tables and optimises download
// -> No download, no texture recreation
grTexDownloadTable(tmu, GR_NCCTABLE_NCC0, &mm_info[ id ].ncc_table);
m_current_id = id;
}
#ifdef OGL_UTEX
else
{
GlideMsg( "TexSource failed\n" );
}
#endif
}
GrMipMapInfo *PGUTexture::GetMipMapInfo( GrMipMapId_t mmid )
{
return ( ( mmid >= 0 ) && ( mmid < MAX_MM ) &&
( mm_info[mmid].valid ) ? &( mm_info[ mmid ] ) : NULL );
}
FxBool PGUTexture::ChangeAttributes( GrMipMapId_t mmid, int width, int height,
GrTextureFormat_t fmt, GrMipMapMode_t mm_mode,
GrLOD_t smallest_lod, GrLOD_t largest_lod,
GrAspectRatio_t aspect, GrTextureClampMode_t s_clamp_mode,
GrTextureClampMode_t t_clamp_mode,
GrTextureFilterMode_t minFilterMode,
GrTextureFilterMode_t magFilterMode )
{
#ifdef OGL_NOTDONE
GlideMsg("PGUTexture::ChangeAttributes(...)\n");
#endif
return FXFALSE;
}
GrMipMapId_t PGUTexture::GetCurrentMipMap( GrChipID_t tmu ) const
{
return m_current_id;
}
FxU32 PGUTexture::MemQueryAvail( GrChipID_t tmu ) const
{
return Textures->GetMemorySize( ) - m_free_mem;
}

View File

@ -0,0 +1,63 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* PGUTexture Class Definition
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef __PGUTEXTURE_H__
#define __PGUTEXTURE_H__
#include "sdk2_glide.h"
class PGUTexture
{
public:
FxU32 MemQueryAvail( GrChipID_t tmu ) const;
GrMipMapId_t GetCurrentMipMap( GrChipID_t tmu ) const;
FxBool ChangeAttributes( GrMipMapId_t mmid, int width, int height,
GrTextureFormat_t fmt, GrMipMapMode_t mm_mode,
GrLOD_t smallest_lod, GrLOD_t largest_lod,
GrAspectRatio_t aspect, GrTextureClampMode_t s_clamp_mode,
GrTextureClampMode_t t_clamp_mode,
GrTextureFilterMode_t minFilterMode,
GrTextureFilterMode_t magFilterMode );
GrMipMapInfo * GetMipMapInfo( GrMipMapId_t mmid );
void Source( GrMipMapId_t id );
void MemReset( void );
void DownloadMipMapLevel( GrMipMapId_t mmid, GrLOD_t lod, const void **src );
void DownloadMipMap( GrMipMapId_t mmid, const void *src, const GuNccTable *table );
GrMipMapId_t AllocateMemory( GrChipID_t tmu, FxU8 odd_even_mask, int width, int height,
GrTextureFormat_t fmt, GrMipMapMode_t mm_mode,
GrLOD_t smallest_lod, GrLOD_t largest_lod,
GrAspectRatio_t aspect, GrTextureClampMode_t s_clamp_mode,
GrTextureClampMode_t t_clamp_mode,
GrTextureFilterMode_t minfilter_mode,
GrTextureFilterMode_t magfilter_mode,
float lod_bias, FxBool trilinear );
PGUTexture( void );
virtual ~PGUTexture( void );
private:
enum { MAX_MM = 1024 };
GrMipMapInfo mm_info[ MAX_MM ];
FxU32 mm_start[ MAX_MM ];
FxU32 m_free_mem;
GrMipMapId_t m_free_id;
GrMipMapId_t m_current_id;
public:
GrMipMapId_t GetCurrentID() {return m_current_id;};
};
extern PGUTexture UTextures;
#endif

View File

@ -0,0 +1,39 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* file for including all precompiled headers
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
// stuff that should be precompiled
// Setup
#include "System.h"
#include "Debug.h"
#include "Optimise.h"
// clib
#include <assert.h>
#include <extras.h>
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
// opengl
#include <gl.h>
#include <glu.h>
#include <glext.h>
// openglide
#include "GlOgl.h"
#include "Glide.h"

View File

@ -0,0 +1,80 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* file for including all platform specific stuff
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
#if defined(__MWERKS__)
#if defined(macintosh)
#define OPENGLIDE_HOST_MAC
// Codewarrior specific
#define PP_Target_Carbon 0
#define PP_Target_Classic (!PP_Target_Carbon)
#define TARGET_API_MAC_CARBON PP_Target_Carbon
#define TARGET_API_MAC_OS8 PP_Target_Classic
// # else if /* Carbon or MachO version */
// # define OPENGLIDE_HOST_MAC
// # endif /* !macintosh */
#else /* !macintosh */
#error "Unknown MetroWerks target platform"
#endif /* !macintosh */
#endif
// Mac specific stuff
#ifdef OPENGLIDE_HOST_MAC
// use plain ASCII only
#define __NO_WIDE_CHAR
// headers
#include <MacHeaders.h>
// platform specific settings
// macos 9 doesn't provide linkage to fogcoord functions
#define OPENGLIDE_DOESN_T_HAVE_FOGCOORD
// macos 9 doesn't provide linkage to blendfunc seperate function
#define OPENGLIDE_DOESN_T_HAVE_BLENDFUNC_SEPERATE
// C and C++ standard calling convention (used on win32)
#define __cdecl
// #define __stdcall
#define __fastcall
#else
#define OPENGLIDE_SYSTEM_HAS_FOGCOORD
#define OPENGLIDE_SYSTEM_HAS_BLENDFUNC_SEPERATE
#endif
// Glide SDK
#include "sdk2_3dfx.h"
// This is used by CodeWarrior to just export the
// symbols needed for the 3DfxGlideLib2.x library
#if defined(__MWERKS__)
#pragma export on
#endif
#include "sdk2_glide.h"
#include "sdk2_glideutl.h"
#if defined(__MWERKS__)
#pragma export off
#endif
#include "sdk2_glidesys.h"
#include "sdk2_sst1vid.h"
// Export some more functions needed by pre glide 2.4 games
// (for instance Quake 3dfx on the Mac)
#ifdef OPENGLIDE_HOST_MAC
#if defined(__MWERKS__)
#pragma export on
#endif
#include "grguMisc.h"
#include "grguSstGlide.h"
#include "grLfb.h"
#include "sst1.h"
#if defined(__MWERKS__)
#pragma export off
#endif
#endif

View File

@ -0,0 +1,529 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* implementation of the TexDB class
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Glide.h"
#include "TexDB.h"
TexDB::Record* TexDB::Record::s_FreeRecords = NULL;
TexDB::RecordArray* TexDB::Record::s_RecordArrays = NULL;
TexDB::SubRecord* TexDB::SubRecord::s_FreeSubRecords = NULL;
int TexDB::RecordArraySize = 16;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
TexDB::TexDB(unsigned int MemorySize)
{
numberOfTexSections = MemorySize >> 15; // ( 32 * 1024 );
m_first = new Record*[ numberOfTexSections ];
for ( unsigned int i = 0; i < numberOfTexSections; i++ )
{
m_first[ i ] = NULL;
}
#ifdef OPTIMISE_TEXTURE_LOOKUP
// Allocate MemorySize / 2 record pointers, because
// a Glide texture can only be downloaded to 8-byte boundaries
m_texmem_2_record = static_cast<Record**>(AllocBuffer(MemorySize >> 3, sizeof(Record*)));
memset(m_texmem_2_record, 0, (MemorySize >> 3) * sizeof(Record*));
#endif
// Prealloc Reocrds proportional to the amount of tex memory
RecordArraySize = MemorySize / (1024 * 1024) * 256; // preallocate 256 records per mb
// Prealloc some texdb records to avoid out of memory problems later
TexDB::Record::Init();
}
TexDB::~TexDB( void )
{
Clear();
delete[] m_first;
TexDB::SubRecord::Cleanup();
#ifdef OPTIMISE_TEXTURE_LOOKUP
if (m_texmem_2_record) FreeBuffer(m_texmem_2_record);
#endif
}
TexDB::Record* TexDB::Find(FxU32 startAddress, const GrTexInfo *info, FxU32 hash, bool *pal_change, SubTexCoord_t* subtexcoords) const
{
// Perform normal search
FxU32 sect = startAddress >> 15; // ( 32 * 1024 );
Record* r;
#ifdef OPTIMISE_TEXTURE_LOOKUP
// We can start searching with the record found via the lookup,
// because it's the one added last to this address,
// and records are added to the front of the linked list
r = m_texmem_2_record[startAddress >> 3];
// If the record has a palette hash,
// then we must find the right paletted texture
if (r == NULL || hash != r->hash)
{
if (r)
{
// Can start from the next record, because we've
// just checked that the current doesn't match
r = r->next;
}
else
{
// lookup empty, search from the beginning
r = m_first[sect];
}
#else
r = m_first[sect];
#endif
for (; r; r = r->next)
{
if (r->Match(startAddress, info, (pal_change == NULL) ? hash : 0))
{
#ifdef OGL_UTEX
GlideMsg("Found tex %d\n", r->texNum);
#endif
break;
}
}
#ifdef OPTIMISE_TEXTURE_LOOKUP
}
#ifdef OGL_UTEX
else if (r)
{
GlideMsg("Found texmem_2_record tex %d\n", r->texNum);
}
#endif
#endif
if (r)
{
if (subtexcoords)
{
#ifdef OGL_UTEX
GlideMsg("Looking for subtexture: ");
GlideMsg("min/max(%g,%g)-(%g,%g), ",
subtexcoords->smin,
subtexcoords->smax,
subtexcoords->tmin,
subtexcoords->tmax);
GlideMsg("w/h(%g,%g), texture(%d,%d)-(%d,%d)\n",
subtexcoords->width,
subtexcoords->height,
subtexcoords->left,
subtexcoords->top,
subtexcoords->texImageWidth,
subtexcoords->texImageHeight);
#endif
// Lookup subrecord
SubRecord* s;
for (s = r->subrecords; s != NULL; s = s->next)
{
if (s->Match(subtexcoords))
{
// bind textures
r->texNum = s->texNum;
r->tex2Num = s->tex2Num;
// The one we've found might have a greater texture than the one
// we're looking for so we have to update the size
subtexcoords->width = s->left;
subtexcoords->height = s->top;
subtexcoords->smin = s->left;
subtexcoords->tmin = s->top;
subtexcoords->texImageWidth = s->texImageWidth;
subtexcoords->texImageHeight = s->texImageHeight;
#ifdef OGL_UTEX
GlideMsg("Found subtex %d\n", s->texNum);
#endif
break;
}
}
if (s == NULL)
{
#ifdef OGL_UTEX
GlideMsg("Removing smaller subtextures in tex_record %d\n", r->texNum);
#endif
// remove any smaller version of the subtextures to avoid artefacts on snow tiles
// This is ok because we're about to create a new texture that contains all those
// smaller textures we're going to wipe
r->WipeInside(subtexcoords);
r = NULL;
}
}
// Palette changed?
if (( pal_change != NULL) && (r->hash != hash ))
{
r->hash = hash;
*pal_change = true;
}
}
return r;
}
void TexDB::WipeRange(FxU32 startAddress, FxU32 endAddress, FxU32 hash)
{
Record** p;
FxU32 stt_sect = startAddress >> 15; // ( 32 * 1024 );
/*
* Textures can be as large as 128K, so
* one that starts 3 sections back can
* extend into this one.
*/
if (stt_sect < 4)
{
stt_sect = 0;
}
else
{
stt_sect -= 4;
}
FxU32 end_sect = endAddress >> 15; // ( 32 * 1024 );
if (end_sect >= numberOfTexSections)
{
end_sect = numberOfTexSections - 1;
}
for(FxU32 i = stt_sect; i <= end_sect; i++)
{
p = &(m_first[i]);
while (*p != NULL)
{
Record* r = *p;
if ((startAddress < r->endAddress) &&
(r->startAddress < endAddress) &&
((hash == 0) || (r->hash == hash)))
{
*p = r->next;
#ifdef OPTIMISE_TEXTURE_LOOKUP
m_texmem_2_record[(r->startAddress) >> 3] = NULL;
#endif
delete r;
#ifdef OGL_UTEX
if (hash)
{
GlideMsg("Wipe tex %d, hash 0x%x\n", r->texNum, r->hash);
}
else
{
GlideMsg("Wipe tex %d\n", r->texNum);
}
#endif
}
else
{
p = &(r->next);
}
}
}
}
TexDB::Record* TexDB::Add(FxU32 startAddress, FxU32 endAddress, const GrTexInfo *info, FxU32 hash, TexDB::TextureMode texturemode, const SubTexCoord_t* subtexcoords)
{
Record *r = NULL;
// Check for existing record
if (subtexcoords)
{
#ifdef OPTIMISE_TEXTURE_LOOKUP
// lookup record
r = m_texmem_2_record[startAddress >> 3];
// needed by TR 1 Gold to work correctly
if (r == NULL || r->Match( startAddress, info, 0) == false)
{
#endif
// @todo: don't do it twice (here and in Find())
FxU32 sect = startAddress >> 15; // ( 32 * 1024 );
for (r = m_first[ sect ]; r != NULL; r = r->next )
{
if ( r->Match( startAddress, info, 0 /*( pal_change == NULL ) ? hash : 0 )*/ ))
{
break;
}
}
#ifdef OPTIMISE_TEXTURE_LOOKUP
}
#endif
}
else
{
#ifdef OGL_UTEX
#ifdef OPTIMISE_TEXTURE_LOOKUP
// lookup record
r = m_texmem_2_record[startAddress >> 3];
if (r)
{
GlideMsg("Warning: Existing TexRecord must be wiped first%d\n", r->texNum);
return NULL;
}
#endif
#endif
}
// Create new record?
if (r == NULL)
{
r = new Record(texturemode);
FxU32 sect = startAddress >> 15; // 32 * 1024
r->startAddress = startAddress;
r->endAddress = endAddress;
r->info = *info;
r->hash = hash;
r->next = m_first[sect];
m_first[sect] = r;
r->subrecords = NULL;
#ifdef OPTIMISE_TEXTURE_LOOKUP
// lookup record
m_texmem_2_record[startAddress >> 3] = r;
#endif
#ifdef OGL_UTEX
GlideMsg("Add tex %d\n", r->texNum);
#endif
}
if (subtexcoords)
{
SubRecord* s = new SubRecord(texturemode);
s->left = subtexcoords->left;
s->top = subtexcoords->top;
s->texImageWidth = subtexcoords->texImageWidth;
s->texImageHeight = subtexcoords->texImageHeight;
s->next = r->subrecords;
r->subrecords = s;
// The caller always queries r for texture names, thus we have to copy
// Note: For debugging the caching efficency, comment out the assignment
r->texNum = s->texNum;
r->tex2Num = s->tex2Num;
#ifdef OGL_UTEX
GlideMsg("Add subtex %d\n", s->texNum);
#endif
}
return r;
}
void TexDB::Clear( void )
{
Record* r;
for ( unsigned int i = 0; i < numberOfTexSections; i++ )
{
r = m_first[ i ];
while ( r != NULL )
{
Record *tmp = r;
r = r->next;
#ifdef OPTIMISE_TEXTURE_LOOKUP
// lookup record
m_texmem_2_record[(tmp->startAddress) >> 3] = NULL;
#endif
delete tmp;
}
m_first[ i ] = NULL;
}
}
///////////////////////////////////////////////////////////////////
// TexDB::Record Class implementation
///////////////////////////////////////////////////////////////////
void TexDB::Record::Init()
{
// Alloc a couple of records in advance
AllocRecords();
}
void TexDB::Record::Cleanup()
{
RecordArray* ra = s_RecordArrays;
while (ra)
{
RecordArray* next = ra->next;
FreeObject(ra);
#ifdef OGL_UTEX_MEM
GlideMsg("Freed TexDB record array at 0x%x\n", ra);
#endif
ra = next;
}
s_RecordArrays = NULL;
s_FreeRecords = NULL;
return;
}
void TexDB::Record::AllocRecords()
{
#ifdef OGL_UTEX_MEM
GlideMsg("Allocating TexDB record array with %d entries\n", RecordArraySize);
#endif
RecordArray* next = s_RecordArrays ? s_RecordArrays->next : NULL;
s_RecordArrays = static_cast<RecordArray*>(AllocObject(sizeof(RecordArray) + (RecordArraySize -1) * sizeof(Record)));
s_RecordArrays->next = next;
for(int i = 0; i < RecordArraySize; i++)
{
s_RecordArrays->records[i].next = s_FreeRecords;
s_FreeRecords = &s_RecordArrays->records[i];
}
}
void* TexDB::Record::operator new(size_t s)
{
Record* p;
if (s_FreeRecords == NULL)
{
AllocRecords();
}
p = s_FreeRecords;
s_FreeRecords = p->next;
#ifdef OGL_UTEX_MEM
GlideMsg("Using TexDB record at 0x%x\n", p);
#endif
return p;
}
void TexDB::Record::operator delete(void* p)
{
#ifdef OGL_UTEX_MEM
GlideMsg("Moving TexDB record at 0x%x to free list\n", p);
#endif
reinterpret_cast<TexDB::Record*>(p)->next = s_FreeRecords;
s_FreeRecords = reinterpret_cast<TexDB::Record*>(p);
}
TexDB::Record::Record(TexDB::TextureMode texturemode)
{
if (texturemode <= Two)
{
GLfloat one;
glGenTextures(1, &texNum);
glPrioritizeTextures(1, &texNum, &one);
if (texturemode == TexDB::Two )
{
glGenTextures(1, &tex2Num);
glPrioritizeTextures(1, &tex2Num, &one);
}
else
{
tex2Num = 0;
}
}
}
TexDB::Record::~Record(void)
{
if (subrecords == NULL)
{
glDeleteTextures(1, &texNum);
if (tex2Num != 0)
{
glDeleteTextures(1, &tex2Num);
}
}
else
{
SubRecord* next = this->subrecords;
for (SubRecord* s = next; next != NULL; s = next)
{
next = s->next;
delete s;
}
}
}
void TexDB::Record::WipeInside(const SubTexCoord_t* subtexcoords)
{
SubRecord** head = &subrecords;
SubRecord* s = *head;
while (s)
{
if (s->IsInside(subtexcoords))
{
#ifdef OGL_UTEX
GlideMsg("Removing subtexture %d: ", s->texNum);
GlideMsg("texture(%d,%d)-(%d,%d)\n",
s->left,
s->top,
s->texImageWidth,
s->texImageHeight);
#endif
*head = s->next;
delete s;
s = *head;
}
else
{
head = &s->next;
s = s->next;
}
}
}
///////////////////////////////////////////////////////////////////
// TexDB::SubRecord Class implementation
///////////////////////////////////////////////////////////////////
TexDB::SubRecord::SubRecord(TexDB::TextureMode texturemode)
{
glGenTextures(1, &texNum);
if (texturemode == TexDB::SubTextureTwo)
{
glGenTextures(1, &tex2Num);
}
else
{
tex2Num = 0;
}
}
TexDB::SubRecord::~SubRecord( void )
{
glDeleteTextures(1, &texNum);
if (tex2Num != 0)
{
glDeleteTextures(1, &tex2Num);
}
}
void* TexDB::SubRecord::operator new(size_t s)
{
SubRecord* p;
if (s_FreeSubRecords == NULL)
{
p = reinterpret_cast<SubRecord*>(NewPtrSys(s));
#ifdef OGL_UTEX_MEM
GlideMsg("Allocated TexDB subrecord at 0x%x\n", p);
#endif
}
else
{
p = s_FreeSubRecords;
s_FreeSubRecords = p->next;
#ifdef OGL_UTEX_MEM
GlideMsg("Using TexDB subrecord at 0x%x\n", p);
#endif
}
return p;
}
void TexDB::SubRecord::operator delete(void* p)
{
#ifdef OGL_UTEX_MEM
GlideMsg("Moving TexDB subrecord at 0x%x to free-list\n", p);
#endif
// reinterpret_cast<TexDB::SubRecord*>(p)->next = s_FreeSubRecords;
SubRecord* s = reinterpret_cast<TexDB::SubRecord*>(p);
s->next = s_FreeSubRecords;
s_FreeSubRecords = s;
}
void TexDB::SubRecord::Cleanup()
{
SubRecord* s = s_FreeSubRecords;
while (s)
{
#ifdef OGL_UTEX_MEM
GlideMsg("Deleting TexDB subrecord at 0x%x\n", s);
#endif
SubRecord* next = s->next;
DisposePtr(reinterpret_cast<Ptr>(s));
s = next;
}
s_FreeSubRecords = NULL;
return;
}

137
MacGLide/OpenGLide/TexDB.h Normal file
View File

@ -0,0 +1,137 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* TexDB Class Definition
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef __TEXDB_H__
#define __TEXDB_H__
struct SubTexCoord_t
{
GLfloat smin; // min max values rfor s & t
GLfloat smax;
GLfloat tmin;
GLfloat tmax;
GLfloat width; // size in OpenGL tex coords
GLfloat height;
unsigned int left; // Pixel origin of the sub texture
unsigned int top;
unsigned int texImageWidth; // power of two
unsigned int texImageHeight; // power of two
};
class TexDB
{
public:
void Clear( void );
enum TextureMode
{
One = 0,
Two = 1,
SubTextureOne = 2,
SubTextureTwo = 3
};
struct SubRecord
{
public:
SubRecord *next;
public:
GLuint texNum;
GLuint tex2Num;
unsigned int left;
unsigned int top;
unsigned int texImageWidth;
unsigned int texImageHeight;
SubRecord(TexDB::TextureMode texturemode);
~SubRecord(void);
inline bool Match(const SubTexCoord_t* subtexcoords) const
{
return (subtexcoords->smin >= left &&
subtexcoords->tmin >= top &&
subtexcoords->smax <= left + texImageWidth &&
subtexcoords->tmax <= top + texImageHeight);
};
inline bool IsInside(const SubTexCoord_t* subtexcoords) const
{
return (subtexcoords->left > left &&
subtexcoords->top > top &&
subtexcoords->left + subtexcoords->texImageWidth < left + texImageWidth &&
subtexcoords->top + subtexcoords->texImageHeight < top + texImageHeight);
};
void* operator new(size_t s);
void operator delete(void* p);
static void Cleanup();
static SubRecord* s_FreeSubRecords;
private:
void* operator new[](size_t s); // not used so we don't need an implementation
void operator delete[](void* p);
};
struct RecordArray;
class Record
{
protected:
static Record* s_FreeRecords;
static RecordArray* s_RecordArrays;
static void AllocRecords();
public:
FxU32 startAddress;
FxU32 endAddress;
Record *next;
SubRecord *subrecords;
public:
GrTexInfo info;
FxU32 hash;
GLuint texNum;
GLuint tex2Num;
GLuint SClampMode;
GLuint TClampMode;
GLuint MinFilterMode;
GLuint MagFilterMode;
public:
Record(TexDB::TextureMode texturemode);
~Record(void);
inline bool Match(FxU32 stt, const GrTexInfo *inf, FxU32 h) const
{
return ((startAddress == stt) &&
(inf->largeLod == info.largeLod) &&
(inf->aspectRatio == info.aspectRatio) &&
(inf->format == info.format) &&
((hash == h) || (h == 0)));
}
void WipeInside(const SubTexCoord_t* subtexcoords);
void* operator new(size_t s);
void operator delete(void* p);
static void Init();
static void Cleanup();
private:
void* operator new[](size_t s); // not used so we don't need an implementation
void operator delete[](void* p); // not used so we don't need an implementation
};
static int RecordArraySize;
struct RecordArray
{
RecordArray* next;
Record records[1];
};
Record* Add(FxU32 startAddress, FxU32 endAddress, const GrTexInfo *info, FxU32 hash, TexDB::TextureMode texturemode, const SubTexCoord_t* subtexcoords);
Record* Find(FxU32 startAddress, const GrTexInfo *info, FxU32 hash, bool *pal_change, SubTexCoord_t* subtexcoords) const;
void WipeRange(FxU32 startAddress, FxU32 endAddress, FxU32 hash);
TexDB(unsigned int MemorySize);
virtual ~TexDB(void);
private:
unsigned int numberOfTexSections;
Record** m_first;
#ifdef OPTIMISE_TEXTURE_LOOKUP
Record** m_texmem_2_record;
#endif
};
#endif

1187
MacGLide/OpenGLide/amd3dx.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,59 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* pre-glide22 buffer access interface
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "grLfb.h"
// These are the functions for the obsolete linear frame buffer interface (pre 2.2)
FX_ENTRY void grLfbBegin(void)
{
// Todo: implment linear framebuffer interface
assert(false);
}
FX_ENTRY void grLfbBypassMode(GrLfbBypassMode_t mode)
{
// Todo: implment linear framebuffer interface
assert(false);
}
FX_ENTRY void GrLfbEnd()
{
// Todo: implment linear framebuffer interface
assert(false);
}
FX_ENTRY const FxU32* grLfbGetReadPtr(GrBuffer_t buffer)
{
// Todo: implment linear framebuffer interface
assert(false);
return NULL;
}
FX_ENTRY void* grLfbGetWritePtr(GrBuffer_t buffer)
{
// Todo: implment linear framebuffer interface
assert(false);
return NULL;
}
FX_ENTRY void* grLfbOrigin(GrOriginLocation_t origin)
{
// Todo: implment linear framebuffer interface
assert(false);
return NULL;
}
FX_ENTRY void grLfbWriteMode(GrLfbWriteMode_t mode)
{
// Todo: implment linear framebuffer interface
assert(false);
}

View File

@ -0,0 +1,35 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* pre-glide24 sst1 functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
#include "sdk2_3dfx.h"
#include "sdk2_glide.h"
// prototypes for obsolete sst1-board functions
#ifdef __cplusplus
extern "C" {
#endif
// These are the functions for the obsolete linear frame buffer interface (pre 2.2)
FX_ENTRY void grLfbBegin(void);
FX_ENTRY void grLfbBypassMode(GrLfbBypassMode_t mode);
FX_ENTRY void GrLfbEnd();
FX_ENTRY const FxU32* grLfbGetReadPtr(GrBuffer_t buffer);
FX_ENTRY void* grLfbGetWritePtr(GrBuffer_t buffer);
FX_ENTRY void* grLfbOrigin(GrOriginLocation_t origin);
FX_ENTRY void grLfbWriteMode(GrLfbWriteMode_t mode);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,356 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* 3DF functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "OGLTables.h"
//*************************************************
FxU32 GetTexSize( const int Lod, const int aspectRatio, const int format )
{
/*
** If the format is one of these:
** GR_TEXFMT_RGB_332
** GR_TEXFMT_YIQ_422
** GR_TEXFMT_ALPHA_8
** GR_TEXFMT_INTENSITY_8
** GR_TEXFMT_ALPHA_INTENSITY_44
** GR_TEXFMT_P_8
** Reduces the size by 2
*/
return nSquareLod[ format > GR_TEXFMT_RSVD1 ][ aspectRatio ][ Lod ];
}
// prototypes
int Read3dfHeader( const char *filename, Gu3dfInfo *data );
//*************************************************
FX_ENTRY FxBool FX_CALL
gu3dfGetInfo( const char *filename, Gu3dfInfo *info )
{
#ifdef OGL_PARTDONE
GlideMsg( "gu3dfGetInfo( %s, --- )\n", filename );
#endif
if ( Read3dfHeader( filename, info ) )
{
#ifdef OGL_DEBUG
GlideMsg( "==========================================\n" );
GlideMsg( "3df file Header: %s\n", filename );
GlideMsg( "Texture Format = %d\n", info->header.format );
GlideMsg( "Aspect = %d\n", info->header.aspect_ratio );
GlideMsg( "LargeLod = %d\nSmall Lod = %d\n", info->header.large_lod, info->header.small_lod );
GlideMsg( "Width = %d Height = %d\n", info->header.width, info->header.height );
GlideMsg( "MemRequired = %d\n", info->mem_required );
GlideMsg( "==========================================\n" );
#endif
return FXTRUE;
}
else
{
return FXFALSE;
}
}
static FxU32 ReadDataLong( FILE *fp )
{
FxU32 data;
FxU8 byte[4];
fread( byte, 4, 1, fp );
data = (((FxU32) byte[ 0 ]) << 24) |
(((FxU32) byte[ 1 ]) << 16) |
(((FxU32) byte[ 2 ]) << 8) |
((FxU32) byte[ 3 ]);
return data;
}
static FxU32 ReadDataShort( FILE *fp )
{
FxU32 data;
FxU8 byte[2];
fread( byte, 2, 1, fp );
data = (((FxU32) byte[ 0 ]) << 8) |
((FxU32) byte[ 1 ]);
return data;
}
//*************************************************
FX_ENTRY FxBool FX_CALL
gu3dfLoad( const char *filename, Gu3dfInfo *data )
{
#ifdef OGL_PARTDONE
GlideMsg( "gu3dfLoad( %s, --- )\n", filename );
#endif
FILE * file3df;
int jump = Read3dfHeader( filename, data );
#ifdef OGL_DEBUG
GlideMsg( "Start of Data (Offset) = %d\n", jump );
GlideMsg( "Total Bytes to be Read = %d\n", data->mem_required );
#endif
file3df = fopen( filename, "rb" );
fseek( file3df, jump, SEEK_SET );
if ( ( data->header.format == GR_TEXFMT_P_8 ) ||
( data->header.format == GR_TEXFMT_AP_88 ) )
{
for( int i = 0; i < 256; i++ )
{
data->table.palette.data[i] = ReadDataLong( file3df );
}
#ifdef OGL_DEBUG
GlideMsg( "Reading Palette\n" );
#endif
}
if ( ( data->header.format == GR_TEXFMT_YIQ_422 ) ||
( data->header.format == GR_TEXFMT_AYIQ_8422 ) )
{
int i;
int pi;
FxU32 pack;
GuNccTable *ncc = &(data->table.nccTable);
for ( i = 0; i < 16; i++ )
{
ncc->yRGB[i] = (FxU8) ReadDataShort( file3df );
}
for ( i = 0; i < 4; i++ )
{
/* Masking with 0x1ff is strange but correct apparently */
ncc->iRGB[i][0] = (FxI16) ( ReadDataShort( file3df ) & 0x1ff );
ncc->iRGB[i][1] = (FxI16) ( ReadDataShort( file3df ) & 0x1ff );
ncc->iRGB[i][2] = (FxI16) ( ReadDataShort( file3df ) & 0x1ff );
}
for ( i = 0; i < 4; i++ )
{
ncc->qRGB[i][0] = (FxI16) ( ReadDataShort( file3df ) & 0x1ff );
ncc->qRGB[i][1] = (FxI16) ( ReadDataShort( file3df ) & 0x1ff );
ncc->qRGB[i][2] = (FxI16) ( ReadDataShort( file3df ) & 0x1ff );
}
pi = 0;
for ( i = 0; i < 4; i++ )
{
pack = ( ncc->yRGB[i*4 + 0] );
pack |= ( ncc->yRGB[i*4 + 1] << 8 );
pack |= ( ncc->yRGB[i*4 + 2] << 16 );
pack |= ( ncc->yRGB[i*4 + 3] << 24 );
ncc->packed_data[pi++] = pack;
}
for ( i = 0; i < 4; i++ )
{
pack = ( ncc->iRGB[i][0] << 18 );
pack |= ( ncc->iRGB[i][1] << 9 );
pack |= ( ncc->iRGB[i][2] );
ncc->packed_data[pi++] = pack;
}
for ( i = 0; i < 4; i++ )
{
pack = ( ncc->qRGB[i][0] << 18 );
pack |= ( ncc->qRGB[i][1] << 9 );
pack |= ( ncc->qRGB[i][2] );
ncc->packed_data[pi++] = pack;
}
}
switch ( data->header.format )
{
case GR_TEXFMT_RGB_565:
case GR_TEXFMT_ARGB_8332:
case GR_TEXFMT_ARGB_1555:
case GR_TEXFMT_AYIQ_8422:
case GR_TEXFMT_ARGB_4444:
case GR_TEXFMT_ALPHA_INTENSITY_88:
case GR_TEXFMT_AP_88:
{
FxU16 *d = (FxU16 *) (data->data);
int i;
for ( i = data->mem_required; i > 0; i -= 2 )
{
*d++ = (FxU16) ReadDataShort( file3df );
}
}
break;
default:
fread( data->data, sizeof( FxU8 ), data->mem_required, file3df );
break;
}
fclose( file3df );
return FXTRUE;
}
GrTextureFormat_t ParseTextureFormat( const char * text )
{
if ( !strcmp( text, "argb1555\n" ) )
{
return GR_TEXFMT_ARGB_1555;
}
if ( !strcmp( text, "argb4444\n" ) )
{
return GR_TEXFMT_ARGB_4444;
}
if ( !strcmp( text, "rgb565\n" ) )
{
return GR_TEXFMT_RGB_565;
}
if ( !strcmp( text, "rgb332\n" ) )
{
return GR_TEXFMT_RGB_332;
}
if ( !strcmp( text, "argb8332\n" ) )
{
return GR_TEXFMT_ARGB_8332;
}
if ( !strcmp( text, "p8\n" ) )
{
return GR_TEXFMT_P_8;
}
if ( !strcmp( text, "ap88\n" ) )
{
return GR_TEXFMT_AP_88;
}
if ( !strcmp( text, "ai44\n" ) )
{
return GR_TEXFMT_ALPHA_INTENSITY_44;
}
if ( !strcmp( text, "yiq\n" ) )
{
return GR_TEXFMT_YIQ_422;
}
if ( !strcmp( text, "ayiq8422\n" ) )
{
return GR_TEXFMT_AYIQ_8422;
}
return 0;
}
int ParseLod( int Lod )
{
switch( Lod )
{
case 256: return GR_LOD_256;
case 128: return GR_LOD_128;
case 64: return GR_LOD_64;
case 32: return GR_LOD_32;
case 16: return GR_LOD_16;
case 8: return GR_LOD_8;
case 4: return GR_LOD_4;
case 2: return GR_LOD_2;
case 1: return GR_LOD_1;
}
return -1;
}
GrAspectRatio_t ParseAspect( int h, int v )
{
switch ( h )
{
case 8: return GR_ASPECT_8x1;
case 4: return GR_ASPECT_4x1;
case 2: return GR_ASPECT_2x1;
case 1:
switch ( v )
{
case 8: return GR_ASPECT_1x8;
case 4: return GR_ASPECT_1x4;
case 2: return GR_ASPECT_1x2;
case 1: return GR_ASPECT_1x1;
}
}
return 0;
}
int Read3dfHeader( const char *filename, Gu3dfInfo *data )
{
FILE * file3df;
char buffer[255];
int temp1,
temp2,
lod1,
lod2,
nWidth,
nHeight;
file3df = fopen( filename, "rb" );
if ( file3df == NULL )
{
return 0;
}
fgets( buffer, 255, file3df );
fgets( buffer, 255, file3df );
data->header.format = ParseTextureFormat( buffer );
fgets( buffer, 255, file3df );
sscanf( buffer, "lod range: %d %d\n", &lod1, &lod2 );
data->header.small_lod = ParseLod( lod1 );
data->header.large_lod = ParseLod( lod2 );
fgets( buffer, 255, file3df );
sscanf( buffer, "aspect ratio: %d %d\n", &temp1, &temp2 );
data->header.aspect_ratio = ParseAspect( temp1, temp2 );
switch ( data->header.aspect_ratio )
{
case GR_ASPECT_8x1: nWidth = lod2; nHeight = lod2 >> 3; break;
case GR_ASPECT_4x1: nWidth = lod2; nHeight = lod2 >> 2; break;
case GR_ASPECT_2x1: nWidth = lod2; nHeight = lod2 >> 1; break;
case GR_ASPECT_1x1: nWidth = lod2; nHeight = lod2; break;
case GR_ASPECT_1x2: nWidth = lod2 >> 1; nHeight = lod2; break;
case GR_ASPECT_1x4: nWidth = lod2 >> 2; nHeight = lod2; break;
case GR_ASPECT_1x8: nWidth = lod2 >> 3; nHeight = lod2; break;
}
data->header.width = nWidth;
data->header.height = nHeight;
{
GrLOD_t l;
data->mem_required = 0;
for ( l = data->header.large_lod; l <= data->header.small_lod; l++ )
data->mem_required += GetTexSize( l, data->header.aspect_ratio, data->header.format );
}
temp1 = ftell( file3df );
fclose( file3df );
return temp1;
}

View File

@ -0,0 +1,270 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Buffer functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "FormatConversion.h"
#include "Framebuffer.h"
#include "Glide.h"
#include "GLRender.h"
#include "GLRenderUpdateState.h"
#include "GLUtil.h"
//*************************************************
//* Clear buffer
//*************************************************
FX_ENTRY void FX_CALL
grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU16 depth )
{
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
GlideMsg( "grBufferClear( %d, %d, %d )\n", color, alpha, depth );
#endif
glReportErrors("grBufferClear");
RenderDrawTriangles( );
s_Framebuffer.OnBeforeBufferClear();
unsigned int Bits = 0;
if ( Glide.State.ColorMask )
{
Bits = GL_COLOR_BUFFER_BIT;
float r, g, b, a;
ConvertColorF(color, r, g, b, a);
if (InternalConfig.GapFix & OpenGLideGapFixFlag_Enabled)
{
Bits |= GL_STENCIL_BUFFER_BIT;
if (InternalConfig.GapFix & OpenGLideGapFixFlag_Debug)
{
// By making the background green,
// holes in the geometry are easy to spot
g = 1.0f;
}
}
glClearColor(r, g, b, a);
glReportError();
}
if ( Glide.State.DepthBufferWritting)
{
glClearDepth( depth * D1OVER65535 );
glReportError();
Bits |= GL_DEPTH_BUFFER_BIT;
}
if ( ! OpenGL.Clipping )
{
glClear( Bits );
glReportError();
}
else
{
glEnable( GL_SCISSOR_TEST );
glClear( Bits );
glReportError();
glDisable( GL_SCISSOR_TEST );
}
glReportError();
}
//*************************************************
//* Swaps front and back Buffer
//*************************************************
FX_ENTRY void FX_CALL
grBufferSwap( int swap_interval )
{
#if defined( OGL_DONE ) || defined( OGL_COMBINE )
GlideMsg( "grBufferSwap( %d )\n", swap_interval );
#endif
glReportErrors("grBufferSwap");
RenderDrawTriangles( );
#ifdef OGL_DEBUG
static float Temp = 1.0f;
if ( OGLRender.FrameTriangles > OGLRender.MaxTriangles )
{
OGLRender.MaxTriangles = OGLRender.FrameTriangles;
}
OGLRender.FrameTriangles = 0;
#endif
// Flush the framebuffer
s_Framebuffer.OnBeforeBufferSwap();
if (InternalConfig.GapFix & OpenGLideGapFixFlag_Enabled)
{
// Disable the cull mode
glDisable(GL_CULL_FACE);
// Disable clip volume hint manually to avoid recursion
if (InternalConfig.EXT_clip_volume_hint && OpenGL.ClipVerticesEnabledState)
{
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
}
// Blend
glDisable(GL_BLEND);
SetBlendState();
// Alpha
glDisable(GL_ALPHA_TEST);
SetChromaKeyAndAlphaState();
// disable depth buffer
glDepthMask(false);
// Enable colormask
glColorMask(true, true, true, false);
// Needed for displaying in-game menus
if (Glide.State.DepthBufferMode != GR_DEPTHBUFFER_DISABLE)
{
glDisable(GL_DEPTH_TEST);
}
if (InternalConfig.EXT_secondary_color)
{
glDisable(GL_COLOR_SUM_EXT);
}
if (OpenGL.Fog)
{
glActiveTextureARB(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_2D);
SetFogModeState();
}
for(long unit_index = 1; unit_index >= 0; unit_index--)
{
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
glDisable(GL_TEXTURE_2D);
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = false;
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = false;
}
SetTextureState();
SetColorCombineState();
SetAlphaCombineState();
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
VERIFY_TEXTURE_ENABLED_STATE();
glStencilFunc(GL_NOTEQUAL, 0x02, 0x03);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glReportError();
GLfloat clearcolor[] =
{
0.0f, 0.0f, 0.0f, 0.0f
};
if (InternalConfig.GapFix & OpenGLideGapFixFlag_Enabled)
{
if (InternalConfig.GapFix & OpenGLideGapFixFlag_Debug)
{
// By making the gaps red, they're easily to spot
clearcolor[0] = 1.0f;
}
}
GLfloat depth = 1.0f;
glBegin(GL_QUADS);
glColor4fv(clearcolor);
glVertex3f(Glide.State.ClipMinX, Glide.State.ClipMinY, depth);
glColor4fv(clearcolor);
glVertex3f(Glide.State.ClipMaxX, Glide.State.ClipMinY, depth);
glColor4fv(clearcolor);
glVertex3f(Glide.State.ClipMaxX, Glide.State.ClipMaxY, depth);
glColor4fv(clearcolor);
glVertex3f(Glide.State.ClipMinX, Glide.State.ClipMaxY, depth);
glEnd();
glStencilFunc(GL_ALWAYS, 0x02, 0x03);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
// Restore state
switch (Glide.State.CullMode)
{
case GR_CULL_DISABLE:
break;
case GR_CULL_NEGATIVE:
case GR_CULL_POSITIVE:
glEnable(GL_CULL_FACE);
break;
}
if (InternalConfig.EXT_clip_volume_hint && OpenGL.ClipVerticesEnabledState)
{
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_NICEST);
}
// restore previous state
if (OpenGL.DepthBufferWritting)
{
glDepthMask(true);
}
if (Glide.State.DepthBufferMode != GR_DEPTHBUFFER_DISABLE)
{
glEnable(GL_DEPTH_TEST);
}
// Restore colormask
bool rgb = Glide.State.ColorMask;
glColorMask(rgb, rgb, rgb, Glide.State.AlphaMask);
if (InternalConfig.EXT_secondary_color)
{
glEnable( GL_COLOR_SUM_EXT );
}
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
VERIFY_TEXTURE_ENABLED_STATE();
}
// @todo: setting the swap interval doesn't seem to work
// - the 3dfx splash animation appears a bit to fast
// and using higher values doesn't work
// -> might be a bug in Classic
GLint swap = swap_interval;
aglSetInteger(pWindowInfo->aglContext, AGL_SWAP_INTERVAL, &swap);
aglReportError();
#if defined (OGL_DONE) || defined (OGL_PARTDONE) || defined (OGL_NOTDONE) || defined(OGL_OPTIMISE_DEBUG)
GlideMsg("Calling aglSwapBuffers() with swapinterval %d\n", swap);
#endif
// swap buffers
aglSwapBuffers(pWindowInfo->aglContext);
s_Framebuffer.OnAfterBufferSwap();
#ifdef OGL_DEBUG
// RDTSC( FinalTick );
// Temp = (float)(FinalTick - InitialTick);
// FpsAux += Temp;
// Frame++;
// RDTSC( InitialTick );
#endif
}
//*************************************************
//* Return the number of queued buffer swap requests
//* Always 0, never pending
//*************************************************
FX_ENTRY int FX_CALL
grBufferNumPending( void )
{
#ifdef OGL_DONE
GlideMsg( "grBufferNumPending( ) = 0\n" );
#endif
RenderDrawTriangles();
// s_Framebuffer.OnBufferNumPending();
return 0;
}
//*************************************************
//* Defines the Buffer to Render
//*************************************************
FX_ENTRY void FX_CALL
grRenderBuffer( GrBuffer_t dwBuffer )
{
#ifdef OGL_DONE
GlideMsg( "grRenderBuffer( %d )\n", dwBuffer );
#endif
glReportErrors("grRenderBuffer");
RenderDrawTriangles( );
Glide.State.RenderBuffer = dwBuffer;
// Valid parameters are only FRONT and BACK ( 0x0 and 0x1 )
OpenGL.RenderBuffer = GL_FRONT + dwBuffer;
glDrawBuffer( OpenGL.RenderBuffer );
glReportError();
}

View File

@ -0,0 +1,668 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Color and Alpha File
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Glide.h"
#include "GlideDisplay.h"
#include "GLColorAlphaCombineEnvTables.h"
#include "GLExtensions.h"
#include "GLRender.h"
#include "GLUtil.h"
#include "GLRenderUpdateState.h"
#include "OGLTables.h"
#include "PGTexture.h"
//*************************************************
//* Sets the Dithering Mode 24->16 bits
//*************************************************
FX_ENTRY void FX_CALL
grDitherMode( GrDitherMode_t mode )
{
CHECK_STATE_CHANGED(Glide.State.DitherMode == mode);
#ifdef OGL_DONE
GlideMsg( "grDitherMode( %d )\n", mode );
#endif
glReportErrors("grDitherMode");
RenderDrawTriangles( );
Glide.State.DitherMode = mode;
if ( mode != GR_DITHER_DISABLE )
{
// GR_DITHER_2x2 or GR_DITHER_4x4
glEnable( GL_DITHER );
}
else
{
glDisable( GL_DITHER );
}
glReportError();
}
//*************************************************
//* Sets the Constant color
//*************************************************
FX_ENTRY void FX_CALL
grConstantColorValue( GrColor_t value )
{
CHECK_STATE_CHANGED(Glide.State.ConstantColorValue == value);
#ifdef OGL_DONE
GlideMsg( "grConstantColorValue( 0x%X )\n", value );
#endif
RenderDrawTriangles();
Glide.State.ConstantColorValue = value;
ConvertColorF(value,
OpenGL.ConstantColor[ 0 ],
OpenGL.ConstantColor[ 1 ],
OpenGL.ConstantColor[ 2 ],
OpenGL.ConstantColor[ 3 ]);
SetConstantColorValueState();
}
//*************************************************
//* Sets the Constant color - obsolete in 2.4
//*************************************************
FX_ENTRY void FX_CALL
grConstantColorValue4( float a, float r, float g, float b )
{
CHECK_STATE_CHANGED(r == Glide.State.Delta0ModeColor[0] &&
g == Glide.State.Delta0ModeColor[1] &&
b == Glide.State.Delta0ModeColor[2] &&
a == Glide.State.Delta0ModeColor[3]);
#ifdef OGL_DONE
GlideMsg( "grConstantColorValue4( %f, %f, %f, %f )\n", a, r, g, b );
#endif
RenderDrawTriangles();
Glide.State.Delta0ModeColor[0] = r;
Glide.State.Delta0ModeColor[1] = g;
Glide.State.Delta0ModeColor[2] = b;
Glide.State.Delta0ModeColor[3] = a;
OpenGL.Delta0Color[0] = r * D1OVER255;
OpenGL.Delta0Color[1] = g * D1OVER255;
OpenGL.Delta0Color[2] = b * D1OVER255;
// according to the linux driver src,
// alpha is completely ignored
// Glide.State.Delta0ModeColor[3] = a * D10255;
// Thus, alpha is take from grConstantColorValue()
OpenGL.Delta0Color[3] = OpenGL.ConstantColor[3];
SetConstantColorValue4State();
}
//*************************************************
//* Sets the Color and Alpha mask
//*************************************************
FX_ENTRY void FX_CALL
grColorMask( FxBool rgb, FxBool a )
{
#ifdef OGL_DONE
GlideMsg( "grColorMask( %s, %s )\n",
rgb ? "TRUE" : "FALSE", a ? "TRUE" : "FALSE" );
#endif
glReportErrors("grColorMask");
RenderDrawTriangles( );
Glide.State.ColorMask = rgb;
Glide.State.AlphaMask = a;
glColorMask( rgb, rgb, rgb, a );
glReportError();
}
FX_ENTRY void FX_CALL
grColorCombine( GrCombineFunction_t function, GrCombineFactor_t factor,
GrCombineLocal_t local, GrCombineOther_t other,
FxBool invert )
{
glReportErrors("grColorCombine");
CHECK_STATE_CHANGED(Glide.State.ColorCombineFunction == function
&& Glide.State.ColorCombineFactor == factor
&& Glide.State.ColorCombineLocal == local
&& Glide.State.ColorCombineOther == other
&& Glide.State.ColorCombineInvert == invert);
#if defined( OGL_DONE ) || defined( OGL_COMBINE )
GlideMsg( "grColorCombine( %d, %d, %d, %d, %s )\n",
function, factor, local, other, invert ? "TRUE" : "FALSE" );
#endif
RenderDrawTriangles( );
// May need to turn the fog texture unit on/off
if ( Glide.State.ColorCombineInvert != invert)
{
SetColorInvertState();
}
Glide.State.ColorCombineFunction = function;
Glide.State.ColorCombineFactor = factor;
Glide.State.ColorCombineLocal = local;
Glide.State.ColorCombineOther = other;
Glide.State.ColorCombineInvert = invert;
// Used by the simple coloralpha model but also to determine whether textures are used
Glide.CLocal = colorCombineTable[ factor ][ function ].local;
Glide.COther = colorCombineTable[ factor ][ function ].other;
if ( colorCombineTable[ factor ][ function ].alocal )
{
Glide.ALocal = true;
}
if ( colorCombineTable[ factor ][ function ].aother )
{
Glide.AOther = true;
}
ColorFunctionFunc = colorCombineTable[ factor ][ function ].func;
ColorFactor3Func = colorCombineTable[ factor ][ function ].factorfunc;
SetColorTextureState();
SetTextureState();
SetColorCombineState();
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
}
inline void _grColorCombineDelta0Mode(bool delta0mode)
{
CHECK_STATE_CHANGED(delta0mode == Glide.State.Delta0Mode);
#if defined(OGL_DONE)
GlideMsg( "_grColorCombineDelta0Mode(%s)\n", delta0mode ? "TRUE" : "FALSE");
#endif
Glide.State.Delta0Mode = delta0mode;
if (delta0mode)
{
SetConstantColorValue4State();
}
else
{
SetConstantColorValueState();
}
}
//*************************************************
FX_ENTRY void FX_CALL
guColorCombineFunction( GrColorCombineFnc_t fnc )
{
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
GlideMsg( "guColorCombineFunction( %d )\n", fnc );
#endif
// @todo: Analyse driver source to find out about ITRGB_DELTA0
// color alpha render modes (in /glide/src/gu.c)
// So far it seems to ignore to iterate the vertex colors (right?)
/* gross hack to get ITRGB_DELTA0 modes working */
// _grColorCombineDelta0Mode( FXFALSE );
bool delta0mode = FXFALSE;
switch ( fnc )
{
case GR_COLORCOMBINE_ZERO: //0x0
grColorCombine( GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_NONE, FXFALSE );
break;
case GR_COLORCOMBINE_CCRGB: //0x1
grColorCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE, FXFALSE );
break;
case GR_COLORCOMBINE_ITRGB: //0x2
grColorCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE );
break;
case GR_COLORCOMBINE_DECAL_TEXTURE: //0x4
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_TEXTURE_TIMES_CCRGB: //0x5
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB: //0x6
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_ADD_ALPHA: //0x8
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA: //0x9
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL_ALPHA,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA_ADD_ITRGB: //0xa
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_TEXTURE_ADD_ITRGB: //0xb
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_TEXTURE_SUB_ITRGB: //0xc
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_DIFF_SPEC_A: //0xe
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_DIFF_SPEC_B: //0xf
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_ONE: //0x10
grColorCombine( GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXTRUE );
break;
case GR_COLORCOMBINE_ITRGB_DELTA0: //0x3
// _grColorCombineDelta0Mode(FXTRUE);
delta0mode = FXTRUE;
grColorCombine(GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_CONSTANT, FXFALSE);
break;
case GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_DELTA0: //0x7
// @todo: May not be correct, as the 3dfx 2.4 pgm doesn't discuss this function.
// Using GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB with constant colors instead.
// In the Glide-Driver src its almost the same, but _grColorCombineDelta0Mode(FXTRUE)
// is called in advance to do something about the iterated colors. At least, this fixes,
// the problems with colors and skidmarks in Carmageddon (Splatpack), so it can't be that bad :^)
// _grColorCombineDelta0Mode(FXTRUE);
delta0mode = FXTRUE;
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_COLORCOMBINE_CCRGB_BLEND_ITRGB_ON_TEXALPHA: //0xd
grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, GR_COMBINE_FACTOR_TEXTURE_ALPHA,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT, FXFALSE);
break;
}
_grColorCombineDelta0Mode(delta0mode);
}
//*************************************************
//* Sets the Alpha Test Reference Value
//*************************************************
FX_ENTRY void FX_CALL
grAlphaTestReferenceValue( GrAlpha_t value )
{
CHECK_STATE_CHANGED(Glide.State.AlphaReferenceValue == value);
#ifdef OGL_DONE
GlideMsg( "grAlphaTestReferenceValue( %d )\n", value );
#endif
RenderDrawTriangles( );
Glide.State.AlphaReferenceValue = value;
OpenGL.AlphaReferenceValue = value * D1OVER255;
// Only call if the state needs to be changed
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
// alpha reference value applies only when the following conditons are true
if ((!OpenGL.ChromaKey || !OpenGL.Texture || OpenGL.Blend)
&& Glide.State.AlphaOther == GR_COMBINE_OTHER_TEXTURE
&& Glide.State.AlphaTestFunction != GR_CMP_ALWAYS)
#endif
SetChromaKeyAndAlphaState();
}
//*************************************************
//* Sets the Alpha Test Function
//*************************************************
FX_ENTRY void FX_CALL
grAlphaTestFunction( GrCmpFnc_t function )
{
CHECK_STATE_CHANGED(Glide.State.AlphaTestFunction == function);
#ifdef OGL_DONE
GlideMsg( "grAlphaTestFunction( %d )\n", function );
#endif
RenderDrawTriangles( );
Glide.State.AlphaTestFunction = function;
// We can do this just because we know the constant values for both OpenGL and Glide
// To port it to anything else than OpenGL we NEED to change this code
OpenGL.AlphaTestFunction = GL_NEVER + function;
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
if ((Glide.State.AlphaOther == GR_COMBINE_OTHER_TEXTURE)
&& (!OpenGL.ChromaKey || OpenGL.Blend || !OpenGL.Texture))
#endif
{
SetChromaKeyAndAlphaState();
}
}
//*************************************************
FX_ENTRY void FX_CALL
grAlphaBlendFunction( GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df,
GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df )
{
glReportErrors("grAlphaBlendFunction");
CHECK_STATE_CHANGED(Glide.State.AlphaBlendRgbSf == rgb_sf
&& Glide.State.AlphaBlendRgbDf == rgb_df
&& Glide.State.AlphaBlendAlphaSf == alpha_sf
&& Glide.State.AlphaBlendAlphaDf == alpha_df);
#ifdef OGL_PARTDONE
GlideMsg( "grAlphaBlendFunction( %d, %d, %d, %d )\n",
rgb_sf, rgb_df, alpha_sf, alpha_df );
#endif
#ifndef OGL_PARTDONE
#ifdef OGL_NOTDONE
// Unhandled glBlendFuncSeperateEXT emulation error
if (Glide.State.AlphaBlendRgbSf != Glide.State.AlphaBlendAlphaSf
|| Glide.State.AlphaBlendRgbDf != Glide.State.AlphaBlendAlphaDf)
{
GlideMsg( "grAlphaBlendFunction( %d, %d, %d, %d ): emulation for sepearate alpha blend function not implemented\n",
rgb_sf, rgb_df, alpha_sf, alpha_df );
}
#endif
#endif
RenderDrawTriangles( );
Glide.State.AlphaBlendRgbSf = rgb_sf;
Glide.State.AlphaBlendRgbDf = rgb_df;
Glide.State.AlphaBlendAlphaSf = alpha_sf;
Glide.State.AlphaBlendAlphaDf = alpha_df;
switch ( rgb_sf )
{
case GR_BLEND_ZERO: OpenGL.SrcBlend = GL_ZERO; break;
case GR_BLEND_ONE: OpenGL.SrcBlend = GL_ONE; break;
case GR_BLEND_DST_COLOR: OpenGL.SrcBlend = GL_DST_COLOR; break;
case GR_BLEND_ONE_MINUS_DST_COLOR: OpenGL.SrcBlend = GL_ONE_MINUS_DST_COLOR; break;
case GR_BLEND_SRC_ALPHA: OpenGL.SrcBlend = GL_SRC_ALPHA; break;
case GR_BLEND_ONE_MINUS_SRC_ALPHA: OpenGL.SrcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
case GR_BLEND_DST_ALPHA: OpenGL.SrcBlend = GL_DST_ALPHA; break;
case GR_BLEND_ONE_MINUS_DST_ALPHA: OpenGL.SrcBlend = GL_ONE_MINUS_DST_ALPHA; break;
case GR_BLEND_ALPHA_SATURATE: OpenGL.SrcBlend = GL_SRC_ALPHA_SATURATE; break;
#ifdef OGL_DEBUG
default:
GlideMsg( "grAlphaBlendFunction: Unknown RGB source blend factor.\n" );
OpenGL.SrcBlend = GL_ONE;
break;
#endif
}
switch ( rgb_df )
{
case GR_BLEND_ZERO: OpenGL.DstBlend = GL_ZERO; break;
case GR_BLEND_ONE: OpenGL.DstBlend = GL_ONE; break;
case GR_BLEND_SRC_COLOR: OpenGL.DstBlend = GL_SRC_COLOR; break;
case GR_BLEND_ONE_MINUS_SRC_COLOR: OpenGL.DstBlend = GL_ONE_MINUS_SRC_COLOR; break;
case GR_BLEND_SRC_ALPHA: OpenGL.DstBlend = GL_SRC_ALPHA; break;
case GR_BLEND_ONE_MINUS_SRC_ALPHA: OpenGL.DstBlend = GL_ONE_MINUS_SRC_ALPHA; break;
case GR_BLEND_DST_ALPHA: OpenGL.DstBlend = GL_DST_ALPHA; break;
case GR_BLEND_ONE_MINUS_DST_ALPHA: OpenGL.DstBlend = GL_ONE_MINUS_DST_ALPHA; break;
case GR_BLEND_PREFOG_COLOR: OpenGL.DstBlend = GL_ONE; break;
#ifdef OGL_DEBUG
default:
GlideMsg( "grAlphaBlendFunction: Unknown RGB destination blend factor.\n" );
OpenGL.DstBlend = GL_ZERO;
break;
#endif
}
switch ( alpha_sf )
{
case GR_BLEND_ZERO: OpenGL.SrcAlphaBlend = GL_ZERO; break;
case GR_BLEND_ONE: OpenGL.SrcAlphaBlend = GL_ONE; break;
case GR_BLEND_DST_COLOR: OpenGL.SrcAlphaBlend = GL_DST_COLOR; break;
case GR_BLEND_ONE_MINUS_DST_COLOR: OpenGL.SrcAlphaBlend = GL_ONE_MINUS_DST_COLOR; break;
case GR_BLEND_SRC_ALPHA: OpenGL.SrcAlphaBlend = GL_SRC_ALPHA; break;
case GR_BLEND_ONE_MINUS_SRC_ALPHA: OpenGL.SrcAlphaBlend = GL_ONE_MINUS_SRC_ALPHA; break;
case GR_BLEND_DST_ALPHA: OpenGL.SrcAlphaBlend = GL_DST_ALPHA; break;
case GR_BLEND_ONE_MINUS_DST_ALPHA: OpenGL.SrcAlphaBlend = GL_ONE_MINUS_DST_ALPHA; break;
case GR_BLEND_ALPHA_SATURATE: OpenGL.SrcAlphaBlend = GL_SRC_ALPHA_SATURATE; break;
}
switch ( alpha_df )
{
case GR_BLEND_ZERO: OpenGL.DstAlphaBlend = GL_ZERO; break;
case GR_BLEND_ONE: OpenGL.DstAlphaBlend = GL_ONE; break;
case GR_BLEND_SRC_COLOR: OpenGL.DstAlphaBlend = GL_SRC_COLOR; break;
case GR_BLEND_ONE_MINUS_SRC_COLOR: OpenGL.DstAlphaBlend = GL_ONE_MINUS_SRC_COLOR; break;
case GR_BLEND_SRC_ALPHA: OpenGL.DstAlphaBlend = GL_SRC_ALPHA; break;
case GR_BLEND_ONE_MINUS_SRC_ALPHA: OpenGL.DstAlphaBlend = GL_ONE_MINUS_SRC_ALPHA; break;
case GR_BLEND_DST_ALPHA: OpenGL.DstAlphaBlend = GL_DST_ALPHA; break;
case GR_BLEND_ONE_MINUS_DST_ALPHA: OpenGL.DstAlphaBlend = GL_ONE_MINUS_DST_ALPHA; break;
case GR_BLEND_PREFOG_COLOR: OpenGL.DstAlphaBlend = GL_ONE; break;
}
OpenGL.Blend = !(( rgb_sf == GR_BLEND_ONE ) && ( rgb_df == GR_BLEND_ZERO ));
SetTextureState();
SetBlendState();
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
}
//*************************************************
FX_ENTRY void FX_CALL
grAlphaCombine( GrCombineFunction_t function, GrCombineFactor_t factor,
GrCombineLocal_t local, GrCombineOther_t other,
FxBool invert )
{
glReportErrors("grAlphaCombine");
CHECK_STATE_CHANGED( Glide.State.AlphaFunction == function
&& Glide.State.AlphaFactor == factor
&& Glide.State.AlphaLocal == local
&& Glide.State.AlphaOther == other
&& Glide.State.AlphaInvert == invert);
#if defined( OGL_DONE ) || defined( OGL_COMBINE )
GlideMsg( "grAlphaCombine( %d, %d, %d, %d, %s )\n",
function, factor, local, other, invert ? "TRUE" : "FALSE" );
#endif
RenderDrawTriangles();
// If OPTIMISE_OPENGL_STATE_CHANGES is not defined,
// the update will always be executed
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
// When the local or other alpha changes,
// the color combine state may need an update
bool bUpdateColorCombineState = (OpenGL.ColorAlphaUnit2 &&
((local != Glide.State.AlphaLocal
&& (Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_LOCAL_ALPHA
|| Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA))
|| (other != Glide.State.AlphaOther
&& (Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_OTHER_ALPHA
|| Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA))
));
#endif
// May need to turn the fog texture unit on/off
if ( Glide.State.AlphaInvert != invert)
{
SetAlphaInvertState();
}
Glide.State.AlphaFunction = function;
Glide.State.AlphaFactor = factor;
Glide.State.AlphaLocal = local;
Glide.State.AlphaOther = other;
Glide.State.AlphaInvert = invert;
// Used by the simple coloralpha model but also to determine whether textures are used
Glide.ALocal = alphaCombineTable[ factor ][ function ].local;
Glide.AOther = alphaCombineTable[ factor ][ function ].other;
AlphaFactorFunc = alphaCombineTable[ factor ][ function ].func;
SetAlphaTextureState();
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
SetTextureState();
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
if (bUpdateColorCombineState)
{
#endif
if (OpenGL.ColorAlphaUnit2) SetColorCombineState();
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
}
#endif
// Update chroma key and alpha because both
// Blend and Texture state might have changed
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
if (OpenGL.ChromaKey && OpenGL.Texture)
{
// Without blend, changing the alpha combine has no effect when chromakeying is enabled
if (OpenGL.Blend)
{
SetChromaKeyAndAlphaState();
SetAlphaCombineState();
}
}
else
{
// If chromakeying is disabled, then everything is already setup correctly,
// and we have just to update the alpha combine setting
SetAlphaCombineState();
}
#else
SetChromaKeyAndAlphaState();
SetAlphaCombineState();
#endif
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
}
//*************************************************
FX_ENTRY void FX_CALL
grAlphaControlsITRGBLighting( FxBool enable )
{
#ifdef OGL_NOTDONE
GlideMsg("grAlphaControlsITRGBALighting( %s )\n", enable ? "TRUE" : "FALSE" );
#endif
}
//*************************************************
FX_ENTRY void FX_CALL
guAlphaSource( GrAlphaSource_t dwMode )
{
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
GlideMsg( "guAlphaSource( %d )\n", dwMode );
#endif
switch ( dwMode )
{
case GR_ALPHASOURCE_CC_ALPHA: //0x00
grAlphaCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE, FXFALSE );
break;
case GR_ALPHASOURCE_ITERATED_ALPHA: //0x01
grAlphaCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE );
break;
case GR_ALPHASOURCE_TEXTURE_ALPHA: //0x02
grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
case GR_ALPHASOURCE_TEXTURE_ALPHA_TIMES_ITERATED_ALPHA: //0x03
grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
break;
}
}
//*************************************************
//* Sets the ChromaKey Value for comparision
//*************************************************
FX_ENTRY void FX_CALL
grChromakeyValue( GrColor_t value )
{
CHECK_STATE_CHANGED(Glide.State.ChromakeyValue == value);
#ifdef OGL_PARTDONE
GlideMsg( "grChromakeyValue( 0x%X )\n", value );
#endif
RenderDrawTriangles( );
ConvertColor4B( value, OpenGL.ChromaColor.C );
Textures->ChromakeyValue( OpenGL.ChromaColor.C );
Glide.State.ChromakeyValue = value;
s_Framebuffer.OnChromaKeyValueChanged();
}
//*************************************************
//* Sets the ChromaKey Mode
//*************************************************
FX_ENTRY void FX_CALL
grChromakeyMode(GrChromakeyMode_t mode)
{
CHECK_STATE_CHANGED(Glide.State.ChromaKeyMode == mode);
#ifdef OGL_PARTDONE
GlideMsg( "grChromakeyMode( %s )\n", mode ? "TRUE" : "FALSE" );
#endif
RenderDrawTriangles();
Textures->ChromakeyMode(mode);
Glide.State.ChromaKeyMode = mode;
if (mode == GR_CHROMAKEY_ENABLE)
{
OpenGL.ChromaKey = true;
}
else
{
OpenGL.ChromaKey = false;
}
// State changes are detected in RenderUpdateState()
}
//*************************************************
FX_ENTRY void FX_CALL
grGammaCorrectionValue( float value )
{
#ifdef OGL_DONE
GlideMsg( "grGammaCorrectionValue( %f )\n", value );
#endif
Glide.State.Gamma = value;
DisplayManager_SetGlideDisplayGamma(value);
}

View File

@ -0,0 +1,160 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Depth (Z/W-Buffer) Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GLRender.h"
//*************************************************
//* Changes Depth Buffer Mode
//*************************************************
FX_ENTRY void FX_CALL
grDepthBufferMode( GrDepthBufferMode_t mode )
{
CHECK_STATE_CHANGED(Glide.State.DepthBufferMode == mode);
#ifdef OGL_DONE
GlideMsg( "grDepthBufferMode( %d )\n", mode );
#endif
glReportErrors("grDepthBufferMode");
RenderDrawTriangles( );
Glide.State.DepthBufferMode = mode;
/*
* In AddTriangle etc. Use of z or w for
* depth buffering is determined by the
* value of OpenGL.DepthBufferType. So
* I set it here.
*/
switch ( mode )
{
case GR_DEPTHBUFFER_DISABLE:
OpenGL.DepthBufferType = 0;
glDisable( GL_DEPTH_TEST );
return;
case GR_DEPTHBUFFER_ZBUFFER:
case GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS:
OpenGL.DepthBufferType = 1;
OpenGL.ZNear = ZBUFFERNEAR;
OpenGL.ZFar = ZBUFFERFAR;
break;
case GR_DEPTHBUFFER_WBUFFER:
case GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS:
OpenGL.DepthBufferType = 0;
OpenGL.ZNear = WBUFFERNEAR;
OpenGL.ZFar = WBUFFERFAR;
break;
}
glEnable( GL_DEPTH_TEST );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
if ( Glide.State.OriginInformation == GR_ORIGIN_LOWER_LEFT )
{
glOrtho(Glide.State.ClipMinX, Glide.State.ClipMaxX,
Glide.State.ClipMinY, Glide.State.ClipMaxY,
OpenGL.ZNear, OpenGL.ZFar);
glViewport(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.ClipMinY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
// Used for the buffer clearing
glScissor(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.ClipMinY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
}
else
{
glOrtho(Glide.State.ClipMinX, Glide.State.ClipMaxX,
Glide.State.ClipMaxY, Glide.State.ClipMinY,
OpenGL.ZNear, OpenGL.ZFar);
glViewport(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.WindowHeight - OpenGL.ClipMaxY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
glScissor(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.WindowHeight - OpenGL.ClipMaxY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
}
glMatrixMode( GL_MODELVIEW );
glReportError();
}
//*************************************************
//* Enables or Disables Depth Buffer Writting
//*************************************************
FX_ENTRY void FX_CALL
grDepthMask( FxBool enable )
{
CHECK_STATE_CHANGED(Glide.State.DepthBufferWritting == enable);
#ifdef OGL_DONE
GlideMsg( "grDepthMask( %d )\n", enable );
#endif
glReportErrors("grDepthMask");
RenderDrawTriangles( );
Glide.State.DepthBufferWritting =
OpenGL.DepthBufferWritting = enable;
glDepthMask( OpenGL.DepthBufferWritting );
glReportError();
}
//*************************************************
//* Sets the Depth Function to use
//*************************************************
FX_ENTRY void FX_CALL
grDepthBufferFunction( GrCmpFnc_t func )
{
#ifdef OGL_DONE
GlideMsg( "grDepthBufferFunction( %d )\n", func );
#endif
glReportErrors("grDepthBufferFunction");
RenderDrawTriangles( );
Glide.State.DepthFunction = func;
// We can do this just because we know the constant values for both OpenGL and Glide
// To port it to anything else than OpenGL we NEED to change this code
OpenGL.DepthFunction = GL_NEVER + func;
glDepthFunc( OpenGL.DepthFunction );
glReportError();
}
//*************************************************
//* Set the depth bias level
//*************************************************
FX_ENTRY void FX_CALL
grDepthBiasLevel( FxI16 level )
{
#ifdef OGL_PARTDONE
GlideMsg( "grDepthBiasLevel( %d )\n", level );
#endif
glReportErrors("grDepthBiasLevel");
RenderDrawTriangles( );
Glide.State.DepthBiasLevel = level;
//OpenGL.DepthBiasLevel = level * D1OVER65536;
OpenGL.DepthBiasLevel = level * 10.0f;
glPolygonOffset( 1.0f, OpenGL.DepthBiasLevel );
if ( level != 0 )
{
glEnable( GL_POLYGON_OFFSET_FILL );
}
else
{
glDisable( GL_POLYGON_OFFSET_FILL );
}
glReportError();
}

View File

@ -0,0 +1,322 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Drawing Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GLRender.h"
#include "GLRenderUpdateState.h"
//*************************************************
//* Draws a Triangle on the screen
//*************************************************
FX_ENTRY void FX_CALL
grDrawTriangle( const GrVertex *a, const GrVertex *b, const GrVertex *c )
{
#ifdef OGL_CRITICAL
GlideMsg( "grDrawTriangle( ---, ---, --- )\n" );
#endif
SetClipVerticesState(false);
RenderAddTriangle( a, b, c, true );
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
//*************************************************
//* Draws a planar polygon on the screen
//*************************************************
FX_ENTRY void FX_CALL
grDrawPlanarPolygonVertexList( int nVertices, const GrVertex vlist[] )
{
#ifdef OGL_CRITICAL
GlideMsg("grDrawPlanarPolygonVertexList( %d, --- )\n", nVertices );
#endif
SetClipVerticesState(false);
for ( int i = 2; i < nVertices; i++ )
{
RenderAddTriangle( &vlist[ 0 ], &vlist[ i - 1 ], &vlist[ i ], true );
}
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
//*************************************************
//* Draws a Line on the screen
//*************************************************
FX_ENTRY void FX_CALL
grDrawLine( const GrVertex *a, const GrVertex *b )
{
#ifdef OGL_CRITICAL
GlideMsg("grDrawLine( ---, --- )\n");
#endif
SetClipVerticesState(false);
RenderAddLine( a, b, true );
}
//*************************************************
//* Draws a Point on the screen
//*************************************************
FX_ENTRY void FX_CALL
grDrawPoint( const GrVertex *a )
{
#ifdef OGL_CRITICAL
GlideMsg( "grDrawPoint( --- )\n" );
#endif
SetClipVerticesState(false);
RenderAddPoint( a, true );
}
//*************************************************
//* Draw a convex non-planar polygon
//*************************************************
FX_ENTRY void FX_CALL
grDrawPolygon( int nverts, const int ilist[], const GrVertex vlist[] )
{
#ifdef OGL_CRITICAL
GlideMsg( "grDrawPolygon( %d, ---, --- )\n" );
#endif
SetClipVerticesState(false);
for ( int i = 2; i < nverts; i++ )
{
RenderAddTriangle( &vlist[ ilist[ 0 ] ],
&vlist[ ilist[ i - 1 ] ],
&vlist[ ilist[ i ] ],
true );
}
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
//*************************************************
//* Draw a convex planar polygon
//*************************************************
FX_ENTRY void FX_CALL
grDrawPlanarPolygon( int nverts, const int ilist[], const GrVertex vlist[] )
{
#ifdef OGL_CRITICAL
GlideMsg( "grDrawPlanarPolygon( %d, ---, --- )\n", nverts );
#endif
SetClipVerticesState(false);
for ( int i = 2; i < nverts; i++ )
{
RenderAddTriangle( &vlist[ ilist[ 0 ] ],
&vlist[ ilist[ i - 1 ] ],
&vlist[ ilist[ i ] ],
true );
}
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
//*************************************************
//* Draw a convex non-planar polygon
//*************************************************
FX_ENTRY void FX_CALL
grDrawPolygonVertexList( int nVertices, const GrVertex vlist[] )
{
#ifdef OGL_CRITICAL
GlideMsg( "grDrawPolygonVertexList( %d, --- )\n", nVertices );
#endif
SetClipVerticesState(false);
for ( int i = 2; i < nVertices; i++ )
{
RenderAddTriangle( &vlist[ 0 ],
&vlist[ i - 1 ],
&vlist[ i ],
true );
}
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
FX_ENTRY void FX_CALL
guAADrawTriangleWithClip( const GrVertex *a, const GrVertex *b,
const GrVertex *c )
{
#ifdef OGL_CRITICAL
GlideMsg("guAADrawTriangleWithClip( ---, ---, --- )\n");
#endif
SetClipVerticesState(true);
RenderAddTriangle( a, b, c, false );
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
FX_ENTRY void FX_CALL
guDrawTriangleWithClip( const GrVertex *a,
const GrVertex *b,
const GrVertex *c )
{
#ifdef OGL_CRITICAL
GlideMsg("guDrawTriangleWithClip( ---, ---, --- )\n");
#endif
SetClipVerticesState(true);
RenderAddTriangle( a, b, c, false );
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
FX_ENTRY void FX_CALL
guDrawPolygonVertexListWithClip( int nVertices, const GrVertex vlist[] )
{
#ifdef OGL_CRITICAL
GlideMsg( "guDrawPolygonVertexListWithClip( %d, --- )\n", nVertices );
#endif
SetClipVerticesState(true);
for ( int i = 2; i < nVertices; i++ )
{
RenderAddTriangle( &vlist[ 0 ],
&vlist[ i - 1 ],
&vlist[ i ],
false );
}
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
FX_ENTRY void FX_CALL
grAADrawLine( const GrVertex *a, const GrVertex *b )
{
#ifdef OGL_CRITICAL
GlideMsg( "grAADrawLine( ---, --- )\n" );
#endif
SetClipVerticesState(false);
RenderAddLine( a, b, true );
}
FX_ENTRY void FX_CALL
grAADrawPoint(const GrVertex *a )
{
#ifdef OGL_CRITICAL
GlideMsg("grAADrawPoint( --- )\n");
#endif
SetClipVerticesState(false);
RenderAddPoint( a, true );
}
FX_ENTRY void FX_CALL
grAADrawPolygon( const int nverts, const int ilist[], const GrVertex vlist[] )
{
#ifdef OGL_CRITICAL
GlideMsg( "grAADrawPolygon( %d, ---, --- )\n", nverts );
#endif
SetClipVerticesState(false);
for ( int i = 2; i < nverts; i++ )
{
RenderAddTriangle( &vlist[ ilist[ 0 ] ],
&vlist[ ilist[ i - 1 ] ],
&vlist[ ilist[ i ] ],
true );
}
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
FX_ENTRY void FX_CALL
grAADrawPolygonVertexList( const int nverts, const GrVertex vlist[] )
{
#ifdef OGL_CRITICAL
GlideMsg( "grAADrawPolygonVertexList( %d, --- )\n", nverts );
#endif
SetClipVerticesState(false);
for ( int i = 2; i < nverts; i++ )
{
RenderAddTriangle( &vlist[ 0 ],
&vlist[ i - 1 ],
&vlist[ i ],
true );
}
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}
FX_ENTRY void FX_CALL
grAADrawTriangle( const GrVertex *a, const GrVertex *b, const GrVertex *c,
FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias )
{
#ifdef OGL_CRITICAL
GlideMsg("grAADrawTriangle( ---, ---, ---, %d, %d, %d )\n",
ab_antialias, bc_antialias, ca_antialias );
#endif
SetClipVerticesState(false);
RenderAddTriangle( a, b, c, true );
if ( Glide.State.RenderBuffer == GR_BUFFER_FRONTBUFFER )
{
RenderDrawTriangles( );
glFlush( );
}
}

View File

@ -0,0 +1,229 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Fog Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GlideSettings.h"
#include "GLRender.h"
#include "GLUtil.h"
#include "GLRenderUpdateState.h"
#include "OGLTables.h"
//*************************************************
//* download a fog table
//* Fog is applied after color combining and before alpha blending.
//*************************************************
FX_ENTRY void FX_CALL
grFogTable( const GrFog_t *ft )
{
#ifdef OGL_DONE
GlideMsg( "grFogTable( --- )\n" );
#endif
if ( InternalConfig.FogMode > OpenGLideFogEmulation_None )
{
memcpy( Glide.FogTable, ft, GR_FOG_TABLE_SIZE * sizeof( FxU8 ) );
Glide.FogTable[ GR_FOG_TABLE_SIZE ] = 255;
for ( FxU32 i = 0; i < GR_FOG_TABLE_SIZE; i++ )
{
for ( FxU32 j = intStartEnd[ i ]; j < intStartEnd[ i + 1 ]; j++ )
{
OpenGL.FogTable[ j ] = (FxU8)( Glide.FogTable[ i ] +
( Glide.FogTable[ i + 1 ] - Glide.FogTable[ i ] ) * ( j - intStartEnd[ i ] ) /
intEndMinusStart[ i ] );
}
}
}
}
//*************************************************
FX_ENTRY void FX_CALL
grFogColorValue( GrColor_t fogcolor )
{
glReportErrors("grFogColorValue");
#ifdef OGL_PARTDONE
GlideMsg( "grFogColorValue( %x )\n", fogcolor );
#endif
RenderDrawTriangles();
Glide.State.FogColorValue = fogcolor;
ConvertColorF(fogcolor,
OpenGL.FogColor[0],
OpenGL.FogColor[1],
OpenGL.FogColor[2],
OpenGL.FogColor[3]);
SetFogColorState();
}
//*************************************************
FX_ENTRY void FX_CALL
grFogMode( GrFogMode_t mode )
{
glReportErrors("grFogMode");
CHECK_STATE_CHANGED(mode == Glide.State.FogMode);
#ifdef OGL_PARTDONE
GlideMsg( "grFogMode( %d )\n", mode );
#endif
RenderDrawTriangles();
Glide.State.FogMode = mode;
OpenGL.Fog = mode & (GR_FOG_WITH_ITERATED_ALPHA | GR_FOG_WITH_TABLE);
SetFogModeState();
}
//*************************************************
FX_ENTRY void FX_CALL
guFogGenerateExp( GrFog_t *fogtable, float density )
{
#ifdef OGL_PARTDONE
GlideMsg( "guFogGenerateExp( ---, %-4.2f )\n", density );
#endif
glReportErrors("guFogGenerateExp");
float f;
float scale;
float dp;
dp = density * guFogTableIndexToW( GR_FOG_TABLE_SIZE - 1 );
scale = 255.0F / ( 1.0F - (float) exp( -dp ) );
for ( int i = 0; i < GR_FOG_TABLE_SIZE; i++ )
{
dp = density * guFogTableIndexToW( i );
f = ( 1.0F - (float) exp( -dp ) ) * scale;
if ( f > 255.0F )
{
f = 255.0F;
}
else if ( f < 0.0F )
{
f = 0.0F;
}
fogtable[ i ] = (GrFog_t) f;
}
if (InternalConfig.FogMode == OpenGLideFogEmulation_Simple)
{
glFogf( GL_FOG_MODE, GL_EXP );
glReportError();
glFogf( GL_FOG_DENSITY, density );
glReportError();
}
}
//*************************************************
FX_ENTRY void FX_CALL
guFogGenerateExp2( GrFog_t *fogtable, float density )
{
#ifdef OGL_PARTDONE
GlideMsg( "guFogGenerateExp2( ---, %-4.2f )\n", density );
#endif
glReportErrors("guFogGenerateExp2");
float Temp;
for ( int i = 0; i < GR_FOG_TABLE_SIZE; i++ )
{
Temp = ( 1.0f - (float) exp( ( -density) * guFogTableIndexToW( i ) ) *
(float)exp( (-density) * guFogTableIndexToW( i ) ) ) * 255.0f;
fogtable[ i ] = (FxU8) Temp;
}
if (InternalConfig.FogMode == OpenGLideFogEmulation_Simple)
{
glFogf( GL_FOG_MODE, GL_EXP2 );
glReportError();
glFogf( GL_FOG_DENSITY, density );
glReportError();
}
}
//*************************************************
FX_ENTRY void FX_CALL
guFogGenerateLinear( GrFog_t *fogtable,
float nearZ, float farZ )
{
#ifdef OGL_PARTDONE
GlideMsg( "guFogGenerateLinear( ---, %-4.2f, %-4.2f )\n", nearZ, farZ );
#endif
glReportErrors("guFogGenerateLinear");
int Start,
End,
i;
for( Start = 0; Start < GR_FOG_TABLE_SIZE; Start++ )
{
if ( guFogTableIndexToW( Start ) >= nearZ )
{
break;
}
}
for( End = 0; End < GR_FOG_TABLE_SIZE; End++ )
{
if ( guFogTableIndexToW( End ) >= farZ )
{
break;
}
}
memset( fogtable, 0, GR_FOG_TABLE_SIZE );
for( i = Start; i <= End; i++ )
{
fogtable[ i ] = (FxU8)((float)( End - Start ) / 255.0f * (float)( i - Start ));
}
for( i = End; i < GR_FOG_TABLE_SIZE; i++ )
{
fogtable[ i ] = 255;
}
if (InternalConfig.FogMode == OpenGLideFogEmulation_Simple)
{
glFogf( GL_FOG_MODE, GL_LINEAR );
glReportError();
glFogf( GL_FOG_START, nearZ );
glReportError();
glFogf( GL_FOG_END, farZ );
glReportError();
if (nearZ <0 || farZ > 1.0)
{
GlideMsg("Warning: guFogGenerateLinear( ---, %-4.2f, %-4.2f ) values out of expected range\n", nearZ, farZ);
}
}
}
//*************************************************
//* convert a fog table index to a floating point eye-space w value
//*************************************************
FX_ENTRY float FX_CALL
guFogTableIndexToW( int i )
{
#ifdef OGL_DONE
GlideMsg( "guFogTableIndexToW( %d )\n", i );
#endif
#ifdef OGL_DEBUG
if ( ( i < 0 ) ||
( i >= GR_FOG_TABLE_SIZE ) )
{
GlideError( "Error on guFogTableIndexToW( %d )\n", i );
}
#endif
return tableIndexToW[ i ];
}

View File

@ -0,0 +1,616 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Linear Frame Buffer Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Glide.h"
#include "GlideApplication.h"
#include "FormatConversion.h"
#include "GLExtensions.h"
#include "GLRender.h"
#include "GLUtil.h"
//*************************************************
FX_ENTRY FxBool FX_CALL
grLfbLock( GrLock_t dwType,
GrBuffer_t dwBuffer,
GrLfbWriteMode_t dwWriteMode,
GrOriginLocation_t dwOrigin,
FxBool bPixelPipeline,
GrLfbInfo_t *lfbInfo )
{
#if defined(OGL_CRITICAL) || defined(OGL_FRAMEBUFFER)
GlideMsg("grLfbLock( %d, %d, %d, %d, %d, 0x%x )\n",
dwType, dwBuffer, dwWriteMode, dwOrigin, bPixelPipeline, lfbInfo);
#endif
#ifdef OGL_NOTDONE
if (dwWriteMode != GR_LFBWRITEMODE_565
&& dwWriteMode != GR_LFBWRITEMODE_1555
&& dwWriteMode != GR_LFBWRITEMODE_888
&& dwWriteMode != GR_LFBWRITEMODE_ANY)
{
GlideMsg("grLfbLock() - dwWriteMode %d not supported\n", dwWriteMode);
}
#endif
glReportErrors("grLfbLock");
dwWriteMode = (dwWriteMode == GR_LFBWRITEMODE_ANY) ? GR_LFBWRITEMODE_565 : dwWriteMode;
lfbInfo->strideInBytes = Glide.WindowWidth * (dwWriteMode >= GR_LFBWRITEMODE_888 ? 4 : 2);
lfbInfo->writeMode = dwWriteMode;
lfbInfo->origin = dwOrigin;
if ( dwType & GR_LFB_WRITE_ONLY )
{
lfbInfo->lfbPtr = Glide.FrameBuffer.Address;
s_Framebuffer.OnBufferLockStartWrite(dwType, dwBuffer, dwWriteMode, dwOrigin, bPixelPipeline);
}
else if (OpenGL.WinOpen == false && Glide.ReadBuffer.Address)
{
BufferStruct* targetbuffer = Glide.ReadBuffer.Address ? &Glide.ReadBuffer : &Glide.TempBuffer;
lfbInfo->lfbPtr = targetbuffer->Address;
lfbInfo->origin = GR_ORIGIN_UPPER_LEFT;
}
else
{
// finish rendering
RenderDrawTriangles();
glFinish();
glReportError();
// Alloc readbuffer
if (Glide.ReadBuffer.Address == NULL)
{
Glide.ReadBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowWidth * Glide.WindowHeight, sizeof(FxU16));
#ifdef OPENGL_DEBUG
GlideMsg("Allocated Readbuffer(%dx%d) at 0x%x\n",
Glide.WindowWidth, Glide.WindowHeight, Glide.ReadBuffer.Address);
#endif
}
// select main memory buffers
BufferStruct* targetbuffer = Glide.ReadBuffer.Address ? &Glide.ReadBuffer : &Glide.TempBuffer;
BufferStruct* sourcebuffer = Glide.ReadBuffer.Address ? &Glide.TempBuffer : &Glide.FrameBuffer;
if (s_Framebuffer.GetRenderBufferChangedForRead() == true)
{
// select buffer size
unsigned long bufferwidth = Glide.ReadBuffer.Address ? OpenGL.WindowWidth : Glide.WindowWidth;
unsigned long bufferheight = Glide.ReadBuffer.Address ? OpenGL.WindowHeight : Glide.WindowHeight;
glReadBuffer(dwBuffer == GR_BUFFER_BACKBUFFER ? GL_BACK : GL_FRONT);
glReportError();
bool scale = bufferwidth != Glide.WindowWidth || bufferheight != Glide.WindowHeight;
GLint glWriteMode;
switch (dwWriteMode)
{
case GR_LFBWRITEMODE_1555: glWriteMode = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
case GR_LFBWRITEMODE_565: glWriteMode = GL_UNSIGNED_SHORT_5_6_5; break;
default: glWriteMode = GL_UNSIGNED_SHORT_5_6_5; break;
}
void* destination = (!scale && dwOrigin == GR_ORIGIN_LOWER_LEFT) ? targetbuffer->Address : sourcebuffer->Address;
#ifdef OPENGL_DEBUG
GlideMsg("Calling glReadPixels(%d, %d, 0x%x)\n", bufferwidth, bufferheight, destination);
#endif
glReadPixels(0, 0,
bufferwidth, bufferheight,
(dwWriteMode == GR_LFBWRITEMODE_1555) ? GL_RGBA : GL_RGB,
glWriteMode,
destination);
glReportError();
#ifdef OPENGL_DEBUG
if (scale)
GlideMsg("Scaling to (%d, %d) from 0x%x to 0x%x\n",
Glide.WindowWidth, Glide.WindowHeight, sourcebuffer->Address, targetbuffer->Address);
#endif
if (dwOrigin == GR_ORIGIN_UPPER_LEFT)
{
// When the OpenGL resolution differs from the Glide resolution,
// the content of the read buffer must be scaled
if (scale)
{
// size/copy from OpenGL-sized buffer to Glide-sized buffer?
FxU16* src;
FxU16* dst = targetbuffer->Address;
int xratio = (bufferwidth << 16) / (Glide.WindowWidth);
int yratio = (bufferheight << 16) / (Glide.WindowHeight);
int u;
int v = 0;
int x;
int y;
for(y = 0; y < Glide.WindowHeight; y++)
{
src = sourcebuffer->Address + (bufferheight -1 - (v >> 16)) * bufferwidth;
u = 0;
for(x = 0;x < Glide.WindowWidth; x++)
{
*dst++ = src[u >> 16];
u += xratio;
}
v += yratio;
}
}
else
{
#ifdef OPENGL_DEBUG
GlideMsg("Copying/Vertical mirroring pixels to destination buffer from 0x%x to 0x%x\n",
sourcebuffer->Address, targetbuffer->Address);
#endif
// Swap pixels during copy from temp to read buffer
for ( int j = 0; j < Glide.WindowHeight; j++ )
{
memcpy(targetbuffer->Address + (j * Glide.WindowWidth),
sourcebuffer->Address + ((bufferheight - 1 - j) * bufferwidth),
2 * Glide.WindowWidth);
}
}
}
else if (scale) // GR_ORIGIN_LOWER_LEFT
{
// size/copy from OpenGL-sized buffer to Glide-sized buffer?
if (scale)
{
// Copy and scale
FxU16* src;
FxU16* dst = targetbuffer->Address;
int xratio = (bufferwidth << 16) / Glide.WindowWidth;
int yratio = (bufferheight << 16) / Glide.WindowHeight;
int u;
int v = 0;
int x;
int y;
for(y = 0; y < Glide.WindowHeight; y++)
{
src = sourcebuffer->Address + (v >> 16) * bufferwidth;
u = 0;
for(x = 0;x < Glide.WindowWidth; x++)
{
*dst++ = src[u >> 16];
u += xratio;
}
v += yratio;
}
}
else
{
#ifdef OPENGL_DEBUG
GlideMsg("Copying/Vertical mirroring not necessary - pixels already in the right orientation\n");
#endif
}
}
// Update with current framebuffer pixels not yet written to vram
// (Obmitting causes incomplete screenshots in Falcon 4.0)
s_Framebuffer.CopyFrameBuffer(targetbuffer->Address);
s_Framebuffer.ResetRenderBufferChangedForRead();
}
// Update buffer struct
targetbuffer->Lock = true;
targetbuffer->Type = dwType;
targetbuffer->Buffer = dwBuffer;
targetbuffer->WriteMode = dwWriteMode;
targetbuffer->PixelPipeline = bPixelPipeline;
lfbInfo->lfbPtr = targetbuffer->Address;
}
return FXTRUE;
}
//*************************************************
FX_ENTRY FxBool FX_CALL
grLfbUnlock( GrLock_t dwType, GrBuffer_t dwBuffer )
{
#if defined(OGL_CRITICAL) || defined(OGL_FRAMEBUFFER)
GlideMsg("grLfbUnlock( %d, %d )\n", dwType, dwBuffer );
#endif
if ( dwType & GR_LFB_WRITE_ONLY )
{
if ( ! Glide.FrameBuffer.Lock )
{
return FXFALSE;
}
s_Framebuffer.OnBufferUnlockEndWrite(dwBuffer);
Glide.FrameBuffer.Lock = false;
return FXTRUE;
}
else
{
BufferStruct* targetbuffer = Glide.ReadBuffer.Address ? &Glide.ReadBuffer : &Glide.TempBuffer;
if (targetbuffer->Lock)
{
// We're not interested in keeping track of unlocks since this breaks
// Framebuffer updates when moving the cursor in Carmageddon movie mode
// (because grLfbReadRegion() is called)
// @todo: -> Doesn't solve the issue
targetbuffer->Lock = false;
return FXTRUE;
}
else
{
return FXFALSE;
}
}
}
//*************************************************
FX_ENTRY FxBool FX_CALL
grLfbReadRegion( GrBuffer_t src_buffer,
FxU32 src_x, FxU32 src_y,
FxU32 src_width, FxU32 src_height,
FxU32 dst_stride, void *dst_data )
{
#if defined(OGL_DONE) || defined(OGL_FRAMEBUFFER)
GlideMsg("grLfbReadRegion( %d, %d, %d, %d, %d, %d, 0x%x )\n",
src_buffer, src_x, src_y, src_width, src_height, dst_stride, dst_data);
#endif
if (s_GlideApplication.GetType() == GlideApplication::Carmageddon)
{
RenderDrawTriangles();
s_Framebuffer.OnLfbReadRegion();
// To render the cursor in Movie-mode correctly, the region
// must be filled with the framebuffer's chromakey color.
// But Carmageddon seems to write a column filled with the
// endian-swapped chromakey value into the framebuffer.
// Workaround:
// Using an endian-symetric chromakey value (outch)
// Also one more pixel than expected must be set in order to
// avoid a black dot in the lower right corner of the cursor.
// All of this could be avoided with PedanticFrameBufferEmulation.
const unsigned jump_dst = ((dst_stride >> 1) - src_width);
unsigned long jump = jump_dst;
const unsigned long pixels = src_width * src_height + 1;
FxU16* d = reinterpret_cast<FxU16*>(dst_data);
FxU16 chromakey = s_Framebuffer.GetChromaKeyValue();
swapshort(&chromakey);
for(unsigned int i = 0; i < pixels; i+=1)
{
d[i] = chromakey;
jump--;
if (jump == 0)
{
jump = jump_dst;
i += jump;
}
}
return FXTRUE;
}
// Copied from the linux sst1 driver src
FxBool rv = FXTRUE;
GrLfbInfo_t info;
//#if (GLIDE_PLATFORM & GLIDE_HW_SST1)
// gc->lfbSliOk = 1;
info.size = sizeof( info );
if ( grLfbLock( GR_LFB_READ_ONLY,
src_buffer,
GR_LFBWRITEMODE_ANY,
GR_ORIGIN_UPPER_LEFT,
FXFALSE,
&info ) ) {
FxU32 *srcData; /* Tracking Source Pointer */
FxU32 *dstData; /* Tracking Destination Pointer */
FxU32 *end; /* Demarks End of each Scanline */
FxU32 srcJump; /* bytes to next scanline */
FxU32 dstJump; /* bytes to next scanline */
FxU32 length; /* bytes to copy in scanline */
FxU32 scanline; /* scanline number */
int aligned; /* word aligned? */
FxU32 odd; /* is src_y odd? ( for sli ) */
dstData = ( FxU32 * ) dst_data;
srcData = ( FxU32 * ) ( ((char*)info.lfbPtr)+
(src_y*info.strideInBytes) +
(src_x<<1) );
scanline = src_height;
length = src_width * 2;
dstJump = dst_stride - length;
srcJump = info.strideInBytes - length;
aligned = !((int)srcData&0x2);
odd = (src_y+src_height) & 0x1;
if ( aligned ) {
while( scanline-- ) {
end = (FxU32*)((char*)srcData + length - 2);
/*
if(gc->scanline_interleaved == FXTRUE) {
if((scanline+odd) & 0x1)
sst1InitSliPciOwner(gc->base_ptr, SST_SLI_MASTER_OWNPCI);
else
sst1InitSliPciOwner(gc->base_ptr, SST_SLI_SLAVE_OWNPCI);
}
*/
while( srcData < end )
*dstData++ = *srcData++;
if ( ((int)length) & 0x2 ) {
(*(FxU16*)dstData) = (*(FxU16*)srcData);
dstData = (FxU32*)(((FxU16*)dstData) + 1 );
srcData = (FxU32*)(((FxU16*)srcData) + 1 );
}
dstData = (FxU32*)(((char*)dstData)+dstJump);
srcData = (FxU32*)(((char*)srcData)+srcJump);
}
} else {
while( scanline-- ) {
end = (FxU32*)((char*)srcData + length - 2);
/*
if(gc->scanline_interleaved == FXTRUE) {
if((scanline+odd) & 0x1)
sst1InitSliPciOwner(gc->base_ptr, SST_SLI_MASTER_OWNPCI);
else
sst1InitSliPciOwner(gc->base_ptr, SST_SLI_SLAVE_OWNPCI);
}
*/
(*(FxU16*)dstData) = (*(FxU16*)srcData);
dstData = (FxU32*)(((FxU16*)dstData) + 1 );
srcData = (FxU32*)(((FxU16*)srcData) + 1 );
while( srcData < end )
*dstData++ = *srcData++;
if ( !(((int)length) & 0x2) ) {
(*(FxU16*)dstData) = (*(FxU16*)srcData);
dstData = (FxU32*)(((FxU16*)dstData) + 1 );
srcData = (FxU32*)(((FxU16*)srcData) + 1 );
}
dstData = (FxU32*)(((char*)dstData)+dstJump);
srcData = (FxU32*)(((char*)srcData)+srcJump);
}
}
grLfbUnlock( GR_LFB_READ_ONLY, src_buffer );
/*
if ( gc->scanline_interleaved )
sst1InitSliPciOwner( gc->base_ptr, SST_SLI_MASTER_OWNPCI );
*/
} else {
rv = FXFALSE;
}
return rv;
}
//*************************************************
FX_ENTRY FxBool FX_CALL
grLfbWriteRegion( GrBuffer_t dst_buffer,
FxU32 dst_x, FxU32 dst_y,
GrLfbSrcFmt_t src_format,
FxU32 src_width, FxU32 src_height,
FxI32 src_stride, void *src_data )
{
#if defined(OGL_DONE) || defined(OGL_FRAMEBUFFER)
GlideMsg("grLfbWriteRegion( %d, %d, %d, %d, %d, %d, %d, 0x%x )\n",
dst_buffer, dst_x, dst_y, src_format, src_width, src_height, src_stride, src_data);
#endif
// Copied from the linux sst1 driver src
FxBool rv = FXTRUE;
GrLfbInfo_t info;
GrLfbWriteMode_t writeMode;
/*
GR_BEGIN_NOFIFOCHECK("grLfbWriteRegion",82);
GDBG_INFO_MORE((gc->myLevel,
"(0x%x,%d,%d,%d,%d,%d,%d,0x%x)\n",
dst_buffer, dst_x, dst_y,
src_format, src_width, src_height,
src_stride, src_data ));
*/
// #if ( GLIDE_PLATFORM & GLIDE_HW_SST1 )
if ( src_format == GR_LFB_SRC_FMT_RLE16 )
writeMode = GR_LFBWRITEMODE_565;
else
writeMode = src_format;
info.size = sizeof( info );
if ( grLfbLock( GR_LFB_WRITE_ONLY | GR_LFB_NOIDLE,
dst_buffer,
writeMode,
GR_ORIGIN_UPPER_LEFT,
FXFALSE,
&info ) ) {
FxU32 *srcData; /* Tracking Source Pointer */
FxU32 *dstData; /* Tracking Destination Pointer */
FxU32 *end; /* Demarks End of each Scanline */
FxI32 srcJump; /* bytes to next scanline */
FxU32 dstJump; /* bytes to next scanline */
FxU32 length; /* bytes to copy in scanline */
FxU32 scanline; /* scanline number */
int aligned; /* word aligned? */
srcData = ( FxU32 * ) src_data;
dstData = ( FxU32 * ) ( ((char*)info.lfbPtr)+
(dst_y*info.strideInBytes) );
scanline = src_height;
switch( src_format ) {
/* 16-bit aligned */
case GR_LFB_SRC_FMT_565:
case GR_LFB_SRC_FMT_555:
case GR_LFB_SRC_FMT_1555:
case GR_LFB_SRC_FMT_ZA16:
dstData = (FxU32*)(((FxU16*)dstData) + dst_x);
length = src_width * 2;
aligned = !((int)dstData&0x2);
srcJump = src_stride - length;
dstJump = info.strideInBytes - length;
if ( aligned )
{
while( scanline-- )
{
// GR_SET_EXPECTED_SIZE(length);
end = (FxU32*)((char*)srcData + length - 2);
while( srcData < end )
{
// GR_SET( dstData[0], srcData[0] );
#ifdef OPENGLIDE_HOST_MAC
swaplong(dstData, srcData);
#else
*dstData = *srcData;
#endif
dstData++;
srcData++;
}
if ( ((int)length) & 0x2 )
{
/*
GR_SET16( (*(FxU16*)&(dstData[0])),
(*(FxU16*)&(srcData[0])) );
*/
(*(FxU16*)&(dstData[0])) = (*(FxU16*)&(srcData[0]));
dstData = (FxU32*)(((FxU16*)dstData) + 1 );
srcData = (FxU32*)(((FxU16*)srcData) + 1 );
}
dstData = (FxU32*)(((char*)dstData)+dstJump);
srcData = (FxU32*)(((char*)srcData)+srcJump);
// GR_CHECK_SIZE_SLOPPY();
}
}
else
{
while( scanline-- ) {
// GR_SET_EXPECTED_SIZE(length);
end = (FxU32*)((char*)srcData + length - 2);
/*
GR_SET16( (*(FxU16*)&(dstData[0])),
(*(FxU16*)&(srcData[0])) );
*/
#ifdef OPENGLIDE_HOST_MAC
swapshort(dstData, srcData);
#else
(*(FxU16*)&(dstData[0])) = (*(FxU16*)&(srcData[0]));
#endif
dstData = (FxU32*)(((FxU16*)dstData) + 1 );
srcData = (FxU32*)(((FxU16*)srcData) + 1 );
while( srcData < end ) {
// GR_SET( dstData[0], srcData[0] );
#ifdef OPENGLIDE_HOST_MAC
swaplong(dstData, srcData);
#else
*dstData = *srcData;
#endif
dstData++;
srcData++;
}
if ( !(length & 0x2) )
{
/*
GR_SET16( (*(FxU16*)&(dstData[0])),
(*(FxU16*)&(srcData[0])) );
*/
#ifdef OPENGLIDE_HOST_MAC
swapshort(dstData, srcData);
#else
(*(FxU16*)&(dstData[0])) = (*(FxU16*)&(srcData[0]));
#endif
dstData = (FxU32*)(((FxU16*)dstData) + 1 );
srcData = (FxU32*)(((FxU16*)srcData) + 1 );
}
dstData = (FxU32*)(((char*)dstData)+dstJump);
srcData = (FxU32*)(((char*)srcData)+srcJump);
// GR_CHECK_SIZE_SLOPPY();
}
}
break;
/* 32-bit aligned */
case GR_LFB_SRC_FMT_888:
case GR_LFB_SRC_FMT_8888:
case GR_LFB_SRC_FMT_565_DEPTH:
case GR_LFB_SRC_FMT_555_DEPTH:
case GR_LFB_SRC_FMT_1555_DEPTH:
dstData = ((FxU32*)dstData) + dst_x;
length = src_width * 4;
srcJump = src_stride - length;
dstJump = info.strideInBytes - length;
while( scanline-- ) {
// GR_SET_EXPECTED_SIZE(length);
end = (FxU32*)((char*)srcData + length);
while( srcData < end ) {
// GR_SET( dstData[0], srcData[0] );
#ifdef OPENGLIDE_HOST_MAC
swaplong(dstData, srcData);
#else
*dstData = *srcData;
#endif
dstData++;
srcData++;
}
dstData = (FxU32*)(((char*)dstData)+dstJump);
srcData = (FxU32*)(((char*)srcData)+srcJump);
// GR_CHECK_SIZE_SLOPPY();
}
break;
case GR_LFB_SRC_FMT_RLE16:
/* needs to be implemented */
rv = FXFALSE;
break;
}
grLfbUnlock( GR_LFB_WRITE_ONLY, dst_buffer );
} else {
rv = FXFALSE;
}
return rv;
}
FX_ENTRY void FX_CALL
grLfbConstantAlpha( GrAlpha_t alpha )
{
#ifdef /* OGL_CRITICAL*/ OGL_DONE
GlideMsg("grLfbConstantAlpha( %lu )\n", alpha );
#endif
s_Framebuffer.SetAlpha(alpha);
}
FX_ENTRY void FX_CALL
grLfbConstantDepth( FxU16 depth )
{
#ifdef /* OGL_CRITICAL*/ OGL_DONE
GlideMsg("grLfbConstantDepth( %u )\n", depth );
#endif
if (OpenGL.DepthBufferType == 1) // == GR_DEPTHBUFFER_ZBUFFER)
{
// map depth to range (0.0, 1.0)
s_Framebuffer.SetDepth(depth * D1OVER65535);
}
else
{
// depth is a float value
#ifdef /* OGL_CRITICAL*/ OGL_DONE
GlideMsg("grLfbConstantDepth( %u ) wbuffer not done\n", depth );
#endif
s_Framebuffer.SetDepth(depth * D1OVER65535);
}
}
FX_ENTRY void FX_CALL
grLfbWriteColorSwizzle( FxBool swizzleBytes, FxBool swapFxU16s )
{
#ifdef /* OGL_CRITICAL*/ OGL_NOTDONE
GlideMsg("grLfbWriteColorSwizzle( %d, %d )\n",
swizzleBytes, swapFxU16s );
#endif
}
FX_ENTRY void FX_CALL
grLfbWriteColorFormat( GrColorFormat_t colorFormat )
{
#ifdef /* OGL_CRITICAL */ OGL_NOTDONE
GlideMsg("grLfbWriteColorFormat( %u )\n", colorFormat );
#endif
}

View File

@ -0,0 +1,325 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Other Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Glide.h"
#include "GLRender.h"
#include "GLRenderUpdateState.h"
// Error Function variable
GLIDEERRORFUNCTION ExternErrorFunction;
//*************************************************
//* Sets the External Error Function to call if
//* Glides Generates and Error
//*************************************************
FX_ENTRY void FX_CALL
grErrorSetCallback( void (*function)(const char *string, FxBool fatal) )
{
#ifdef OGL_DONE
GlideMsg( "grErrorSetCallback( --- )\n" );
#endif
ExternErrorFunction = function;
}
//*************************************************
//* Sets the Cull Mode
//*************************************************
FX_ENTRY void FX_CALL
grCullMode( GrCullMode_t mode )
{
#ifdef OGL_DONE
GlideMsg( "grCullMode( %d )\n", mode );
#endif
glReportErrors("grCullMode");
RenderDrawTriangles( );
Glide.State.CullMode = mode;
switch ( Glide.State.CullMode )
{
case GR_CULL_DISABLE:
glDisable( GL_CULL_FACE );
glCullFace( GL_BACK ); // This will be called in initialization
break;
case GR_CULL_NEGATIVE:
glEnable( GL_CULL_FACE );
if ( Glide.State.OriginInformation == GR_ORIGIN_LOWER_LEFT )
{
glFrontFace( GL_CCW );
}
else
{
glFrontFace( GL_CW );
}
break;
case GR_CULL_POSITIVE:
glEnable( GL_CULL_FACE );
if ( Glide.State.OriginInformation == GR_ORIGIN_LOWER_LEFT )
{
glFrontFace( GL_CW );
}
else
{
glFrontFace( GL_CCW );
}
break;
}
glReportError();
}
//*************************************************
//* Set the size and location of the hardware clipping window
//*************************************************
FX_ENTRY void FX_CALL
grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy )
{
CHECK_STATE_CHANGED(Glide.State.ClipMinX == minx
&& Glide.State.ClipMinY == miny
&& Glide.State.ClipMaxX == maxx
&& Glide.State.ClipMaxY == maxy);
#ifdef OGL_PARTDONE
GlideMsg( "grClipWindow( %d, %d, %d, %d )\n", minx, miny, maxx, maxy );
#endif
RenderDrawTriangles( );
s_Framebuffer.OnClipWindow();
// Store the Glide clipping coords
Glide.State.ClipMinX = minx;
Glide.State.ClipMaxX = maxx;
Glide.State.ClipMinY = miny;
Glide.State.ClipMaxY = maxy;
// calculate the corresponding OpenGL coords
// (the multiplication has to come first because the values are integers)
OpenGL.ClipMinX = OpenGL.WindowWidth * minx / Glide.WindowWidth;
OpenGL.ClipMaxX = OpenGL.WindowWidth * maxx / Glide.WindowWidth;
OpenGL.ClipMinY = OpenGL.WindowHeight * miny / Glide.WindowHeight;
OpenGL.ClipMaxY = OpenGL.WindowHeight * maxy / Glide.WindowHeight;
bool clip = ((Glide.State.ClipMinX != 0) ||
(Glide.State.ClipMinY != 0) ||
(Glide.State.ClipMaxX != Glide.WindowWidth) ||
(Glide.State.ClipMaxY != Glide.WindowHeight));
OpenGL.Clipping = clip;
SetClipVerticesState(clip);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
if ( Glide.State.OriginInformation == GR_ORIGIN_LOWER_LEFT )
{
// Used for geometry clipping
glOrtho(Glide.State.ClipMinX, Glide.State.ClipMaxX,
Glide.State.ClipMinY, Glide.State.ClipMaxY,
OpenGL.ZNear, OpenGL.ZFar);
glViewport(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.ClipMinY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
// Used for the buffer clearing
glScissor(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.ClipMinY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
}
else
{
// Used for geometry clipping
glOrtho(Glide.State.ClipMinX, Glide.State.ClipMaxX,
Glide.State.ClipMaxY, Glide.State.ClipMinY,
OpenGL.ZNear, OpenGL.ZFar );
glViewport(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.WindowHeight - OpenGL.ClipMaxY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
// Used for the buffer clearing
glScissor(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.WindowHeight - OpenGL.ClipMaxY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
}
glMatrixMode( GL_MODELVIEW );
}
//*************************************************
FX_ENTRY void FX_CALL
grDisableAllEffects( void )
{
#ifdef OGL_PARTDONE
GlideMsg( "grDisableAllEffects( )\n" );
#endif
grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO );
grAlphaTestFunction( GR_CMP_ALWAYS );
grChromakeyMode( GR_CHROMAKEY_DISABLE );
grDepthBufferMode( GR_DEPTHBUFFER_DISABLE );
grFogMode( GR_FOG_DISABLE );
}
//*************************************************
FX_ENTRY void FX_CALL
grResetTriStats( void )
{
#ifdef OGL_NOTDONE
GlideMsg( "grResetTriStats( )\n" );
#endif
}
//*************************************************
FX_ENTRY void FX_CALL
grTriStats( FxU32 *trisProcessed, FxU32 *trisDrawn )
{
#ifdef OGL_NOTDONE
GlideMsg( "grTriStats( )\n" );
#endif
}
//*************************************************
FX_ENTRY void FX_CALL
grHints( GrHint_t hintType, FxU32 hintMask )
{
switch( hintType )
{
case GR_HINT_STWHINT:
CHECK_STATE_CHANGED(Glide.State.STWHint == hintMask);
#ifdef OGL_PARTDONE
GlideMsg("grHints( %d, %d )\n", hintType, hintMask);
#endif
RenderDrawTriangles();
Glide.State.STWHint = hintMask;
break;
default:
#ifdef OGL_NOTDONE
GlideMsg("grHints( %d, %d )\n", hintType, hintMask);
#endif
break;
}
}
/*
//*************************************************
FX_ENTRY void FX_CALL
grSplash( float x, float y, float width, float height, FxU32 frame )
{
#ifdef OGL_NOTDONE
GlideMsg( "grSplash( %-4.2f, %-4.2f, %-4.2f, %-4.2f, %lu )\n",
x, y, width, height, frame );
#endif
}
*/
//*************************************************
FX_ENTRY void FX_CALL
ConvertAndDownloadRle( GrChipID_t tmu,
FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
FxU8 *bm_data,
long bm_h,
FxU32 u0,
FxU32 v0,
FxU32 width,
FxU32 height,
FxU32 dest_width,
FxU32 dest_height,
FxU16 *tlut )
{
#ifdef OGL_NOTDONE
GlideMsg( "ConvertAndDownloadRle( %d, %lu, %d, %d, %d, %d, %d, ---, %l, %lu, %lu, %lu, %lu, %lu, %lu, --- )\n",
tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, bm_h, u0, v0, width, height,
dest_width, dest_height );
#endif
}
//*************************************************
FX_ENTRY void FX_CALL
grCheckForRoom( FxI32 n )
{
#ifdef OGL_NOTDONE
GlideMsg( "grCheckForRoom( %l )\n", n );
#endif
}
//*************************************************
FX_ENTRY void FX_CALL
grParameterData( FxU32 param, FxU32 components, FxU32 type, FxI32 offset )
{
#ifdef OGL_NOTDONE
GlideMsg( "grParameterData( %lu, %lu, %lu, %l )\n",
param, components, type, offset );
#endif
}
//*************************************************
FX_ENTRY int FX_CALL
guEncodeRLE16( void *dst,
void *src,
FxU32 width,
FxU32 height )
{
#ifdef OGL_NOTDONE
GlideMsg( "guEncodeRLE16( ---, ---, %lu, %lu ) = 1\n", width, height );
#endif
return 1;
}
//*************************************************
FX_ENTRY FxU32 FX_CALL
guEndianSwapFxU16s( FxU32 value )
{
#ifdef OGL_DONE
GlideMsg( "guEndianSwapFxU16s( %lu )\n", value );
#endif
return ( value << 16 ) | ( value >> 16 );
}
//*************************************************
FX_ENTRY FxU16 FX_CALL
guEndianSwapBytes( FxU16 value )
{
#ifdef OGL_DONE
GlideMsg( "guEndianSwapBytes( %u )\n", value );
#endif
return ( value << 8 ) | ( value >> 8 );
}
FX_ENTRY void FX_CALL
guMovieStart( void )
{
#ifdef OGL_NOTDONE
GlideMsg( "guMovieStart( ) - Not Supported\n" );
#endif
}
FX_ENTRY void FX_CALL
guMovieStop( void )
{
#ifdef OGL_NOTDONE
GlideMsg( "guMovieStop( ) - Not Supported\n" );
#endif
}
FX_ENTRY void FX_CALL
guMovieSetName( const char *name )
{
#ifdef OGL_NOTDONE
GlideMsg( "guMovieSetName( ) - Not Supported\n" );
#endif
}

View File

@ -0,0 +1,34 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Other Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef GRGUMISC_H_
#define GRGUMISC_H_
typedef void (*GLIDEERRORFUNCTION)( const char *string, FxBool fatal );
extern GLIDEERRORFUNCTION ExternErrorFunction;
// functions not defined in the SDK but part of either
// - earlier versions of Glide 2.4
// - Part of the GLide 3 interface
#ifdef __cplusplus
extern "C" {
#endif
FX_ENTRY void FX_CALL guMovieStart(void);
FX_ENTRY void FX_CALL guMovieStop(void);
FX_ENTRY void FX_CALL guMovieSetName(const char *name);
FX_ENTRY void FX_CALL grParameterData(FxU32 param, FxU32 components, FxU32 type, FxI32 offset);
FX_ENTRY FxU32 FX_CALL guEndianSwapFxU16s(FxU32 value);
#ifdef __cplusplus
}
#endif
#endif /*GRGUMISC_H_*/

View File

@ -0,0 +1,854 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Sst Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "Glide.h"
#include "GlideApplication.h"
#include "GlideDisplay.h"
#include "GlideSettings.h"
#include "GLExtensions.h"
#include "GLRender.h"
#include "GLUtil.h"
#include "OGLTables.h"
#include "PGTexture.h"
//*************************************************
//* Returns the current Glide Version
//*************************************************
FX_ENTRY void FX_CALL
grGlideGetVersion( char version[80] )
{
#ifdef OGL_DONE
GlideMsg( "grGlideGetVersion( --- )\n" );
#endif
sprintf(version, "Glide 2.45 - %s %s", OpenGLideProductName, OpenGLideVersion);
}
//*************************************************
//* Initializes what is needed
//*************************************************
FX_ENTRY void FX_CALL
grGlideInit( void )
{
#ifdef OGL_DONE
GlideMsg( "grGlideInit( )\n" );
#endif
if ( OpenGL.GlideInit )
{
grGlideShutdown( );
}
memset( &Glide, 0, sizeof( GlideStruct ) );
memset( &OpenGL, 0, sizeof( OpenGLStruct ) );
Glide.ActiveVoodoo = 0;
Glide.State.VRetrace = FXTRUE;
ExternErrorFunction = NULL;
/*
#ifdef OGL_DEBUG
RDTSC( FinalTick );
RDTSC( InitialTick );
Fps = FpsAux = Frame = 0;
#endif
*/
OpenGL.GlideInit = true;
Glide.TextureMemory = UserConfig.TextureMemorySize * 1024 * 1024;
Textures = new PGTexture( Glide.TextureMemory );
if ( Textures == NULL )
{
GlideError( "Cannot allocate enough memory for Texture Buffer in User setting, using default" );
}
Glide.TexMemoryMaxPosition = (FxU32)Glide.TextureMemory;
}
//*************************************************
//* Finishes everything
//*************************************************
FX_ENTRY void FX_CALL
grGlideShutdown( void )
{
if ( !OpenGL.GlideInit )
{
return;
}
OpenGL.GlideInit = false;
#ifdef OGL_DEBUG
RDTSC( FinalTick );
#endif
#ifdef OGL_DONE
GlideMsg( "grGlideShutdown()\n" );
#endif
grSstWinClose( );
if (Textures) delete Textures;
}
//*************************************************
//* Sets all Glide State Variables
//*************************************************
FX_ENTRY void FX_CALL
grGlideSetState( const GrState *state )
{
#ifdef OGL_PARTDONE
GlideMsg( "grGlideSetState( --- )\n" );
#endif
// Ensure the state size is not too large
assert(sizeof(GlideState) < sizeof(GrState));
GlideState StateTemp;
memcpy( &StateTemp, state, sizeof( GlideState ) );
Glide.State.ColorFormat = StateTemp.ColorFormat;
grRenderBuffer( StateTemp.RenderBuffer );
grDepthBufferMode( StateTemp.DepthBufferMode );
grDepthBufferFunction( StateTemp.DepthFunction );
grDepthMask( StateTemp.DepthBufferWritting );
grDepthBiasLevel( StateTemp.DepthBiasLevel );
grDitherMode( StateTemp.DitherMode );
grChromakeyValue( StateTemp.ChromakeyValue );
grChromakeyMode( StateTemp.ChromaKeyMode );
grAlphaTestReferenceValue( StateTemp.AlphaReferenceValue );
grAlphaTestFunction( StateTemp.AlphaTestFunction );
grColorMask( StateTemp.ColorMask, StateTemp.AlphaMask );
grConstantColorValue( StateTemp.ConstantColorValue );
grFogColorValue( StateTemp.FogColorValue );
grFogMode( StateTemp.FogMode );
grCullMode( StateTemp.CullMode );
grTexClampMode( GR_TMU0, StateTemp.SClampMode, StateTemp.TClampMode );
grTexFilterMode( GR_TMU0, StateTemp.MinFilterMode, StateTemp.MagFilterMode );
grTexMipMapMode( GR_TMU0, StateTemp.MipMapMode, StateTemp.LodBlend );
grColorCombine( StateTemp.ColorCombineFunction, StateTemp.ColorCombineFactor,
StateTemp.ColorCombineLocal, StateTemp.ColorCombineOther, StateTemp.ColorCombineInvert );
grAlphaCombine( StateTemp.AlphaFunction, StateTemp.AlphaFactor, StateTemp.AlphaLocal, StateTemp.AlphaOther, StateTemp.AlphaInvert );
grTexCombine( GR_TMU0, StateTemp.TextureCombineCFunction, StateTemp.TextureCombineCFactor,
StateTemp.TextureCombineAFunction, StateTemp.TextureCombineAFactor,
StateTemp.TextureCombineRGBInvert, StateTemp.TextureCombineAInvert );
grAlphaBlendFunction( StateTemp.AlphaBlendRgbSf, StateTemp.AlphaBlendRgbDf, StateTemp.AlphaBlendAlphaSf, StateTemp.AlphaBlendAlphaDf );
grClipWindow( StateTemp.ClipMinX, StateTemp.ClipMinY, StateTemp.ClipMaxX, StateTemp.ClipMaxY );
grSstOrigin( StateTemp.OriginInformation );
grTexSource( GR_TMU0, StateTemp.TexSource.StartAddress, StateTemp.TexSource.EvenOdd, &StateTemp.TexSource.Info );
grTexLodBiasValue(GR_TMU0, StateTemp.LodBias);
}
//*************************************************
//* Gets all Glide State Variables
//*************************************************
FX_ENTRY void FX_CALL
grGlideGetState( GrState *state )
{
#ifdef OGL_PARTDONE
GlideMsg( "grGlideGetState( --- )\n" );
#endif
// Ensure the state size is not too large
assert(sizeof(GlideState) < sizeof(GrState));
memcpy( state, &Glide.State, sizeof( GlideState ) );
}
//*************************************************
FX_ENTRY void FX_CALL
grGlideShamelessPlug( const FxBool on )
{
#ifdef OGL_DONE
GlideMsg( "grGlideShamelessPlug( %d )\n", on );
#endif
InternalConfig.ShamelessPlug = on;
}
//*************************************************
//* Returns the number of Voodoo Boards Instaled
//*************************************************
FX_ENTRY FxBool FX_CALL
grSstQueryBoards( GrHwConfiguration *hwConfig )
{
#ifdef OGL_DONE
GlideMsg( "grSstQueryBoards( --- )\n" );
#endif
memset(hwConfig, 0, sizeof(GrHwConfiguration));
hwConfig->num_sst = 1;
return FXTRUE;
}
//*************************************************
FX_ENTRY FxBool FX_CALL
grSstWinOpen(FxU32 hwnd,
GrScreenResolution_t res,
GrScreenRefresh_t ref,
GrColorFormat_t cformat,
GrOriginLocation_t org_loc,
int num_buffers,
int num_aux_buffers)
{
if ( OpenGL.WinOpen )
{
grSstWinClose( );
}
// Some games read from the buffer after the window has been closed
// As a result, freeing the read buffer must be deferred until the
// next call to grSstWinOpen() or unloading the library
if (Glide.ReadBuffer.Address)
{
FreeFrameBuffer(Glide.ReadBuffer.Address);
Glide.ReadBuffer.Address = NULL;
}
#ifdef OGL_DONE
GlideMsg( "grSstWinOpen( %d, %d, %d, %d, %d, %d, %d )\n",
hwnd, res, ref, cformat, org_loc, num_buffers, num_aux_buffers );
#endif
Glide.Resolution = res;
#ifdef OGL_DEBUG
if ( Glide.Resolution > GR_RESOLUTION_400x300 )
{
GlideError( "grSstWinOpen: res = GR_RESOLUTION_NONE\n" );
return FXFALSE;
}
if ( Glide.Refresh > GR_REFRESH_120Hz )
{
GlideError( "grSstWinOpen: Refresh Incorrect\n" );
return FXFALSE;
}
#endif
Glide.WindowWidth = windowDimensions[ Glide.Resolution ].width;
Glide.WindowHeight = windowDimensions[ Glide.Resolution ].height;
// Set the size of the opengl window (might be different from Glide window size)
if (UserConfig.Resolution == 0)
{
// Does only work if the library is loaded at startup, before the game changes the screen resolution
if (DisplayManager_GetDesktopDisplayResolution(OpenGL.WindowWidth, OpenGL.WindowHeight) != noErr)
{
// Use the resuolution requested by the game
OpenGL.WindowWidth = Glide.WindowWidth;
OpenGL.WindowHeight = Glide.WindowHeight;
}
}
else if (UserConfig.Resolution <= 16)
{
// multiply the original size by the resolution factor
OpenGL.WindowWidth = Glide.WindowWidth * UserConfig.Resolution;
OpenGL.WindowHeight = Glide.WindowHeight * UserConfig.Resolution;
}
else if (UserConfig.Resolution >= 512)
{
// override the resolution
OpenGL.WindowWidth = UserConfig.Resolution;
// Glide games have a fixed 4/3 aspect ratio
OpenGL.WindowHeight = UserConfig.Resolution * 3 / 4;
}
else
{
// Use the resuolution requested by the game
OpenGL.WindowWidth = Glide.WindowWidth;
OpenGL.WindowHeight = Glide.WindowHeight;
}
Glide.WindowTotalPixels = Glide.WindowWidth * Glide.WindowHeight;
Glide.Refresh = ref;
Glide.State.ColorFormat = cformat;
Glide.NumBuffers = num_buffers;
Glide.AuxBuffers = num_aux_buffers;
OpenGL.Refresh = windowRefresh[ Glide.Refresh ];
OpenGL.WaitSignal = (FxU32)( 1000 / OpenGL.Refresh );
memset(&Glide.FrameBuffer, 0, sizeof(BufferStruct));
memset(&Glide.TempBuffer, 0, sizeof(BufferStruct));
memset(&Glide.ReadBuffer, 0, sizeof(BufferStruct));
// Initing OpenGL Window
if ( !InitWindow(hwnd))
{
return FXFALSE;
}
// Note: The OpenGL resolution might have changed during the call to InitWindow().
// As a result, buffers must be allocated afterwards
const unsigned long openglpixels = OpenGL.WindowWidth * OpenGL.WindowHeight;
// At first, allocate a framebuffer for 16bit pixel data only (will be expanded on demand)
unsigned long buffertypesize = sizeof(FxU16); // (dwWriteMode >= GR_LFBWRITEMODE_888) ? sizeof(FxU32) : sizeof(FxU16);
Glide.FrameBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowTotalPixels * buffertypesize + openglpixels * sizeof(FxU32), 1);
Glide.TempBuffer.Address = &Glide.FrameBuffer.Address[Glide.WindowTotalPixels * buffertypesize >> 1];
memset( Glide.FrameBuffer.Address, 0, Glide.WindowTotalPixels * buffertypesize);
memset( Glide.TempBuffer.Address, 0, openglpixels * sizeof(FxU32));
// Prealloc readbuffer for Carmageddon, because allocating it on demand
// (when moving the cursor in Movie mode) would produce an OutOfMemory error)
if (Glide.ReadBuffer.Address == NULL &&
s_GlideApplication.GetType() == GlideApplication::Carmageddon)
{
Glide.ReadBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowTotalPixels, sizeof(FxU16));
#ifdef OPENGL_DEBUG
GlideMsg("Allocated Readbuffer(%dx%d) at 0x%x\n",
Glide.WindowWidth, Glide.WindowHeight, Glide.ReadBuffer.Address);
#endif
}
// Initialise the frame buffer emulation
RenderInitialize();
s_Framebuffer.initialise(&Glide.FrameBuffer, &Glide.TempBuffer);
#ifdef OGL_DONE
GlideMsg( "----Start of grSstWinOpen()\n" );
#endif
// All should be disabled
//depth buffering, fog, chroma-key, alpha blending, alpha testing
#ifdef OPTIMISE_GLIDE_STATE_CHANGES
// When state change optimising is enabled, passing in default values of 0
// will not initialise the corresponding values in the OpenGL struct,
// because the optimising code assumes, it has already been set earlier.
// By writing values other than 0 to glide state variables which will
// become 0 below, the OpenGL values are initialises as exspected.
// For functions that are called by other functions during the
// initialisation, like grColorCombine, explicit default values
// are given, (in this case by grAlphaCombine)
// grTexClampMode
Glide.State.SClampMode = -1;
Glide.State.TClampMode = -1;
// grTexMipMapMode
Glide.State.MipMapMode = -1;
Glide.State.LodBlend = -1;
// grCullMode
Glide.State.CullMode = -1;
// grDepthMask
Glide.State.DepthBufferWritting = -1;
// grDepthBufferMode
Glide.State.DepthBufferMode = -1;
// grChromakeyValue
Glide.State.ChromakeyValue = -1;
// grAlphaTestReferenceValue
Glide.State.AlphaReferenceValue = -1.0f;
// grDepthBiasLevel
Glide.State.DepthBiasLevel = -1;
// grFogMode
Glide.State.FogMode = -1;
// grFogColorValue
Glide.State.FogColorValue = -1;
// grHints
Glide.State.STWHint = -1;
// color combine
Glide.State.ColorCombineFunction = GR_COMBINE_FUNCTION_LOCAL;
Glide.State.ColorCombineFactor = GR_COMBINE_FACTOR_LOCAL;
Glide.State.ColorCombineLocal = GR_COMBINE_LOCAL_CONSTANT;
Glide.State.ColorCombineOther = GR_COMBINE_OTHER_CONSTANT;
Glide.State.ColorCombineInvert = FXTRUE;
// alpha combine
Glide.State.AlphaFunction = GR_COMBINE_FUNCTION_LOCAL;
Glide.State.AlphaFactor = GR_COMBINE_FACTOR_LOCAL;
Glide.State.AlphaLocal = GR_COMBINE_LOCAL_CONSTANT;
Glide.State.AlphaOther = GR_COMBINE_OTHER_CONSTANT;
Glide.State.AlphaInvert = FXTRUE;
// Blend
Glide.State.AlphaBlendRgbSf = -1;
Glide.State.AlphaBlendRgbDf = -1;
Glide.State.AlphaBlendAlphaSf = -1;
Glide.State.AlphaBlendAlphaDf = -1;
// tex combine
Glide.State.TextureCombineCFunction = GR_COMBINE_FUNCTION_ZERO;
Glide.State.TextureCombineCFactor = GR_COMBINE_FACTOR_NONE;
Glide.State.TextureCombineAFunction = GR_COMBINE_FUNCTION_ZERO;
Glide.State.TextureCombineAFactor = GR_COMBINE_FACTOR_NONE;
Glide.State.TextureCombineRGBInvert = FXFALSE;
Glide.State.TextureCombineAInvert = FXFALSE;
// Alpha function
Glide.State.AlphaTestFunction = -1;
Glide.State.AlphaOther = -1;
// Chromakeying
Glide.State.ChromaKeyMode = GR_CHROMAKEY_ENABLE;
Glide.State.ChromakeyValue = 0xffffffff;
// constant color value
Glide.State.ConstantColorValue = 0;
// lod bias
Glide.State.LodBias = -1;
#endif
Glide.State.OriginInformation = org_loc;
grClipWindow( 0, 0, Glide.WindowWidth, Glide.WindowHeight );
grSstOrigin( org_loc );
grTexClampMode( 0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP );
grTexMipMapMode( 0, GR_MIPMAP_DISABLE, FXFALSE );
grTexFilterMode( 0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR );
grFogMode( GR_FOG_DISABLE );
grCullMode( GR_CULL_DISABLE );
grRenderBuffer( GR_BUFFER_BACKBUFFER );
grAlphaTestFunction( GR_CMP_ALWAYS );
grDitherMode( GR_DITHER_4x4 );
// grColorCombine depends on grAlphaCombine,
// so we have to call grAlphaCombine first
grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_NONE,
GR_COMBINE_OTHER_CONSTANT,
FXFALSE );
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_ITERATED,
GR_COMBINE_OTHER_ITERATED,
FXFALSE );
grTexCombine( GR_TMU0,GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE );
grAlphaControlsITRGBLighting( FXFALSE );
grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO );
grColorMask( FXTRUE, FXFALSE );
grDepthMask( FXFALSE );
grDepthBufferMode( GR_DEPTHBUFFER_DISABLE );
grDepthBufferFunction( GR_CMP_LESS );
// chroma-key value, alpha test reference, constant depth value,
// constant alpha value, etc.) and pixel rendering statistic counters
// are initialized to 0x00.
grChromakeyMode( GR_CHROMAKEY_DISABLE );
grChromakeyValue( 0x00 );
grAlphaTestReferenceValue( 0x00 );
grDepthBiasLevel( 0x00 );
grFogColorValue( 0x00 );
grConstantColorValue( 0xFFFFFFFF );
grGammaCorrectionValue( 1.6f );
grHints( GR_HINT_STWHINT, 0 );
grTexLodBiasValue(GR_TMU0, 0.0f);
#ifdef OGL_DONE
GlideMsg( "----End of grSstWinOpen()\n" );
#endif
OpenGL.WinOpen = true;
glFinish( );
// Show the splash screen? (code copied from the linux driver src)
if (UserConfig.NoSplash == false)
{
// Obsolete because state is preserved in grSplash
// GrState state;
// grGlideGetState(&state);
// @todo: There seem to be several versions of the splash screen
/*
#if (GLIDE_PLATFORM & GLIDE_OS_WIN32)
grSstOrigin( GR_ORIGIN_LOWER_LEFT );
if (!_GlideRoot.environment.noSplash) {
HMODULE newSplash;
if (newSplash = LoadLibrary("3dfxsplash2.dll")) {
FARPROC fxSplash;
if (fxSplash = GetProcAddress(newSplash, "_fxSplash@16")) {
fxSplash(hWnd, gc->state.screen_width,
gc->state.screen_height, nAuxBuffers);
// _GlideRoot.environment.noSplash = 1;
UserConfig.NoSplash = true;
}
}
}
#endif // (GLIDE_PLATFORM & GLIDE_OS_WIN32)
*/
/* If it's still 0, then do the old one */
if (UserConfig.NoSplash == false)
{
grSplash(0.0f, 0.0f,
static_cast<float>(Glide.WindowWidth),
static_cast<float>(Glide.WindowHeight),
0);
// The splash screen is displayed once, and because the
// internal config is reinitialised each time grWinOpen()
// is called, the value must be reset in the user config
UserConfig.NoSplash = true;
}
// grGlideSetState(&state);
}
return FXTRUE;
}
//*************************************************
//* Close the graphics display device
//*************************************************
FX_ENTRY void FX_CALL
grSstWinClose( void )
{
#ifdef OGL_DONE
GlideMsg( "grSstWinClose()\n" );
#endif
if ( ! OpenGL.WinOpen )
{
return;
}
OpenGL.WinOpen = false;
#ifdef OGL_DEBUG
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg( "** Debug Information **\n" );
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg( "MaxTriangles in Frame = %d\n", OGLRender.MaxTriangles );
GlideMsg( "MaxTriangles in Sequence = %d\n", OGLRender.MaxSequencedTriangles );
GlideMsg( "Mean value of Triangles in Sequence = %g\n",
static_cast<float>(OGLRender.OverallTriangles) / static_cast<float>(OGLRender.OverallRenderTriangleCalls));
GlideMsg( "Overall triangles = %d\n", OGLRender.OverallTriangles);
GlideMsg( "Overall lines = %d\n", OGLRender.OverallLines);
GlideMsg( "Overall points = %d\n", OGLRender.OverallPoints);
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg( "MaxZ = %f\nMinZ = %f\n", OGLRender.MaxZ, OGLRender.MinZ );
GlideMsg( "MaxX = %f\nMinX = %f\nMaxY = %f\nMinY = %f\n",
OGLRender.MaxX, OGLRender.MinX, OGLRender.MaxY, OGLRender.MinY );
GlideMsg( "MaxS = %f\nMinS = %f\nMaxT = %f\nMinT = %f\n",
OGLRender.MaxS, OGLRender.MinS, OGLRender.MaxT, OGLRender.MinT );
GlideMsg( "MaxF = %f\nMinF = %f\n", OGLRender.MaxF, OGLRender.MinF );
GlideMsg( "MaxR = %f\nMinR = %f\n", OGLRender.MaxR, OGLRender.MinR );
GlideMsg( "MaxG = %f\nMinG = %f\n", OGLRender.MaxG, OGLRender.MinG );
GlideMsg( "MaxB = %f\nMinB = %f\n", OGLRender.MaxB, OGLRender.MinR );
GlideMsg( "MaxA = %f\nMinA = %f\n", OGLRender.MaxA, OGLRender.MinA );
GlideMsg( OGL_LOG_SEPARATE );
GlideMsg( "Texture Information:\n" );
GlideMsg( " 565 = %d\n", Textures->Num_565_Tex );
GlideMsg( " c565 = %d\n", Textures->Num_565_Chromakey_Tex );
GlideMsg( " 1555 = %d\n", Textures->Num_1555_Tex );
GlideMsg( "c1555 = %d\n", Textures->Num_1555_Chromakey_Tex );
GlideMsg( " 4444 = %d\n", Textures->Num_4444_Tex );
GlideMsg( "c4444 = %d\n", Textures->Num_4444_Chromakey_Tex );
GlideMsg( " 332 = %d\n", Textures->Num_332_Tex );
GlideMsg( " 8332 = %d\n", Textures->Num_8332_Tex );
GlideMsg( "Alpha = %d\n", Textures->Num_Alpha_Tex );
GlideMsg( " AI88 = %d\n", Textures->Num_AlphaIntensity88_Tex );
GlideMsg( " AI44 = %d\n", Textures->Num_AlphaIntensity44_Tex );
GlideMsg( " AP88 = %d\n", Textures->Num_AlphaPalette_Tex );
GlideMsg( " P8 = %d\n", Textures->Num_Palette_Tex );
GlideMsg( " cP8 = %d\n", Textures->Num_Palette_Chromakey_Tex );
GlideMsg( "Inten = %d\n", Textures->Num_Intensity_Tex );
GlideMsg( " YIQ = %d\n", Textures->Num_YIQ_Tex );
GlideMsg( " AYIQ = %d\n", Textures->Num_AYIQ_Tex );
GlideMsg( "Other = %d\n", Textures->Num_Other_Tex );
GlideMsg( OGL_LOG_SEPARATE );
#endif
if (s_GlideApplication.GetType() == GlideApplication::FutureCop)
{
// Store the read buffer for read out after the window has been closed
// (needed by FutureCop LAPD)
// @todo: writemode, buffer and origin are hardwired,
// so this might not work for other games
#ifdef OGL_DEBUG
GlideMsg("----MacGLide readbuffer copy----\n");
#endif
GrLfbInfo_t lfbinfo;
if (grLfbLock(GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER, GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &lfbinfo))
{
grLfbUnlock(GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER);
}
#ifdef OGL_DEBUG
GlideMsg(OGL_LOG_SEPARATE);
#endif
}
Textures->Clear();
GLExtensionsCleanup();
RenderFree();
FinaliseOpenGLWindow();
FreeFrameBuffer(Glide.FrameBuffer.Address);
Glide.FrameBuffer.Address = NULL;
Glide.TempBuffer.Address = NULL;
// Freeing the readbuffer is be deferred until
// reopening the window or unloading the library
}
//*************************************************
//* Returns the Hardware Configuration
//*************************************************
FX_ENTRY FxBool FX_CALL
grSstQueryHardware( GrHwConfiguration *hwconfig )
{
#ifdef OGL_DONE
GlideMsg( "grSstQueryHardware( --- )\n" );
#endif
hwconfig->num_sst = 1;
hwconfig->SSTs[0].type = UserConfig.BoardType;
switch (hwconfig->SSTs[0].type)
{
case GR_SSTTYPE_VOODOO:
hwconfig->SSTs[0].sstBoard.VoodooConfig.fbRam = UserConfig.FrameBufferMemorySize;
// GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS and GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS
// modes are not available in revision 1 of the Pixelfx chip
hwconfig->SSTs[0].sstBoard.VoodooConfig.fbiRev = 2;
hwconfig->SSTs[0].sstBoard.VoodooConfig.nTexelfx = UserConfig.GlideTextureUnits;
hwconfig->SSTs[0].sstBoard.VoodooConfig.sliDetect = FXFALSE;
for(int tmu = 0; tmu < UserConfig.GlideTextureUnits; tmu++)
{
hwconfig->SSTs[tmu].sstBoard.VoodooConfig.tmuConfig[0].tmuRev = 1;
hwconfig->SSTs[tmu].sstBoard.VoodooConfig.tmuConfig[0].tmuRam = UserConfig.TextureMemorySize;
}
break;
case GR_SSTTYPE_SST96:
hwconfig->SSTs[0].sstBoard.SST96Config.fbRam = UserConfig.FrameBufferMemorySize;
hwconfig->SSTs[0].sstBoard.SST96Config.nTexelfx = UserConfig.GlideTextureUnits;
hwconfig->SSTs[0].sstBoard.SST96Config.tmuConfig.tmuRev = 1;
hwconfig->SSTs[0].sstBoard.SST96Config.tmuConfig.tmuRam = UserConfig.TextureMemorySize;
break;
case GR_SSTTYPE_AT3D:
hwconfig->SSTs[0].sstBoard.AT3DConfig.rev = 1; // whatsoever
break;
case GR_SSTTYPE_Voodoo2:
hwconfig->SSTs[0].sstBoard.Voodoo2Config.fbRam = UserConfig.FrameBufferMemorySize;
// GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS and GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS
// modes are not available in revision 1 of the Pixelfx chip
hwconfig->SSTs[0].sstBoard.Voodoo2Config.fbiRev = 2;
hwconfig->SSTs[0].sstBoard.Voodoo2Config.nTexelfx = UserConfig.GlideTextureUnits;
hwconfig->SSTs[0].sstBoard.Voodoo2Config.sliDetect = FXFALSE;
for(int tmu = 0; tmu < UserConfig.GlideTextureUnits; tmu++)
{
hwconfig->SSTs[tmu].sstBoard.Voodoo2Config.tmuConfig[0].tmuRev = 1;
hwconfig->SSTs[tmu].sstBoard.Voodoo2Config.tmuConfig[0].tmuRam = UserConfig.TextureMemorySize;
}
break;
}
return FXTRUE;
}
//*************************************************
//* Selects which Voodoo Board is Active
//*************************************************
FX_ENTRY void FX_CALL
grSstSelect( int which_sst )
{
#ifdef OGL_DONE
GlideMsg( "grSstSelect( %d )\n", which_sst );
#endif
// Nothing Needed Here but...
Glide.ActiveVoodoo = which_sst;
}
//*************************************************
//* Returns the Screen Height
//*************************************************
FX_ENTRY FxU32 FX_CALL
grSstScreenHeight( void )
{
#ifdef OGL_DONE
GlideMsg( "grSstScreenHeight()\n" );
#endif
return Glide.WindowHeight;
}
//*************************************************
//* Returns the Screen Width
//*************************************************
FX_ENTRY FxU32 FX_CALL
grSstScreenWidth( void )
{
#ifdef OGL_DONE
GlideMsg( "grSstScreenWidth()\n" );
#endif
return Glide.WindowWidth;
}
//*************************************************
//* Sets the Y Origin
//*************************************************
FX_ENTRY void FX_CALL
grSstOrigin( GrOriginLocation_t origin )
{
#ifdef OGL_DONE
GlideMsg( "grSstSetOrigin( %d )\n", origin );
#endif
glReportErrors("grSstOrigin");
RenderDrawTriangles( );
Glide.State.OriginInformation = origin;
glMatrixMode( GL_PROJECTION );
glReportError();
glLoadIdentity( );
glReportError();
switch ( origin )
{
case GR_ORIGIN_LOWER_LEFT:
glOrtho(Glide.State.ClipMinX, Glide.State.ClipMaxX,
Glide.State.ClipMinY, Glide.State.ClipMaxY,
OpenGL.ZNear, OpenGL.ZFar);
glReportError();
glViewport(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.ClipMinY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
glReportError();
glScissor(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.ClipMinY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
glReportError();
break;
case GR_ORIGIN_UPPER_LEFT:
glOrtho(Glide.State.ClipMinX, Glide.State.ClipMaxX,
Glide.State.ClipMaxY, Glide.State.ClipMinY,
OpenGL.ZNear, OpenGL.ZFar);
glReportError();
glViewport(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.WindowHeight - OpenGL.ClipMaxY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
glReportError();
glScissor(OpenGL.OriginX + OpenGL.ClipMinX,
OpenGL.OriginY + OpenGL.WindowHeight - OpenGL.ClipMaxY,
OpenGL.ClipMaxX - OpenGL.ClipMinX,
OpenGL.ClipMaxY - OpenGL.ClipMinY);
glReportError();
break;
}
glMatrixMode( GL_MODELVIEW );
glReportError();
grCullMode( Glide.State.CullMode );
}
//*************************************************
FX_ENTRY void FX_CALL
grSstPerfStats( GrSstPerfStats_t * pStats )
{
#ifdef OGL_NOTDONE
GlideMsg( "grSstPerfStats\n" );
#endif
}
//*************************************************
FX_ENTRY void FX_CALL
grSstResetPerfStats( void )
{
#ifdef OGL_NOTDONE
GlideMsg( "grSstResetPerfStats( )\n" );
#endif
}
//*************************************************
FX_ENTRY FxU32 FX_CALL
grSstVideoLine( void )
{
#ifdef OGL_NOTDONE
GlideMsg( "grSstVideoLine( )\n" );
#endif
return 0;
}
//*************************************************
FX_ENTRY FxBool FX_CALL
grSstVRetraceOn( void )
{
#ifdef OGL_NOTDONE
GlideMsg( "grSstVRetraceOn( )\n" );
#endif
return Glide.State.VRetrace;
}
//*************************************************
FX_ENTRY FxBool FX_CALL
grSstIsBusy( void )
{
#ifdef OGL_NOTDONE
GlideMsg( "grSstIsBusy( )\n" );
#endif
return FXFALSE;
}
//*************************************************
FX_ENTRY FxBool FX_CALL
grSstControl( GrControl_t code )
{
#ifdef OGL_PARTDONE
GlideMsg( "grSstControl( %lu )\n", code );
#endif
if (code == GR_CONTROL_ACTIVATE)
{
RestoreOpenGLWindow();
}
else if (code == GR_CONTROL_DEACTIVATE)
{
HideOpenGLWindow();
}
else if (code == GR_CONTROL_RESIZE)
{
}
else if (code == GR_CONTROL_MOVE)
{
}
return code;
}
//*************************************************
FX_ENTRY FxBool FX_CALL
grSstControlMode( GrControl_t mode )
{
#ifdef OGL_PARTDONE
GlideMsg( "grSstControlMode( %d )\n", mode );
#endif
switch ( mode )
{
case GR_CONTROL_ACTIVATE:
RestoreOpenGLWindow();
break;
case GR_CONTROL_DEACTIVATE:
HideOpenGLWindow();
break;
case GR_CONTROL_RESIZE:
case GR_CONTROL_MOVE:
break;
}
return FXTRUE;
}
//*************************************************
//* Return the Value of the graphics status register
//*************************************************
FX_ENTRY FxU32 FX_CALL
grSstStatus( void )
{
#ifdef OGL_PARTDONE
GlideMsg( "grSstStatus( )\n" );
#endif
// FxU32 Status = 0x0FFFF43F;
FxU32 Status = 0x0FFFF03F;
// Vertical Retrace
Status |= ( ! Glide.State.VRetrace ) << 6;
return Status;
// Bits
// 5:0 PCI FIFO free space (0x3F = free)
// 6 Vertical Retrace ( 0 = active, 1 = inactive )
// 7 PixelFx engine busy ( 0 = engine idle )
// 8 TMU busy ( 0 = engine idle )
// 9 Voodoo Graphics busy ( 0 = idle )
// 11:10 Displayed buffer ( 0 = buffer 0, 1 = buffer 1, 2 = auxiliary buffer, 3 = reserved )
// 27:12 Memory FIFO ( 0xFFFF = FIFO empty )
// 30:28 Number of swap buffers commands pending
// 31 PCI interrupt generated ( not implemented )
}
//*************************************************
//* Returns when Glides is Idle
//*************************************************
FX_ENTRY void FX_CALL
grSstIdle( void )
{
#ifdef OGL_DONE
GlideMsg( "grSetIdle( )\n" );
#endif
glReportErrors("grSetIdle");
RenderDrawTriangles( );
glFlush( );
glFinish( );
glReportError();
}

View File

@ -0,0 +1,27 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Sst Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#ifndef GRGUSSTGLIDE_H_
#define GRGUSSTGLIDE_H_
// functions not defined in the SDK but part of either
// - earlier versions of Glide 2.4
// - Part of the GLide 3 interface
#ifdef __cplusplus
extern "C" {
#endif
FX_ENTRY FxBool FX_CALL grSstControlMode(GrControl_t mode);
#ifdef __cplusplus
}
#endif
#endif /*GRGUSSTGLIDE_H_*/

View File

@ -0,0 +1,849 @@
//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* Glide Texture Functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "GlideSettings.h"
#include "GLextensions.h"
#include "GLRender.h"
#include "GLRenderUpdateState.h"
#include "PGTexture.h"
#include "PGUTexture.h"
// Functions
//*************************************************
//* Return the lowest start address for texture downloads
//*************************************************
FX_ENTRY FxU32 FX_CALL
grTexMinAddress( GrChipID_t tmu )
{
#ifdef OGL_DONE
GlideMsg( "grTexMinAddress( %d ) = 0\n", tmu );
#endif
return (FxU32) 0;
}
//*************************************************
//* Return the highest start address for texture downloads
//*************************************************
FX_ENTRY FxU32 FX_CALL
grTexMaxAddress( GrChipID_t tmu )
{
#ifdef OGL_DONE
GlideMsg( "grTexMaxAddress( %d ) = %lu\n", tmu, Glide.TexMemoryMaxPosition );
#endif
return (FxU32)( Glide.TexMemoryMaxPosition );
}
//*************************************************
//* Specify the current texture source for rendering
//*************************************************
FX_ENTRY void FX_CALL
grTexSource( GrChipID_t tmu,
FxU32 startAddress,
FxU32 evenOdd,
GrTexInfo *info )
{
#ifdef OPTIMISE_GLIDE_STATE_CHANGES
const GrTexInfo* current = Textures->GetCurrentTexInfo();
#endif
CHECK_STATE_CHANGED(Glide.State.TexSource.StartAddress == startAddress &&
Glide.State.TexSource.EvenOdd == evenOdd &&
current->aspectRatio == info->aspectRatio &&
current->format == info->format &&
current->largeLod == info->largeLod &&
current->smallLod == info->smallLod);
#ifdef OGL_PARTDONE
GlideMsg("grTexSource( %d, 0x%x, 0x%x, (%u, %u, ar=%u, fmt=%u) )\n",
tmu, startAddress, evenOdd,
info->smallLod, info->largeLod, info->aspectRatio, info->format);
#endif
// We're emulating tmu0 only
if ( tmu != GR_TMU0 )
{
return;
}
#ifdef OGL_DEBUG
if((startAddress & 7 ) != 0 || startAddress < 0 || startAddress > Glide.TexMemoryMaxPosition)
{
if (startAddress != GR_NULL_MIPMAP_HANDLE)
{
GlideMsg("Warning: grTexSource(%d, %d, %d, xxx) invalid startAddress\n", tmu, startAddress, evenOdd);
}
}
#endif
RenderDrawTriangles();
Glide.State.TexSource.StartAddress = startAddress;
Glide.State.TexSource.EvenOdd = evenOdd;
Textures->Source( startAddress, evenOdd, info );
}
//*************************************************
//* Return the texture memory consumed by a texture
//*************************************************
FX_ENTRY FxU32 FX_CALL
grTexTextureMemRequired( FxU32 dwEvenOdd, GrTexInfo *texInfo )
{
#ifdef OGL_DONE
GlideMsg( "grTexTextureMemRequired( %u, --- )\n", dwEvenOdd );
#endif
return Textures->TextureMemRequired( dwEvenOdd, texInfo );
}
//*************************************************
//* Return the texture memory consumed by a texture
//*************************************************
FX_ENTRY void FX_CALL
grTexDownloadMipMap( GrChipID_t tmu,
FxU32 startAddress,
FxU32 evenOdd,
GrTexInfo *info )
{
#ifdef OGL_PARTDONE
GlideMsg( "grTexDownloadMipMap(%d, 0x%x, 0x%x, (%u, %u, ar=%u, fmt=%u) )\n",
tmu, startAddress, evenOdd,
info->smallLod, info->largeLod, info->aspectRatio, info->format);
#endif
if ( tmu != GR_TMU0 )
{
return;
}
RenderDrawTriangles( );
info->smallLod = info->largeLod;
Textures->DownloadMipMap( startAddress, evenOdd, info );
}
//*************************************************
FX_ENTRY void FX_CALL
grTexDownloadMipMapLevel( GrChipID_t tmu,
FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
void *data )
{
#ifdef OGL_PARTDONE
GlideMsg( "grTexDownloadMipMapLevel( %d, 0x%x, %d, %d, %d, %d, 0x%x, --- )\n",
tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd );
#endif
if ( ( tmu != GR_TMU0 ) || ( thisLod != largeLod ) )
{
return;
}
Textures->DownloadMipMapLevel(startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data);
}
//*************************************************
FX_ENTRY void FX_CALL
grTexDownloadMipMapLevelPartial( GrChipID_t tmu,
FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
void *data,
int start,
int end )
{
#ifdef OGL_PARTDONE
GlideMsg( "grTexDownloadMipMapLevelPartial( %d, 0x%x, %d, %d, %d, fmt=%d, 0x%x, ---, %d, %d )\n",
tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, start, end );
#endif
if ( ( tmu != GR_TMU0 ) || ( thisLod != largeLod ) )
{
return;
}
Textures->DownloadMipMapLevelPartial(startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data, start, end);
}
//*************************************************
//* Set the texture map clamping/wrapping mode
//*************************************************
FX_ENTRY void FX_CALL
grTexClampMode( GrChipID_t tmu,
GrTextureClampMode_t s_clampmode,
GrTextureClampMode_t t_clampmode )
{
CHECK_STATE_CHANGED( Glide.State.SClampMode == s_clampmode
&& Glide.State.TClampMode == t_clampmode);
#ifdef OGL_DONE
GlideMsg( "grTexClampMode( %d, %d, %d )\n",
tmu, s_clampmode, t_clampmode );
#endif
if ( tmu != GR_TMU0 )
{
return;
}
RenderDrawTriangles( );
Glide.State.SClampMode = s_clampmode;
Glide.State.TClampMode = t_clampmode;
switch ( s_clampmode )
{
case GR_TEXTURECLAMP_CLAMP: OpenGL.SClampMode = InternalConfig.EXT_SGIS_texture_edge_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; break;
case GR_TEXTURECLAMP_WRAP: OpenGL.SClampMode = GL_REPEAT; break;
}
switch ( t_clampmode )
{
case GR_TEXTURECLAMP_CLAMP: OpenGL.TClampMode = InternalConfig.EXT_SGIS_texture_edge_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; break;
case GR_TEXTURECLAMP_WRAP: OpenGL.TClampMode = GL_REPEAT; break;
}
}
void grTexFilterMode_update(GrChipID_t tmu,
GrTextureFilterMode_t minfilter_mode,
GrTextureFilterMode_t magfilter_mode)
{
if ( tmu != GR_TMU0 )
{
return;
}
RenderDrawTriangles( );
Glide.State.MinFilterMode = minfilter_mode;
Glide.State.MagFilterMode = magfilter_mode;
// At least on Rage 128 OpenGL Engine 1.1.ATI-5.99, GL_NEAREST_MIPMAP_LINEAR
// and GL_NEAREST_MIPMAP_NEAREST seem to cause textures to not be displayed
// As a result, mipmaps are only available on renderers with EXT_SGIS_generate_mipmap
FxBool mipmapmode = InternalConfig.Mipmapping; // && InternalConfig.EXT_SGIS_generate_mipmap;
switch ( minfilter_mode )
{
case GR_TEXTUREFILTER_POINT_SAMPLED:
if ( ( Glide.State.MipMapMode != GR_MIPMAP_DISABLE ) && mipmapmode)
{
if ( Glide.State.LodBlend )
{
OpenGL.MinFilterMode = GL_NEAREST_MIPMAP_LINEAR;
}
else
{
OpenGL.MinFilterMode = GL_NEAREST_MIPMAP_NEAREST;
}
}
else
{
OpenGL.MinFilterMode = GL_NEAREST;
}
break;
case GR_TEXTUREFILTER_BILINEAR:
if (mipmapmode)
{
if ( Glide.State.LodBlend )
{
OpenGL.MinFilterMode = GL_LINEAR_MIPMAP_LINEAR;
}
else
{
OpenGL.MinFilterMode = GL_LINEAR_MIPMAP_NEAREST;
}
}
else
{
OpenGL.MinFilterMode = GL_LINEAR;
}
break;
}
switch ( magfilter_mode )
{
case GR_TEXTUREFILTER_POINT_SAMPLED:
OpenGL.MagFilterMode = GL_NEAREST;
break;
case GR_TEXTUREFILTER_BILINEAR:
OpenGL.MagFilterMode = GL_LINEAR;
break;
}
}
//*************************************************
//* Set the texture Min/Mag Filter
//*************************************************
FX_ENTRY void FX_CALL
grTexFilterMode( GrChipID_t tmu,
GrTextureFilterMode_t minfilter_mode,
GrTextureFilterMode_t magfilter_mode)
{
if (InternalConfig.TextureSmoothing) return;
CHECK_STATE_CHANGED(Glide.State.MinFilterMode == minfilter_mode
&& Glide.State.MagFilterMode == magfilter_mode);
#ifdef OGL_PARTDONE
GlideMsg("grTexFilterMode( %d, %d, %d )\n",
tmu, minfilter_mode, magfilter_mode);
#endif
grTexFilterMode_update(tmu, minfilter_mode, magfilter_mode);
}
//*************************************************
//* Set the texture MipMap Mode
//*************************************************
FX_ENTRY void FX_CALL
grTexMipMapMode( GrChipID_t tmu,
GrMipMapMode_t mode,
FxBool lodBlend )
{
if (InternalConfig.TextureSmoothing) return;
CHECK_STATE_CHANGED(Glide.State.MipMapMode == mode
&& Glide.State.LodBlend == lodBlend);
#ifdef OGL_PARTDONE
GlideMsg("grTexMipMapMode( %d, %d, %d )\n",
tmu, mode, lodBlend );
#endif
if ( tmu != GR_TMU0 )
{
return;
}
Glide.State.MipMapMode = mode;
Glide.State.LodBlend = lodBlend;
grTexFilterMode_update(tmu,
Glide.State.MinFilterMode,
Glide.State.MagFilterMode);
}
//*************************************************
//* Returns the memory occupied by a texture
//*************************************************
FX_ENTRY FxU32 FX_CALL
grTexCalcMemRequired( GrLOD_t lodmin, GrLOD_t lodmax,
GrAspectRatio_t aspect, GrTextureFormat_t fmt )
{
#ifdef OGL_DONE
GlideMsg( "grTexCalcMemRequired( %d, %d, %d, %d )\n",
lodmin, lodmax, aspect, fmt );
#endif
static GrTexInfo texInfo;
texInfo.aspectRatio = aspect;
texInfo.format = fmt;
texInfo.largeLod = lodmax;
texInfo.smallLod = lodmin;
return Textures->TextureMemRequired( 0, &texInfo );
}
//*************************************************
//* Download a subset of an NCC table or color palette
//*************************************************
FX_ENTRY void FX_CALL
grTexDownloadTablePartial( GrChipID_t tmu,
GrTexTable_t type,
void *data,
int start,
int end )
{
#ifdef OGL_PARTDONE
GlideMsg( "grTexDownloadTablePartial( %d, %d, ---, %d, %d )\n",
tmu, type, start, end );
#endif
if ( tmu != GR_TMU0 )
{
return;
}
RenderDrawTriangles( );
Textures->DownloadTable( type, (FxU32*)data, start, end + 1 - start );
}
//*************************************************
//* download an NCC table or color palette
//*************************************************
FX_ENTRY void FX_CALL
grTexDownloadTable( GrChipID_t tmu,
GrTexTable_t type,
void *data )
{
#ifdef OGL_PARTDONE
GlideMsg( "grTexDownloadTable( %d, %d, --- )\n", tmu, type );
#endif
if ( tmu != GR_TMU0 )
{
return;
}
RenderDrawTriangles( );
Textures->DownloadTable( type, (FxU32*)data, 0, 256 );
}
//*************************************************
FX_ENTRY void FX_CALL
grTexLodBiasValue( GrChipID_t tmu, float bias )
{
glReportErrors("grTexLodBiasValue");
#ifdef OGL_NOTDONE
GlideMsg( "grTexLodBiasValue( %d, %d )\n", tmu, bias );
#endif
if (tmu != GR_TMU0)
{
return;
}
CHECK_STATE_CHANGED(bias == Glide.State.LodBias);
RenderDrawTriangles();
Glide.State.LodBias = bias;
if ( InternalConfig.EXT_texture_lod_bias )
{
if (OpenGL.ColorAlphaUnit2)
{
for(int unit_index = 1; unit_index >= 0; unit_index--)
{
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias);
}
}
else
{
glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias );
}
}
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
}
//*************************************************
FX_ENTRY void FX_CALL
grTexNCCTable( GrChipID_t tmu, GrNCCTable_t NCCTable )
{
#ifdef OGL_DONE
GlideMsg( "grTexNCCTable( %d, %u )\n", tmu, NCCTable );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
return;
}
RenderDrawTriangles();
Textures->NCCTable( NCCTable );
}
//*************************************************
FX_ENTRY void FX_CALL
grTexDetailControl( GrChipID_t tmu,
int lod_bias,
FxU8 detail_scale,
float detail_max )
{
// CHECK_STATE_CHANGED(...)
#ifdef OGL_NOTDONE
GlideMsg( "grTexDetailControl( %d, %d, %d, %-4.2f )\n",
tmu, lod_bias, detail_scale, detail_max );
#endif
}
//*************************************************
FX_ENTRY void FX_CALL
grTexMultibase( GrChipID_t tmu,
FxBool enable )
{
#ifdef OGL_NOTDONE
GlideMsg( "grTexMultibase( %d, %d )\n", tmu, enable );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
return;
}
}
//*************************************************
FX_ENTRY void FX_CALL
grTexMultibaseAddress( GrChipID_t tmu,
GrTexBaseRange_t range,
FxU32 startAddress,
FxU32 evenOdd,
GrTexInfo *info )
{
#ifdef OGL_NOTDONE
GlideMsg( "grTexMultibaseAddress( %d, %d, %lu, %lu, --- )\n",
tmu, range, startAddress, evenOdd );
#endif
}
//*************************************************
FX_ENTRY void FX_CALL
grTexCombine( GrChipID_t tmu,
GrCombineFunction_t rgb_function,
GrCombineFactor_t rgb_factor,
GrCombineFunction_t alpha_function,
GrCombineFactor_t alpha_factor,
FxBool rgb_invert,
FxBool alpha_invert )
{
CHECK_STATE_CHANGED( Glide.State.TextureCombineCFunction == rgb_function
&& Glide.State.TextureCombineCFactor == rgb_factor
&& Glide.State.TextureCombineAFunction == alpha_function
&& Glide.State.TextureCombineAFactor == alpha_factor
&& Glide.State.TextureCombineRGBInvert == rgb_invert
&& Glide.State.TextureCombineAInvert == alpha_invert);
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
GlideMsg( "grTexCombine( %d, %d, %d, %d, %d, %d, %d )\n",
tmu, rgb_function, rgb_factor, alpha_function, alpha_factor,
rgb_invert, alpha_invert );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
return;
}
RenderDrawTriangles( );
if (Glide.State.TextureCombineCFunction != rgb_function ||
Glide.State.TextureCombineCFactor != rgb_factor)
{
Glide.State.TextureCombineCFunction = rgb_function;
Glide.State.TextureCombineCFactor = rgb_factor;
SetColorTextureState();
SetTextureState();
}
if (Glide.State.TextureCombineAFunction != alpha_function ||
Glide.State.TextureCombineAFactor != alpha_factor)
{
Glide.State.TextureCombineAFunction = alpha_function;
Glide.State.TextureCombineAFactor = alpha_factor;
SetAlphaTextureState();
SetTextureState();
}
if (Glide.State.TextureCombineRGBInvert != rgb_invert)
{
Glide.State.TextureCombineRGBInvert = rgb_invert;
SetColorCombineState();
SetAlphaCombineState();
}
if (Glide.State.TextureCombineAInvert != alpha_invert)
{
Glide.State.TextureCombineAInvert = alpha_invert;
SetAlphaCombineState();
}
}
//*************************************************
FX_ENTRY void FX_CALL
grTexCombineFunction( GrChipID_t tmu, GrTextureCombineFnc_t func )
{
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
GlideMsg( "grTexCombineFunction( %d, %d )\n", tmu, func );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
return;
}
switch ( func )
{
case GR_TEXTURECOMBINE_ZERO: // 0x00 per component
grTexCombine( tmu, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO,
GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_DECAL: // Clocal decal texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_OTHER: // Cother pass through
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_ADD: // Cother + Clocal additive texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_MULTIPLY: // Cother * Clocal modulated texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_SUBTRACT: // Cother Clocal subtractive texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_ONE: // 255 0xFF per component
grTexCombine( tmu, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO,
GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO, FXTRUE, FXTRUE );
break;
// case GR_TEXTURECOMBINE_DETAIL: // blend (Cother, Clocal) detail textures with detail on selected TMU
// case GR_TEXTURECOMBINE_DETAIL_OTHER: // blend (Cother, Clocal) detail textures with detail on neighboring TMU
// case GR_TEXTURECOMBINE_TRILINEAR_ODD: // blend (Cother, Clocal) LOD blended textures with odd levels on selected TMU
// case GR_TEXTURECOMBINE_TRILINEAR_EVEN: // blend (Cother, Clocal) LOD blended textures with even levels on selected TMU
// break;
}
}
//*************************************************
//* Return the amount of unallocated texture memory on a Texture Mapping Unit
//*************************************************
FX_ENTRY FxU32 FX_CALL
guTexMemQueryAvail( GrChipID_t tmu )
{
#ifdef OGL_PARTDONE
GlideMsg( "guTexMemQueryAvail( %d ) = %u\n", tmu, UTextures.MemQueryAvail( tmu ) );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
return 0;
}
return UTextures.MemQueryAvail( tmu );
}
//*************************************************
FX_ENTRY void FX_CALL
guTexCombineFunction( GrChipID_t tmu, GrTextureCombineFnc_t func )
{
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
GlideMsg( "guTexCombineFunction( %d, %d )\n", tmu, func );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
return;
}
switch ( func )
{
case GR_TEXTURECOMBINE_ZERO: // 0x00 per component
grTexCombine( tmu, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO,
GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_DECAL: // Clocal decal texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_OTHER: // Cother pass through
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_ADD: // Cother + Clocal additive texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_MULTIPLY: // Cother * Clocal modulated texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_SUBTRACT: // Cother Clocal subtractive texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_ONE: // 255 0xFF per component
grTexCombine( tmu, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO,
GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO, FXTRUE, FXTRUE );
break;
// case GR_TEXTURECOMBINE_DETAIL: // blend (Cother, Clocal) detail textures with detail on selected TMU
// case GR_TEXTURECOMBINE_DETAIL_OTHER: // blend (Cother, Clocal) detail textures with detail on neighboring TMU
// case GR_TEXTURECOMBINE_TRILINEAR_ODD: // blend (Cother, Clocal) LOD blended textures with odd levels on selected TMU
// case GR_TEXTURECOMBINE_TRILINEAR_EVEN: // blend (Cother, Clocal) LOD blended textures with even levels on selected TMU
// break;
}
}
//*************************************************
FX_ENTRY GrMipMapId_t FX_CALL
guTexGetCurrentMipMap( GrChipID_t tmu )
{
#ifdef OGL_DONE
GlideMsg( "guTexGetCurrentMipMap( %d ) = %d\n", tmu, UTextures.GetCurrentMipMap( tmu ) );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
return GR_NULL_MIPMAP_HANDLE;
}
return UTextures.GetCurrentMipMap( tmu );
}
//*************************************************
FX_ENTRY FxBool FX_CALL
guTexChangeAttributes( GrMipMapId_t mmid,
int width, int height,
GrTextureFormat_t fmt,
GrMipMapMode_t mm_mode,
GrLOD_t smallest_lod, GrLOD_t largest_lod,
GrAspectRatio_t aspect,
GrTextureClampMode_t s_clamp_mode,
GrTextureClampMode_t t_clamp_mode,
GrTextureFilterMode_t minFilterMode,
GrTextureFilterMode_t magFilterMode )
{
#ifdef OGL_DONE
GlideMsg( "guTexChangeAttributes( %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d )\n",
mmid, width, height, fmt, mm_mode, smallest_lod, largest_lod, aspect,
s_clamp_mode, t_clamp_mode, minFilterMode, magFilterMode );
#endif
return UTextures.ChangeAttributes( mmid, width, height, fmt, mm_mode,
smallest_lod, largest_lod, aspect, s_clamp_mode, t_clamp_mode,
minFilterMode, magFilterMode );
}
//*************************************************
FX_ENTRY GrMipMapInfo * FX_CALL
guTexGetMipMapInfo( GrMipMapId_t mmid )
{
#ifdef OGL_DONE
GlideMsg( "guTexGetMipMapInfo( ) = 0x%p\n" );
#endif
return UTextures.GetMipMapInfo( mmid );
}
//*************************************************
FX_ENTRY void FX_CALL
guTexMemReset( void )
{
#ifdef OGL_PARTDONE
GlideMsg( "guTexMemReset( )\n" );
#endif
UTextures.MemReset( );
Textures->Clear( );
}
//*************************************************
FX_ENTRY void FX_CALL
guTexDownloadMipMapLevel( GrMipMapId_t mmid, GrLOD_t lod, const void **src )
{
#ifdef OGL_DONE
GlideMsg( "guTexDownloadMipMapLevel( %d, %d, 0x%p )\n", mmid, lod, src );
#endif
UTextures.DownloadMipMapLevel( mmid, lod, src );
}
//*************************************************
FX_ENTRY void FX_CALL
guTexDownloadMipMap( GrMipMapId_t mmid, const void *src, const GuNccTable *table )
{
#ifdef OGL_DONE
GlideMsg( "guTexDownloadMipMap( %d, 0x%p, 0x%p )\n", mmid, src, table );
#endif
UTextures.DownloadMipMap( mmid, src, table );
}
//*************************************************
FX_ENTRY GrMipMapId_t FX_CALL
guTexAllocateMemory( GrChipID_t tmu,
FxU8 odd_even_mask,
int width, int height,
GrTextureFormat_t fmt,
GrMipMapMode_t mm_mode,
GrLOD_t smallest_lod, GrLOD_t largest_lod,
GrAspectRatio_t aspect,
GrTextureClampMode_t s_clamp_mode,
GrTextureClampMode_t t_clamp_mode,
GrTextureFilterMode_t minfilter_mode,
GrTextureFilterMode_t magfilter_mode,
float lod_bias,
FxBool trilinear )
{
#ifdef OGL_DONE
GlideMsg( "guTexAllocateMemory( %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d )\n",
tmu, odd_even_mask, width, height, fmt, mm_mode, smallest_lod, largest_lod, aspect,
s_clamp_mode, t_clamp_mode, minfilter_mode, magfilter_mode, lod_bias, trilinear );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
return GR_NULL_MIPMAP_HANDLE;
}
return UTextures.AllocateMemory( tmu, odd_even_mask, width, height, fmt, mm_mode,
smallest_lod, largest_lod, aspect, s_clamp_mode, t_clamp_mode,
minfilter_mode, magfilter_mode, lod_bias, trilinear );
}
//*************************************************
FX_ENTRY void FX_CALL
guTexSource( GrMipMapId_t id )
{
// Works because the current id isn't changed in UTextures.Source
// when id is GR_NULL_MIPMAP_HANDLE (todo: this might be a bug)
CHECK_STATE_CHANGED(id == GR_NULL_MIPMAP_HANDLE || id == UTextures.GetCurrentID());
#ifdef OGL_DONE
GlideMsg( "guTexSource( %d )\n", id );
#endif
RenderDrawTriangles();
UTextures.Source( id );
}
//*************************************************
FX_ENTRY FxU16 * FX_CALL
guTexCreateColorMipMap( void )
{
#ifdef OGL_NOTDONE
GlideMsg( "guTexCreateColorMipMap( ) = NULL\n" );
#endif
return NULL;
}

View File

@ -0,0 +1,122 @@
/*
** Copyright (c) 1995, 3Dfx Interactive, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of 3Dfx Interactive, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
**
** $Revision: 1.2 $
** $Date: 2003/11/02 16:29:59 $
*/
#ifndef __3DFX_H__
#define __3DFX_H__
/*
** basic data types
*/
typedef unsigned char FxU8;
typedef signed char FxI8;
typedef unsigned short FxU16;
typedef signed short FxI16;
typedef signed long FxI32;
typedef unsigned long FxU32;
typedef int FxBool;
typedef float FxFloat;
typedef double FxDouble;
/*
** color types
*/
typedef unsigned long FxColor_t;
typedef struct { float r, g, b, a; } FxColor4;
/*
** fundamental types
*/
#define FXTRUE 1
#define FXFALSE 0
/*
** helper macros
*/
#define FXUNUSED( a ) ((void)(a))
#define FXBIT( i ) ( 1L << (i) )
/*
** export macros
*/
#if defined(CPPDLL)
#define DLLEXPORT extern "C" __declspec(dllexport)
# define FX_ENTRY DLLEXPORT
# define FX_CALL __stdcall
#elif defined(__MSC__)
# if defined (MSVC16)
# define FX_ENTRY
# define FX_CALL
# else
# define FX_ENTRY extern
# define FX_CALL __stdcall
# endif
#elif defined(__WATCOMC__)
# define FX_ENTRY extern
# define FX_CALL __stdcall
#elif defined (__IBMC__) || defined (__IBMCPP__)
/* IBM Visual Age C/C++: */
# define FX_ENTRY extern
# define FX_CALL __stdcall
#elif defined(__DJGPP__)
# define FX_ENTRY extern
# define FX_CALL
#elif defined(__unix__)
# define FX_ENTRY extern
# define FX_CALL
#elif defined(__MWERKS__)
# if macintosh
# define FX_ENTRY extern
# define FX_CALL
# else /* !macintosh */
# error "Unknown MetroWerks target platform"
# endif /* !macintosh */
#else
# warning define FX_ENTRY & FX_CALL for your compiler
# define FX_ENTRY extern
# define FX_CALL
#endif
/*
** x86 compiler specific stuff
*/
#if defined(__BORLANDC_)
# define REALMODE
# define REGW( a, b ) ((a).x.b)
# define REGB( a, b ) ((a).h.b)
# define INT86( a, b, c ) int86(a,b,c)
# define INT86X( a, b, c, d ) int86x(a,b,c,d)
# define RM_SEG( a ) FP_SEG( a )
# define RM_OFF( a ) FP_OFF( a )
#elif defined(__WATCOMC__)
# undef FP_SEG
# undef FP_OFF
# define REGW( a, b ) ((a).w.b)
# define REGB( a, b ) ((a).h.b)
# define INT86( a, b, c ) int386(a,b,c)
# define INT86X( a, b, c, d ) int386x(a,b,c,d)
# define RM_SEG( a ) ( ( ( ( FxU32 ) (a) ) & 0x000F0000 ) >> 4 )
# define RM_OFF( a ) ( ( FxU16 ) (a) )
#endif
#endif /* !__3DFX_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
/*
** Copyright (c) 1995, 3Dfx Interactive, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of 3Dfx Interactive, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
n** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
**
** $Header: /cvsroot/macglide/MacGLide/OpenGLide/sdk2_glidesys.h,v 1.2 2003/11/02 16:29:59 jens-olaf Exp $
** $Log: sdk2_glidesys.h,v $
** Revision 1.2 2003/11/02 16:29:59 jens-olaf
** Commented out code that has been copied to ../Mac/OpenGLide/
**
** Revision 1.1 2002/12/05 13:50:21 fbarros
** 3dfx sdk 2 header file
**
** Revision 1.1.1.1 2001/06/25 18:00:50 paul
** v006 from sourceforge
**
** Revision 1.1.1.1 2001/02/01 16:24:51 fbarros
** Version 0.06
**
** CVs: ----------------------------------------------------------------------
**
*/
#ifndef __GLIDESYS_H__
#define __GLIDESYS_H__
/*
n** -----------------------------------------------------------------------
** COMPILER/ENVIRONMENT CONFIGURATION
** -----------------------------------------------------------------------
*/
/* Endianness is stored in bits [30:31] */
#define GLIDE_ENDIAN_SHIFT 30
#define GLIDE_ENDIAN_LITTLE (0x1 << GLIDE_ENDIAN_SHIFT)
#define GLIDE_ENDIAN_BIG (0x2 << GLIDE_ENDIAN_SHIFT)
/* OS is stored in bits [0:6] */
#define GLIDE_OS_SHIFT 0
#define GLIDE_OS_UNIX 0x1
#define GLIDE_OS_DOS32 0x2
#define GLIDE_OS_WIN32 0x4
#define GLIDE_OS_SYSTEM7 0x8
#define GLIDE_OS_OS2 0x10
#define GLIDE_OS_OTHER 0x20 /* For Proprietary Arcade HW */
/* Sim vs. Hardware is stored in bits [7:8] */
#define GLIDE_SST_SHIFT 7
#define GLIDE_SST_SIM (0x1 << GLIDE_SST_SHIFT)
#define GLIDE_SST_HW (0x2 << GLIDE_SST_SHIFT )
/* Hardware Type is stored in bits [9:12] */
#define GLIDE_HW_SHIFT 9
#define GLIDE_HW_SST1 (0x1 << GLIDE_HW_SHIFT)
#define GLIDE_HW_SST96 (0x2 << GLIDE_HW_SHIFT)
#define GLIDE_HW_SSTH3 (0x4 << GLIDE_HW_SHIFT)
#define GLIDE_HW_SST2 (0x8 << GLIDE_HW_SHIFT)
/*
** Make sure we handle all instances of WIN32
*/
#ifndef __WIN32__
# if defined ( _WIN32 ) || defined (WIN32) || defined(__NT__)
# define __WIN32__
# endif
#endif
/* We need two checks on the OS: one for endian, the other for OS */
/* Check for endianness */
#if defined(__IRIX__) || defined(__sparc__) || defined(MACOS)
# define GLIDE_ENDIAN GLIDE_ENDIAN_BIG
#else
# define GLIDE_ENDIAN GLIDE_ENDIAN_LITTLE
#endif
/* Check for OS */
#if defined(__IRIX__) || defined(__sparc__) || defined(__linux__)
# define GLIDE_OS GLIDE_OS_UNIX
#elif defined(__DOS__)
# define GLIDE_OS GLIDE_OS_DOS32
#elif defined(__WIN32__)
# define GLIDE_OS GLIDE_OS_WIN32
#endif
/* Check for Simulator vs. Hardware */
#ifdef GLIDE_SIMULATOR
# define GLIDE_SST GLIDE_SST_SIM
#else
# define GLIDE_SST GLIDE_SST_HW
#endif
/* Check for type of hardware */
#ifdef SST96
# define GLIDE_HW GLIDE_HW_SST96
#elif defined(SSTH3)
# define GLIDE_HW GLIDE_HW_SSTH3
#elif defined(SST2)
# define GLIDE_HW GLIDE_HW_SST2
#else /* Default to SST1 */
# define GLIDE_HW GLIDE_HW_SST1
#endif
#define GLIDE_PLATFORM (GLIDE_ENDIAN | GLIDE_OS | GLIDE_SST | GLIDE_HW)
/*
** Control the number of TMUs
*/
#ifndef GLIDE_NUM_TMU
# define GLIDE_NUM_TMU 2
#endif
#if ( ( GLIDE_NUM_TMU < 0 ) && ( GLIDE_NUM_TMU > 3 ) )
# error "GLIDE_NUM_TMU set to an invalid value"
#endif
#endif /* __GLIDESYS_H__ */

View File

@ -0,0 +1,197 @@
/*
** Copyright (c) 1995, 3Dfx Interactive, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of 3Dfx Interactive, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
**
** $Header: /cvsroot/macglide/MacGLide/OpenGLide/sdk2_glideutl.h,v 1.2 2003/11/02 16:29:59 jens-olaf Exp $
** $Log: sdk2_glideutl.h,v $
** Revision 1.2 2003/11/02 16:29:59 jens-olaf
** Commented out code that has been copied to ../Mac/OpenGLide/
**
** Revision 1.1 2002/12/05 13:50:21 fbarros
** 3dfx sdk 2 header file
**
** Revision 1.1.1.1 2001/06/25 18:00:50 paul
** v006 from sourceforge
**
** Revision 1.1.1.1 2001/02/01 16:24:51 fbarros
** Version 0.06
**
** CVs: ----------------------------------------------------------------------
**
*
* 11 1/07/98 11:18a Atai
* remove GrMipMapInfo and GrGC.mm_table in glide3
*
* 10 1/06/98 6:47p Atai
* undo grSplash and remove gu routines
*
* 9 1/05/98 6:04p Atai
* move 3df gu related data structure from glide.h to glideutl.h
*
* 8 12/18/97 2:13p Peter
* fogTable cataclysm
*
* 7 12/15/97 5:52p Atai
* disable obsolete glide2 api for glide3
*
* 6 8/14/97 5:32p Pgj
* remove dead code per GMT
*
* 5 6/12/97 5:19p Pgj
* Fix bug 578
*
* 4 3/05/97 9:36p Jdt
* Removed guFbWriteRegion added guEncodeRLE16
*
* 3 1/16/97 3:45p Dow
* Embedded fn protos in ifndef FX_GLIDE_NO_FUNC_PROTO
*/
/* Glide Utility routines */
#ifndef __GLIDEUTL_H__
#define __GLIDEUTL_H__
#ifdef __cplusplus
extern "C" {
#endif
#if defined(GLIDE3) && defined(GLIDE3_ALPHA)
/*
** 3DF texture file structs
*/
typedef struct
{
FxU32 width, height;
int small_lod, large_lod;
GrAspectRatio_t aspect_ratio;
GrTextureFormat_t format;
} Gu3dfHeader;
typedef struct
{
FxU8 yRGB[16];
FxI16 iRGB[4][3];
FxI16 qRGB[4][3];
FxU32 packed_data[12];
} GuNccTable;
typedef struct {
FxU32 data[256];
} GuTexPalette;
typedef union {
GuNccTable nccTable;
GuTexPalette palette;
} GuTexTable;
typedef struct
{
Gu3dfHeader header;
GuTexTable table;
void *data;
FxU32 mem_required; /* memory required for mip map in bytes. */
} Gu3dfInfo;
#endif
#ifndef FX_GLIDE_NO_FUNC_PROTO
/*
** rendering functions
*/
#ifndef GLIDE3_ALPHA
FX_ENTRY void FX_CALL
guAADrawTriangleWithClip( const GrVertex *a, const GrVertex
*b, const GrVertex *c);
FX_ENTRY void FX_CALL
guDrawTriangleWithClip(
const GrVertex *a,
const GrVertex *b,
const GrVertex *c
);
FX_ENTRY void FX_CALL
guDrawPolygonVertexListWithClip( int nverts, const GrVertex vlist[] );
/*
** hi-level rendering utility functions
*/
FX_ENTRY void FX_CALL
guAlphaSource( GrAlphaSource_t mode );
FX_ENTRY void FX_CALL
guColorCombineFunction( GrColorCombineFnc_t fnc );
FX_ENTRY int FX_CALL
guEncodeRLE16( void *dst,
void *src,
FxU32 width,
FxU32 height );
FX_ENTRY FxU16 * FX_CALL
guTexCreateColorMipMap( void );
#endif /* !GLIDE3_ALPHA */
#ifdef GLIDE3
FX_ENTRY void FX_CALL
guGammaCorrectionRGB( FxFloat red, FxFloat green, FxFloat blue );
#endif
/*
** fog stuff
*/
FX_ENTRY float FX_CALL
guFogTableIndexToW( int i );
FX_ENTRY void FX_CALL
guFogGenerateExp( GrFog_t fogtable[], float density );
FX_ENTRY void FX_CALL
guFogGenerateExp2( GrFog_t fogtable[], float density );
FX_ENTRY void FX_CALL
guFogGenerateLinear(GrFog_t fogtable[],
float nearZ, float farZ );
/*
** endian stuff
*/
#ifndef GLIDE3_ALPHA
FX_ENTRY FxU32 FX_CALL
guEndianSwapWords( FxU32 value );
FX_ENTRY FxU16 FX_CALL
guEndianSwapBytes( FxU16 value );
#endif /* !GLIDE3_ALPHA */
/*
** hi-level texture manipulation tools.
*/
FX_ENTRY FxBool FX_CALL
gu3dfGetInfo( const char *filename, Gu3dfInfo *info );
FX_ENTRY FxBool FX_CALL
gu3dfLoad( const char *filename, Gu3dfInfo *data );
#endif /* FX_GLIDE_NO_FUNC_PROTO */
#ifdef __cplusplus
}
#endif
#endif /* __GLIDEUTL_H__ */

View File

@ -0,0 +1,120 @@
/*
** Copyright (c) 1995, 3Dfx Interactive, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of 3Dfx Interactive, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
**
** $Header: /cvsroot/macglide/MacGLide/OpenGLide/sdk2_sst1vid.h,v 1.2 2003/11/02 16:29:59 jens-olaf Exp $
** $Log: sdk2_sst1vid.h,v $
** Revision 1.2 2003/11/02 16:29:59 jens-olaf
** Commented out code that has been copied to ../Mac/OpenGLide/
**
** Revision 1.1 2002/12/05 13:50:21 fbarros
** 3dfx sdk 2 header file
**
** Revision 1.1.1.1 2001/06/25 18:00:49 paul
** v006 from sourceforge
**
** Revision 1.1.1.1 2001/02/01 16:24:51 fbarros
** Version 0.06
**
** CVs: ----------------------------------------------------------------------
**
*
* 4 9/09/97 7:35p Sellers
* Added 400x300 resolution
*
* 3 8/24/97 9:31a Sellers
* moved new video timing to sst1vid.h
* redefined 1600x1280 to be 1600x1200
*
* 2 6/05/97 11:14p Pgj
*
* 5 7/24/96 3:43p Sellers
* added 512x384 @ 60 Hz for arcade monitors
* added 512x256 @ 60 Hz for arcade monitors
*
* 4 7/18/96 10:58a Sellers
* fixed FT and TF clock delay values for lower frequencies with
* .5/.5 combos
*
* 3 6/18/96 6:54p Sellers
* added sst1InitShutdownSli() to fix Glide Splash screen problems with
* SLI
*
* 2 6/13/96 7:45p Sellers
* added "voodoo.ini" support
* added DirectX support
* misc cleanup
*
* 2 6/11/96 1:43p Sellers
* added support for 60, 75, 85, and 120 Hz refresh rates for "most"
* resolutions
*
* 1 5/08/96 5:43p Paik
* Video definitions
*/
#ifndef __SST1VID_H__
#define __SST1VID_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Video defines */
typedef FxI32 GrScreenRefresh_t;
#define GR_REFRESH_60Hz 0x0
#define GR_REFRESH_70Hz 0x1
#define GR_REFRESH_72Hz 0x2
#define GR_REFRESH_75Hz 0x3
#define GR_REFRESH_80Hz 0x4
#define GR_REFRESH_90Hz 0x5
#define GR_REFRESH_100Hz 0x6
#define GR_REFRESH_85Hz 0x7
#define GR_REFRESH_120Hz 0x8
#define GR_REFRESH_NONE 0xff
typedef FxI32 GrScreenResolution_t;
#define GR_RESOLUTION_320x200 0x0
#define GR_RESOLUTION_320x240 0x1
#define GR_RESOLUTION_400x256 0x2
#define GR_RESOLUTION_512x384 0x3
#define GR_RESOLUTION_640x200 0x4
#define GR_RESOLUTION_640x350 0x5
#define GR_RESOLUTION_640x400 0x6
#define GR_RESOLUTION_640x480 0x7
#define GR_RESOLUTION_800x600 0x8
#define GR_RESOLUTION_960x720 0x9
#define GR_RESOLUTION_856x480 0xa
#define GR_RESOLUTION_512x256 0xb
#define GR_RESOLUTION_1024x768 0xC
#define GR_RESOLUTION_1280x1024 0xD
#define GR_RESOLUTION_1600x1200 0xE
#define GR_RESOLUTION_400x300 0xF
#define GR_RESOLUTION_NONE 0xff
#ifdef GR_RESOLUTION_MAX
#undef GR_RESOLUTION_MAX
#endif
#ifdef GR_RESOLUTION_MIN
#undef GR_RESOLUTION_MIN
#endif
#define GR_RESOLUTION_MIN GR_RESOLUTION_320x200
#define GR_RESOLUTION_MAX GR_RESOLUTION_1600x1200
#ifdef __cplusplus
}
#endif
#endif /* __SST1VID_H__ */

View File

@ -0,0 +1,55 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* pre-glide22 buffer access interface
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "sst1.h"
// Called by Quake 1 3dfx on the Mac
// (resolves error message: sst1InitMapBoard nicht gefunden)
//
// See also: http://www.xlr8yourmac.com/feedback/voodoo2gen.html
// ¥ Quake 1.09.x does not work. A programmer friend of mine says
// this is because Quake makes a call to an obsolete Glide function
// (sstInitMapBoard or similar call) which I hear was purposefully
// left out of these relatively up-to-date Glide 2.x drivers ...
// Parameters from
// http://home.y3m.net/horde/chora/co.php/homeworld/src/rgl/glide3/include/sst1init3.h?sbt=3&ord=1&r=1.1.1.1
FX_ENTRY FxU32* FX_CALL sst1InitMapBoard(FxU32 param1)
{
#ifdef OGL_NOTDONE
GlideMsg("sst1InitMapBoard(%d)\n", param1);
#endif
return 0;
}
FX_ENTRY FxBool FX_CALL sst1InitGamma(FxU32* param1, double param2)
{
#ifdef OGL_NOTDONE
GlideMsg("sst1InitGamma(%d, %g)\n", param1, param2);
#endif
return FXTRUE;
}
FX_ENTRY FxBool FX_CALL grSstOpen(GrScreenResolution_t res,
GrScreenRefresh_t refresh,
GrColorFormat_t cFormat,
GrOriginLocation_t locateOrigin,
GrSmoothingMode_t smoothMode,
int numBuffers)
{
#ifdef OGL_DONE
GlideMsg("grSstOpen( %d, %d, %d, %d, %d, %d, %d)\n", res, refresh, cFormat, locateOrigin, smoothMode, numBuffers);
#endif
return grSstWinOpen( 0, res, refresh, cFormat, locateOrigin, numBuffers, 0);
}

35
MacGLide/OpenGLide/sst1.h Normal file
View File

@ -0,0 +1,35 @@
//**************************************************************
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
//* http://macglide.sourceforge.net/
//*
//* pre-glide24 sst1 functions
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#pragma once
#include "sdk2_3dfx.h"
#include "sdk2_glide.h"
// prototypes for obsolete sst1-board functions
#ifdef __cplusplus
extern "C" {
#endif
FX_ENTRY FxU32* FX_CALL sst1InitMapBoard(FxU32 param1);
FX_ENTRY FxBool FX_CALL sst1InitGamma(FxU32* param1, double param2);
FX_ENTRY FxBool FX_CALL grSstOpen(GrScreenResolution_t res,
GrScreenRefresh_t refresh,
GrColorFormat_t cFormat,
GrOriginLocation_t locateOrigin,
GrSmoothingMode_t smoothMode,
int numBuffers);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,5 @@
#pragma once
#include "Glide.h"
extern void _grShamelessPlug(void);

View File

@ -0,0 +1,22 @@
#pragma once
#ifndef _DRIVERSRC_DEFINES_H_
#define _DRIVERSRC_DEFINES_H_
#include "sdk2_glide.h"
#define GLIDE_PLUG
// #define GLIDE_PLATFORM
// #define GLIDE_HW_SST1
// #define GLIDE_HW_SST96
#define GR_BEGIN_NOFIFOCHECK(x,y)
#define GDBG_INFO_MORE(x)
// #define GR_END()
#define GR_DIENTRY(f,r,p) r f p
// These defines are obsolete in the emulation
// (they can be commented out in the src)
// #define GR_SET_EXPECTED_SIZE(n,p)
// #define GR_CHECK_SIZE_SLOPPY()
#endif //_DRIVERSRC_DEFINES_H_

View File

@ -0,0 +1,122 @@
/*
* THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
* PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
* TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
* INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
* DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
* THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
* FULL TEXT OF THE NON-WARRANTY PROVISIONS.
*
* USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
* RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
* TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
* AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
* SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
* THE UNITED STATES.
*
* COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
*/
static int banner_width = 180;
static int banner_height = 90;
static unsigned short banner_data[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x52aa, 0xad34, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2922, 0xacee, 0x39a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x93ea, 0xd5d0, 0x944d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9383, 0xd506, 0x8beb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbc63, 0xd506, 0xd58d, 0x7b6a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a82, 0xd4e4, 0xd504, 0xc54d, 0x2943, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5202, 0xd4e3, 0xd4e3, 0xd505, 0xcd6d, 0x5aa8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3961, 0xc483, 0xd503, 0xd504, 0xd569, 0x8baa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5268, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9364, 0xd4e2, 0xd4e2, 0xd4e2, 0xd505, 0xc54e, 0x4206, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa3e3, 0xd504, 0xd546, 0xd504, 0xd525, 0xc54d, 0x2103, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20e1, 0x93a4, 0xcd4c, 0x20e2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbc86, 0xd504, 0xd547, 0xd548, 0xd504, 0xd526, 0xbd2f, 0x2944, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7ae3, 0xd504, 0xd56a, 0xd634, 0xd569, 0xd525, 0xdd69, 0x8369, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x49c3, 0xb487, 0xd504, 0xd528, 0x5246, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2901, 0x6ac4, 0x1081, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x528a, 0x39e7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xd526, 0xd548, 0xd5cf, 0xd613, 0xd527, 0xd505, 0xd548, 0xacae, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x49a1, 0xcce5, 0xd56a, 0xde12, 0xde98, 0xddce, 0xd548, 0xdd04, 0xc52e, 0x18e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72c5, 0xcce7, 0xd504, 0xd503, 0xd527, 0x7b48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x49e2, 0x9b83, 0xc4a4, 0xac23, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5247, 0xc570, 0x736a, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9363, 0xd505, 0xd58c, 0xd634, 0xd678, 0xd5f1, 0xd548, 0xd504, 0xd58b, 0x942c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18a1, 0xb444, 0xdd48, 0xddf0, 0xde98, 0xdeb9, 0xde55, 0xdd6b, 0xdd03, 0xdd8b, 0x7349, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2902, 0x9be6, 0xd527, 0xd524, 0xd524, 0xdd03, 0xd526, 0x9c09, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20e1, 0x72c4, 0xac25, 0xd4e3, 0xd4e3, 0xd4e3, 0x8345, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbc85, 0xd5cf, 0xacef, 0x4227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbc85, 0xd526, 0xd5f1, 0xd698, 0xd6ba, 0xd699, 0xd5cf, 0xd547, 0xd525, 0xd5ae, 0x7b6a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8b43, 0xdd04, 0xddae, 0xde76, 0xdeda, 0xdeda, 0xdeba, 0xddcf, 0xdd25, 0xdd47, 0xbd0c, 0x1081, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a04, 0xbc86, 0xdd24, 0xdd26, 0xddcf, 0xddcf, 0xdd25, 0xdd26, 0xb4ca, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41a3, 0x8b64, 0xc4a6, 0xd503, 0xd4e3, 0xd4e3, 0xd4e3, 0xd507, 0x49e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9362, 0xd4e3, 0xd56b, 0xcdb2, 0x83cc, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xd525, 0xd548, 0xd613, 0xd6b9, 0xd6ba, 0xd6ba, 0xd677, 0xddae, 0xd527, 0xdd25, 0xd58d, 0x62c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xd505, 0xdd68, 0xde34, 0xdeda, 0xdedb, 0xdedb, 0xdeda, 0xde33, 0xdd8a, 0xdd25, 0xdd8c, 0x6b09, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72e5, 0xcd06, 0xdd24, 0xdd68, 0xde33, 0xdeb9, 0xde34, 0xdd46, 0xdd25, 0xcd49, 0x20c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18c1, 0x6aa4, 0xa404, 0xd4e4, 0xd504, 0xd549, 0xd5ae, 0xd5ad, 0xd548, 0xd505, 0xbc86, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a21, 0xd4e2, 0xd4e3, 0xd506, 0xd58c, 0xb531, 0x5248, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9363, 0xd504, 0xd5ad, 0xd655, 0xdeba, 0xdeba, 0xdeba, 0xdeba, 0xde76, 0xddae, 0xdd04, 0xdd47, 0xc54d, 0x4a06, 0x0000, 0x0000, 0x0000, 0x2921, 0xbc84, 0xdd46, 0xde11, 0xde98, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeb8, 0xddf0, 0xdd46, 0xdd47, 0xbcec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2922, 0x9c07, 0xdd26, 0xdd26, 0xdd8a, 0xde55, 0xdeb9, 0xdedb, 0xde55, 0xdd8b, 0xdd25, 0xdd47, 0x5246, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3983, 0x8b65, 0xbcc8, 0xd526, 0xd526, 0xd56a, 0xd612, 0xd676, 0xd698, 0xd5f2, 0xd525, 0xd506, 0x93c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18a1, 0xc462, 0xd4e3, 0xd503, 0xd504, 0xd527, 0xcdd1, 0x8c0d, 0x18e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbc86, 0xd505, 0xd5f1, 0xde98, 0xd6ba, 0xdeda, 0xdedb, 0xdedb, 0xdeba, 0xde55, 0xdd8c, 0xdd25, 0xdd26, 0xbd2e, 0x2943, 0x0000, 0x0000, 0x9b83, 0xdd26, 0xddcd, 0xde77, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xde33, 0xdd89, 0xdd25, 0xddad, 0x6ae9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5204, 0xbca8, 0xdd46, 0xdd48, 0xddcf, 0xdeb8, 0xdeda, 0xdedb, 0xdedb, 0xde97, 0xddee, 0xdd25, 0xdd46, 0x7b68, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a44, 0xa3e6, 0xcce5, 0xd504, 0xd547, 0xd58c, 0xd633, 0xd698, 0xd6ba, 0xd6ba, 0xd678, 0xd5d0, 0xd504, 0xd527, 0x6286, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9b82, 0xd548, 0xd58b, 0xd549, 0xd4e3, 0xd505, 0xd58c, 0xbd51, 0x5aa9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a24, 0xd526, 0xd526, 0xde35, 0xdeba, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeb9, 0xde34, 0xdd6a, 0xdd25, 0xdd26, 0xacac, 0x1081, 0x6aa3, 0xd504, 0xdd48, 0xde76, 0xdeda, 0xdedb, 0xdedb, 0xdefb, 0xdedb, 0xdedb, 0xdeda, 0xde97, 0xddcf, 0xdd25, 0xdd47, 0xb4ee, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7b25, 0xd507, 0xdd24, 0xdd8a, 0xde32, 0xdeb9, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xde97, 0xddef, 0xdd46, 0xdd46, 0x9c2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2922, 0x7b26, 0xbc86, 0xd525, 0xdd04, 0xd546, 0xddd0, 0xde55, 0xd699, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd634, 0xd58c, 0xd504, 0xc4e9, 0x20c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a62, 0xd527, 0xd5d0, 0xd656, 0xd5ad, 0xd527, 0xd505, 0xd527, 0xd5b0, 0x944d, 0x2924, 0x0000, 0x0000, 0x0000, 0x0000, 0x9384, 0xd525, 0xd58a, 0xde56, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeb9, 0xde55, 0xdd48, 0xdd24, 0xdd24, 0xa3c3, 0xc4a4, 0xdd48, 0xde10, 0xdeb9, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdefb, 0xdedb, 0xde54, 0xdd68, 0xdd26, 0xdd8a, 0x5a87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2922, 0xa407, 0xdd26, 0xdd45, 0xddab, 0xde55, 0xdeda, 0xdedb, 0xdefb, 0xdedb, 0xdefb, 0xdedb, 0xdeb8, 0xde32, 0xdd46, 0xdd25, 0xb4cb, 0x0000, 0x0000, 0x0000, 0x5224, 0x9be7, 0xcce7, 0xdd04, 0xdd47, 0xdd8b, 0xde11, 0xde97, 0xdeba, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xd6b9, 0xd612, 0xd569, 0xd504, 0xa3e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20e1, 0xc4c5, 0xd5af, 0xd698, 0xd698, 0xd634, 0xd58c, 0xd525, 0xd526, 0xd56a, 0xbd70, 0x62e9, 0x0000, 0x0000, 0x0000, 0xbc85, 0xd526, 0xddf0, 0xde98, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeb9, 0xde32, 0xdd48, 0xdd25, 0xdd24, 0xdd46, 0xddcd, 0xdeb8, 0xdeda, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xde97, 0xddee, 0xdd46, 0xdd46, 0xacad, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5224, 0xc4e9, 0xdd25, 0xdd47, 0xde10, 0xde97, 0xdeda, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xde75, 0xdd68, 0xdd25, 0xcd29, 0x3142, 0x7306, 0xb467, 0xd527, 0xdd25, 0xdd48, 0xddce, 0xde54, 0xde98, 0xdeba, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xde98, 0xd5d0, 0xd546, 0xd526, 0x7305, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18c2, 0x39a5, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa3e4, 0xd56b, 0xd655, 0xd6ba, 0xd6ba, 0xd698, 0xd5f1, 0xd549, 0xd504, 0xd525, 0xd5ad, 0x9c6d, 0x3163, 0x5a23, 0xd525, 0xdd47, 0xde55, 0xdeb9, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeb9, 0xde32, 0xddce, 0xddcd, 0xde11, 0xde97, 0xdeda, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xded9, 0xde54, 0xdd47, 0xdd46, 0xddcd, 0x5246, 0x0000, 0x0000, 0x0000, 0x0000, 0x8347, 0xd527, 0xdd46, 0xdd8a, 0xde32, 0xded9, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xde97, 0xddab, 0xdd46, 0xdd24, 0xcd06, 0xdd46, 0xdd46, 0xdd8b, 0xddcd, 0xde76, 0xdeb9, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xd654, 0xd58b, 0xd525, 0xcd4a, 0x3163, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3143, 0x5a65, 0x7b27, 0x9bc7, 0xac46, 0xc4a5, 0x93e8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72a2, 0xd548, 0xd5f1, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6b9, 0xd656, 0xd5ae, 0xd525, 0xd504, 0xdd47, 0xc4c6, 0xb444, 0xdd26, 0xdd8a, 0xde97, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefa, 0xde97, 0xddab, 0xdd46, 0xdd67, 0xa48d, 0x0000, 0x0000, 0x3163, 0xac27, 0xdd68, 0xdd45, 0xddcd, 0xde75, 0xdeda, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xde97, 0xddcd, 0xdd47, 0xdd24, 0xdd67, 0xddac, 0xde12, 0xde76, 0xdeda, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xde12, 0xd569, 0xd526, 0xb468, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2103, 0x4a26, 0x7307, 0x93a6, 0xa426, 0xbca7, 0xd506, 0xd4e3, 0xd4e2, 0xd4e2, 0xd4e3, 0xb445, 0x18a1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3141, 0xcce5, 0xd5ad, 0xd6b9, 0xd6ba, 0xd6ba, 0xd6ba, 0xdeba, 0xde99, 0xd654, 0xd56a, 0xd525, 0xdd03, 0xdd03, 0xdd48, 0xddef, 0xdeb8, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xded9, 0xde52, 0xdd68, 0xdd45, 0xd5af, 0x4a05, 0x5a65, 0xc4e7, 0xdd46, 0xdd68, 0xddef, 0xde96, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xde76, 0xddef, 0xde31, 0xdeb8, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xddce, 0xdd25, 0xd547, 0x8366, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x39a4, 0x62c7, 0x8388, 0x9c29, 0xb487, 0xccc5, 0xd507, 0xd504, 0xd504, 0xd505, 0xd527, 0xd528, 0xd548, 0xd505, 0xd4e2, 0xc4c6, 0x4182, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xabe2, 0xd56b, 0xd678, 0xd6ba, 0xdeba, 0xd6ba, 0xdeda, 0xdeda, 0xdeba, 0xde98, 0xd5f0, 0xddad, 0xdd8c, 0xddcf, 0xde97, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xded9, 0xddab, 0xdd45, 0xdd68, 0xc4a7, 0xd548, 0xdd46, 0xdd89, 0xde32, 0xe6d9, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xdeda, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xde98, 0xdd8c, 0xdd04, 0xd56b, 0x4a04, 0x0000, 0x2944, 0x5a87, 0x7b48, 0x93e7, 0xac68, 0xc4ea, 0xd56a, 0xd527, 0xd525, 0xd505, 0xd526, 0xd549, 0xd58c, 0xd5d0, 0xd5f3, 0xd635, 0xd656, 0xd655, 0xd58c, 0xd506, 0xccc4, 0x6264, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7ae2, 0xd549, 0xd634, 0xd6b9, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeda, 0xdeda, 0xdeb9, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe6fa, 0xde31, 0xdd89, 0xe546, 0xdd45, 0xe567, 0xddaa, 0xe696, 0xe6fa, 0xe71b, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeba, 0xde54, 0xdd6b, 0xdd03, 0xcd08, 0xa448, 0xbcc9, 0xd528, 0xd526, 0xd525, 0xd505, 0xd505, 0xd526, 0xd528, 0xd56a, 0xd5ce, 0xd633, 0xd677, 0xd699, 0xd699, 0xd6ba, 0xd6ba, 0xd6ba, 0xd677, 0xd5cf, 0xd506, 0xd505, 0x8345, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a48, 0xa48c, 0x940a, 0x734a, 0x4207, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3961, 0xd506, 0xd5cf, 0xde98, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xad75, 0x39e7, 0x39e7, 0x39e7, 0x39e7, 0x8430, 0x94b2, 0xb5b6, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71b, 0xe6d9, 0xe653, 0xe5ed, 0xe5cc, 0xe631, 0xe6b8, 0xe6fb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdeda, 0xdeb9, 0xde10, 0xdd49, 0xdd03, 0xdd03, 0xdd04, 0xdd27, 0xd547, 0xd569, 0xd5ae, 0xddf1, 0xd634, 0xd676, 0xd698, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd678, 0xd5f1, 0xd506, 0xd504, 0xa427, 0x1081, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a43, 0xc4a5, 0xd505, 0xd56c, 0xbd2d, 0xa4ae, 0x83cc, 0x5ac8, 0x2124, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb446, 0xddab, 0xde97, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0x8430, 0x39e7, 0x39e7, 0x39e7, 0x39e7, 0x4208, 0x39e7, 0x4208, 0x738e, 0xa534, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71b, 0xe71b, 0xe71b, 0xe71b, 0xe71b, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdeda, 0xde75, 0xddce, 0xddcd, 0xde11, 0xde54, 0xde55, 0xde77, 0xdeba, 0xdeba, 0xdeba, 0xdeba, 0xdeba, 0xdeba, 0xdeba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd699, 0xd5f2, 0xd547, 0xd504, 0xbc85, 0x2922, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a21, 0xc482, 0xd4e3, 0xd504, 0xd505, 0xd527, 0xd56b, 0xcd90, 0xb4cd, 0x942c, 0x734b, 0x39c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x8323, 0xdd47, 0xde54, 0xdeb9, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0x5aeb, 0x39e7, 0x39e7, 0x39e7, 0x4208, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0xb5b6, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdeda, 0xdeda, 0xdeba, 0xdeda, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd613, 0xd56a, 0xd505, 0xcd08, 0x5204, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a21, 0xc4a3, 0xd526, 0xd569, 0xd526, 0xd505, 0xd505, 0xd504, 0xd525, 0xd548, 0xd5ae, 0xbd4e, 0xa48e, 0x838a, 0x5a45, 0x51e2, 0xd506, 0xddf0, 0xde97, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xb5b6, 0x39e7, 0x39e7, 0x39e7, 0x39e7, 0x4208, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0xad55, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe71c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xd6ba, 0xd6ba, 0xd6ba, 0xd6ba, 0xd655, 0xd58d, 0xd503, 0xd549, 0x72e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a21, 0xc4c6, 0xd5ae, 0xd677, 0xd655, 0xd612, 0xd5cf, 0xd56a, 0xd525, 0xd503, 0xd503, 0xd504, 0xd526, 0xd547, 0xccc4, 0xd505, 0xddce, 0xde77, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xd6ba, 0x738e, 0x39e7, 0x39e7, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0xbdd7, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xd6ba, 0xdedb, 0xd6ba, 0xd677, 0xd58c, 0xd526, 0xd505, 0x93c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a21, 0xccc6, 0xd5cd, 0xd677, 0xd699, 0xd6ba, 0xd6b9, 0xd699, 0xde77, 0xd611, 0xd58b, 0xdd47, 0xdd26, 0xdd26, 0xdd69, 0xde33, 0xdeb8, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xd69a, 0x39e7, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0xc638, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xa514, 0xbdd7, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xd6ba, 0xd6ba, 0xd698, 0xd5ad, 0xd526, 0xd505, 0xb48a, 0x18c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xccc6, 0xd5f1, 0xd677, 0xd6ba, 0xdeba, 0xd6ba, 0xdeba, 0xdeba, 0xdeb9, 0xde98, 0xde55, 0xde76, 0xde97, 0xdeb9, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xd6ba, 0x8430, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0xad55, 0xe71c, 0xe71c, 0xe71c, 0xad75, 0x4228, 0x4a49, 0x7bcf, 0xad75, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xde98, 0xd611, 0xd527, 0xd504, 0xc52b, 0x39a3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xccc5, 0xd5f1, 0xd698, 0xd6ba, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0x8430, 0x39e7, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x7bcf, 0xe71c, 0xe71c, 0xe71c, 0x7bcf, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x8c71, 0xbdf7, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xad75, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xde98, 0xde33, 0xd547, 0xd525, 0xcd28, 0x6286, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xcce7, 0xd5f1, 0xde98, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xc638, 0xb5b6, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xb5b6, 0x9cd3, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x52aa, 0xce59, 0xe71c, 0xce59, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0xa514, 0xce79, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0x9cf3, 0x4a49, 0x4a49, 0x9cf3, 0xbdf7, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xde34, 0xdd69, 0xdd25, 0xd569, 0x8389, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xcce6, 0xd5f0, 0xdeb9, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xc638, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0xbdf7, 0xe73c, 0x8c71, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x7bef, 0xb596, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xce79, 0x4a69, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0xad55, 0x9cf3, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xde55, 0xddad, 0xdd04, 0xdd26, 0xb4cb, 0x3185, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xcd09, 0xde11, 0xdeb9, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xbdd7, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x9cf3, 0xce59, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x528a, 0x528a, 0x528a, 0xb5b6, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0x7bef, 0x4a69, 0x4a69, 0x632c, 0x4a49, 0x4a49, 0x528a, 0x4a49, 0x630c, 0x4228, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeb9, 0xddf0, 0xdd47, 0xdd04, 0xdd26, 0xd58b, 0xd5d0, 0xc56f, 0xbcee, 0xa46c, 0x940b, 0x838a, 0x6b09, 0x5247, 0x2123, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7b03, 0xdd47, 0xde32, 0xdeb9, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xbdd7, 0xbdd7, 0xbdd7, 0x9cd3, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x8c71, 0x9cf3, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x528a, 0x528a, 0x528a, 0x528a, 0x528a, 0x528a, 0x52aa, 0x52aa, 0xc638, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0x4a69, 0x7bef, 0x4a69, 0x632c, 0x4a69, 0x630c, 0x4a49, 0x7bcf, 0x4a49, 0x8c71, 0x630c, 0x4228, 0xe71c, 0xd6ba, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdeba, 0xde75, 0xddef, 0xdd69, 0xdd26, 0xdd26, 0xdd26, 0xdd05, 0xd505, 0xd525, 0xd526, 0xd526, 0xd548, 0xd549, 0xd56c, 0xc4e8, 0xb4a9, 0xa44a, 0x93eb, 0x7b6a, 0x62c8, 0x41e5, 0x18c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5204, 0x8b86, 0xbc86, 0xd505, 0xdd26, 0xddce, 0xdeb9, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0x9492, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4a49, 0x7bcf, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x528a, 0x528a, 0x528a, 0x528a, 0x528a, 0x528a, 0x52aa, 0x52aa, 0x52aa, 0x52aa, 0xbdd7, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0x9492, 0xb596, 0xc618, 0x7bef, 0x4a69, 0x7bef, 0x4a49, 0x8c71, 0x4a49, 0x4a49, 0xad75, 0x4a49, 0x7bcf, 0x9cf3, 0x4228, 0x8c51, 0xce59, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeb9, 0xde76, 0xde54, 0xde33, 0xd611, 0xd5d0, 0xd5ae, 0xd58d, 0xd56b, 0xd549, 0xd527, 0xd525, 0xd504, 0xd4e3, 0xd4e3, 0xd504, 0xd504, 0xd506, 0xbc65, 0x4a25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a44, 0x9385, 0xbc65, 0xd527, 0xdd26, 0xdd46, 0xddad, 0xde55, 0xdeb9, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0x630c, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x528a, 0x528a, 0x528a, 0x528a, 0x52aa, 0x52aa, 0x52aa, 0x52aa, 0x52aa, 0x52aa, 0x52aa, 0x5acb, 0xad55, 0xef7d, 0xef7d, 0xf79e, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xc638, 0xd69a, 0xef5d, 0xef5d, 0xc618, 0xc618, 0x4a69, 0x9492, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0xce79, 0x9cf3, 0x4228, 0x4228, 0x630c, 0x4228, 0x9cd3, 0xbdd7, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeda, 0xdeba, 0xdeba, 0xd6ba, 0xd6b9, 0xd699, 0xd698, 0xd678, 0xd677, 0xd656, 0xd5f2, 0xd548, 0xd504, 0xd4c2, 0x9bc4, 0x3121, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a44, 0x93a6, 0xbca6, 0xd525, 0xd526, 0xdd47, 0xdd8c, 0xde11, 0xde76, 0xdeb9, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xad55, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x528a, 0x528a, 0x528a, 0x528a, 0x52aa, 0x52aa, 0x52aa, 0x52aa, 0x5acb, 0x5acb, 0x5acb, 0x5acb, 0x5acb, 0x5acb, 0xce59, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xc638, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xd69a, 0xce59, 0xef5d, 0x9492, 0x8c71, 0x4a49, 0x4a49, 0xbdf7, 0xbdf7, 0x4228, 0x4228, 0x4228, 0x73ae, 0x4228, 0x4208, 0x73ae, 0xbdd7, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xd6ba, 0xd6ba, 0xd698, 0xd634, 0xd56a, 0xd505, 0xbc85, 0x6262, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18c1, 0x5a65, 0x93a4, 0xc4a5, 0xd525, 0xd505, 0xd548, 0xd5ad, 0xd633, 0xde77, 0xdeb9, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0x8c51, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x39e7, 0x2165, 0x2185, 0x2186, 0x21c6, 0x2a07, 0x3228, 0x4228, 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x528a, 0x528a, 0x94b2, 0x8410, 0x52aa, 0x52aa, 0x52aa, 0x5acb, 0x5acb, 0x5acb, 0x5acb, 0x5acb, 0x5acb, 0x5aeb, 0x5aeb, 0x5aeb, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xbdd7, 0x52aa, 0x52aa, 0xa534, 0xd69a, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xc618, 0x8c71, 0x7bcf, 0x4a49, 0x4228, 0x4228, 0x8c71, 0xe73c, 0x4228, 0x630c, 0x4208, 0x8c51, 0x8c51, 0xad55, 0xe71c, 0xc638, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xd6ba, 0xdeba, 0xd656, 0xd5ce, 0xd527, 0xd4e5, 0x9ba3, 0x2901, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18c1, 0x6264, 0x9bc5, 0xc4a5, 0xd505, 0xd525, 0xd549, 0xd5ae, 0xd634, 0xde98, 0xdeba, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0x8c51, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x1904, 0x08e3, 0x0903, 0x0944, 0x0985, 0x09c6, 0x09e6, 0x09e6, 0x21e7, 0x3a08, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x528a, 0x8410, 0xef7d, 0xef7d, 0xd6ba, 0xad55, 0x8430, 0x5acb, 0x5acb, 0x5acb, 0x5aeb, 0x5aeb, 0x5aeb, 0x5aeb, 0x630c, 0x5aeb, 0xbdf7, 0xf7be, 0xf7be, 0xf7be, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0x5acb, 0x52aa, 0x52aa, 0x52aa, 0x528a, 0xd69a, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0x8c71, 0xbdf7, 0x8430, 0x7bcf, 0x8c71, 0x4228, 0x73ae, 0x4228, 0x630c, 0x4208, 0x9cd3, 0x4208, 0x4208, 0xce79, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xd698, 0xd612, 0xd56b, 0xd504, 0xbc85, 0x5a43, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20e1, 0x6a83, 0x9bc4, 0xc4c6, 0xd505, 0xd526, 0xd569, 0xd5cf, 0xd655, 0xd698, 0xd6b9, 0xdeba, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0x8c51, 0x4208, 0x4208, 0x4208, 0x4208, 0x2986, 0x08c3, 0x08e3, 0x0903, 0x0924, 0x0965, 0x09c6, 0x09e7, 0x09e6, 0x09c6, 0x0985, 0x31c7, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x4228, 0xad75, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xbdf7, 0x8c51, 0x5aeb, 0x5aeb, 0x630c, 0x630c, 0x630c, 0x630c, 0x630c, 0x8c71, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf79e, 0xad75, 0x5acb, 0x5acb, 0x4228, 0x3186, 0x39c7, 0xb596, 0xdefb, 0xef5d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xbdd7, 0x9492, 0x4228, 0x4228, 0x4228, 0x4228, 0x4208, 0x4208, 0x4208, 0x4208, 0x9cd3, 0xbdf7, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeb9, 0xde55, 0xd5ad, 0xdd27, 0xd506, 0x93a5, 0x20e1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3143, 0x9bc5, 0xc4c5, 0xd4e3, 0xd4e3, 0xd505, 0xd58c, 0xd633, 0xd698, 0xd6b9, 0xd6ba, 0xd6ba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xb5b6, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xad55, 0x4208, 0x4208, 0x4208, 0x4208, 0x08e3, 0x08c3, 0x08c3, 0x0903, 0x0924, 0x0965, 0x09a6, 0x09e6, 0x09e7, 0x09c6, 0x0985, 0x0924, 0x4228, 0x4a69, 0x528a, 0x39e7, 0x08c2, 0x2165, 0x632c, 0x8c92, 0xb5b6, 0xd69a, 0xef7d, 0xf7be, 0xf7be, 0x9cf3, 0x630c, 0x630c, 0x630c, 0x632c, 0x632c, 0x632c, 0x632c, 0xdefb, 0xffdf, 0xffdf, 0xffdf, 0xf7be, 0xf7be, 0xdedb, 0x5aeb, 0x5acb, 0x52aa, 0x18e3, 0x0861, 0x0861, 0x4208, 0x73ae, 0x4208, 0x9cd3, 0x9492, 0xd69a, 0xdefb, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0x7bcf, 0x9cf3, 0x8c71, 0x4228, 0x4208, 0x4208, 0x4208, 0x4208, 0x9cd3, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdeba, 0xde97, 0xde11, 0xdd47, 0xd526, 0xbc86, 0x6244, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3121, 0x6a82, 0x9b82, 0xbc63, 0xd505, 0xd58b, 0xd612, 0xd677, 0xd6b9, 0xd6ba, 0xdeba, 0xdeda, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0x738e, 0x39e7, 0xc638, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0x9cf3, 0x4208, 0x4228, 0x4228, 0x1924, 0x08c3, 0x08e3, 0x0965, 0x0985, 0x09a6, 0x09e7, 0x0a28, 0x0a28, 0x09e7, 0x09a6, 0x0945, 0x31c6, 0x528a, 0x4a49, 0x0903, 0x08c2, 0x08c2, 0x08c2, 0x0903, 0x0965, 0x0965, 0x3a69, 0x73cf, 0x9d34, 0xce79, 0x9cf3, 0x632c, 0x632c, 0x6b4d, 0x6b4d, 0x6b4d, 0x6b4d, 0xb5b6, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xa514, 0x5aeb, 0x5aeb, 0x39c7, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x10a2, 0x0861, 0x0861, 0x632c, 0x4228, 0xce59, 0x7bcf, 0xa534, 0xdefb, 0xdedb, 0xe73c, 0xe73c, 0xce79, 0x4228, 0xe73c, 0xce59, 0xbdf7, 0x8c51, 0x4208, 0x4208, 0xbdd7, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdeb8, 0xde54, 0xdd8c, 0xdd25, 0xd505, 0x93a5, 0x20e1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4181, 0x7ae3, 0xa3e5, 0xc4a5, 0xd548, 0xd5cf, 0xde55, 0xde77, 0xdeb9, 0xdeba, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xbdd7, 0x39e7, 0x39e7, 0x39e7, 0x8430, 0xce59, 0xe73c, 0xe71c, 0xe73c, 0xad75, 0x4208, 0x4208, 0x4208, 0x2985, 0x08e3, 0x0985, 0x09c6, 0x0a27, 0x0a28, 0x09e7, 0x0a07, 0x0a68, 0x0aa9, 0x0a69, 0x09c6, 0x2165, 0x4a69, 0x2185, 0x08e3, 0x08c2, 0x08c2, 0x08a2, 0x0903, 0x0944, 0x0965, 0x0965, 0x0965, 0x0985, 0x0985, 0x2a28, 0x3a28, 0x52cb, 0x6b4d, 0x6b4d, 0x6b6d, 0x6b6d, 0xad55, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xe71c, 0x630c, 0x630c, 0x52aa, 0x2104, 0x3186, 0x0861, 0x0861, 0x31a6, 0x0861, 0x6b4d, 0x0861, 0x39c7, 0x4a49, 0x6b4d, 0xad55, 0x0861, 0x0861, 0x4a69, 0x0861, 0x8c51, 0x7bcf, 0xbdd7, 0xc618, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xbdf7, 0xce59, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdeda, 0xde97, 0xddcf, 0xdd46, 0xdd26, 0xbc86, 0x5a43, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18a1, 0x5202, 0x8b43, 0xac25, 0xcd07, 0xdd8c, 0xddf0, 0xde54, 0xde98, 0xdeda, 0xdeda, 0xdedb, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0x8430, 0x39e7, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x8c51, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x31c7, 0x0944, 0x09a6, 0x09a5, 0x09e7, 0x0a27, 0x0a68, 0x0a28, 0x0a07, 0x0a28, 0x0a89, 0x0a89, 0x09c6, 0x31e7, 0x0903, 0x08e3, 0x08c2, 0x08e3, 0x08c2, 0x08c3, 0x0944, 0x0965, 0x0965, 0x0965, 0x0985, 0x0985, 0x09a6, 0x0985, 0x0965, 0x3a28, 0x632c, 0x738e, 0x738e, 0x738e, 0xffff, 0xffff, 0xffff, 0xffff, 0x9492, 0x632c, 0x630c, 0x5acb, 0x39e7, 0x5acb, 0xc638, 0xc618, 0xbdd7, 0x39e7, 0x7bcf, 0x0861, 0x4208, 0x0861, 0x6b4d, 0x8c51, 0x0861, 0x2945, 0x2945, 0x8430, 0x10a2, 0x10a2, 0x10a2, 0x94b2, 0x738e, 0xdedb, 0xad75, 0xb5b6, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdeb9, 0xde32, 0xdd8a, 0xdd47, 0xd506, 0x8b86, 0x20c1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20e1, 0x6262, 0x9384, 0xb465, 0xd548, 0xddce, 0xde33, 0xde76, 0xdeb9, 0xdeda, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0x39e7, 0x39e7, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x4208, 0x31e7, 0x2186, 0x52ca, 0x634d, 0x1144, 0x09a6, 0x0a48, 0x0a89, 0x0a68, 0x0a48, 0x0a68, 0x0a48, 0x0965, 0x0924, 0x08e3, 0x0924, 0x0965, 0x0944, 0x0924, 0x0965, 0x09a6, 0x0985, 0x0965, 0x0965, 0x0985, 0x09a6, 0x0985, 0x0965, 0x0965, 0x1985, 0x632c, 0x73ae, 0x738e, 0xdedb, 0xffff, 0xffff, 0xb596, 0x6b4d, 0x632c, 0x4208, 0x2124, 0x31a6, 0x7bef, 0xe73c, 0xf7be, 0xef5d, 0xc618, 0x528a, 0x4228, 0x73ae, 0x7bcf, 0x8c71, 0x10a2, 0x4a49, 0x94b2, 0x3186, 0x7bcf, 0x2945, 0x4a49, 0x0861, 0x2104, 0x2945, 0x8c51, 0x0861, 0x39c7, 0xdefb, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xde76, 0xdd8a, 0xdd46, 0xdd25, 0xd56b, 0xac8d, 0x6b09, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3961, 0x72c3, 0x9bc4, 0xcce6, 0xddab, 0xde33, 0xdeda, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0x8c51, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x3186, 0x0903, 0x0924, 0x0903, 0x08e3, 0x0944, 0x0965, 0x0a68, 0x0aca, 0x0aca, 0x0aa9, 0x0a89, 0x09c6, 0x0924, 0x0903, 0x0985, 0x09c6, 0x09e7, 0x09e6, 0x09a6, 0x09c6, 0x0a27, 0x0a07, 0x09e7, 0x09e7, 0x09e6, 0x09a6, 0x0985, 0x0965, 0x0944, 0x2165, 0x6b6d, 0x7bcf, 0xffff, 0xffff, 0xffff, 0x6b6d, 0x6b4d, 0x5acb, 0x0861, 0x0861, 0x0861, 0x0861, 0xb596, 0xf7be, 0xf7be, 0xf7be, 0x7bef, 0x528a, 0x528a, 0x8410, 0xef7d, 0xdedb, 0xe73c, 0xdedb, 0x7bcf, 0x738e, 0x39c7, 0x2104, 0x0861, 0x10a2, 0x528a, 0x2104, 0x0861, 0x94b2, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xde75, 0xddcd, 0xdd47, 0xdd25, 0xdd47, 0xddce, 0xc56f, 0x8c2d, 0x4207, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4181, 0xbc85, 0xdd68, 0xde11, 0xdeda, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0x8c51, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x39e7, 0x08e3, 0x08e3, 0x0944, 0x0903, 0x08e3, 0x0924, 0x0965, 0x0a48, 0x0aa9, 0x0aea, 0x0b0b, 0x0aca, 0x09c6, 0x0924, 0x0985, 0x0944, 0x0965, 0x09e7, 0x09e7, 0x09e7, 0x09e7, 0x09e7, 0x09e7, 0x0a48, 0x0a89, 0x0aa9, 0x0a89, 0x0a28, 0x09c6, 0x0945, 0x0904, 0x5acb, 0x7bef, 0xc638, 0xe71c, 0xce79, 0x738e, 0x6b4d, 0x2945, 0x0861, 0x0861, 0x0861, 0x0861, 0xa514, 0xf7be, 0xf7be, 0xf7be, 0xbdd7, 0x528a, 0x528a, 0x528a, 0xd6ba, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xce59, 0x8c51, 0x94b2, 0xa534, 0xad75, 0x9cd3, 0x4a49, 0x39c7, 0xc638, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xde97, 0xddef, 0xdd69, 0xdd46, 0xdd25, 0xdd47, 0xd5af, 0xacce, 0x6b2a, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41a1, 0xc4a6, 0xdd47, 0xde11, 0xdeb8, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0x8c51, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x31a6, 0x08c2, 0x08c2, 0x0924, 0x0904, 0x08e3, 0x0904, 0x09e6, 0x0a48, 0x0a89, 0x0aaa, 0x0aca, 0x0a89, 0x0924, 0x0985, 0x09e7, 0x0985, 0x0944, 0x0944, 0x0985, 0x638d, 0x4aeb, 0x09c6, 0x09c6, 0x09e7, 0x0a48, 0x0aa9, 0x0aca, 0x0aaa, 0x0a89, 0x0a28, 0x0965, 0x3a08, 0x8410, 0x7bef, 0x7bcf, 0x7bcf, 0x738e, 0x4a49, 0x0861, 0x0861, 0x0861, 0x0861, 0x4a49, 0xef5d, 0xffdf, 0xf7be, 0xf7be, 0xdefb, 0x52aa, 0x528a, 0x528a, 0xbdd7, 0xf79e, 0xef7d, 0xef7d, 0xd69a, 0xa514, 0x4208, 0x94b2, 0xd69a, 0xef5d, 0xef5d, 0xce79, 0xd69a, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdeda, 0xde98, 0xde54, 0xddce, 0xdd48, 0xdd25, 0xdd48, 0xdd8c, 0xc570, 0x942d, 0x4a27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x49c2, 0xc4a5, 0xdd46, 0xddf0, 0xdeb7, 0xdeda, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0x8c51, 0x39e7, 0x39e7, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x39e7, 0x08c2, 0x08c2, 0x0944, 0x0924, 0x0924, 0x0944, 0x0985, 0x09e7, 0x0a28, 0x0a68, 0x0a69, 0x09a5, 0x0944, 0x0985, 0x0985, 0x0985, 0x0965, 0x0965, 0x73cf, 0xffdf, 0xffdf, 0xa534, 0x52cb, 0x3a69, 0x19e7, 0x0a27, 0x0a69, 0x0aa9, 0x0a89, 0x0a89, 0x0a68, 0x1985, 0x7bef, 0x8410, 0x7bef, 0x7bcf, 0x632c, 0x1082, 0x0861, 0x0861, 0x0861, 0x0861, 0xc618, 0xffdf, 0xdedb, 0x9492, 0xb5b6, 0xd6ba, 0x94b2, 0x528a, 0x528a, 0x8410, 0xf79e, 0xc638, 0x9492, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4228, 0x5aeb, 0x8c71, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdeda, 0xde97, 0xddf0, 0xdd6a, 0xdd26, 0xdd26, 0xdd47, 0xd58d, 0xaccd, 0x732a, 0x18e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x49e2, 0xc4c5, 0xdd46, 0xddef, 0xde98, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xad75, 0x8c51, 0x4208, 0x4208, 0x4208, 0x31a6, 0x31c7, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x10e3, 0x0924, 0x0965, 0x0944, 0x0944, 0x0944, 0x0924, 0x0944, 0x0985, 0x09a6, 0x0944, 0x08e3, 0x09c6, 0x09a6, 0x0965, 0x0965, 0x0965, 0x21e7, 0xb5b6, 0xa514, 0x632c, 0x632c, 0x6b4d, 0x6b6d, 0x6b6d, 0x428a, 0x0a48, 0x0a89, 0x0a89, 0x0a68, 0x0a27, 0x09c6, 0x73ae, 0x8430, 0x7bef, 0x7bcf, 0x3186, 0x0861, 0x0861, 0x0861, 0x0861, 0x3186, 0xc618, 0xffff, 0xef7d, 0x2124, 0x0861, 0x0861, 0x4228, 0x4a69, 0x528a, 0x528a, 0x8410, 0x4a69, 0x4a69, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4a49, 0x4228, 0x4228, 0xb596, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xde98, 0xde34, 0xddcf, 0xdd47, 0xdd04, 0xd525, 0xd569, 0xc54e, 0x940b, 0x4a27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5203, 0xccc5, 0xdd68, 0xde10, 0xdeb9, 0xdedb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xbdf7, 0x9cf3, 0x6b4d, 0x08e3, 0x08e3, 0x2165, 0x31c7, 0x39e7, 0x3a07, 0x7bef, 0x4249, 0x0985, 0x09c6, 0x09a6, 0x0965, 0x0985, 0x1185, 0x1965, 0x0903, 0x08e3, 0x08a2, 0x0924, 0x09c6, 0x09a6, 0x0985, 0x0985, 0x09a6, 0x3a49, 0x5aeb, 0x630c, 0x632c, 0x6b4d, 0x6b4d, 0x6b6d, 0x738e, 0x3208, 0x09e7, 0x0a89, 0x0a89, 0x0a48, 0x09c6, 0x0944, 0xad96, 0x9cd3, 0x8410, 0x52aa, 0x0861, 0x0861, 0x0861, 0x0861, 0x18c3, 0x5aeb, 0x630c, 0xffff, 0xffff, 0x9cd3, 0x0861, 0x0861, 0x0861, 0x39c7, 0x528a, 0x528a, 0x4a69, 0x4a69, 0x4a49, 0x39c7, 0x39e7, 0x4228, 0x4a49, 0x4228, 0x7bcf, 0xad55, 0xd69a, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdedb, 0xdedb, 0xdeda, 0xdeba, 0xde98, 0xde11, 0xdd6a, 0xd504, 0xd504, 0xd505, 0xd549, 0xb445, 0x7305, 0x2102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a22, 0xcce6, 0xdd69, 0xde10, 0xded9, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0x634d, 0x08c2, 0x08e3, 0x0903, 0x0924, 0x0944, 0x0944, 0x0924, 0x08e3, 0x0944, 0x09a6, 0x09a6, 0x0985, 0x0965, 0x31c7, 0x29a6, 0x08e3, 0x08e3, 0x08c2, 0x0944, 0x0985, 0x0985, 0x0965, 0x0944, 0x21c6, 0x5acb, 0x5aeb, 0x630c, 0x632c, 0x6b4d, 0x6b4d, 0x6b6d, 0x4aaa, 0x0944, 0x0985, 0x0a69, 0x0a68, 0x0a28, 0x09a6, 0x0965, 0x3a69, 0x4228, 0x528a, 0x10a2, 0x0861, 0x0861, 0x0861, 0x0861, 0x4a69, 0x632c, 0x630c, 0xffff, 0xffff, 0xc638, 0x31a6, 0x0861, 0x0861, 0x10a2, 0x4a69, 0x4a69, 0x4208, 0x2965, 0x10a2, 0x0861, 0x0861, 0x1082, 0x39e7, 0x7bcf, 0xdefb, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdedb, 0xdeda, 0xdeda, 0xdeb9, 0xde97, 0xde54, 0xde12, 0xddcf, 0xdd6a, 0xdd25, 0xd504, 0xc4a4, 0xac04, 0x8b64, 0x6aa4, 0x2943, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a42, 0xccc5, 0xdd68, 0xde10, 0xdeb9, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xef5d, 0xe71c, 0x3a28, 0x08a2, 0x08e3, 0x08e3, 0x0924, 0x0944, 0x0965, 0x0944, 0x08e3, 0x08e3, 0x0965, 0x09a6, 0x09a6, 0x0985, 0x1185, 0x0924, 0x08e3, 0x08e3, 0x0924, 0x0924, 0x0944, 0x0965, 0x09a6, 0x11a6, 0x4a8a, 0x5aeb, 0x5aeb, 0x630c, 0x632c, 0x632c, 0x634d, 0x4289, 0x09a6, 0x0965, 0x0985, 0x0a89, 0x0a89, 0x0a27, 0x09c6, 0x0944, 0x0903, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x31a6, 0x9cf3, 0x630c, 0xa534, 0xb5b6, 0x5aeb, 0x5acb, 0x4228, 0x0861, 0x0861, 0x0861, 0x2945, 0x18e3, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0xb596, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdeda, 0xdeda, 0xdeb8, 0xde54, 0xddee, 0xdd69, 0xdd46, 0xdd26, 0xcce6, 0xb444, 0x9b83, 0x72c2, 0x49c2, 0x1081, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6242, 0xcce5, 0xdd68, 0xde32, 0xdeb9, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0x7bef, 0x08a2, 0x0924, 0x0903, 0x0924, 0x0944, 0x0944, 0x0944, 0x0903, 0x08e3, 0x0985, 0x09c6, 0x0985, 0x0965, 0x0965, 0x0924, 0x0903, 0x0924, 0x09a6, 0x09a6, 0x0965, 0x0944, 0x0965, 0x3a28, 0x5acb, 0x5aeb, 0x5aeb, 0x630c, 0x630c, 0x52aa, 0x2a28, 0x09a6, 0x09a6, 0x0985, 0x09c6, 0x0aa9, 0x0aa9, 0x0a68, 0x09e7, 0x0965, 0x08c3, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x39c7, 0x630c, 0x5aeb, 0x5aeb, 0x5acb, 0x528a, 0x18e3, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x4a49, 0x9492, 0xd6ba, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe6fb, 0xded9, 0xde96, 0xde53, 0xde10, 0xddac, 0xdd68, 0xdd45, 0xd505, 0xbc64, 0xa3c4, 0x8303, 0x5a22, 0x20c1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a62, 0xd4e6, 0xdd68, 0xde32, 0xdeb8, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xa555, 0x08a2, 0x0944, 0x0944, 0x0965, 0x0944, 0x0965, 0x0965, 0x0924, 0x0924, 0x0985, 0x0965, 0x0924, 0x0944, 0x0965, 0x0944, 0x0924, 0x0985, 0x09c6, 0x09c6, 0x09e7, 0x09a6, 0x0965, 0x21a6, 0x31e7, 0x3a28, 0x3269, 0x3248, 0x11a6, 0x0985, 0x09e6, 0x09a6, 0x0985, 0x09a6, 0x09e6, 0x0a48, 0x0a89, 0x0a68, 0x0a07, 0x3269, 0x7c10, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x5acb, 0x52aa, 0x4208, 0x2945, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x4a69, 0x94b2, 0xce59, 0xef7d, 0xf79e, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71b, 0xe6fb, 0xe6d9, 0xe674, 0xe630, 0xe5aa, 0xdd68, 0xdd47, 0xdd47, 0xccc6, 0xac25, 0x8b64, 0x6284, 0x3142, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6aa3, 0xd505, 0xdd48, 0xde54, 0xdeb9, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xce79, 0x0944, 0x0965, 0x0985, 0x0985, 0x0985, 0x0985, 0x09a6, 0x09a6, 0x0985, 0x0985, 0x0965, 0x0945, 0x0985, 0x0985, 0x0965, 0x09a6, 0x0a07, 0x0a07, 0x09e7, 0x09e7, 0x09e7, 0x0985, 0x0924, 0x0944, 0x0985, 0x0a07, 0x09e7, 0x0985, 0x0965, 0x09c6, 0x09c6, 0x0985, 0x0a27, 0x0a48, 0x0a28, 0x0a48, 0x0a48, 0x0a28, 0xa555, 0xb5b6, 0x0861, 0x0861, 0x0861, 0x0861, 0x2104, 0x2124, 0x0861, 0x0861, 0x2945, 0x4228, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x10a2, 0x3186, 0xb5b6, 0xf79e, 0xf7be, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71b, 0xe6f9, 0xe631, 0xe5cc, 0xe568, 0xe568, 0xd507, 0xb466, 0x93a5, 0x72a3, 0x4182, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72c3, 0xd505, 0xdd69, 0xde33, 0xdeb9, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xb5b6, 0x52eb, 0x09a6, 0x0985, 0x0944, 0x0924, 0x0944, 0x0985, 0x0965, 0x0965, 0x0944, 0x636d, 0x532c, 0x0985, 0x09c6, 0x0a28, 0x0a27, 0x0a28, 0x0a07, 0x0a07, 0x09c6, 0x0965, 0x0944, 0x0944, 0x0965, 0x09e6, 0x0a07, 0x09a6, 0x0965, 0x09c6, 0x09e7, 0x09c6, 0x0a48, 0x0a89, 0x0aca, 0x0aa9, 0x0a69, 0x6c0f, 0xf7be, 0xc618, 0x0861, 0x0861, 0x0861, 0x1082, 0x5acb, 0x6b4d, 0x4228, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x18c3, 0x0861, 0x0861, 0x2104, 0x4a49, 0xad55, 0xf7be, 0xf7be, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71b, 0xe6d8, 0xe5ec, 0xe589, 0xe566, 0x9be6, 0x1081, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72c3, 0xd4e4, 0xdd6a, 0xde32, 0xdeb9, 0xdeda, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xdefb, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xe73c, 0xc659, 0x9d13, 0x73ef, 0x4aca, 0x4289, 0x428a, 0x5b4d, 0x8c92, 0xc638, 0xf79e, 0x9d14, 0x0985, 0x0a69, 0x0a89, 0x0a28, 0x0a07, 0x0a07, 0x0a28, 0x09e7, 0x0985, 0x0944, 0x0924, 0x0944, 0x09c6, 0x0a07, 0x09c6, 0x0965, 0x09a6, 0x0a27, 0x0a28, 0x0a48, 0x0a69, 0x0aca, 0x0aea, 0x53ef, 0xef7d, 0xffff, 0xe73c, 0x18c3, 0x0861, 0x0861, 0x0861, 0x18c3, 0x2965, 0x39c7, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x2124, 0x7bef, 0xc638, 0xc618, 0x0861, 0x0861, 0x0861, 0x39c7, 0x8410, 0xf7be, 0xf7be, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe6f9, 0xe5ee, 0xe567, 0xdd68, 0x8326, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7ae3, 0xd505, 0xdd04, 0xdd26, 0xdd48, 0xdd69, 0xdd6a, 0xdd8b, 0xdd8b, 0xddab, 0xddab, 0xddcc, 0xddee, 0xddee, 0xde0f, 0xe60f, 0xe630, 0xe674, 0xe6b7, 0xe6d7, 0xe6d8, 0xe6d7, 0xe6f9, 0xe71b, 0xe73c, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xc659, 0x0a07, 0x0a89, 0x0a89, 0x0a28, 0x09c6, 0x09c6, 0x0a07, 0x0a48, 0x0a27, 0x09c6, 0x0985, 0x0985, 0x09c6, 0x0a27, 0x09e6, 0x09a5, 0x09a6, 0x09c6, 0x0a07, 0x0a48, 0x0a68, 0x0a89, 0x7491, 0xef7d, 0xffff, 0xffff, 0xffff, 0x9492, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x5aeb, 0xad55, 0xb5b6, 0x9492, 0x630c, 0x52aa, 0xad55, 0xe73c, 0xffff, 0xffff, 0xffdf, 0x5acb, 0x0861, 0x0861, 0x10a2, 0x4228, 0xce59, 0x9cf3, 0x632c, 0x9492, 0xd6ba, 0xf79e, 0xf79e, 0xf79e, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe71b, 0xe6d8, 0xe60f, 0xe588, 0xdd69, 0x7b06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3961, 0x49c2, 0x5202, 0x5a22, 0x6a62, 0x6aa3, 0x7ae3, 0x8303, 0x8b44, 0x8b64, 0x93a4, 0x9bc5, 0xa3e5, 0xac25, 0xb446, 0xb466, 0xbca6, 0xc4c7, 0xcce7, 0xcd08, 0xd528, 0xdd68, 0xe5cc, 0xe693, 0xe71b, 0xef3c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xef7d, 0xadd7, 0x84d2, 0x536d, 0x1a68, 0x0a07, 0x09c6, 0x09e6, 0x0a28, 0x0a48, 0x0a48, 0x09e7, 0x0985, 0x0965, 0x0985, 0x09a6, 0x0985, 0x0944, 0x0924, 0x0965, 0x09a6, 0x3aeb, 0xb5d7, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xf7be, 0xad55, 0x39e7, 0x0861, 0x0861, 0x0861, 0x52aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xb5b6, 0x0861, 0x0861, 0x0861, 0x630c, 0x9cd3, 0x3186, 0x2124, 0x31a6, 0xa534, 0xf79e, 0xf79e, 0xf79e, 0xef7d, 0xf79e, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71b, 0xe6b6, 0xe60f, 0xe567, 0xdd6a, 0x72e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2901, 0xbc86, 0xe60f, 0xe6b6, 0xe73b, 0xef3c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xe75d, 0xce79, 0xa575, 0x7c71, 0x434c, 0x0a89, 0x0a68, 0x0a28, 0x09c6, 0x0944, 0x0924, 0x0965, 0x0965, 0x0944, 0x21c6, 0x634c, 0xb5b6, 0xf79e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xf79e, 0xce79, 0x9cf3, 0x7bcf, 0x5acb, 0xf79e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xef7d, 0x9cf3, 0x73ae, 0x39e7, 0x630c, 0xb596, 0x0861, 0x0861, 0x39e7, 0xce59, 0xf79e, 0xf79e, 0xf79e, 0xf79d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe696, 0xe5ec, 0xe568, 0xdd48, 0x6ae6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20c1, 0xb446, 0xe5aa, 0xe651, 0xe71b, 0xef3c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xe73c, 0xce9a, 0xb5f7, 0x9d34, 0x94b2, 0x94b2, 0x9d34, 0xad75, 0xc659, 0xef5d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xf79e, 0xdefb, 0xe71c, 0x94b2, 0x9cf3, 0xad55, 0xf7be, 0xf7be, 0xf79e, 0xf77c, 0xf739, 0xf6f6, 0xef39, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71b, 0xe6b6, 0xe5cc, 0xe568, 0xd548, 0x62a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa3e5, 0xe5a9, 0xe630, 0xe6f9, 0xef3c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf79e, 0xf738, 0xf671, 0xf62e, 0xf64f, 0xf64f, 0xee91, 0xeed6, 0xef3a, 0xef5c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71b, 0xe6b7, 0xe5ab, 0xe567, 0xd549, 0x6285, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8b65, 0xe588, 0xe631, 0xe6f8, 0xef3c, 0xef3c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xf7be, 0xf7be, 0xf79d, 0xf738, 0xf670, 0xf5ea, 0xf5eb, 0xf62c, 0xee0b, 0xedeb, 0xee0c, 0xee71, 0xeeb5, 0xeef8, 0xef19, 0xef3b, 0xef3c, 0xef3c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71b, 0xe695, 0xe5cc, 0xe568, 0xd549, 0x6264, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7b05, 0xe568, 0xe60f, 0xe6d7, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xef7d, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xf7be, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xf7be, 0xf7be, 0xf7be, 0xf738, 0xf670, 0xf5eb, 0xd54b, 0x8bca, 0xb4ce, 0xcd6e, 0xe60d, 0xedeb, 0xedca, 0xedeb, 0xedec, 0xee2e, 0xee73, 0xeed7, 0xef1a, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe73c, 0xe71c, 0xe71b, 0xe695, 0xe5cd, 0xe546, 0xd54b, 0x5a45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6aa3, 0xdd48, 0xe5ed, 0xe6d7, 0xe73b, 0xe73c, 0xef5d, 0xef5d, 0xef5d, 0xef3b, 0xef19, 0xeef8, 0xeeb4, 0xee71, 0xee70, 0xeed5, 0xf75a, 0xf79e, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffd, 0xff12, 0xfed0, 0xff34, 0xffbb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xf7be, 0xf7be, 0xf759, 0xf691, 0xf5eb, 0xcd2c, 0x0000, 0x0000, 0x0000, 0x2924, 0x62e9, 0x93ea, 0xb48a, 0xcd2b, 0xe5cc, 0xedca, 0xeda9, 0xedca, 0xe60e, 0xe674, 0xe6b6, 0xe6d8, 0xe6f9, 0xe6fa, 0xe71b, 0xe71c, 0xe71b, 0xe674, 0xe5ab, 0xe567, 0xcd29, 0x5224, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a23, 0xdd48, 0xe5cb, 0xe6b7, 0xe73b, 0xef3c, 0xef3c, 0xef3b, 0xef19, 0xeeb4, 0xee50, 0xedec, 0xedca, 0xdd69, 0xcd29, 0xedea, 0xee2d, 0xf718, 0xf79e, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffc, 0xff76, 0xff76, 0xfffd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffba, 0xfed0, 0xfeae, 0xfe8e, 0xfed1, 0xff57, 0xffdd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffde, 0xf7be, 0xf79c, 0xf6b3, 0xf60b, 0xdd8c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3163, 0x6ac7, 0x93c9, 0xb48a, 0xcd2a, 0xe58a, 0xe5aa, 0xe5cb, 0xe5cc, 0xe5cd, 0xe60f, 0xe673, 0xe6b7, 0xe6d8, 0xe653, 0xe5aa, 0xe567, 0xcd08, 0x5205, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x49e2, 0xcd08, 0xe5cc, 0xe6b5, 0xe71a, 0xe71b, 0xe6f9, 0xeeb5, 0xee30, 0xedcb, 0xedca, 0xd54a, 0xac27, 0x72c5, 0x20c1, 0xa407, 0xedeb, 0xf670, 0xf719, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffd, 0xff77, 0xfecf, 0xfecf, 0xff33, 0xfffc, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffe, 0xff76, 0xfed0, 0xbceb, 0xc50b, 0xfe8f, 0xfeaf, 0xff13, 0xffbc, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xf7be, 0xf7be, 0xf6d5, 0xf60b, 0xe5ed, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3984, 0x6ac6, 0x93a7, 0xac47, 0xcce8, 0xe589, 0xe588, 0xe588, 0xe5aa, 0xe5ed, 0xe5cd, 0xe567, 0xe547, 0xcd09, 0x49e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3962, 0xc4a6, 0xe5cb, 0xe672, 0xe6f9, 0xe673, 0xe60f, 0xe5cb, 0xeda9, 0xcd08, 0x9be6, 0x6284, 0x1081, 0x0000, 0x0000, 0x0000, 0xbcc9, 0xedeb, 0xf6b3, 0xf75a, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffdf, 0xffdf, 0xffde, 0xffde, 0xffde, 0xffde, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffe, 0xff77, 0xfef1, 0xfed0, 0xfecf, 0xfecf, 0xff54, 0xfffc, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffe, 0xff55, 0xfed0, 0x7b69, 0x0000, 0x8389, 0xee2e, 0xfeaf, 0xfed1, 0xff78, 0xffdd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffdf, 0xffbe, 0xf6f5, 0xf62c, 0xee2e, 0x3163, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3162, 0x6aa5, 0x93a6, 0xac46, 0xccc6, 0xdd47, 0xe567, 0xdd46, 0xe546, 0xcd09, 0x41c4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2901, 0xbc86, 0xe587, 0xe5aa, 0xe5ec, 0xe5a9, 0xe568, 0xc4c7, 0x93a6, 0x5a24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xdd6a, 0xf60c, 0xf6f7, 0xf77c, 0xf79e, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffde, 0xffde, 0xffbd, 0xff16, 0xfed2, 0xfef3, 0xff79, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffb9, 0xff32, 0xff12, 0xaced, 0xacec, 0xff11, 0xfed0, 0xff75, 0xfffc, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffd, 0xff54, 0xfeb0, 0x41e5, 0x0000, 0x0000, 0x39a4, 0xbccb, 0xfe8f, 0xfe8f, 0xff14, 0xffbb, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffbe, 0xf6f5, 0xf62c, 0xf64d, 0x4a05, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3983, 0x6ac4, 0x9385, 0xac25, 0xccc6, 0xc4ea, 0x41c4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20c1, 0xac26, 0xe567, 0xe567, 0xdd47, 0xbc87, 0x8b86, 0x49c3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41c3, 0xedeb, 0xf64e, 0xf718, 0xf79d, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffbe, 0xffbd, 0xff59, 0xfeb1, 0xfe6e, 0xfe6d, 0xfe8e, 0xff14, 0xffdd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffe, 0xff55, 0xfef0, 0xde53, 0x2103, 0x0000, 0xacee, 0xff11, 0xff11, 0xff75, 0xfffd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffd, 0xff11, 0xe60e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7327, 0xe5ee, 0xfe8f, 0xfed1, 0xff57, 0xffde, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffdf, 0xffbe, 0xf6f6, 0xf64d, 0xf64d, 0x62a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41a3, 0x41e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9be6, 0xdd27, 0xb446, 0x8324, 0x41a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7b05, 0xf5eb, 0xf690, 0xf739, 0xf79d, 0xf7be, 0xf7be, 0xf7be, 0xf7be, 0xffbd, 0xff7a, 0xfef4, 0xfe6e, 0xfe4d, 0xf66f, 0xee0d, 0xfe6e, 0xfed1, 0xff78, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xff97, 0xff12, 0xf713, 0x62e8, 0x0000, 0x0000, 0x0000, 0xad0e, 0xff32, 0xff11, 0xff75, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffc, 0xfef1, 0xc54d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3163, 0xb4ab, 0xfe6e, 0xfeaf, 0xfef3, 0xffbb, 0xffde, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffdf, 0xffde, 0xff37, 0xf66e, 0xf64d, 0x7b26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41a3, 0x72e5, 0x3121, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9be7, 0xf60c, 0xf6b3, 0xf75b, 0xf79d, 0xf7be, 0xf7be, 0xf7be, 0xff7b, 0xfef4, 0xfe6f, 0xfe4d, 0xfe90, 0xd5af, 0x6ae8, 0x7b48, 0xfeb0, 0xfe8e, 0xff14, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffb, 0xff33, 0xff33, 0xa4ef, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0e, 0xff11, 0xff12, 0xff75, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffc, 0xfef1, 0xa48c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6ac6, 0xddcd, 0xfe8e, 0xfeb0, 0xff58, 0xffdd, 0xffff, 0xffff, 0xffff, 0xffdf, 0xffde, 0xff37, 0xf66f, 0xf64d, 0x8b88, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbca8, 0xf60c, 0xf6f6, 0xf77c, 0xf7be, 0xf7be, 0xf77c, 0xf716, 0xf66f, 0xfe4d, 0xfe4d, 0xe610, 0x83aa, 0x18a2, 0x0000, 0x0000, 0xcd8f, 0xfe6e, 0xfed1, 0xff98, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffd, 0xff54, 0xff11, 0xd674, 0x2123, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0e, 0xff11, 0xff11, 0xff75, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffb9, 0xfef1, 0x7b69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2943, 0xa449, 0xf64e, 0xfe8f, 0xff14, 0xff9b, 0xfffe, 0xffff, 0xffdf, 0xffdf, 0xff37, 0xfe8f, 0xf64d, 0x9be8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd54a, 0xf62d, 0xf75a, 0xf79d, 0xf77c, 0xf738, 0xf691, 0xfe4d, 0xfe4d, 0xee50, 0xa46c, 0x2943, 0x0000, 0x0000, 0x0000, 0x0000, 0x62a7, 0xfe8f, 0xfeaf, 0xfef2, 0xffdd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffe, 0xffb8, 0xfef1, 0xf6f3, 0x62e9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0d, 0xff11, 0xff11, 0xff97, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffd, 0xff97, 0xfef2, 0x41e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6286, 0xd58d, 0xfe6e, 0xfed1, 0xff37, 0xffbd, 0xffde, 0xffdf, 0xff79, 0xfeb1, 0xfe4d, 0xac49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41a3, 0xedeb, 0xf64e, 0xf75a, 0xf75a, 0xf6d4, 0xf62d, 0xf62d, 0xf64f, 0xb4ed, 0x4a06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbd2e, 0xfeaf, 0xfeb0, 0xff77, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffb, 0xff33, 0xff32, 0xa4cf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xaced, 0xff32, 0xff12, 0xffb8, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffd, 0xff96, 0xe650, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20e2, 0x9c09, 0xf62e, 0xfe8e, 0xfed1, 0xff9c, 0xffde, 0xff79, 0xfed2, 0xfe4d, 0xb48a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72e5, 0xf60c, 0xf66f, 0xf6b2, 0xf66f, 0xf62c, 0xf66e, 0xcd8e, 0x6ae8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a06, 0xf690, 0xfeaf, 0xff12, 0xffdc, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffc, 0xff76, 0xff32, 0xd652, 0x18c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0e, 0xff32, 0xff32, 0xffb8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffc, 0xff75, 0xc56e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5205, 0xcd2b, 0xfe6e, 0xfeb0, 0xff36, 0xff36, 0xfed2, 0xfe4d, 0xc4ea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9bc7, 0xf60b, 0xf60b, 0xf60b, 0xf62c, 0xddce, 0x838a, 0x18a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xacad, 0xfeb0, 0xfed0, 0xffb9, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xff98, 0xff11, 0xf714, 0x5ac8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0e, 0xff31, 0xff53, 0xffb8, 0xffff, 0xffff, 0xffff, 0xffff, 0xfffb, 0xff53, 0xa4ac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8ba8, 0xeded, 0xfe6d, 0xfe8f, 0xfe8f, 0xfe4d, 0xcd2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb489, 0xf60b, 0xf60c, 0xe60e, 0x9c2a, 0x2943, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3184, 0xee2f, 0xfed0, 0xff33, 0xffdb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffda, 0xff55, 0xff75, 0x9ccf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0d, 0xff32, 0xff53, 0xffb8, 0xffff, 0xffff, 0xffff, 0xffda, 0xff33, 0x7b89, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x49e4, 0xc4eb, 0xfe4d, 0xfe4d, 0xfe4d, 0xdd6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd54b, 0xee0e, 0xb4ab, 0x41e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x940b, 0xfef1, 0xfef1, 0xff98, 0xfffe, 0xffff, 0xffff, 0xfffe, 0xff76, 0xff53, 0xd654, 0x18c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0d, 0xff32, 0xff33, 0xffd8, 0xffff, 0xfffd, 0xffb8, 0xff13, 0x41e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7b27, 0xe5cc, 0xfe4d, 0xe5ed, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x39c7, 0xc5b4, 0x6ae7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2103, 0xde0f, 0xfef1, 0xff34, 0xffdb, 0xffff, 0xffff, 0xff97, 0xff32, 0xf736, 0x52a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xaced, 0xff32, 0xff32, 0xffb7, 0xff96, 0xff32, 0xe691, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3983, 0xb48a, 0xee2f, 0x2103, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18c3, 0x18c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7348, 0xff12, 0xfef0, 0xff77, 0xfffe, 0xfffc, 0xff33, 0xff74, 0x9c8e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0d, 0xff33, 0xff32, 0xff32, 0xff11, 0xc58e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7329, 0x2944, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xcdb0, 0xfed0, 0xff11, 0xff33, 0xff32, 0xff33, 0xd655, 0x18c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0e, 0xff32, 0xff32, 0xff11, 0xa48c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x62a7, 0xfed1, 0xfef1, 0xfef1, 0xff12, 0xf734, 0x5268, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0d, 0xff53, 0xff32, 0x7b68, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb52e, 0xff11, 0xff11, 0xff75, 0x948e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad0e, 0xfef1, 0x41e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a05, 0xf6b0, 0xff33, 0xce12, 0x18c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x940a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa48c, 0xef15, 0x4a47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2964, 0x73ac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};
#define banner_pixel 16200
#define MAXR 31
#define MINR 0
#define MAXG 63
#define MING 0
#define MAXB 31
#define MINB 0

View File

@ -0,0 +1,27 @@
/*
* THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
* PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
* TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
* INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
* DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
* THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
* FULL TEXT OF THE NON-WARRANTY PROVISIONS.
*
* USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
* RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
* TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
* AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
* SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
* THE UNITED STATES.
*
* COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
*/
#ifndef __FX_INLINE_H__
#define __FX_INLINE_H__
/* The # of 2-byte entries in the hw fog table */
#define kInternalFogTableEntryCount 0x40UL
#endif /* __FX_INLINE_H__ */

View File

@ -0,0 +1,199 @@
/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
**
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.
**
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
**
** $Header: /cvsroot/macglide/MacGLide/glide2x/sst1/glide/src/gbanner.c,v 1.2 2005/07/20 20:45:56 jens-olaf Exp $
** $Log: gbanner.c,v $
** Revision 1.2 2005/07/20 20:45:56 jens-olaf
** Commented out unwanted code instead of using #define statements
**
** Revision 1.1 2005/07/09 21:28:54 jens-olaf
** Added splash screen and shameless plug
**
** Revision 1.1.1.1 1999/12/07 21:48:52 joseph
** Initial checkin into SourceForge.
**
*
* 9 5/02/97 2:08p Pgj
* screen_width/height now FxU32
*
* 8 3/16/97 2:24a Jdt
* Fixed bug. Didn't initialize info.
*
* 7 3/12/97 11:51p Jdt
* Watcom warning.
*
* 6 3/12/97 4:20p Jdt
* Fixed for VG96 and optimized SST-1
*
* 5 2/26/97 11:55a Jdt
* Updated banner for new lfb api
*
* 4 12/23/96 1:37p Dow
* chagnes for multiplatform glide
**
*/
/*
#include <3dfx.h>
#include <glidesys.h>
#define FX_DLL_DEFINITION
#include <fxdll.h>
#include <glide.h>
#include "fxglide.h"
*/
// OpenGLide specific
#include "../../../driversrc_defines.h"
#ifdef GLIDE_PLUG
#include "banner.inc"
#endif
/* display the translucent 3Dfx powerfield logo */
void
_grShamelessPlug( void )
{
// #ifdef GLIDE_PLUG
GrState state;
GrLfbInfo_t info;
GR_BEGIN_NOFIFOCHECK("_grShamelessPlug",80);
GDBG_INFO_MORE((gc->myLevel,"()\n"));
// #if ( GLIDE_PLATFORM & GLIDE_HW_SST1 )
grGlideGetState( &state );
grDisableAllEffects();
grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_CONSTANT,
GR_COMBINE_OTHER_TEXTURE, FXFALSE );
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_NONE,
GR_COMBINE_OTHER_TEXTURE,
FXFALSE );
grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,
GR_BLEND_ONE_MINUS_SRC_ALPHA,
GR_BLEND_ZERO, GR_BLEND_ZERO );
grClipWindow( 0, 0,
Glide.WindowWidth - 1,
Glide.WindowHeight - 1);
grDepthMask(FXFALSE);
grDepthBufferFunction(GR_CMP_ALWAYS);
grDepthBufferMode( GR_DEPTHBUFFER_DISABLE );
grChromakeyValue( 0x0000 );
grChromakeyMode( GR_CHROMAKEY_ENABLE );
grLfbConstantAlpha( (FxU8) 90);
grLfbWriteColorFormat(GR_COLORFORMAT_ARGB);
/* Attempt to lock with pixpipe enabled */
info.size = sizeof( info );
if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER,
GR_LFBWRITEMODE_565,GR_ORIGIN_UPPER_LEFT,
FXTRUE, &info ) ) {
FxU32 *dstData;
FxU32 dstJump;
FxU32 *srcData;
FxI32 srcJump;
FxU32 srcScanlineLength;
FxU32 scrWidth = Glide.WindowWidth;
FxU32 scrHeight = Glide.WindowHeight;
FxU32 scanline;
/* Draw Banner in lower right of screen */
if ( scrWidth < (FxU32)banner_width ) return;
if ( scrHeight < (FxU32)banner_height ) return;
dstData = static_cast<unsigned long*>(info.lfbPtr);
dstData = (FxU32*)( ((char*)dstData) +
(info.strideInBytes*((scrHeight-1)-banner_height)) +
((scrWidth-banner_width)<<1) );
dstJump = ((info.strideInBytes >> 1) - banner_width)>>1;
srcData = (FxU32*)&banner_data[banner_width*(banner_height-1)];
srcScanlineLength = banner_width>>1;
srcJump = (-banner_width);
for( scanline = 0; scanline < (FxU32)banner_height; scanline++ ) {
FxU32 *end = srcData + srcScanlineLength;
while( srcData < end ) *dstData++ = *srcData++;
dstData += dstJump;
srcData += srcJump;
}
grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
}
grGlideSetState( &state );
/*
#elif ( GLIDE_PLATFORM & GLIDE_HW_SST96 )
FXUNUSED( state );
info.size = sizeof( info );
if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER,
GR_LFBWRITEMODE_565,GR_ORIGIN_UPPER_LEFT,
FXFALSE, &info ) ) {
FxU16 *dstData;
FxU32 dstJump;
FxU16 *srcData;
FxI32 srcJump;
FxU32 srcScanlineLength;
FxU32 scrWidth = gc->state.screen_width;
FxU32 scrHeight = gc->state.screen_height;
FxU32 scanline;
// Draw Banner in lower right of screen
if ( scrWidth < (FxU32)banner_width ) return;
if ( scrHeight < (FxU32)banner_height ) return;
dstData = info.lfbPtr;
dstData = (FxU16*)( ((char*)dstData) +
(info.strideInBytes*((scrHeight-1)-banner_height)) +
((scrWidth-banner_width)<<1) );
dstJump = ((info.strideInBytes >> 1) - banner_width);
srcData = (FxU16*)&banner_data[banner_width*(banner_height-1)];
srcScanlineLength = banner_width;
srcJump = (-banner_width)*2;
for( scanline = 0; scanline < (FxU32)banner_height; scanline++ ) {
FxU16 *end = srcData + srcScanlineLength;
while( srcData < end ) {
if ( *srcData )
*dstData = *srcData;
dstData++;
srcData++;
}
dstData += dstJump;
srcData += srcJump;
}
grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
}
#else
# error "Shameless Plug Unimplemented on this Hardware"
#endif
*/
// GR_END();
// #endif
} /* _grShamelessPlug */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff