Added Uq-Ruan Masters game - it compiles but does not work (renders too slowly? Another problem?)
This commit is contained in:
204
project/jni/application/sc2/AUTHORS
Normal file
204
project/jni/application/sc2/AUTHORS
Normal file
@@ -0,0 +1,204 @@
|
||||
We worship these two higher beings for making the original, legendary game:
|
||||
Fred Ford
|
||||
Paul Reiche III
|
||||
|
||||
|
||||
The Ur-Quan Masters port:
|
||||
-------------------------
|
||||
|
||||
Core team (in alphabetical order):
|
||||
Serge van den Boom <svdb@stack.nl>
|
||||
Mika Kolehmainen <mk@kapsi.fi>
|
||||
Michael Chapman Martin <mcmartin@gmail.com>
|
||||
Chris Nelson <chris@toysforbob.com>
|
||||
Alex Volkov <codepro@usa.net>
|
||||
|
||||
Additional programming (in alphabetical order):
|
||||
Geoffrey Hausheer <uqm-devel@phracturedblue.com>
|
||||
Nicolas Simonds <uqm@submedia.net>
|
||||
|
||||
Music remixers (in alphabetical order):
|
||||
Jouni Airaksinen <markvera@spacesynth.net>
|
||||
Tore Aune Fjellstad
|
||||
Espen Gätzschmann
|
||||
Aaron J. Grier <agrier@poofygoof.com>
|
||||
Dan Nicholson <dan@kosmic.org>
|
||||
George Nowik <norgio@attbi.com>
|
||||
Riku Nuottajärvi <riku.nuottajarvi@pp.inet.fi>
|
||||
Erol Otus <erol@toysforbob.com>
|
||||
|
||||
Other contributions (in alphabetical order):
|
||||
Jouni Airaksinen <markvera@spacesynth.net> (Startup Menu)
|
||||
Karl Bartel <karlb@gmx.net>
|
||||
Travis Chase <cftc@shaw.ca> (BeOS port)
|
||||
Felix Lazarev <felix@freedo.org> (3DO internals)
|
||||
Parker MacMillan
|
||||
Sanjay Madhav <madhav@usc.edu> (code patches)
|
||||
Robert McNamara <robert@americantenor.com> (MacOS X stuff)
|
||||
Mike Melanson (ADPCM basis from FFmpeg used for DUK audio)
|
||||
Mudrony Laszlo <mudronyl@dragon.klte.hu> (PC/DOS content unpacking)
|
||||
Erol Otus <erol@toysforbob.com> (Splash screen)
|
||||
Brian Rogers <burpmaster@truffula.net>
|
||||
Horatiu Romosan <hory@post.ro> (v0.1 Win32 installer)
|
||||
Zarla Sheenaza <astronia@aol.com> (0.6 Win32 installer graphics)
|
||||
Joffrey Smith (setup graphics)
|
||||
Peter van Valderen <p.vanvalderen@chello.nl>
|
||||
Alex Volkov <codepro@usa.net> (additional slides)
|
||||
Alexander Waseleski <Paxtez@hotmail.com> (code patches)
|
||||
Yukki (v0.1 Win32 installer graphics)
|
||||
|
||||
|
||||
Original game:
|
||||
--------------
|
||||
|
||||
Programming & technology:
|
||||
Fred Ford
|
||||
|
||||
Game design and fiction:
|
||||
Paul Reiche III
|
||||
|
||||
3DO programming:
|
||||
Ken Ford
|
||||
Fred Ford
|
||||
Brad Van Tighem
|
||||
|
||||
Producer (3DO version):
|
||||
Mark Wallace
|
||||
|
||||
3DO production:
|
||||
Paul Reiche III
|
||||
Richard Antaki
|
||||
|
||||
Starring the voices of:
|
||||
Richard Antaki ....... Thraddash
|
||||
Alex Bennett ......... Starbase Commander
|
||||
Rich Betz ............ Ariloulaleelay
|
||||
............ Druuge
|
||||
Roy Blumenfeld ....... Zoq-Fot-Pik
|
||||
David Bryce .......... Kohr-Ah
|
||||
.......... Ilwrath
|
||||
.......... Shofixti
|
||||
.......... Spathi
|
||||
Lauren Forcella ...... Supox
|
||||
Greg Johnson ......... Orz
|
||||
......... Pkunk
|
||||
......... Utwig
|
||||
Bruce Leyland ........ Yehat
|
||||
Erol Otus ............ Chmmr
|
||||
Paul Reiche III ...... Mycon
|
||||
...... Talking Pet
|
||||
Brad Van Tighem ...... Slylandro Speaker
|
||||
Madeleine Wild ....... Zoq-Fot-Pik
|
||||
....... Syreen
|
||||
....... VUX
|
||||
Larry Zee ............ Umgah
|
||||
............ Melnorme
|
||||
............ Ur-Quan
|
||||
840-AV ............... Slylandro Probe
|
||||
Paul II, Paul III .... Victory Sequence
|
||||
Arianna & Devin Reiche
|
||||
|
||||
Voice effects:
|
||||
Jeff Forehan
|
||||
Burke Treischmann
|
||||
Mark Miller
|
||||
|
||||
Voice editing:
|
||||
Richard Antaki
|
||||
Paul Reiche III
|
||||
Burke Treischmann
|
||||
Steve Henefin
|
||||
Jeremy Bredow
|
||||
Erik Griss
|
||||
Brad Van Tighem
|
||||
|
||||
Art and animation:
|
||||
George Barr
|
||||
Paul Reiche III
|
||||
Erol Otus
|
||||
Greg Johnson
|
||||
Kyle Balda
|
||||
Jeff Rianda
|
||||
Taunya Shiffer
|
||||
Leonard Robel
|
||||
Greg Hammond
|
||||
Armand Cabrera
|
||||
Silicon Knights
|
||||
|
||||
Additional writing:
|
||||
Greg Johnson
|
||||
Mat Genser
|
||||
Robert Leyland
|
||||
Iain McCaig
|
||||
Tomi Quintana
|
||||
Erol Otus
|
||||
Leonard Robel
|
||||
John Estes
|
||||
|
||||
Music:
|
||||
Burke Treischmann
|
||||
Dan Nicholson
|
||||
Riku Nuottajärvi
|
||||
Eric Berge
|
||||
Erol Otus
|
||||
Marc Brown
|
||||
Aaron Grier
|
||||
Kevin Palivec
|
||||
Tommy Dunbar
|
||||
|
||||
3D cinemagraphics:
|
||||
Gene Bodio
|
||||
Phil Le Marbre
|
||||
TrueMotion(R) "S" Video Compression by The Duck Corporation
|
||||
|
||||
Product marketing manager (3DO version):
|
||||
Jim Curry
|
||||
|
||||
3DO testers:
|
||||
Susan Michele
|
||||
Jeremy Bredow
|
||||
Wes Gittens
|
||||
Ty Johnson
|
||||
Tate Schieferle
|
||||
Carolina Esmurdoc
|
||||
Rob Johnson
|
||||
Kevin Kwan
|
||||
Joe Ganis
|
||||
Chang Fadel
|
||||
Erik Griss
|
||||
Eugene Law
|
||||
Mark Ybarra
|
||||
Steve Groll
|
||||
Tim Jordan
|
||||
Matt Young
|
||||
|
||||
PC/DOS testers:
|
||||
Pam Levins
|
||||
Tomi Quintana
|
||||
Joel Dinolt
|
||||
Robert Daly
|
||||
Greg Hammond
|
||||
B.J. Shea
|
||||
Robert Leyland
|
||||
Sean Vikoren
|
||||
Mike Ebert
|
||||
Tony Hsieh
|
||||
ROL
|
||||
Ed Gwynn
|
||||
Akila Redmer
|
||||
Russell Bornschlegel
|
||||
Steve Graziano
|
||||
Mark Voorsanger
|
||||
|
||||
Special thanks to:
|
||||
Greg Johnson
|
||||
John Ratcliffe
|
||||
|
||||
Paul's Foundation:
|
||||
Laurie
|
||||
Devin
|
||||
and Arianna
|
||||
|
||||
Got us 86'ed out of a restaurant in Las Vegas:
|
||||
Madeline Canepa (we love her anyway)
|
||||
|
||||
21
project/jni/application/sc2/AppSettings.cfg
Normal file
21
project/jni/application/sc2/AppSettings.cfg
Normal file
@@ -0,0 +1,21 @@
|
||||
AppSettingVersion=4
|
||||
LibSdlVersion=1.2
|
||||
AppName="Ur-Quan Masters"
|
||||
AppFullName=com.sourceforge.sc2
|
||||
ScreenOrientation=h
|
||||
AppDataDownloadUrl="Main game data is 11 Mb|-http://prdownloads.sourceforge.net/sc2/uqm-0.6.0-content.uqm?download^3DO music (19 Mb)|-http://prdownloads.sourceforge.net/sc2/uqm-0.6.0-3domusic.uqm?download^UQM music remix pack 1 (50 Mb)|-http://prdownloads.sourceforge.net/sc2/uqm-remix-pack1.zip?download^UQM music remix pack 2 (60 Mb)|-http://prdownloads.sourceforge.net/sc2/uqm-remix-pack2.zip?download^UQM music remix pack 3 (40 Mb)|-http://prdownloads.sourceforge.net/sc2/uqm-remix-pack3.zip?download^Voice (115 Mb)|http://prdownloads.sourceforge.net/sc2/uqm-0.6.0-voice.uqm?download"
|
||||
SdlVideoResize=y
|
||||
NeedDepthBuffer=n
|
||||
AppUsesMouse=n
|
||||
AppNeedsArrowKeys=y
|
||||
AppUsesJoystick=n
|
||||
AppUsesMultitouch=n
|
||||
RedefinedKeys="RETURN RCTRL KP_PLUS KP_MINUS ESCAPE F10"
|
||||
AppTouchscreenKeyboardKeysAmount=2
|
||||
MultiABI=n
|
||||
AppVersionCode=1001
|
||||
AppVersionName="1.0.01"
|
||||
CompiledLibraries="sdl_image"
|
||||
AppCflags='-O0 -DTHREADLIB_SDL=1 -DTIMELIB=SDL -DOVCODEC_TREMOR=1 -DNETPLAY=1 -DHAVE_REGEX=1 -DHAVE_GETOPT_LONG=1'
|
||||
AppLdflags='-Lbin/ndk/local/armeabi -ltremor'
|
||||
ReadmeText='^You may press "Home" now - the data will be downloaded in background'
|
||||
5
project/jni/application/sc2/BUGS
Normal file
5
project/jni/application/sc2/BUGS
Normal file
@@ -0,0 +1,5 @@
|
||||
All known bugs and missing features are listed in our online bug database,
|
||||
which can be found at
|
||||
http://bugs.uqm.stack.nl/
|
||||
New bugs that you may find can be reported at the same location.
|
||||
|
||||
944
project/jni/application/sc2/COPYING
Normal file
944
project/jni/application/sc2/COPYING
Normal file
@@ -0,0 +1,944 @@
|
||||
|
||||
The Ur-Quan Masters
|
||||
Copyright (C) 1992, 2002 Toys for Bob, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be entertaining,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details. A copy of the
|
||||
General Public License is included at the end of this document.
|
||||
|
||||
The content -- voiceovers, dialogue, graphics, sounds, and music --
|
||||
are copyright (C) 1992, 1993, 2002 Toys for Bob, Inc. or their
|
||||
respective creators. The content may be used freely under the
|
||||
terms of the Creative Commons Attribution-NonCommercial-ShareAlike
|
||||
2.5 license (included below, and also available at
|
||||
http://creativecommons.org/licenses/by-nc-sa/2.5/). The content
|
||||
may also be copied freely as part of a distribution of The Ur-Quan
|
||||
Masters.
|
||||
|
||||
The documentation -- excluding documentation that is part of the
|
||||
code or otherwise clearly governed by the preceding licenses --
|
||||
may be used freely under the terms of the Creative Commons
|
||||
Attribution 2.0 license (included below, and also available at
|
||||
http://creativecommons.org/licenses/by/2.0/).
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, 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 or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
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 give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
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 Program or any portion
|
||||
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
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 Program, 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 Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) 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; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, 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 executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or 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 counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||
|
||||
5. 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 Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program 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 to
|
||||
this License.
|
||||
|
||||
7. 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 Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program 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 Program.
|
||||
|
||||
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.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program 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.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 Program
|
||||
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 Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, 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
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), 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 Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
CREATIVE COMMONS LICENSE
|
||||
Attribution-NonCommercial-ShareAlike 2.5
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL
|
||||
SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT
|
||||
RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS"
|
||||
BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION
|
||||
PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
|
||||
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
|
||||
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
|
||||
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
|
||||
TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE
|
||||
RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
|
||||
CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "Collective Work" means a work, such as a periodical issue,
|
||||
anthology or encyclopedia, in which the Work in its entirety in
|
||||
unmodified form, along with a number of other contributions,
|
||||
constituting separate and independent works in themselves, are
|
||||
assembled into a collective whole. A work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work (as
|
||||
defined below) for the purposes of this License.
|
||||
|
||||
b. "Derivative Work" means a work based upon the Work or upon the
|
||||
Work and other pre-existing works, such as a translation,
|
||||
musical arrangement, dramatization, fictionalization, motion
|
||||
picture version, sound recording, art reproduction, abridgment,
|
||||
condensation, or any other form in which the Work may be recast,
|
||||
transformed, or adapted, except that a work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work for the
|
||||
purpose of this License. For the avoidance of doubt, where the
|
||||
Work is a musical composition or sound recording, the
|
||||
synchronization of the Work in timed-relation with a moving
|
||||
image ("synching") will be considered a Derivative Work for the
|
||||
purpose of this License.
|
||||
|
||||
c. "Licensor" means the individual or entity that offers the Work
|
||||
under the terms of this License.
|
||||
|
||||
d. "Original Author" means the individual or entity who created the
|
||||
Work.
|
||||
|
||||
e. "Work" means the copyrightable work of authorship offered under
|
||||
the terms of this License.
|
||||
|
||||
f. "You" means an individual or entity exercising rights under this
|
||||
License who has not previously violated the terms of this
|
||||
License with respect to the Work, or who has received express
|
||||
permission from the Licensor to exercise rights under this
|
||||
License despite a previous violation.
|
||||
|
||||
g. "License Elements" means the following high-level license
|
||||
attributes as selected by Licensor and indicated in the title of
|
||||
this License: Attribution, Noncommercial, ShareAlike.
|
||||
|
||||
2. Fair Use Rights. Nothing in this license is intended to reduce,
|
||||
limit, or restrict any rights arising from fair use, first sale or
|
||||
other limitations on the exclusive rights of the copyright owner
|
||||
under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License,
|
||||
Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-exclusive, perpetual (for the duration of the applicable
|
||||
copyright) license to exercise the rights in the Work as stated
|
||||
below:
|
||||
|
||||
a. to reproduce the Work, to incorporate the Work into one or more
|
||||
Collective Works, and to reproduce the Work as incorporated in
|
||||
the Collective Works;
|
||||
|
||||
b. to create and reproduce Derivative Works;
|
||||
|
||||
c. to distribute copies or phonorecords of, display publicly,
|
||||
perform publicly, and perform publicly by means of a digital
|
||||
audio transmission the Work including as incorporated in
|
||||
Collective Works;
|
||||
|
||||
d. to distribute copies or phonorecords of, display publicly,
|
||||
perform publicly, and perform publicly by means of a digital
|
||||
audio transmission Derivative Works;
|
||||
|
||||
The above rights may be exercised in all media and formats whether
|
||||
now known or hereafter devised. The above rights include the right
|
||||
to make such modifications as are technically necessary to exercise
|
||||
the rights in other media and formats. All rights not expressly
|
||||
granted by Licensor are hereby reserved, including but not limited
|
||||
to the rights set forth in Sections 4(e) and 4(f).
|
||||
|
||||
4. Restrictions.
|
||||
|
||||
The license granted in Section 3 above is expressly made subject to and
|
||||
limited by the following restrictions:
|
||||
|
||||
a. You may distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work only under the terms of this
|
||||
License, and You must include a copy of, or the Uniform Resource
|
||||
Identifier for, this License with every copy or phonorecord of
|
||||
the Work You distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform. You may not offer or impose any
|
||||
terms on the Work that alter or restrict the terms of this
|
||||
License or the recipients' exercise of the rights granted
|
||||
hereunder. You may not sublicense the Work. You must keep intact
|
||||
all notices that refer to this License and to the disclaimer of
|
||||
warranties. You may not distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform the Work with any
|
||||
technological measures that control access or use of the Work in
|
||||
a manner inconsistent with the terms of this License
|
||||
Agreement. The above applies to the Work as incorporated in a
|
||||
Collective Work, but this does not require the Collective Work
|
||||
apart from the Work itself to be made subject to the terms of
|
||||
this License. If You create a Collective Work, upon notice from
|
||||
any Licensor You must, to the extent practicable, remove from
|
||||
the Collective Work any credit as required by clause 4(d), as
|
||||
requested. If You create a Derivative Work, upon notice from any
|
||||
Licensor You must, to the extent practicable, remove from the
|
||||
Derivative Work any credit as required by clause 4(d), as
|
||||
requested.
|
||||
|
||||
b. You may distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform a Derivative Work only under the
|
||||
terms of this License, a later version of this License with the
|
||||
same License Elements as this License, or a Creative Commons
|
||||
iCommons license that contains the same License Elements as this
|
||||
License (e.g. Attribution-NonCommercial-ShareAlike 2.5
|
||||
Japan). You must include a copy of, or the Uniform Resource
|
||||
Identifier for, this License or other license specified in the
|
||||
previous sentence with every copy or phonorecord of each
|
||||
Derivative Work You distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform. You may not offer or
|
||||
impose any terms on the Derivative Works that alter or restrict
|
||||
the terms of this License or the recipients' exercise of the
|
||||
rights granted hereunder, and You must keep intact all notices
|
||||
that refer to this License and to the disclaimer of
|
||||
warranties. You may not distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform the Derivative Work with
|
||||
any technological measures that control access or use of the
|
||||
Work in a manner inconsistent with the terms of this License
|
||||
Agreement. The above applies to the Derivative Work as
|
||||
incorporated in a Collective Work, but this does not require the
|
||||
Collective Work apart from the Derivative Work itself to be made
|
||||
subject to the terms of this License.
|
||||
|
||||
c. You may not exercise any of the rights granted to You in Section
|
||||
3 above in any manner that is primarily intended for or directed
|
||||
toward commercial advantage or private monetary
|
||||
compensation. The exchange of the Work for other copyrighted
|
||||
works by means of digital file-sharing or otherwise shall not be
|
||||
considered to be intended for or directed toward commercial
|
||||
advantage or private monetary compensation, provided there is no
|
||||
payment of any monetary compensation in connection with the
|
||||
exchange of copyrighted works.
|
||||
|
||||
d. If you distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work or any Derivative Works or
|
||||
Collective Works, You must keep intact all copyright notices for
|
||||
the Work and provide, reasonable to the medium or means You are
|
||||
utilizing: (i) the name of the Original Author (or pseudonym, if
|
||||
applicable) if supplied, and/or (ii) if the Original Author
|
||||
and/or Licensor designate another party or parties (e.g. a
|
||||
sponsor institute, publishing entity, journal) for attribution
|
||||
in Licensor's copyright notice, terms of service or by other
|
||||
reasonable means, the name of such party or parties; the title
|
||||
of the Work if supplied; to the extent reasonably practicable,
|
||||
the Uniform Resource Identifier, if any, that Licensor specifies
|
||||
to be associated with the Work, unless such URI does not refer
|
||||
to the copyright notice or licensing information for the Work;
|
||||
and in the case of a Derivative Work, a credit identifying the
|
||||
use of the Work in the Derivative Work (e.g., "French
|
||||
translation of the Work by Original Author," or "Screenplay
|
||||
based on original Work by Original Author"). Such credit may be
|
||||
implemented in any reasonable manner; provided, however, that in
|
||||
the case of a Derivative Work or Collective Work, at a minimum
|
||||
such credit will appear where any other comparable authorship
|
||||
credit appears and in a manner at least as prominent as such
|
||||
other comparable authorship credit.
|
||||
|
||||
e. For the avoidance of doubt, where the Work is a musical composition:
|
||||
|
||||
i. Performance Royalties Under Blanket Licenses. Licensor
|
||||
reserves the exclusive right to collect, whether
|
||||
individually or via a performance rights society
|
||||
(e.g. ASCAP, BMI, SESAC), royalties for the public
|
||||
performance or public digital performance (e.g. webcast)
|
||||
of the Work if that performance is primarily intended for
|
||||
or directed toward commercial advantage or private
|
||||
monetary compensation.
|
||||
|
||||
ii. Mechanical Rights and Statutory Royalties. Licensor
|
||||
reserves the exclusive right to collect, whether
|
||||
individually or via a music rights agency or designated
|
||||
agent (e.g. Harry Fox Agency), royalties for any
|
||||
phonorecord You create from the Work ("cover version")
|
||||
and distribute, subject to the compulsory license created
|
||||
by 17 USC Section 115 of the US Copyright Act (or the
|
||||
equivalent in other jurisdictions), if Your distribution
|
||||
of such cover version is primarily intended for or
|
||||
directed toward commercial advantage or private monetary
|
||||
compensation.
|
||||
|
||||
f. Webcasting Rights and Statutory Royalties. For the avoidance of
|
||||
doubt, where the Work is a sound recording, Licensor reserves
|
||||
the exclusive right to collect, whether individually or via a
|
||||
performance-rights society (e.g. SoundExchange), royalties for
|
||||
the public digital performance (e.g. webcast) of the Work,
|
||||
subject to the compulsory license created by 17 USC Section 114
|
||||
of the US Copyright Act (or the equivalent in other
|
||||
jurisdictions), if Your public digital performance is primarily
|
||||
intended for or directed toward commercial advantage or private
|
||||
monetary compensation.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING,
|
||||
LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR
|
||||
WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED,
|
||||
STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF
|
||||
TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY,
|
||||
OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED
|
||||
WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability.
|
||||
|
||||
EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||
LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT
|
||||
OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. This License and the rights granted hereunder will terminate
|
||||
automatically upon any breach by You of the terms of this
|
||||
License. Individuals or entities who have received Derivative
|
||||
Works or Collective Works from You under this License, however,
|
||||
will not have their licenses terminated provided such
|
||||
individuals or entities remain in full compliance with those
|
||||
licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any
|
||||
termination of this License.
|
||||
|
||||
b. Subject to the above terms and conditions, the license granted
|
||||
here is perpetual (for the duration of the applicable copyright
|
||||
in the Work). Notwithstanding the above, Licensor reserves the
|
||||
right to release the Work under different license terms or to
|
||||
stop distributing the Work at any time; provided, however that
|
||||
any such election will not serve to withdraw this License (or
|
||||
any other license that has been, or is required to be, granted
|
||||
under the terms of this License), and this License will continue
|
||||
in full force and effect unless terminated as stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You distribute or publicly digitally perform the Work
|
||||
or a Collective Work, the Licensor offers to the recipient a
|
||||
license to the Work on the same terms and conditions as the
|
||||
license granted to You under this License.
|
||||
|
||||
b. Each time You distribute or publicly digitally perform a
|
||||
Derivative Work, Licensor offers to the recipient a license to
|
||||
the original Work on the same terms and conditions as the
|
||||
license granted to You under this License.
|
||||
|
||||
c. If any provision of this License is invalid or unenforceable
|
||||
under applicable law, it shall not affect the validity or
|
||||
enforceability of the remainder of the terms of this License,
|
||||
and without further action by the parties to this agreement,
|
||||
such provision shall be reformed to the minimum extent necessary
|
||||
to make such provision valid and enforceable.
|
||||
|
||||
d. No term or provision of this License shall be deemed waived and
|
||||
no breach consented to unless such waiver or consent shall be in
|
||||
writing and signed by the party to be charged with such waiver
|
||||
or consent.
|
||||
|
||||
e. This License constitutes the entire agreement between the
|
||||
parties with respect to the Work licensed here. There are no
|
||||
understandings, agreements or representations with respect to
|
||||
the Work not specified here. Licensor shall not be bound by any
|
||||
additional provisions that may appear in any communication from
|
||||
You. This License may not be modified without the mutual written
|
||||
agreement of the Licensor and You.
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be
|
||||
liable to You or any party on any legal theory for any damages
|
||||
whatsoever, including without limitation any general, special,
|
||||
incidental or consequential damages arising in connection to this
|
||||
license. Notwithstanding the foregoing two (2) sentences, if Creative
|
||||
Commons has expressly identified itself as the Licensor hereunder, it
|
||||
shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the
|
||||
Work is licensed under the CCPL, neither party will use the trademark
|
||||
"Creative Commons" or any related trademark or logo of Creative
|
||||
Commons without the prior written consent of Creative Commons. Any
|
||||
permitted use will be in compliance with Creative Commons'
|
||||
then-current trademark usage guidelines, as may be published on its
|
||||
website or otherwise made available upon request from time to time.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
CREATIVE COMMONS LICENSE ATTRIBUTION-2.0
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
|
||||
DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
|
||||
CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS
|
||||
PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE
|
||||
WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS
|
||||
PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
|
||||
AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS
|
||||
YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF
|
||||
SUCH TERMS AND CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "Collective Work" means a work, such as a periodical issue,
|
||||
anthology or encyclopedia, in which the Work in its entirety in
|
||||
unmodified form, along with a number of other contributions,
|
||||
constituting separate and independent works in themselves, are
|
||||
assembled into a collective whole. A work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work (as
|
||||
defined below) for the purposes of this License.
|
||||
|
||||
b. "Derivative Work" means a work based upon the Work or upon the
|
||||
Work and other pre-existing works, such as a translation,
|
||||
musical arrangement, dramatization, fictionalization, motion
|
||||
picture version, sound recording, art reproduction, abridgment,
|
||||
condensation, or any other form in which the Work may be recast,
|
||||
transformed, or adapted, except that a work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work for the
|
||||
purpose of this License. For the avoidance of doubt, where the
|
||||
Work is a musical composition or sound recording, the
|
||||
synchronization of the Work in timed-relation with a moving
|
||||
image ("synching") will be considered a Derivative Work for the
|
||||
purpose of this License.
|
||||
|
||||
c. "Licensor" means the individual or entity that offers the Work
|
||||
under the terms of this License.
|
||||
|
||||
d. "Original Author" means the individual or entity who created the
|
||||
Work.
|
||||
|
||||
e. "Work" means the copyrightable work of authorship offered under
|
||||
the terms of this License.
|
||||
|
||||
f. "You" means an individual or entity exercising rights under this
|
||||
License who has not previously violated the terms of this
|
||||
License with respect to the Work, or who has received express
|
||||
permission from the Licensor to exercise rights under this
|
||||
License despite a previous violation.
|
||||
|
||||
2. Fair Use Rights. Nothing in this license is intended to reduce,
|
||||
limit, or restrict any rights arising from fair use, first sale or
|
||||
other limitations on the exclusive rights of the copyright owner
|
||||
under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License,
|
||||
Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-exclusive, perpetual (for the duration of the applicable
|
||||
copyright) license to exercise the rights in the Work as stated
|
||||
below:
|
||||
|
||||
a. to reproduce the Work, to incorporate the Work into one or more
|
||||
Collective Works, and to reproduce the Work as incorporated in
|
||||
the Collective Works;
|
||||
|
||||
b. to create and reproduce Derivative Works;
|
||||
|
||||
c. to distribute copies or phonorecords of, display publicly,
|
||||
perform publicly, and perform publicly by means of a digital
|
||||
audio transmission the Work including as incorporated in
|
||||
Collective Works;
|
||||
|
||||
d. to distribute copies or phonorecords of, display publicly,
|
||||
perform publicly, and perform publicly by means of a digital
|
||||
audio transmission Derivative Works.
|
||||
|
||||
e. For the avoidance of doubt, where the work is a musical
|
||||
composition:
|
||||
|
||||
i. Performance Royalties Under Blanket Licenses. Licensor
|
||||
waives the exclusive right to collect, whether
|
||||
individually or via a performance rights society
|
||||
(e.g. ASCAP, BMI, SESAC), royalties for the public
|
||||
performance or public digital performance (e.g. webcast)
|
||||
of the Work.
|
||||
|
||||
ii. Mechanical Rights and Statutory Royalties. Licensor
|
||||
waives the exclusive right to collect, whether
|
||||
individually or via a music rights agency or designated
|
||||
agent (e.g. Harry Fox Agency), royalties for any
|
||||
phonorecord You create from the Work ("cover version")
|
||||
and distribute, subject to the compulsory license created
|
||||
by 17 USC Section 115 of the US Copyright Act (or the
|
||||
equivalent in other jurisdictions).
|
||||
|
||||
f. Webcasting Rights and Statutory Royalties. For the avoidance of
|
||||
doubt, where the Work is a sound recording, Licensor waives the
|
||||
exclusive right to collect, whether individually or via a
|
||||
performance-rights society (e.g. SoundExchange), royalties for
|
||||
the public digital performance (e.g. webcast) of the Work,
|
||||
subject to the compulsory license created by 17 USC Section 114
|
||||
of the US Copyright Act (or the equivalent in other
|
||||
jurisdictions).
|
||||
|
||||
The above rights may be exercised in all media and formats whether
|
||||
now known or hereafter devised. The above rights include the right
|
||||
to make such modifications as are technically necessary to exercise
|
||||
the rights in other media and formats. All rights not expressly
|
||||
granted by Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly
|
||||
made subject to and limited by the following restrictions:
|
||||
|
||||
a. You may distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work only under the terms of this
|
||||
License, and You must include a copy of, or the Uniform Resource
|
||||
Identifier for, this License with every copy or phonorecord of
|
||||
the Work You distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform. You may not offer or impose any
|
||||
terms on the Work that alter or restrict the terms of this
|
||||
License or the recipients' exercise of the rights granted
|
||||
hereunder. You may not sublicense the Work. You must keep intact
|
||||
all notices that refer to this License and to the disclaimer of
|
||||
warranties. You may not distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform the Work with any
|
||||
technological measures that control access or use of the Work in
|
||||
a manner inconsistent with the terms of this License
|
||||
Agreement. The above applies to the Work as incorporated in a
|
||||
Collective Work, but this does not require the Collective Work
|
||||
apart from the Work itself to be made subject to the terms of
|
||||
this License. If You create a Collective Work, upon notice from
|
||||
any Licensor You must, to the extent practicable, remove from
|
||||
the Collective Work any reference to such Licensor or the
|
||||
Original Author, as requested. If You create a Derivative Work,
|
||||
upon notice from any Licensor You must, to the extent
|
||||
practicable, remove from the Derivative Work any reference to
|
||||
such Licensor or the Original Author, as requested.
|
||||
|
||||
b. If you distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work or any Derivative Works or
|
||||
Collective Works, You must keep intact all copyright notices for
|
||||
the Work and give the Original Author credit reasonable to the
|
||||
medium or means You are utilizing by conveying the name (or
|
||||
pseudonym if applicable) of the Original Author if supplied; the
|
||||
title of the Work if supplied; to the extent reasonably
|
||||
practicable, the Uniform Resource Identifier, if any, that
|
||||
Licensor specifies to be associated with the Work, unless such
|
||||
URI does not refer to the copyright notice or licensing
|
||||
information for the Work; and in the case of a Derivative Work,
|
||||
a credit identifying the use of the Work in the Derivative Work
|
||||
(e.g., "French translation of the Work by Original Author," or
|
||||
"Screenplay based on original Work by Original Author"). Such
|
||||
credit may be implemented in any reasonable manner; provided,
|
||||
however, that in the case of a Derivative Work or Collective
|
||||
Work, at a minimum such credit will appear where any other
|
||||
comparable authorship credit appears and in a manner at least as
|
||||
prominent as such other comparable authorship credit.
|
||||
|
||||
5. Representations, Warranties and Disclaimer. UNLESS OTHERWISE
|
||||
MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK
|
||||
AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
|
||||
CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
|
||||
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
|
||||
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF
|
||||
ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW
|
||||
THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY
|
||||
TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY
|
||||
APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY
|
||||
LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE
|
||||
OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE
|
||||
WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. This License and the rights granted hereunder will terminate
|
||||
automatically upon any breach by You of the terms of this
|
||||
License. Individuals or entities who have received Derivative
|
||||
Works or Collective Works from You under this License, however,
|
||||
will not have their licenses terminated provided such
|
||||
individuals or entities remain in full compliance with those
|
||||
licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any
|
||||
termination of this License.
|
||||
|
||||
b. Subject to the above terms and conditions, the license granted
|
||||
here is perpetual (for the duration of the applicable copyright
|
||||
in the Work). Notwithstanding the above, Licensor reserves the
|
||||
right to release the Work under different license terms or to
|
||||
stop distributing the Work at any time; provided, however that
|
||||
any such election will not serve to withdraw this License (or
|
||||
any other license that has been, or is required to be, granted
|
||||
under the terms of this License), and this License will continue
|
||||
in full force and effect unless terminated as stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You distribute or publicly digitally perform the Work
|
||||
or a Collective Work, the Licensor offers to the recipient a
|
||||
license to the Work on the same terms and conditions as the
|
||||
license granted to You under this License.
|
||||
|
||||
b. Each time You distribute or publicly digitally perform a
|
||||
Derivative Work, Licensor offers to the recipient a license to
|
||||
the original Work on the same terms and conditions as the
|
||||
license granted to You under this License.
|
||||
|
||||
c. If any provision of this License is invalid or unenforceable
|
||||
under applicable law, it shall not affect the validity or
|
||||
enforceability of the remainder of the terms of this License,
|
||||
and without further action by the parties to this agreement,
|
||||
such provision shall be reformed to the minimum extent necessary
|
||||
to make such provision valid and enforceable.
|
||||
|
||||
d. No term or provision of this License shall be deemed waived and
|
||||
no breach consented to unless such waiver or consent shall be in
|
||||
writing and signed by the party to be charged with such waiver
|
||||
or consent.
|
||||
|
||||
e. This License constitutes the entire agreement between the
|
||||
parties with respect to the Work licensed here. There are no
|
||||
understandings, agreements or representations with respect to
|
||||
the Work not specified here. Licensor shall not be bound by any
|
||||
additional provisions that may appear in any communication from
|
||||
You. This License may not be modified without the mutual written
|
||||
agreement of the Licensor and You.
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be
|
||||
liable to You or any party on any legal theory for any damages
|
||||
whatsoever, including without limitation any general, special,
|
||||
incidental or consequential damages arising in connection to this
|
||||
license. Notwithstanding the foregoing two (2) sentences, if Creative
|
||||
Commons has expressly identified itself as the Licensor hereunder, it
|
||||
shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the
|
||||
Work is licensed under the CCPL, neither party will use the trademark
|
||||
"Creative Commons" or any related trademark or logo of Creative
|
||||
Commons without the prior written consent of Creative Commons. Any
|
||||
permitted use will be in compliance with Creative Commons'
|
||||
then-current trademark usage guidelines, as may be published on its
|
||||
website or otherwise made available upon request from time to time.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
||||
1082
project/jni/application/sc2/ChangeLog
Normal file
1082
project/jni/application/sc2/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
135
project/jni/application/sc2/Contributing
Normal file
135
project/jni/application/sc2/Contributing
Normal file
@@ -0,0 +1,135 @@
|
||||
These are some guidelines for people who want to contribute to the code.
|
||||
Don't be surprised if your contributions get tossed in the bit-bucket if you
|
||||
do not follow them. We don't want to be unfriendly, but our time is limited.
|
||||
These guidelines are there so that you won't waste both our and your time.
|
||||
|
||||
Before making changes:
|
||||
- Read this entire document
|
||||
- See if the the Bugzilla bug database at
|
||||
http://bugs.uqm.stack.nl/ contains any comments on what you're planning
|
||||
to do.
|
||||
- Make sure you're using the most recent Subversion version
|
||||
- Discuss in advance what you're planning to do, with the core team.
|
||||
The best place to do this is on #sc2 on irc.freenode.net.
|
||||
This prevents you from wasting your time when
|
||||
- someone else is already working on your issue
|
||||
- we've got a very clear idea of how we want it to be
|
||||
- the code you're planning to change will be completely rewritten
|
||||
in the near future.
|
||||
- Don't bother on adding "great ideas" you have for the game;
|
||||
Our current goal is a straight port. The code is GPL, so feel free
|
||||
to start your own modified version, but don't bother sending them
|
||||
in for the official version.
|
||||
|
||||
Making changes:
|
||||
- Follow the coding style of the existing source. You don't have to like it,
|
||||
we don't even always do, but we've accepted this as our standard. The main
|
||||
reason is that this is very close to the original style.
|
||||
Trying to start a discussion about the standard is pointless and is
|
||||
definately NOT appreciated.
|
||||
- Use 1 tab per indentation level
|
||||
- Use no more than 76 chars on a line, when using a tabsize of 4.
|
||||
- Use 2 extra indentation levels for the continuation of a broken line,
|
||||
like this:
|
||||
if (blablablabla || foobar ||
|
||||
zut || linefiller ||
|
||||
morezut)
|
||||
printf ("Yeah!\n");
|
||||
- Don't use tabs for anything but indenting. If you would, and someone
|
||||
has a different tab size, or something in the line changes, other stuff
|
||||
on the line may or may not move, depending on where on the line it is.
|
||||
If you for instance want to align a list of declarations, use spaces,
|
||||
like this:
|
||||
{
|
||||
<TAB>long l,
|
||||
<TAB> m;
|
||||
<TAB>int i;
|
||||
}
|
||||
(Though in this particular case, I personally would repeat the 'long',
|
||||
or place l and m on the same line)
|
||||
- Put { on a seperate line, both for the start of a function and
|
||||
for the start of a block.
|
||||
- one space around binary operators, and after commas.
|
||||
- one space between the function name and following '(', both in
|
||||
declaration and call (unusual as it is).
|
||||
- one space after 'if', 'while', 'do', 'for' and 'switch'.
|
||||
- even for short selections or repetitions, don't have the statement
|
||||
to execute on the same line as the guard. So:
|
||||
if (a)
|
||||
a--;
|
||||
- Use unix-style line-endings, that is '\n' only. If the editor you're
|
||||
using doesn't support this, please pass your code through a conversion
|
||||
program before submitting.
|
||||
- Don't hurry into changing code. All code is there for a reason. Be sure
|
||||
you understand that reason before changing it. Don't just go recode a part
|
||||
because you think that would be easier than trying to understand the
|
||||
original. If you don't have the skills or patience to do so, this is not
|
||||
the place for you.
|
||||
- Only use portable functions. The code is intended to work on Windows,
|
||||
Linux, FreeBSD, BeOS and MacOS X.
|
||||
Try to avoid unnecessary system-dependant code, but use #ifdefs if you
|
||||
really have to.
|
||||
- No shortcuts. Don't assume anything about user input (like the length),
|
||||
and check the return values of functions that may fail.
|
||||
- Your code shouldn't cause any compile-time or runtime-warnings. We know
|
||||
the current source is far from warning-free, but those should be removed
|
||||
eventually and we don't want to make it worse.
|
||||
- Don't add comment lines saying things like "This line added by <me>".
|
||||
These comments only foul the code and don't add anything for people
|
||||
reading it. You'll still be credited in the Changelog, and for large
|
||||
contributions (or many small ones) in the authors list. We have
|
||||
Subversion for when we need to find out when what changes were made.
|
||||
|
||||
Making the patches:
|
||||
- One issue per patch.
|
||||
We need to keep track of what's being changed, and multiple changes
|
||||
in one patch will make that more difficult.
|
||||
Also, we might want to accept one patch, and reject the other.
|
||||
- Use unified diffs.
|
||||
That way, there's a bigger chance the patch can be automatically applied
|
||||
successfully against modified files.
|
||||
- Make the patches against the current Subversion tree.
|
||||
|
||||
Test the patches:
|
||||
- If possible, test your changes both on Windows and a *nix platform, or
|
||||
send them to someone to test them for you.
|
||||
|
||||
Getting the patches committed:
|
||||
- Either attach the patches to the appropriate bug report in the Bugzilla
|
||||
bug database or send them to one of the committers, in plain-text format.
|
||||
This can be done by email, DCC from within the #sc2 channel, or by
|
||||
mentioning an URL where we can get the patch.
|
||||
The committers are listed below (in alphabetical order), with their
|
||||
particular field of expertise with the source. Though all of us
|
||||
should have enough experience to deal with most issues not explicitely
|
||||
mentioned.
|
||||
Serge van den Boom (svdb at stack.nl), Meep-Eep at #sc2
|
||||
- Resource system
|
||||
- 3DO historical code
|
||||
- *nix build system
|
||||
- Netplay
|
||||
- General issues (particularly on *nix)
|
||||
Mika Kolehmainen (mk at kapsi.fi), Gwl at #sc2
|
||||
- Graphics
|
||||
- Sound
|
||||
- General issues
|
||||
Michael Martin (mcmartin at stanford.edu), McMartin at #sc2
|
||||
- Threading
|
||||
- Alien communications code
|
||||
- Graphics
|
||||
- Input system
|
||||
- In-game configuration
|
||||
- General issues
|
||||
Alex Volkov (codepro at usa.net), fOSSiL at #sc2
|
||||
- Graphics
|
||||
- Sound (particularly MixSDL)
|
||||
- General issues
|
||||
- Only submit code that can be used under the GPL. By submitting code you
|
||||
hold the copyright to, you agree that it can be used under the term of
|
||||
the GPL. If you use code by someone else, make sure that it can be used
|
||||
under the GPL and let us know, so that adequate credit can be given.
|
||||
|
||||
|
||||
Initial version of this file by Serge van den Boom, 2002-12-05.
|
||||
|
||||
|
||||
21
project/jni/application/sc2/README
Normal file
21
project/jni/application/sc2/README
Normal file
@@ -0,0 +1,21 @@
|
||||
You're looking at the readme for 'The Ur-Quan Masters', a volunteer
|
||||
project that intends to bring the classic game 'Star Control II' to
|
||||
modern systems.
|
||||
|
||||
The program code that comprises 'The Ur-Quan Masters' was derived from code
|
||||
written by Toys for Bob, Inc. for the 3DO version of 'Star Control II', with
|
||||
their permission and encouragement.
|
||||
|
||||
If you've got this file from the source tree, you can find everything
|
||||
you need to get started in INSTALL (INSTALL.mingw for MinGW) and
|
||||
doc/users/unixinstall.
|
||||
|
||||
The home page of the project is located at http://sc2.sourceforge.net/
|
||||
You can find links to downloads, our bug database, and our forum there.
|
||||
|
||||
Have fun!
|
||||
|
||||
|
||||
Star Control II is a registered trademark of Accolade, Inc.
|
||||
All other trademarks and tradenames belong to their respective owners.
|
||||
|
||||
370
project/jni/application/sc2/WhatsNew
Normal file
370
project/jni/application/sc2/WhatsNew
Normal file
@@ -0,0 +1,370 @@
|
||||
This file tries to organize and describe the changes between releases.
|
||||
Changes are broadly classified into the following categories:
|
||||
|
||||
- New Features: These are either elements of the original games that
|
||||
were first implemented in this release, or actually new capabilities
|
||||
that are visible to the user.
|
||||
|
||||
- Bugfixes: The removal of visible Bad Things from the code.
|
||||
|
||||
- Internal Changes: The removal of invisible Bad Things from the code,
|
||||
or changes in the way the program itself is structured. These are
|
||||
unlikely to be of interest to you unless you plan on coding
|
||||
extensions.
|
||||
|
||||
Version 0.6
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- Netplay! You can now engage in Super Melee over the Internet.
|
||||
- Key configuration is now entirely in-game.
|
||||
- UQM now compiles and runs on 64-bit systems.
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- The Quit button (F10) now works properly when used during the
|
||||
introduction sequence.
|
||||
- Various small fixes to text and conversation logic.
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- The setup menu now reads all its text from the content, easing
|
||||
translation.
|
||||
- The MOD player for PC-style music can now be linked against an
|
||||
external version of libmikmod.
|
||||
- Various code cleanups and memory optimizations.
|
||||
|
||||
Version 0.5
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- The Starmap is searchable! Type / then the beginning of the
|
||||
constellation name, and you can tab through all possible
|
||||
completions.
|
||||
- New 'hq' scaler, based on Maxim Stepin's "HQ2X" scaler. See
|
||||
www.hiend3d.com/hq2x.html for more details.
|
||||
- Scalers can use MMX/SSE/3DNow! instructions for significant speed
|
||||
improvements. The "Processor pack" is necessary for compilation of
|
||||
same on VC6.
|
||||
- Imported DOS versions of many graphics; these have richer palettes
|
||||
and so generally look better
|
||||
- There's a proper credit roll at the end of the game now.
|
||||
- Superior Planet handling: topographical maps scaled far more
|
||||
precisely; optional 3DO-style throbbing slave shield; planets are
|
||||
finally rotating spheres instead of spotlit cylinders or rectangles.
|
||||
The old PC-style "Entering Planetary Orbit..." screen is back.
|
||||
- Setup Menu far more complete and easy to use, and selections made in
|
||||
the Setup Menu will actually persist when you restart the program
|
||||
- Added support for the Tremor Ogg Vorbis decoder (avoids floating point
|
||||
math)
|
||||
- Home, End and BackSpace keys work as you'd expect in text input.
|
||||
- Most of the game works with Unicode properly now, and so, with proper
|
||||
font characters installed, will work with non-Latin alphabets. (On
|
||||
Windows, Unicode input requires a very recent version of SDL.)
|
||||
- Text may be input with the joystick again, as on the 3DO. The
|
||||
available characters are stored in content/lbm/joyalpha.txt.
|
||||
- The intro now plays only when a new game is started.
|
||||
- Color depth is now determined entirely automatically.
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Only SELECT and CANCEL trigger the fade-to-black at the end of a
|
||||
Super Melee, solving the issue of invisible "Really Quit?" menus for
|
||||
Super Melee. The "quit during fades" problem in general is still
|
||||
extant.
|
||||
- Many dialog, and comm animation, and general graphical fixes
|
||||
- Keypress status is not reset when entering battle mode, so (for
|
||||
instance) Melnorme ships can continue to charge a shot across
|
||||
battles.
|
||||
- The Melnorme would occasionally strip off Plot Points as part of a
|
||||
fuel deal. No longer.
|
||||
- Bugs in the original code prevented certain ships from properly
|
||||
spawning in "uncontrolled" space. The "wilds" are now a bit wilder,
|
||||
as apparently originally intended.
|
||||
- Venus's atmospheric density was incorrectly corrected in the 3DO
|
||||
version. It's been correctly corrected now.
|
||||
- Scheduled plot events work properly, even when the game suddenly
|
||||
skips ahead in time.
|
||||
- Fixed version checking in unix build scripts. SDL 1.2.10 is now
|
||||
recognised as newer than 1.2.9.
|
||||
- Spliced communications can be safely skipped past now.
|
||||
- Fixed fast escape weirdness (bug #619)
|
||||
- Threading system no longer assumes that there is no thread 0; this
|
||||
permits compilation on AmigaOS.
|
||||
- Relative paths and fallback paths work properly now.
|
||||
- Scalers now use surface pitch instead of image width - this is
|
||||
reported to solve many strange display problems in non-OpenGL mode
|
||||
on Macs
|
||||
- Ending sequences may now be safely paused.
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- Added the rest of devel/ and users/ documentation into MSVC .dsp
|
||||
files.
|
||||
- Control scheme upgraded. Old versions of keys.cfg will no longer
|
||||
work.
|
||||
- PNG transparency info (tRNS chunk) is now set properly, based on
|
||||
info in the .ani files.
|
||||
- Paletted images should render much faster now, and collisions
|
||||
between mods are less likely.
|
||||
- New font engine: fonts are loaded and treated as alpha-channel-only
|
||||
images, with font effects handled as backing images.
|
||||
- Melee works properly with alpha-channel graphics new, even when
|
||||
mipmapped.
|
||||
- Lander report drawing handled more sensibly now
|
||||
- Binary resource indexes have been replaced with textual ones.
|
||||
- All spritework is done internally in 32BPP.
|
||||
- Removed MikMod i/o hacks.
|
||||
- The temp files for representing star and group data are now kept in
|
||||
memory instead.
|
||||
- Separate config_win.h file for build.sh builds on Windows
|
||||
- Lowered some animation rates to reasonable levels, lowering CPU
|
||||
usage.
|
||||
- Changed comm subtitle caching scheme. Should kill the "blue comm
|
||||
screen" problem forever.
|
||||
- Refactored setup menu code to use generic widgets.
|
||||
- Cleaner build output. Set '$MAKE_VERBOSE' to 1 for old output.
|
||||
- Improved dependency tracking for unix build system. "./build.sh uqm
|
||||
depend" is now only needed for checking for new source files.
|
||||
|
||||
Version 0.4
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- Savegame slot defaults to the last one used during this play
|
||||
- PC intro and ending sequence are now present
|
||||
- 3DO intro and ending movies are supported for those who have these
|
||||
movies from the 3DO CD of Star Control II
|
||||
- Improved slave shield graphics
|
||||
- Added a new -l option to produce logfiles
|
||||
- Added a new 'triscan' scaler derived from scale2x
|
||||
- Made the fact that self-destructing ships grant resources more obvious
|
||||
- Added a "config dir" option for holding saves and melee information
|
||||
- Cocoa hooks
|
||||
- Setup menu now permits configuration of some options. They do not
|
||||
yet persist past program quit, though.
|
||||
- Added a "--version" option
|
||||
- Melee images are now based on the (richer) DOS content
|
||||
- 3-step melee zooming as per the PC version is now implemented
|
||||
- It is now possible to complete the game without ever allying with the
|
||||
Starbase (if one is insane; this is known on the forum as "Beating The
|
||||
Game Differently" - but bugs and plot elements preventing this have been
|
||||
fixed or evaded under this circumstance).
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Fixes to the Quit Confirmation dialog
|
||||
- Collisions/encounters with "invisible" fleeing ships gone
|
||||
- Other ships insystem remain in proper locations after planet landing
|
||||
- Fixed some keyboard "focus" problems where flight controls were
|
||||
being cleared at inappropriate times, or interfering with menus
|
||||
- Graphics fixes
|
||||
- Subtitle timings work in the absence of oggs
|
||||
- Conversation summaries with Melnorme no longer crash
|
||||
- --contentdir argument may now have spaces
|
||||
- $HOME isn't required for Unix systems anymore
|
||||
- Fuel estimates fixed (original bug)
|
||||
- Fuel usage on planet landing now correcly reported on all versions
|
||||
- MOD music will play on big-endian machines under high-quality now
|
||||
- Space marines die in a self-destructing Scout
|
||||
- ZFP speech is properly vertically aligned now
|
||||
- Various odd behaviors when loading in HyperSpace now fixed
|
||||
- Quitting from the Roster screen no longer crashes
|
||||
- Many dialog fixes
|
||||
- The "Blue Comm Screen" problem no longer occurs
|
||||
- Combat Energy computation in Outfit Flagship screen corrected
|
||||
- A game crash that manifested when pausing after 85 minutes has been
|
||||
corrected
|
||||
- Main menu version number drawn more consistently
|
||||
- Transparency bugfixes - 3DO ending credits, planets in battle
|
||||
- Content packs may also be named ".uqm" - these are really still
|
||||
zip files, but you can't expand them by accident.
|
||||
- One may now configure a joystick without crashing the game if the
|
||||
joystick is not present
|
||||
- Music volume normalized throughout the game
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- Thread system completely reworked to provide more detailed thread
|
||||
information, and to prevent resource leaks
|
||||
- Sound code is now virtualized and separate from game logic
|
||||
- Fine-grained control of menu sounds
|
||||
- Input system fully unified - all parts of the game use the same
|
||||
basic structure now
|
||||
- Build scripts made more robust
|
||||
- Window-drawing code was lifted out of confirm.c and made more general
|
||||
- Lots of debugging functions
|
||||
- Unicode support for game dialogs and fonts
|
||||
- Lots of code cleanups
|
||||
- Documentation of more internals
|
||||
|
||||
|
||||
Version 0.3
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- PC-style shipyard graphics, complete with animated power lines
|
||||
- Selling ships in the shipyards has slightly different controls
|
||||
that make it harder to sell ships accidentally
|
||||
- Main menu displays version number
|
||||
- Added a '-g' option to control gamma correction
|
||||
- Planet spin has been improved
|
||||
- Trilinear (mipmap-based) scaling in melee
|
||||
- PC-style conversation summaries have been implemented
|
||||
- Ship location display in status bar matches original more closely
|
||||
- Game flags (such as AWARE_OF_SAMATRA) that were ignored by half the
|
||||
game (even in the original) now are more universally available
|
||||
- Oscilloscope and Mini-Map have borders now
|
||||
- Commander Hayes won't let you rescue him until he's explained his
|
||||
predicament
|
||||
- Confirmation dialogs are now menu-based
|
||||
- Positional sound effects are available for OpenAL
|
||||
- Delete key works on Super-Melee team editing
|
||||
- Exit key from the Main Menu will quit the game
|
||||
- Quit option available in GAME menu
|
||||
- New Main Menu graphics: Setup (not yet implemented) and Quit are
|
||||
options at the Main Menu now
|
||||
- Cubic resampling in high quality audio mode
|
||||
- PC-style alien outtakes when game is completed
|
||||
- 2 more ship slots in melee, as the PC Star Control 2 had.
|
||||
- All the standard melee teams from the Star Control 2 PC version.
|
||||
- Support for 50 savegames, instead of just 10
|
||||
- 'CREW'/'BATT' instead of icons in melee when using PC menus
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Text entry doesn't freeze up lander reports anymore
|
||||
- VUX warps in at proper range
|
||||
- Distance-based ship effects (Syreen, Slylandro, Kohr-Ah) were screen
|
||||
size dependent
|
||||
- Line clipping fixed
|
||||
- Various communication animation glitches solved
|
||||
- Various melee crashes solved
|
||||
- Various race conditions eliminated
|
||||
- Scaling of graphics is handled by the rendering thread now, solving
|
||||
issues where the background and object scales would drift out of
|
||||
sync
|
||||
- Subtitle text is clipped more carefully
|
||||
- Objects can no longer be scaled to total invisibility
|
||||
- Various dialogue fixes
|
||||
- Crossfade glitches eliminated
|
||||
- Pause and Exit keys function properly everywhere
|
||||
- Visit Count overflow with Yehat and Chmmr patched
|
||||
- Wav loader and color transforms are now endian safe
|
||||
- Menu glitches when leaving the "GAME" menu are gone
|
||||
- Druuge transactions no longer baselessly increase crew cost
|
||||
- Lander speed has been retimed to match 3DO
|
||||
- Audio resampling works now correctly (less cracklings)
|
||||
- MixSDL buffer underrun handling fixed
|
||||
- Some memory leaks have been eliminated
|
||||
- Fixes and speed improvements on bilinear, biadapt, biadv scalers
|
||||
- Various minor graphics glitch fixes
|
||||
- Crew death on planet is now counted properly in all cases
|
||||
- Mouse cursor is now hidden in fullscreen mode
|
||||
- Guardian in Blazer mode being drained by DOGI will no longer
|
||||
result in a non-blazer Guardian with Blazer effects.
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- Legacy graphics code stripped down tremendously, a lot of "poor
|
||||
man's object orientation" has fallen away too. Many uses of
|
||||
function pointers with only one possible value replaced with simple
|
||||
direct calls.
|
||||
- Crossfades require you to explicitly cache the screen before drawing
|
||||
the transition target
|
||||
- User Input code has been completely rewritten
|
||||
- File I/O code has been completely rewritten
|
||||
- Subtitle drawing is now cached as its own sprite; communication
|
||||
screens are much less graphics intensive now
|
||||
- DRAWABLE_DESC uses separately allocated arrays for its frames
|
||||
|
||||
|
||||
Version 0.2
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- Planet info "coarse scan" information available and properly rendered,
|
||||
either in 3DO way (symbols) or PC (text)
|
||||
- 3D spinning planet in orbit window is present, with antialiasing and
|
||||
phong lighting and an animated approach
|
||||
- Pixel-perfect collision detection; Spathi/Mycon are thus playable, and
|
||||
the game is now beatable
|
||||
- Build system enhanced and generalized to handle OpenBSD and FreeBSD cleanly.
|
||||
- Oscilloscope display works in communication now
|
||||
- Color-shading in planet scans
|
||||
- Earth with its slave shield now functions properly
|
||||
- Outfit Starship and Shipyard graphics re-extracted
|
||||
- Save data and temp files are put in a separate directory now
|
||||
- Star sizes and colors are properly differentiated.
|
||||
- Planet surface is smoothed, blurred, and randomized slightly when it's
|
||||
magnified
|
||||
- SIS Status window fully implemented (including gradiated fonts from PC
|
||||
version)
|
||||
- Dialogue "slider" shows how far along the speech is; rewind/forward works
|
||||
- 'ESC' alone lets you emergency-warp-escape
|
||||
- Optional PC version menus
|
||||
- Preliminary support for MacOS X (needs more work)
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Melee screens cleaned up, SuperMelee menus work.
|
||||
- Subtitles now render for all alien races
|
||||
- Major editing of subtitles to match more closely the speeches
|
||||
- Speech and subtitles are now synchronized properly
|
||||
- Autopilot indicator doesn't take over the top of the screen anymore.
|
||||
- Entering star systems on autopilot doesn't crash the system.
|
||||
- Planet scan is properly erased when cancelling/landing
|
||||
- Initial display of planet surface on landing is at correct position
|
||||
- Spheres of influence now move correctly on the starmap
|
||||
- Melnorme correctly compute the required additional credits
|
||||
- Team names switching when selecting the next ship to fight in melee fixed
|
||||
- Commas left dots behind on planetary reports; this is fixed
|
||||
- Screen resets properly after loading/saving
|
||||
- Dialog choices wrap properly
|
||||
- Precursor ship crew count now placed correctly in melee
|
||||
- 'Cued' color transforms in conversations occur at the right time now
|
||||
- SIS correctly predicts its own fuel usage now
|
||||
- Melnorme no longer give away fuel
|
||||
- Flagship modules are properly aligned
|
||||
- The PC soundtrack now loops correctly
|
||||
- Lander upgrades were drawn incorrectly
|
||||
- Autopilot now works in QuasiSpace without fuel
|
||||
- Captain portraits in melee are updated properly now
|
||||
- If you have over 1000 units of a resource, those numbers are properly
|
||||
cleared
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- SDL_mixer has been abandoned in favor of either OpenAL or the new
|
||||
"MixSDL" library built on the basic SDL_audio routines
|
||||
- Color transforms in communications are merged into the core animation
|
||||
thread now, improving speed and stability
|
||||
- Much more flexible handling of commandline options
|
||||
- All allocated memory is allocated through 'safe' routines that abort if
|
||||
the allocation fails.
|
||||
- Thread library now includes condition variables
|
||||
- Threads can tell the rendering thread to sleep until everything they've
|
||||
requested is done
|
||||
- The rendering thread has been recoded to use no heap space and to have a
|
||||
far smaller memory footprint.
|
||||
- Added a special #define, DCQ_OF_DOOM, which simulates severe overload
|
||||
stresses.
|
||||
- SAI and related scalers removed due to GPL incompatibilities; similar
|
||||
algorithms reimplemented under GPL.
|
||||
- Files for the intro and ending sequence have been successfully extracted
|
||||
- Rendering thread routines are somewhat more modular than before
|
||||
- Created a new set of graphics primitives that's much easier to use
|
||||
- Only parts of the screen that actually changed are updated
|
||||
- Input code rewritten entirely
|
||||
- Various functions have their names changed to avoid conflicts with
|
||||
core library routines on OS X
|
||||
|
||||
|
||||
Version 0.1
|
||||
-------------
|
||||
Initial release.
|
||||
BIN
project/jni/application/sc2/icon.png
Normal file
BIN
project/jni/application/sc2/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
20
project/jni/application/sc2/src/Makeinfo
Normal file
20
project/jni/application/sc2/src/Makeinfo
Normal file
@@ -0,0 +1,20 @@
|
||||
uqm_SUBDIRS="libs res uqm"
|
||||
|
||||
if [ "$uqm_HAVE_GETOPT_LONG" = 0 ]; then
|
||||
uqm_SUBDIRS="$uqm_SUBDIRS getopt"
|
||||
fi
|
||||
|
||||
case "$HOST_SYSTEM" in
|
||||
Darwin)
|
||||
uqm_SUBDIRS="$uqm_SUBDIRS darwin"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$uqm_HAVE_REGEX" = 0 ]; then
|
||||
uqm_SUBDIRS="$uqm_SUBDIRS regex"
|
||||
fi
|
||||
|
||||
uqm_CFILES="options.c port.c uqm.c"
|
||||
|
||||
test_CFILES=test.c
|
||||
|
||||
21
project/jni/application/sc2/src/config.h
Normal file
21
project/jni/application/sc2/src/config.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* This file contains some compile-time configuration options.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* In this case, build.sh is not run to generate a config file, so
|
||||
* we use a default file config_vc6.h instead.
|
||||
* If you want anything else than the defaults, you'll have to edit
|
||||
* that file manually. */
|
||||
# include "config_vc6.h"
|
||||
#elif defined(__SYMBIAN32__)
|
||||
# include "symbian/config.h"
|
||||
#elif defined (__MINGW32__) || defined (__CYGWIN__)
|
||||
/* If we're compiling on MS Windows using build.sh, use
|
||||
* config_win.h, generated from src/config_win.h.in. */
|
||||
# include "config_win.h"
|
||||
#else
|
||||
/* If we're compiling in unix, use config_unix.h, generated from
|
||||
* src/config_unix.h.in by build.sh. */
|
||||
# include "config_unix.h"
|
||||
#endif
|
||||
|
||||
67
project/jni/application/sc2/src/config_unix.h
Normal file
67
project/jni/application/sc2/src/config_unix.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* This file contains some compile-time configuration options for *nix
|
||||
* systems.
|
||||
* config_unix.h is generated from config_unix.h.in by build.sh
|
||||
* When building on MS Windows using build.sh (MinGW, Cygwin),
|
||||
* config_win.h is generated from src/config_win.h.in.
|
||||
* When using MSVC on MS Windows, you'll have to edit src/msvc++/config.h
|
||||
* manually if you want anything else than the defaults.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_UNIX_H
|
||||
#define _CONFIG_UNIX_H
|
||||
|
||||
/* Directory where the UQM game data is located */
|
||||
#define CONTENTDIR "."
|
||||
|
||||
/* Directory where game data will be stored */
|
||||
#define USERDIR "."
|
||||
|
||||
/* Directory where config files will be stored */
|
||||
#define CONFIGDIR USERDIR
|
||||
|
||||
/* Directory where supermelee teams will be stored */
|
||||
#define MELEEDIR "${UQM_CONFIG_DIR}/teams/"
|
||||
|
||||
/* Directory where save games will be stored */
|
||||
#define SAVEDIR "${UQM_CONFIG_DIR}/save/"
|
||||
|
||||
/* Defined if words are stored with the most significant byte first */
|
||||
#ifdef __ARMEL__
|
||||
#undef WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
/* Defined if your system has readdir_r of its own */
|
||||
#define HAVE_READDIR_R 1
|
||||
|
||||
/* Defined if your system has setenv of its own */
|
||||
#ifndef HAVE_SETENV
|
||||
#define HAVE_SETENV 1
|
||||
#endif
|
||||
|
||||
/* Defined if your system has strupr of its own */
|
||||
#undef HAVE_STRUPR
|
||||
|
||||
/* Defined if your system has strcasecmp of its own */
|
||||
#define HAVE_STRCASECMP_UQM 1
|
||||
// Not using "HAVE_STRCASECMP" as that conflicts with SDL.
|
||||
|
||||
/* Defined if your system has stricmp of its own */
|
||||
#undef HAVE_STRICMP
|
||||
|
||||
/* Defined if your system has getopt_long */
|
||||
#define HAVE_GETOPT_LONG 1
|
||||
|
||||
/* Defined if your system has iswgraph of its own*/
|
||||
#define HAVE_ISWGRAPH 1
|
||||
|
||||
/* Defined if your system has wchar_t of its own */
|
||||
#define HAVE_WCHAR_T 1
|
||||
|
||||
/* Defined if your system has wint_t of its own */
|
||||
#define HAVE_WINT_T 1
|
||||
|
||||
/* Defined if your system has _Bool of its own */
|
||||
#define HAVE__BOOL 1
|
||||
|
||||
#endif /* _CONFIG_UNIX_H */
|
||||
|
||||
63
project/jni/application/sc2/src/config_unix.h.in
Normal file
63
project/jni/application/sc2/src/config_unix.h.in
Normal file
@@ -0,0 +1,63 @@
|
||||
/* This file contains some compile-time configuration options for *nix
|
||||
* systems.
|
||||
* config_unix.h is generated from config_unix.h.in by build.sh
|
||||
* When building on MS Windows using build.sh (MinGW, Cygwin),
|
||||
* config_win.h is generated from src/config_win.h.in.
|
||||
* When using MSVC on MS Windows, you'll have to edit src/msvc++/config.h
|
||||
* manually if you want anything else than the defaults.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_UNIX_H
|
||||
#define _CONFIG_UNIX_H
|
||||
|
||||
/* Directory where the UQM game data is located */
|
||||
#define CONTENTDIR "@CONTENTDIR@"
|
||||
|
||||
/* Directory where game data will be stored */
|
||||
#define USERDIR "~/.uqm/"
|
||||
|
||||
/* Directory where config files will be stored */
|
||||
#define CONFIGDIR USERDIR
|
||||
|
||||
/* Directory where supermelee teams will be stored */
|
||||
#define MELEEDIR "${UQM_CONFIG_DIR}/teams/"
|
||||
|
||||
/* Directory where save games will be stored */
|
||||
#define SAVEDIR "${UQM_CONFIG_DIR}/save/"
|
||||
|
||||
/* Defined if words are stored with the most significant byte first */
|
||||
@WORDS_BIGENDIAN@
|
||||
|
||||
/* Defined if your system has readdir_r of its own */
|
||||
@HAVE_READDIR_R@
|
||||
|
||||
/* Defined if your system has setenv of its own */
|
||||
@HAVE_SETENV@
|
||||
|
||||
/* Defined if your system has strupr of its own */
|
||||
@HAVE_STRUPR@
|
||||
|
||||
/* Defined if your system has strcasecmp of its own */
|
||||
@HAVE_STRCASECMP_UQM@
|
||||
// Not using "HAVE_STRCASECMP" as that conflicts with SDL.
|
||||
|
||||
/* Defined if your system has stricmp of its own */
|
||||
@HAVE_STRICMP@
|
||||
|
||||
/* Defined if your system has getopt_long */
|
||||
@HAVE_GETOPT_LONG@
|
||||
|
||||
/* Defined if your system has iswgraph of its own*/
|
||||
@HAVE_ISWGRAPH@
|
||||
|
||||
/* Defined if your system has wchar_t of its own */
|
||||
@HAVE_WCHAR_T@
|
||||
|
||||
/* Defined if your system has wint_t of its own */
|
||||
@HAVE_WINT_T@
|
||||
|
||||
/* Defined if your system has _Bool of its own */
|
||||
@HAVE__BOOL@
|
||||
|
||||
#endif /* _CONFIG_UNIX_H */
|
||||
|
||||
61
project/jni/application/sc2/src/config_vc6.h
Normal file
61
project/jni/application/sc2/src/config_vc6.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* This file contains some compile-time configuration options for MS Windows
|
||||
* systems when building using MSVC.
|
||||
* Change the values below if you want anything other than the defaults.
|
||||
* For *nix systems, config_unix.h is used, which is generated by build.sh
|
||||
* from src/config_unix.h.in.
|
||||
* When building on MS Windows using build.sh (MinGW, Cygwin),
|
||||
* config_win.h is generated from src/config_win.h.in.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
/* Directory where the UQM game data is located */
|
||||
#define CONTENTDIR "../content/"
|
||||
|
||||
/* Directory where game data will be stored */
|
||||
//#define USERDIR "../userdata/"
|
||||
#define USERDIR "%APPDATA%/uqm/"
|
||||
|
||||
/* Directory where config files will be stored */
|
||||
#define CONFIGDIR USERDIR
|
||||
|
||||
/* Directory where supermelee teams will be stored */
|
||||
#define MELEEDIR "%UQM_CONFIG_DIR%/teams/"
|
||||
|
||||
/* Directory where save games will be stored */
|
||||
#define SAVEDIR "%UQM_CONFIG_DIR%/save/"
|
||||
|
||||
/* Define if words are stored with the most significant byte first */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* Defined if your system has readdir_r of its own */
|
||||
#undef HAVE_READDIR_R
|
||||
|
||||
/* Defined if your system has setenv of its own */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
/* Defined if your system has strupr of its own */
|
||||
#define HAVE_STRUPR
|
||||
|
||||
/* Defined if your system has strcasecmp of its own */
|
||||
#undef HAVE_STRCASECMP_UQM
|
||||
// Not using "HAVE_STRCASECMP" as that conflicts with SDL.
|
||||
|
||||
/* Defined if your system has stricmp of its own */
|
||||
#define HAVE_STRICMP
|
||||
|
||||
/* Defined if your system has getopt_long */
|
||||
#undef HAVE_GETOPT_LONG
|
||||
|
||||
/* Defined if your system has iswgraph of its own*/
|
||||
#define HAVE_ISWGRAPH
|
||||
|
||||
/* Defined if your system has wchar_t of its own */
|
||||
#define HAVE_WCHAR_T
|
||||
|
||||
/* Defined if your system has wint_t of its own */
|
||||
#define HAVE_WINT_T
|
||||
|
||||
#endif /* _CONFIG_H */
|
||||
|
||||
65
project/jni/application/sc2/src/config_win.h.in
Normal file
65
project/jni/application/sc2/src/config_win.h.in
Normal file
@@ -0,0 +1,65 @@
|
||||
/* This file contains some compile-time configuration options for MS Windows
|
||||
* systems when building using build.sh (MinGW, Cygwin).
|
||||
* config_win.h is generated from src/config_win.h.in by build.sh
|
||||
* For building using MSVC, you'll have to edit src/msvc++/config.h manually
|
||||
* if you want anything else than the defaults.
|
||||
* For *nix systems, config_unix.h is used, which is generated by build.sh
|
||||
* from src/config_unix.h.in.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_WIN_H
|
||||
#define _CONFIG_WIN_H
|
||||
|
||||
/* Directory where the UQM game data is located */
|
||||
#define CONTENTDIR "../content/"
|
||||
|
||||
/* Directory where game data will be stored */
|
||||
//#define USERDIR "../userdata/"
|
||||
#define USERDIR "%APPDATA%/uqm/"
|
||||
|
||||
/* Directory where config files will be stored */
|
||||
#define CONFIGDIR USERDIR
|
||||
|
||||
/* Directory where supermelee teams will be stored */
|
||||
#define MELEEDIR "%UQM_CONFIG_DIR%/teams/"
|
||||
|
||||
/* Directory where save games will be stored */
|
||||
#define SAVEDIR "%UQM_CONFIG_DIR%/save/"
|
||||
|
||||
/* Defined if words are stored with the most significant byte first */
|
||||
@WORDS_BIGENDIAN@
|
||||
|
||||
/* Defined if your system has readdir_r of its own */
|
||||
@HAVE_READDIR_R@
|
||||
|
||||
/* Defined if your system has setenv of its own */
|
||||
@HAVE_SETENV@
|
||||
|
||||
/* Defined if your system has strupr of its own */
|
||||
@HAVE_STRUPR@
|
||||
|
||||
/* Defined if your system has strcasecmp of its own */
|
||||
@HAVE_STRCASECMP_UQM@
|
||||
// Not using "HAVE_STRCASECMP" as that conflicts with SDL.
|
||||
|
||||
/* Defined if your system has stricmp of its own */
|
||||
@HAVE_STRICMP@
|
||||
|
||||
/* Defined if your system has getopt_long */
|
||||
@HAVE_GETOPT_LONG@
|
||||
|
||||
/* Defined if your system has iswgraph of its own*/
|
||||
@HAVE_ISWGRAPH@
|
||||
|
||||
/* Defined if your system has wchar_t of its own */
|
||||
@HAVE_WCHAR_T@
|
||||
|
||||
/* Defined if your system has wint_t of its own */
|
||||
@HAVE_WINT_T@
|
||||
|
||||
/* Defined if your system has _Bool of its own */
|
||||
@HAVE__BOOL@
|
||||
|
||||
#endif /* _CONFIG_WIN_H */
|
||||
|
||||
|
||||
127
project/jni/application/sc2/src/endian_uqm.h
Normal file
127
project/jni/application/sc2/src/endian_uqm.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Endian swapping, taken from SDL-1.2.5 sources and modified
|
||||
* Original copyright (C) Sam Lantinga
|
||||
*/
|
||||
|
||||
#ifndef _ENDIAN_UQM_H
|
||||
#define _ENDIAN_UQM_H
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
|
||||
#if defined (__APPLE__) && defined (__GNUC__)
|
||||
// When using the MacOS gcc compiler to build universal binaries,
|
||||
// each file will be compiled once for each platform.
|
||||
// This means that checking endianness beforehand from build.sh will not do,
|
||||
// but fortunately, gcc defines __BIG_ENDIAN__ or __LITTLE_ENDIAN__ on
|
||||
// this platform.
|
||||
# if defined(__BIG_ENDIAN__)
|
||||
# undef WORDS_BIGENDIAN
|
||||
# define WORDS_BIGENDIAN
|
||||
# elif defined(__LITTLE_ENDIAN__)
|
||||
# undef WORDS_BIGENDIAN
|
||||
# else
|
||||
// Neither __BIG_ENDIAN__ nor __LITTLE_ENDIAN__ is defined.
|
||||
// Fallback to using the build.sh defined value.
|
||||
# endif
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || \
|
||||
defined(__DMC__) || defined(__SC__) || \
|
||||
defined(__WATCOMC__) || defined(__LCC__)
|
||||
#ifndef __inline__
|
||||
#define __inline__ __inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The macros used to swap values */
|
||||
/* Try to use superfast macros on systems that support them */
|
||||
#ifdef linux
|
||||
#include <endian.h>
|
||||
#ifdef __arch__swab16
|
||||
#define UQM_Swap16 __arch__swab16
|
||||
#endif
|
||||
#ifdef __arch__swab32
|
||||
#define UQM_Swap32 __arch__swab32
|
||||
#endif
|
||||
#endif /* linux */
|
||||
/* Use inline functions for compilers that support them, and static
|
||||
functions for those that do not. Because these functions become
|
||||
static for compilers that do not support inline functions, this
|
||||
header should only be included in files that actually use them.
|
||||
*/
|
||||
#ifndef UQM_Swap16
|
||||
static __inline__ uint16 UQM_Swap16(uint16 D)
|
||||
{
|
||||
return((D<<8)|(D>>8));
|
||||
}
|
||||
#endif
|
||||
#ifndef UQM_Swap32
|
||||
static __inline__ uint32 UQM_Swap32(uint32 D)
|
||||
{
|
||||
return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
|
||||
}
|
||||
#endif
|
||||
#ifdef UQM_INT64
|
||||
#ifndef UQM_Swap64
|
||||
static __inline__ uint64 UQM_Swap64(uint64 val)
|
||||
{
|
||||
uint32 hi, lo;
|
||||
|
||||
/* Separate into high and low 32-bit values and swap them */
|
||||
lo = (uint32)(val&0xFFFFFFFF);
|
||||
val >>= 32;
|
||||
hi = (uint32)(val&0xFFFFFFFF);
|
||||
val = UQM_Swap32(lo);
|
||||
val <<= 32;
|
||||
val |= UQM_Swap32(hi);
|
||||
return(val);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#ifndef UQM_Swap64
|
||||
/* This is mainly to keep compilers from complaining in SDL code.
|
||||
If there is no real 64-bit datatype, then compilers will complain about
|
||||
the fake 64-bit datatype that SDL provides when it compiles user code.
|
||||
*/
|
||||
#define UQM_Swap64(X) (X)
|
||||
#endif
|
||||
#endif /* UQM_INT64 */
|
||||
|
||||
|
||||
/* Byteswap item from the specified endianness to the native endianness
|
||||
* or vice versa.
|
||||
*/
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
#define UQM_SwapLE16(X) (X)
|
||||
#define UQM_SwapLE32(X) (X)
|
||||
#define UQM_SwapLE64(X) (X)
|
||||
#define UQM_SwapBE16(X) UQM_Swap16(X)
|
||||
#define UQM_SwapBE32(X) UQM_Swap32(X)
|
||||
#define UQM_SwapBE64(X) UQM_Swap64(X)
|
||||
#else
|
||||
#define UQM_SwapLE16(X) UQM_Swap16(X)
|
||||
#define UQM_SwapLE32(X) UQM_Swap32(X)
|
||||
#define UQM_SwapLE64(X) UQM_Swap64(X)
|
||||
#define UQM_SwapBE16(X) (X)
|
||||
#define UQM_SwapBE32(X) (X)
|
||||
#define UQM_SwapBE64(X) (X)
|
||||
#endif
|
||||
|
||||
#endif /* _ENDIAN_H */
|
||||
14
project/jni/application/sc2/src/libs/Makeinfo
Normal file
14
project/jni/application/sc2/src/libs/Makeinfo
Normal file
@@ -0,0 +1,14 @@
|
||||
uqm_SUBDIRS="callback decomp file graphics heap input list math memory
|
||||
resource sound strings task threads time uio video log"
|
||||
if [ -n "$uqm_USE_INTERNAL_MIKMOD" ]; then
|
||||
uqm_SUBDIRS="$uqm_SUBDIRS mikmod"
|
||||
fi
|
||||
|
||||
if [ -n "$uqm_NETPLAY" ]; then
|
||||
uqm_SUBDIRS="$uqm_SUBDIRS network"
|
||||
fi
|
||||
|
||||
#if [ "$DEBUG" = 1 ]; then
|
||||
# uqm_SUBDIRS="$UQM_SUBDIRS debug"
|
||||
#fi
|
||||
|
||||
2
project/jni/application/sc2/src/libs/alarm.h
Normal file
2
project/jni/application/sc2/src/libs/alarm.h
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "callback/alarm.h"
|
||||
|
||||
2
project/jni/application/sc2/src/libs/callback.h
Normal file
2
project/jni/application/sc2/src/libs/callback.h
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "callback/callback.h"
|
||||
|
||||
2
project/jni/application/sc2/src/libs/callback/Makeinfo
Normal file
2
project/jni/application/sc2/src/libs/callback/Makeinfo
Normal file
@@ -0,0 +1,2 @@
|
||||
uqm_CFILES="alarm.c callback.c"
|
||||
|
||||
134
project/jni/application/sc2/src/libs/callback/alarm.c
Normal file
134
project/jni/application/sc2/src/libs/callback/alarm.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2006 Serge van den Boom <svdb@stack.nl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "alarm.h"
|
||||
|
||||
#include "libs/heap.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
Heap *alarmHeap;
|
||||
|
||||
|
||||
static inline Alarm *
|
||||
Alarm_alloc(void) {
|
||||
return malloc(sizeof (Alarm));
|
||||
}
|
||||
|
||||
static inline void
|
||||
Alarm_free(Alarm *alarm) {
|
||||
free(alarm);
|
||||
}
|
||||
|
||||
static inline int
|
||||
AlarmTime_compare(const AlarmTime t1, const AlarmTime t2) {
|
||||
if (t1 < t2)
|
||||
return -1;
|
||||
if (t2 > t2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
Alarm_compare(const Alarm *a1, const Alarm *a2) {
|
||||
return AlarmTime_compare(a1->time, a2->time);
|
||||
}
|
||||
|
||||
void
|
||||
Alarm_init(void) {
|
||||
assert(alarmHeap == NULL);
|
||||
alarmHeap = Heap_new((HeapValue_Comparator) Alarm_compare,
|
||||
4, 4, 0.8);
|
||||
}
|
||||
|
||||
void
|
||||
Alarm_uninit(void) {
|
||||
assert(alarmHeap != NULL);
|
||||
|
||||
while (Heap_hasMore(alarmHeap)) {
|
||||
Alarm *alarm = (Alarm *) Heap_pop(alarmHeap);
|
||||
Alarm_free(alarm);
|
||||
}
|
||||
Heap_delete(alarmHeap);
|
||||
alarmHeap = NULL;
|
||||
}
|
||||
|
||||
static inline AlarmTime
|
||||
AlarmTime_nowMS(void) {
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
Alarm *
|
||||
Alarm_addRelativeMs(Uint32 ms, AlarmCallback callback,
|
||||
AlarmCallbackArg arg) {
|
||||
Alarm *alarm;
|
||||
|
||||
assert(alarmHeap != NULL);
|
||||
|
||||
alarm = Alarm_alloc();
|
||||
alarm->time = AlarmTime_nowMS() + ms;
|
||||
alarm->callback = callback;
|
||||
alarm->arg = arg;
|
||||
|
||||
Heap_add(alarmHeap, (HeapValue *) alarm);
|
||||
|
||||
return alarm;
|
||||
}
|
||||
|
||||
void
|
||||
Alarm_remove(Alarm *alarm) {
|
||||
assert(alarmHeap != NULL);
|
||||
Heap_remove(alarmHeap, (HeapValue *) alarm);
|
||||
Alarm_free(alarm);
|
||||
}
|
||||
|
||||
// It is safe to call this function again from inside a callback function
|
||||
// that it called. It should not be called from multiple threads at once.
|
||||
void
|
||||
Alarm_process(void) {
|
||||
AlarmTime now;
|
||||
|
||||
assert(alarmHeap != NULL);
|
||||
|
||||
now = AlarmTime_nowMS();
|
||||
while (Heap_hasMore(alarmHeap)) {
|
||||
Alarm *alarm = (Alarm *) Heap_first(alarmHeap);
|
||||
|
||||
if (now < alarm->time)
|
||||
break;
|
||||
|
||||
Heap_pop(alarmHeap);
|
||||
alarm->callback(alarm->arg);
|
||||
Alarm_free(alarm);
|
||||
}
|
||||
}
|
||||
|
||||
Uint32
|
||||
Alarm_timeBeforeNextMs(void) {
|
||||
Alarm *alarm;
|
||||
|
||||
if (!Heap_hasMore(alarmHeap))
|
||||
return UINT32_MAX;
|
||||
|
||||
alarm = (Alarm *) Heap_first(alarmHeap);
|
||||
return alarmTimeToMsUint32(alarm->time);
|
||||
}
|
||||
|
||||
|
||||
54
project/jni/application/sc2/src/libs/callback/alarm.h
Normal file
54
project/jni/application/sc2/src/libs/callback/alarm.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2006 Serge van den Boom <svdb@stack.nl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _ALARM_H
|
||||
#define _ALARM_H
|
||||
|
||||
#include "port.h"
|
||||
#include "types.h"
|
||||
|
||||
#include SDL_INCLUDE(SDL.h)
|
||||
typedef Uint32 AlarmTime;
|
||||
static inline Uint32
|
||||
alarmTimeToMsUint32(AlarmTime time) {
|
||||
return (Uint32) time;
|
||||
}
|
||||
|
||||
typedef struct Alarm Alarm;
|
||||
typedef void *AlarmCallbackArg;
|
||||
typedef void (*AlarmCallback)(AlarmCallbackArg arg);
|
||||
|
||||
struct Alarm {
|
||||
size_t index;
|
||||
// For the HeapValue 'base struct'.
|
||||
|
||||
AlarmTime time;
|
||||
AlarmCallback callback;
|
||||
AlarmCallbackArg arg;
|
||||
};
|
||||
|
||||
void Alarm_init(void);
|
||||
void Alarm_uninit(void);
|
||||
Alarm *Alarm_addRelativeMs(Uint32 ms, AlarmCallback callback,
|
||||
AlarmCallbackArg arg);
|
||||
void Alarm_remove(Alarm *alarm);
|
||||
void Alarm_process(void);
|
||||
Uint32 Alarm_timeBeforeNextMs(void);
|
||||
|
||||
#endif /* _ALARM_H */
|
||||
|
||||
173
project/jni/application/sc2/src/libs/callback/callback.c
Normal file
173
project/jni/application/sc2/src/libs/callback/callback.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2006 Serge van den Boom <svdb@stack.nl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "port.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct CallbackLink CallbackLink;
|
||||
|
||||
#define CALLBACK_INTERNAL
|
||||
#include "callback.h"
|
||||
|
||||
struct CallbackLink {
|
||||
CallbackLink *next;
|
||||
CallbackFunction callback;
|
||||
CallbackArg arg;
|
||||
};
|
||||
|
||||
static CallbackLink *callbacks;
|
||||
static CallbackLink **callbacksEnd;
|
||||
static CallbackLink *const *callbacksProcessEnd;
|
||||
|
||||
static inline void
|
||||
CallbackList_lock(void) {
|
||||
// TODO
|
||||
// Necessary for reentrant operation
|
||||
}
|
||||
|
||||
static inline void
|
||||
CallbackList_unlock(void) {
|
||||
// TODO
|
||||
// Necessary for reentrant operation
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline bool
|
||||
CallbackList_isLocked(void) {
|
||||
// TODO
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
Callback_init(void) {
|
||||
callbacks = NULL;
|
||||
callbacksEnd = &callbacks;
|
||||
callbacksProcessEnd = &callbacks;
|
||||
}
|
||||
|
||||
// Callbacks are guaranteed to be called in the order that they are queued.
|
||||
CallbackID
|
||||
Callback_add(CallbackFunction callback, CallbackArg arg) {
|
||||
CallbackLink *link = malloc(sizeof (CallbackLink));
|
||||
link->callback = callback;
|
||||
link->arg = arg;
|
||||
link->next = NULL;
|
||||
|
||||
CallbackList_lock();
|
||||
*callbacksEnd = link;
|
||||
callbacksEnd = &link->next;
|
||||
CallbackList_unlock();
|
||||
return (CallbackID) link;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CallbackLink_delete(CallbackLink *link) {
|
||||
free(link);
|
||||
}
|
||||
|
||||
// Pre: CallbackList is locked.
|
||||
static CallbackLink **
|
||||
CallbackLink_find(CallbackLink *link) {
|
||||
CallbackLink **ptr;
|
||||
|
||||
//assert(CallbackList_isLocked());
|
||||
for (ptr = &callbacks; *ptr != NULL; ptr = &(*ptr)->next) {
|
||||
if (*ptr == link)
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
Callback_remove(CallbackID id) {
|
||||
CallbackLink *link = (CallbackLink *) id;
|
||||
CallbackLink **linkPtr;
|
||||
|
||||
CallbackList_lock();
|
||||
|
||||
linkPtr = CallbackLink_find(link);
|
||||
if (linkPtr == NULL) {
|
||||
CallbackList_unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (callbacksEnd == &(*linkPtr)->next)
|
||||
callbacksEnd = linkPtr;
|
||||
if (callbacksProcessEnd == &(*linkPtr)->next)
|
||||
callbacksProcessEnd = linkPtr;
|
||||
*linkPtr = (*linkPtr)->next;
|
||||
|
||||
CallbackList_unlock();
|
||||
|
||||
CallbackLink_delete(link);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
CallbackLink_doCallback(CallbackLink *link) {
|
||||
(link->callback)(link->arg);
|
||||
}
|
||||
|
||||
// Call all queued callbacks currently in the queue. Callbacks queued
|
||||
// from inside the called functions will not be processed until the next
|
||||
// call of Callback_process().
|
||||
// It is allowed to remove callbacks from inside the called functions.
|
||||
// NB: Callback_process() must never be called from more than one thread
|
||||
// at the same time. It's the only sensible way to ensure that the
|
||||
// callbacks are called in the order in which they were queued.
|
||||
// It is however allowed to call Callback_process() from inside the
|
||||
// callback function called by Callback_process() itself.
|
||||
void
|
||||
Callback_process(void) {
|
||||
CallbackLink *link;
|
||||
|
||||
// We set 'callbacksProcessEnd' to callbacksEnd. Callbacks added
|
||||
// from inside a callback function will be placed after
|
||||
// callbacksProcessEnd, and will hence not be processed this
|
||||
// call of Callback_process().
|
||||
CallbackList_lock();
|
||||
callbacksProcessEnd = callbacksEnd;
|
||||
CallbackList_unlock();
|
||||
|
||||
for (;;) {
|
||||
CallbackList_lock();
|
||||
if (callbacksProcessEnd == &callbacks) {
|
||||
CallbackList_unlock();
|
||||
break;
|
||||
}
|
||||
assert(callbacks != NULL);
|
||||
// If callbacks == NULL, then callbacksProcessEnd == &callbacks
|
||||
link = callbacks;
|
||||
callbacks = link->next;
|
||||
if (callbacksEnd == &link->next)
|
||||
callbacksEnd = &callbacks;
|
||||
if (callbacksProcessEnd == &link->next)
|
||||
callbacksProcessEnd = &callbacks;
|
||||
CallbackList_unlock();
|
||||
|
||||
CallbackLink_doCallback(link);
|
||||
CallbackLink_delete(link);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
41
project/jni/application/sc2/src/libs/callback/callback.h
Normal file
41
project/jni/application/sc2/src/libs/callback/callback.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2006 Serge van den Boom <svdb@stack.nl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _CALLBACK_H
|
||||
#define _CALLBACK_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef CALLBACK_INTERNAL
|
||||
typedef CallbackLink *CallbackID;
|
||||
#else
|
||||
typedef void *CallbackID;
|
||||
// Uniquely identifies a queued callback.
|
||||
#endif
|
||||
#define CallbackID_invalid ((CallbackID ) NULL)
|
||||
|
||||
typedef void *CallbackArg;
|
||||
typedef void (*CallbackFunction)(CallbackArg arg);
|
||||
|
||||
void Callback_init(void);
|
||||
CallbackID Callback_add(CallbackFunction callback, CallbackArg arg);
|
||||
bool Callback_remove(CallbackID id);
|
||||
void Callback_process(void);
|
||||
|
||||
#endif /* _CALLBACK_H */
|
||||
|
||||
24
project/jni/application/sc2/src/libs/cdplib.h
Normal file
24
project/jni/application/sc2/src/libs/cdplib.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
* Nota bene: later versions of the GNU General Public License do not apply
|
||||
* to this program.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CDPLIB_H
|
||||
#define _CDPLIB_H
|
||||
|
||||
#include "cdp/cdp.h"
|
||||
|
||||
#endif /* _CDPLIB_H */
|
||||
89
project/jni/application/sc2/src/libs/compiler.h
Normal file
89
project/jni/application/sc2/src/libs/compiler.h
Normal file
@@ -0,0 +1,89 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _COMPILER_H
|
||||
#define _COMPILER_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef uint8 BYTE;
|
||||
typedef uint8 UBYTE;
|
||||
typedef sint8 SBYTE;
|
||||
typedef uint16 UWORD;
|
||||
typedef sint16 SWORD;
|
||||
typedef uint32 DWORD;
|
||||
typedef sint32 SDWORD;
|
||||
|
||||
typedef UWORD COUNT;
|
||||
typedef SWORD SIZE;
|
||||
|
||||
typedef char UNICODE;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FALSE = 0,
|
||||
TRUE
|
||||
} BOOLEAN;
|
||||
|
||||
typedef void (*PVOIDFUNC) (void);
|
||||
typedef BOOLEAN (*PBOOLFUNC) (void);
|
||||
typedef BYTE (*PBYTEFUNC) (void);
|
||||
typedef UWORD (*PUWORDFUNC) (void);
|
||||
typedef SWORD (*PSWORDFUNC) (void);
|
||||
typedef DWORD (*PDWORDFUNC) (void);
|
||||
|
||||
#define MAKE_BYTE(lo, hi) ((BYTE) (((BYTE) (hi) << (BYTE) 4) | (BYTE) (lo)))
|
||||
#define LONIBBLE(x) ((BYTE) ((BYTE) (x) & (BYTE) 0x0F))
|
||||
#define HINIBBLE(x) ((BYTE) ((BYTE) (x) >> (BYTE) 4))
|
||||
#define MAKE_WORD(lo, hi) ((UWORD) ((BYTE) (hi) << 8) | (BYTE) (lo))
|
||||
#define LOBYTE(x) ((BYTE) ((UWORD) (x)))
|
||||
#define HIBYTE(x) ((BYTE) ((UWORD) (x) >> 8))
|
||||
#define MAKE_DWORD(lo, hi) (((DWORD) (hi) << 16) | (UWORD) (lo))
|
||||
#define LOWORD(x) ((UWORD) ((DWORD) (x)))
|
||||
#define HIWORD(x) ((UWORD) ((DWORD) (x) >> 16))
|
||||
|
||||
|
||||
// To be moved to port.h:
|
||||
// _ALIGNED_ANY specifies an alignment suitable for any type
|
||||
// _ALIGNED_ON specifies a caller-supplied alignment (should be a power of 2)
|
||||
#if defined(__GNUC__)
|
||||
# define _PACKED __attribute__((packed))
|
||||
# define _ALIGNED_ANY __attribute__((aligned))
|
||||
# define _ALIGNED_ON(bytes) __attribute__((aligned(bytes)))
|
||||
#elif defined(_MSC_VER)
|
||||
# define _ALIGNED_ANY
|
||||
//# define _ALIGNED_ON(bytes) __declspec(align(bytes))
|
||||
// __declspec(align(bytes)) expects a constant. 'sizeof (type)'
|
||||
// will not do. This is something that needs some attention,
|
||||
// once we find someone with a 64 bits Windows machine.
|
||||
// Leaving it alone for now.
|
||||
# define _PACKED
|
||||
# define _ALIGNED_ON(bytes)
|
||||
#elif defined(__ARMCC__)
|
||||
# define _PACKED __attribute__((packed))
|
||||
# define _ALIGNED_ANY __attribute__((aligned))
|
||||
# define _ALIGNED_ON(bytes) __attribute__((aligned(bytes)))
|
||||
#elif defined(__WINSCW__)
|
||||
# define _PACKED
|
||||
# define _ALIGNED_ANY
|
||||
# define _ALIGNED_ON(bytes)
|
||||
#endif
|
||||
|
||||
#endif /* _COMPILER_H */
|
||||
|
||||
48
project/jni/application/sc2/src/libs/declib.h
Normal file
48
project/jni/application/sc2/src/libs/declib.h
Normal file
@@ -0,0 +1,48 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DECLIB_H
|
||||
#define _DECLIB_H
|
||||
|
||||
#include "libs/compiler.h"
|
||||
typedef struct _LZHCODE_DESC* DECODE_REF;
|
||||
|
||||
enum
|
||||
{
|
||||
FILE_STREAM = 0,
|
||||
MEMORY_STREAM
|
||||
};
|
||||
typedef BYTE STREAM_TYPE;
|
||||
|
||||
enum
|
||||
{
|
||||
STREAM_READ = 0,
|
||||
STREAM_WRITE
|
||||
};
|
||||
typedef BYTE STREAM_MODE;
|
||||
|
||||
extern DECODE_REF copen (void *InStream, STREAM_TYPE SType,
|
||||
STREAM_MODE SMode);
|
||||
extern DWORD cclose (DECODE_REF DecodeRef);
|
||||
extern void cfilelength (DECODE_REF DecodeRef, DWORD *pfilelen);
|
||||
extern COUNT cread (void *pStr, COUNT size, COUNT count,
|
||||
DECODE_REF DecodeRef);
|
||||
extern COUNT cwrite (const void *pStr, COUNT size, COUNT count,
|
||||
DECODE_REF DecodeRef);
|
||||
|
||||
#endif /* _DECLIB_H */
|
||||
1
project/jni/application/sc2/src/libs/decomp/Makeinfo
Normal file
1
project/jni/application/sc2/src/libs/decomp/Makeinfo
Normal file
@@ -0,0 +1 @@
|
||||
uqm_CFILES="lzdecode.c lzencode.c update.c"
|
||||
415
project/jni/application/sc2/src/libs/decomp/lzdecode.c
Normal file
415
project/jni/application/sc2/src/libs/decomp/lzdecode.c
Normal file
@@ -0,0 +1,415 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* LZHUF.C English version 1.0
|
||||
* Based on Japanese version 29-NOV-1988
|
||||
* LZSS coded by Haruhiko OKUMURA
|
||||
* Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
|
||||
* Edited and translated to English by Kenji RIKITAKE
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "lzh.h"
|
||||
#include "libs/reslib.h"
|
||||
|
||||
PLZHCODE_DESC _lpCurCodeDesc;
|
||||
STREAM_TYPE _StreamType;
|
||||
BYTE* _Stream;
|
||||
UWORD _workbuf;
|
||||
BYTE _workbuflen;
|
||||
|
||||
/* get one bit */
|
||||
static SWORD
|
||||
GetBit (void)
|
||||
{
|
||||
SWORD i;
|
||||
|
||||
while (_workbuflen <= 8)
|
||||
{
|
||||
if ((i = InChar ()) < 0)
|
||||
i = 0;
|
||||
_workbuf |= i << (8 - _workbuflen);
|
||||
_workbuflen += 8;
|
||||
}
|
||||
i = (_workbuf & 0xFFFF) >> (16 - 1);
|
||||
_workbuf = (_workbuf << 1) & 0xFFFF;
|
||||
_workbuflen--;
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
static UWORD
|
||||
GetBits (BYTE num_bits)
|
||||
{
|
||||
SWORD i;
|
||||
|
||||
while (_workbuflen <= 8)
|
||||
{
|
||||
if ((i = InChar ()) < 0)
|
||||
i = 0;
|
||||
_workbuf |= i << (8 - _workbuflen);
|
||||
_workbuflen += 8;
|
||||
}
|
||||
i = (_workbuf & 0xFFFF) >> (16 - num_bits);
|
||||
_workbuf = (_workbuf << num_bits) & 0xFFFF;
|
||||
_workbuflen -= num_bits;
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* initialize freq tree */
|
||||
|
||||
void
|
||||
StartHuff (void)
|
||||
{
|
||||
COUNT i, j;
|
||||
|
||||
for (i = 0; i < N_CHAR; i++)
|
||||
{
|
||||
_lpCurCodeDesc->freq[i] = 1;
|
||||
_lpCurCodeDesc->son[i] = i + T;
|
||||
_lpCurCodeDesc->prnt[i + T] = i;
|
||||
}
|
||||
i = 0; j = N_CHAR;
|
||||
while (j <= R)
|
||||
{
|
||||
_lpCurCodeDesc->freq[j] = _lpCurCodeDesc->freq[i] + _lpCurCodeDesc->freq[i + 1];
|
||||
_lpCurCodeDesc->son[j] = i;
|
||||
_lpCurCodeDesc->prnt[i] = _lpCurCodeDesc->prnt[i + 1] = j;
|
||||
i += 2; j++;
|
||||
}
|
||||
_lpCurCodeDesc->freq[T] = 0xffff;
|
||||
_lpCurCodeDesc->prnt[R] = 0;
|
||||
}
|
||||
|
||||
DECODE_REF
|
||||
copen (void *InStream, STREAM_TYPE SType, STREAM_MODE SMode)
|
||||
{
|
||||
DWORD StreamLength;
|
||||
|
||||
_StreamType = SType;
|
||||
_Stream = InStream;
|
||||
if (SMode == STREAM_WRITE) /* writing */
|
||||
{
|
||||
OutChar (0); /* skip future StreamLength */
|
||||
OutChar (0);
|
||||
OutChar (0);
|
||||
OutChar (0);
|
||||
|
||||
StreamLength = 0;
|
||||
}
|
||||
else /* reading */
|
||||
{
|
||||
BYTE lobyte, hibyte;
|
||||
UWORD loword, hiword;
|
||||
|
||||
lobyte = (BYTE)InChar ();
|
||||
hibyte = (BYTE)InChar ();
|
||||
loword = MAKE_WORD (lobyte, hibyte);
|
||||
lobyte = (BYTE)InChar ();
|
||||
hibyte = (BYTE)InChar ();
|
||||
hiword = MAKE_WORD (lobyte, hibyte);
|
||||
|
||||
StreamLength = MAKE_DWORD (loword, hiword);
|
||||
}
|
||||
|
||||
if (StreamLength == 0xFFFFFFFF
|
||||
|| (_lpCurCodeDesc = AllocCodeDesc ()) == NULL)
|
||||
{
|
||||
FreeCodeDesc (_lpCurCodeDesc);
|
||||
_lpCurCodeDesc = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lpCurCodeDesc->Stream = _Stream;
|
||||
_lpCurCodeDesc->StreamType = _StreamType;
|
||||
_lpCurCodeDesc->StreamMode = SMode;
|
||||
_lpCurCodeDesc->StreamLength = StreamLength;
|
||||
_lpCurCodeDesc->buf_index = N - F;
|
||||
memset (&_lpCurCodeDesc->text_buf[0], ' ', N - F);
|
||||
|
||||
StartHuff ();
|
||||
}
|
||||
|
||||
return ((DECODE_REF)_lpCurCodeDesc);
|
||||
}
|
||||
|
||||
DWORD
|
||||
cclose (PLZHCODE_DESC lpCodeDesc)
|
||||
{
|
||||
_lpCurCodeDesc = lpCodeDesc;
|
||||
if (_lpCurCodeDesc)
|
||||
{
|
||||
DWORD StreamIndex;
|
||||
|
||||
if (_lpCurCodeDesc->CleanupFunc)
|
||||
(*_lpCurCodeDesc->CleanupFunc) ();
|
||||
|
||||
StreamIndex = lpCodeDesc->StreamIndex;
|
||||
FreeCodeDesc (lpCodeDesc);
|
||||
_lpCurCodeDesc = NULL;
|
||||
|
||||
return (StreamIndex);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
cfilelength (PLZHCODE_DESC lpCodeDesc, DWORD *pfilelen)
|
||||
{
|
||||
if (lpCodeDesc == 0)
|
||||
*pfilelen = 0;
|
||||
else
|
||||
*pfilelen = lpCodeDesc->StreamLength;
|
||||
}
|
||||
|
||||
/* decoder table */
|
||||
static const BYTE d_code[256] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
|
||||
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
|
||||
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
|
||||
0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
|
||||
0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
|
||||
0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
|
||||
0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
|
||||
0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
|
||||
0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
|
||||
0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
|
||||
0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
|
||||
0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
};
|
||||
static const BYTE d_len[256] =
|
||||
{
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
};
|
||||
|
||||
/* decode upper 6 bits from given table */
|
||||
#define DecodePosition(p) \
|
||||
{ \
|
||||
while (_workbuflen <= 8) \
|
||||
{ \
|
||||
*(p) = InChar (); \
|
||||
_workbuf |= *(p) << (8 - _workbuflen); \
|
||||
_workbuflen += 8; \
|
||||
} \
|
||||
*(p) = HIBYTE (_workbuf); \
|
||||
_workbuf = (_workbuf << 8) & 0xFFFF; \
|
||||
_workbuflen -= 8; \
|
||||
\
|
||||
/* input lower 6 bits directly */ \
|
||||
j = d_len[*(p)]; \
|
||||
*(p) = ((UWORD)d_code[*(p)] << 6) \
|
||||
| (((*(p) << j) | GetBits (j)) & 0x3f); \
|
||||
}
|
||||
|
||||
/* start searching tree from the root to leaves.
|
||||
* choose node #(son[]) if input bit == 0
|
||||
* else choose #(son[]+1) (input bit == 1)
|
||||
*/
|
||||
#define DecodeChar(c) \
|
||||
{ \
|
||||
for (*(c) = lpCodeDesc->son[R]; \
|
||||
*(c) < T; \
|
||||
*(c) = lpCodeDesc->son[*(c) + GetBit ()]) \
|
||||
; \
|
||||
_update (*(c)); \
|
||||
*(c) -= T; \
|
||||
}
|
||||
|
||||
COUNT
|
||||
cread (void *buf, COUNT size, COUNT count, PLZHCODE_DESC lpCodeDesc)
|
||||
{
|
||||
COUNT r, j, i;
|
||||
BYTE *lpStr;
|
||||
|
||||
if ((_lpCurCodeDesc = lpCodeDesc) == 0)
|
||||
return (0);
|
||||
|
||||
size *= count;
|
||||
if (lpCodeDesc->StreamIndex + size > lpCodeDesc->StreamLength)
|
||||
{
|
||||
size /= count;
|
||||
count = (COUNT)((lpCodeDesc->StreamLength
|
||||
- lpCodeDesc->StreamIndex) / size);
|
||||
|
||||
size *= count;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return (0);
|
||||
|
||||
lpStr = (BYTE*)buf;
|
||||
_StreamType = lpCodeDesc->StreamType;
|
||||
|
||||
_Stream = lpCodeDesc->Stream;
|
||||
_workbuf = lpCodeDesc->workbuf;
|
||||
_workbuflen = lpCodeDesc->workbuflen;
|
||||
|
||||
lpCodeDesc->StreamIndex += size;
|
||||
r = lpCodeDesc->buf_index;
|
||||
j = lpCodeDesc->bytes_left;
|
||||
if (j)
|
||||
{
|
||||
lpCodeDesc->bytes_left = 0;
|
||||
i = lpCodeDesc->restart_index;
|
||||
|
||||
goto ReenterRun;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
COUNT c;
|
||||
|
||||
DecodeChar (&c);
|
||||
|
||||
if (c < 256)
|
||||
{
|
||||
size--;
|
||||
|
||||
*lpStr++ = lpCodeDesc->text_buf[r++ & (N - 1)] = (BYTE)c;
|
||||
}
|
||||
else
|
||||
{
|
||||
COUNT copy_size;
|
||||
|
||||
//i is a COUNT;
|
||||
DecodePosition(&i);
|
||||
i = r - i - 1;
|
||||
j = c - 255 + THRESHOLD;
|
||||
ReenterRun:
|
||||
if (j > size)
|
||||
{
|
||||
lpCodeDesc->bytes_left = j - size;
|
||||
lpCodeDesc->restart_index = i + size;
|
||||
j = size;
|
||||
}
|
||||
|
||||
size -= j;
|
||||
do
|
||||
{
|
||||
COUNT loc_size;
|
||||
|
||||
i &= (N - 1);
|
||||
r &= (N - 1);
|
||||
if ((i < r && i + j > r) || (i > r && i + j > r + N))
|
||||
copy_size = (r - i) & (N - 1);
|
||||
else if ((copy_size = j) > N)
|
||||
copy_size = N;
|
||||
|
||||
loc_size = copy_size;
|
||||
if (i + loc_size > N)
|
||||
{
|
||||
COUNT k;
|
||||
|
||||
k = N - i;
|
||||
memcpy (lpStr, &lpCodeDesc->text_buf[i], k);
|
||||
lpStr += k;
|
||||
loc_size -= k;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
memcpy (lpStr, &lpCodeDesc->text_buf[i], loc_size);
|
||||
lpStr += loc_size;
|
||||
i += loc_size;
|
||||
|
||||
lpStr -= copy_size;
|
||||
|
||||
loc_size = copy_size;
|
||||
if (r + loc_size > N)
|
||||
{
|
||||
COUNT k;
|
||||
|
||||
k = N - r;
|
||||
memcpy (&lpCodeDesc->text_buf[r], lpStr, k);
|
||||
lpStr += k;
|
||||
loc_size -= k;
|
||||
r = 0;
|
||||
}
|
||||
|
||||
memcpy (&lpCodeDesc->text_buf[r], lpStr, loc_size);
|
||||
lpStr += loc_size;
|
||||
r += loc_size;
|
||||
} while (j -= copy_size);
|
||||
}
|
||||
} while (size);
|
||||
|
||||
lpCodeDesc->buf_index = r;
|
||||
lpCodeDesc->Stream = _Stream;
|
||||
lpCodeDesc->workbuf = _workbuf;
|
||||
lpCodeDesc->workbuflen = _workbuflen;
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
468
project/jni/application/sc2/src/libs/decomp/lzencode.c
Normal file
468
project/jni/application/sc2/src/libs/decomp/lzencode.c
Normal file
@@ -0,0 +1,468 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* LZHUF.C English version 1.0
|
||||
* Based on Japanese version 29-NOV-1988
|
||||
* LZSS coded by Haruhiko OKUMURA
|
||||
* Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
|
||||
* Edited and translated to English by Kenji RIKITAKE
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "lzh.h"
|
||||
#include "libs/reslib.h"
|
||||
|
||||
static UWORD match_position, match_length;
|
||||
static SWORD *lson;
|
||||
static SWORD *rson;
|
||||
static SWORD *dad;
|
||||
static SWORD *encode_arrays;
|
||||
|
||||
#define AllocEncodeArrays() \
|
||||
HCalloc ( \
|
||||
(((N + 1) + (N + 257) + (N + 1)) \
|
||||
* sizeof (lson[0])))
|
||||
#define FreeCodeArrays HFree
|
||||
|
||||
static BOOLEAN
|
||||
InitTree (void)
|
||||
{
|
||||
if ((encode_arrays = AllocEncodeArrays ()) == NULL)
|
||||
{
|
||||
FreeCodeArrays (encode_arrays);
|
||||
encode_arrays = NULL;
|
||||
return (FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SWORD i;
|
||||
|
||||
lson = encode_arrays;
|
||||
rson = lson + (N + 1);
|
||||
dad = rson + (N + 257);
|
||||
|
||||
for (i = N + 1; i <= N + 256; i++)
|
||||
rson[i] = NIL; /* root */
|
||||
for (i = 0; i < N; i++)
|
||||
dad[i] = NIL; /* node */
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
InsertNode (SWORD r)
|
||||
{
|
||||
SWORD p, cmp;
|
||||
BYTE *lpBuf;
|
||||
|
||||
cmp = 1;
|
||||
lpBuf = _lpCurCodeDesc->text_buf;
|
||||
p = N + 1 + lpBuf[r];
|
||||
rson[r] = lson[r] = NIL;
|
||||
match_length = 0;
|
||||
for (;;)
|
||||
{
|
||||
UWORD i;
|
||||
|
||||
if (cmp >= 0)
|
||||
{
|
||||
if (rson[p] != NIL)
|
||||
p = rson[p];
|
||||
else
|
||||
{
|
||||
rson[p] = r;
|
||||
dad[r] = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lson[p] != NIL)
|
||||
p = lson[p];
|
||||
else
|
||||
{
|
||||
lson[p] = r;
|
||||
dad[r] = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
i = F;
|
||||
{
|
||||
SWORD _r, _p;
|
||||
|
||||
_r = r;
|
||||
_p = p;
|
||||
while (--i && (cmp = lpBuf[++_r] - lpBuf[++_p]) == 0)
|
||||
;
|
||||
}
|
||||
if ((i = F - i) > THRESHOLD)
|
||||
{
|
||||
if (i > match_length)
|
||||
{
|
||||
match_position = ((r - p) & (N - 1)) - 1;
|
||||
if ((match_length = i) >= F)
|
||||
break;
|
||||
}
|
||||
else if (i == match_length)
|
||||
{
|
||||
if ((i = ((r - p) & (N - 1)) - 1) < match_position)
|
||||
{
|
||||
match_position = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dad[r] = dad[p];
|
||||
lson[r] = lson[p];
|
||||
rson[r] = rson[p];
|
||||
dad[lson[p]] = r;
|
||||
dad[rson[p]] = r;
|
||||
if (rson[dad[p]] == p)
|
||||
rson[dad[p]] = r;
|
||||
else
|
||||
lson[dad[p]] = r;
|
||||
dad[p] = NIL; /* remove p */
|
||||
}
|
||||
|
||||
static void
|
||||
DeleteNode (SWORD p)
|
||||
{
|
||||
SWORD q;
|
||||
|
||||
if (dad[p] == NIL)
|
||||
return; /* unregistered */
|
||||
if (rson[p] == NIL)
|
||||
q = lson[p];
|
||||
else if (lson[p] == NIL)
|
||||
q = rson[p];
|
||||
else
|
||||
{
|
||||
q = lson[p];
|
||||
if (rson[q] != NIL)
|
||||
{
|
||||
do
|
||||
{
|
||||
q = rson[q];
|
||||
} while (rson[q] != NIL);
|
||||
rson[dad[q]] = lson[q];
|
||||
dad[lson[q]] = dad[q];
|
||||
lson[q] = lson[p];
|
||||
dad[lson[p]] = q;
|
||||
}
|
||||
rson[q] = rson[p];
|
||||
dad[rson[p]] = q;
|
||||
}
|
||||
dad[q] = dad[p];
|
||||
if (rson[dad[p]] == p)
|
||||
rson[dad[p]] = q;
|
||||
else
|
||||
lson[dad[p]] = q;
|
||||
dad[p] = NIL;
|
||||
}
|
||||
|
||||
static void
|
||||
Putcode (SWORD l, UWORD c)
|
||||
{
|
||||
_workbuf |= c >> _workbuflen;
|
||||
if ((_workbuflen += l) >= 8)
|
||||
{
|
||||
OutChar ((BYTE)(_workbuf >> 8));
|
||||
++_lpCurCodeDesc->StreamIndex;
|
||||
if ((_workbuflen -= 8) >= 8)
|
||||
{
|
||||
OutChar ((BYTE)(_workbuf));
|
||||
++_lpCurCodeDesc->StreamIndex;
|
||||
_workbuflen -= 8;
|
||||
_workbuf = c << (l - _workbuflen);
|
||||
}
|
||||
else
|
||||
{
|
||||
_workbuf <<= 8;
|
||||
}
|
||||
_workbuf &= 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EncodeChar (UWORD c)
|
||||
{
|
||||
UWORD i;
|
||||
SWORD j, k;
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
k = _lpCurCodeDesc->prnt[c + T];
|
||||
|
||||
/* search connections from leaf node to the root */
|
||||
do
|
||||
{
|
||||
i >>= 1;
|
||||
|
||||
/*
|
||||
if node's address is odd, output 1
|
||||
else output 0
|
||||
*/
|
||||
if (k & 1)
|
||||
i += 0x8000;
|
||||
|
||||
j++;
|
||||
} while ((k = _lpCurCodeDesc->prnt[k]) != R);
|
||||
Putcode (j, i);
|
||||
_update (c + T);
|
||||
}
|
||||
|
||||
static void
|
||||
EncodePosition (UWORD c)
|
||||
{
|
||||
UWORD i;
|
||||
/*
|
||||
* Tables for encoding/decoding upper 6 bits of
|
||||
* sliding dictionary pointer
|
||||
*/
|
||||
/* encoder table */
|
||||
static const BYTE p_len[64] =
|
||||
{
|
||||
0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
|
||||
};
|
||||
|
||||
static const BYTE p_code[64] =
|
||||
{
|
||||
0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
|
||||
0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
|
||||
0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
|
||||
0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
|
||||
0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
|
||||
0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
|
||||
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
|
||||
/* output upper 6 bits with encoding */
|
||||
i = c >> 6;
|
||||
Putcode (p_len[i], (UWORD)p_code[i] << 8);
|
||||
|
||||
/* output lower 6 bits directly */
|
||||
Putcode (6, (c & 0x3f) << 10);
|
||||
}
|
||||
|
||||
static void
|
||||
UninitTree (void)
|
||||
{
|
||||
if (_workbuflen)
|
||||
{
|
||||
OutChar ((BYTE)(_workbuf >> 8));
|
||||
++_lpCurCodeDesc->StreamIndex;
|
||||
}
|
||||
|
||||
FreeCodeArrays (encode_arrays);
|
||||
encode_arrays = NULL;
|
||||
lson = NULL;
|
||||
rson = NULL;
|
||||
dad = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_encode_cleanup (void)
|
||||
{
|
||||
UWORD r, s, last_match_length, len;
|
||||
|
||||
_StreamType = _lpCurCodeDesc->StreamType;
|
||||
_Stream = _lpCurCodeDesc->Stream;
|
||||
_workbuf = _lpCurCodeDesc->workbuf;
|
||||
_workbuflen = _lpCurCodeDesc->workbuflen;
|
||||
|
||||
r = _lpCurCodeDesc->buf_index;
|
||||
s = _lpCurCodeDesc->restart_index;
|
||||
last_match_length = _lpCurCodeDesc->bytes_left;
|
||||
if (_lpCurCodeDesc->StreamLength >= F)
|
||||
len = F;
|
||||
else
|
||||
{
|
||||
UWORD i;
|
||||
|
||||
for (i = 1; i <= F; i++)
|
||||
InsertNode (r - i);
|
||||
InsertNode (r);
|
||||
|
||||
len = (UWORD)_lpCurCodeDesc->StreamLength;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (last_match_length--)
|
||||
{
|
||||
DeleteNode (s);
|
||||
if (--len == 0)
|
||||
{
|
||||
BYTE lobyte, hibyte;
|
||||
UWORD loword, hiword;
|
||||
|
||||
UninitTree ();
|
||||
|
||||
_lpCurCodeDesc->StreamIndex += 4;
|
||||
/* rewind */
|
||||
if (_lpCurCodeDesc->StreamType == FILE_STREAM)
|
||||
SeekResFile ((uio_Stream *)_Stream,
|
||||
-(int)_lpCurCodeDesc->StreamIndex, SEEK_CUR);
|
||||
else /* _lpCurCodeDesc->StreamType == MEMORY_STREAM */
|
||||
_Stream = (BYTE*)_Stream - _lpCurCodeDesc->StreamIndex;
|
||||
|
||||
loword = LOWORD (_lpCurCodeDesc->StreamLength);
|
||||
lobyte = LOBYTE (loword);
|
||||
hibyte = HIBYTE (loword);
|
||||
OutChar (lobyte);
|
||||
OutChar (hibyte);
|
||||
hiword = HIWORD (_lpCurCodeDesc->StreamLength);
|
||||
lobyte = LOBYTE (hiword);
|
||||
hibyte = HIBYTE (hiword);
|
||||
OutChar (lobyte);
|
||||
OutChar (hibyte);
|
||||
|
||||
return;
|
||||
}
|
||||
s = (s + 1) & (N - 1);
|
||||
r = (r + 1) & (N - 1);
|
||||
InsertNode (r);
|
||||
}
|
||||
if (match_length > len)
|
||||
match_length = len;
|
||||
if (match_length <= THRESHOLD)
|
||||
{
|
||||
match_length = 1;
|
||||
EncodeChar (_lpCurCodeDesc->text_buf[r]);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeChar (255 - THRESHOLD + match_length);
|
||||
EncodePosition (match_position);
|
||||
}
|
||||
last_match_length = match_length;
|
||||
}
|
||||
}
|
||||
|
||||
COUNT
|
||||
cwrite (const void *buf, COUNT size, COUNT count, PLZHCODE_DESC lpCodeDesc)
|
||||
{
|
||||
UWORD r, s, last_match_length;
|
||||
BYTE *lpBuf;
|
||||
const BYTE *lpStr;
|
||||
|
||||
if ((_lpCurCodeDesc = lpCodeDesc) == 0
|
||||
|| (size *= count) == 0)
|
||||
return (0);
|
||||
|
||||
_StreamType = lpCodeDesc->StreamType;
|
||||
_Stream = lpCodeDesc->Stream;
|
||||
_workbuf = lpCodeDesc->workbuf;
|
||||
_workbuflen = lpCodeDesc->workbuflen;
|
||||
lpStr = (const BYTE *) buf;
|
||||
lpBuf = lpCodeDesc->text_buf;
|
||||
|
||||
r = lpCodeDesc->buf_index;
|
||||
s = lpCodeDesc->restart_index;
|
||||
last_match_length = lpCodeDesc->bytes_left;
|
||||
if (last_match_length)
|
||||
{
|
||||
lpCodeDesc->StreamLength += size;
|
||||
goto EncodeRestart;
|
||||
}
|
||||
else if (lpCodeDesc->StreamLength < F)
|
||||
{
|
||||
UWORD i;
|
||||
|
||||
if ((i = (UWORD)lpCodeDesc->StreamLength) == 0)
|
||||
{
|
||||
if (!InitTree ())
|
||||
return (0);
|
||||
|
||||
_lpCurCodeDesc->StreamIndex = 0;
|
||||
lpCodeDesc->CleanupFunc = _encode_cleanup;
|
||||
}
|
||||
|
||||
lpCodeDesc->StreamLength += size;
|
||||
|
||||
for (; i < F && size; ++i, --size)
|
||||
lpBuf[r + i] = *lpStr++;
|
||||
if (i < F)
|
||||
goto EncodeExit;
|
||||
|
||||
for (i = 1; i <= F; i++)
|
||||
InsertNode (r - i);
|
||||
InsertNode (r);
|
||||
if (size == 0)
|
||||
goto EncodeExit;
|
||||
}
|
||||
else
|
||||
lpCodeDesc->StreamLength += size;
|
||||
|
||||
do
|
||||
{
|
||||
if (match_length > F)
|
||||
match_length = F;
|
||||
if (match_length <= THRESHOLD)
|
||||
{
|
||||
match_length = 1;
|
||||
EncodeChar (lpBuf[r]);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeChar (255 - THRESHOLD + match_length);
|
||||
EncodePosition (match_position);
|
||||
}
|
||||
last_match_length = match_length;
|
||||
EncodeRestart:
|
||||
while (last_match_length && size)
|
||||
{
|
||||
BYTE c;
|
||||
|
||||
--size;
|
||||
--last_match_length;
|
||||
|
||||
DeleteNode (s);
|
||||
c = *lpStr++;
|
||||
lpBuf[s] = c;
|
||||
if (s < F - 1)
|
||||
lpBuf[s + N] = c;
|
||||
s = (s + 1) & (N - 1);
|
||||
r = (r + 1) & (N - 1);
|
||||
InsertNode (r);
|
||||
}
|
||||
} while (last_match_length == 0);
|
||||
|
||||
EncodeExit:
|
||||
lpCodeDesc->buf_index = r;
|
||||
lpCodeDesc->restart_index = s;
|
||||
lpCodeDesc->bytes_left = last_match_length;
|
||||
|
||||
lpCodeDesc->Stream = _Stream;
|
||||
lpCodeDesc->workbuf = _workbuf;
|
||||
lpCodeDesc->workbuflen = _workbuflen;
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
91
project/jni/application/sc2/src/libs/decomp/lzh.h
Normal file
91
project/jni/application/sc2/src/libs/decomp/lzh.h
Normal file
@@ -0,0 +1,91 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _LZH_H
|
||||
#define _LZH_H
|
||||
|
||||
#include "libs/declib.h"
|
||||
#include "libs/memlib.h"
|
||||
|
||||
/* LZSS Parameters */
|
||||
|
||||
#define N 4096 /* Size of string buffer */
|
||||
#define F 16 /* Size of look-ahead buffer */
|
||||
//#define F 60 /* Size of look-ahead buffer */
|
||||
#define THRESHOLD 2
|
||||
#define NIL N /* End of tree's node */
|
||||
|
||||
/* Huffman coding parameters */
|
||||
|
||||
#define N_CHAR (256 - THRESHOLD + F)
|
||||
/* character code (= 0..N_CHAR-1) */
|
||||
#define T (N_CHAR * 2 - 1) /* Size of table */
|
||||
#define R (T - 1) /* root position */
|
||||
#define MAX_FREQ 0x8000
|
||||
/* update when cumulative frequency */
|
||||
|
||||
struct _LZHCODE_DESC
|
||||
{
|
||||
COUNT buf_index, restart_index, bytes_left;
|
||||
BYTE text_buf[N + F - 1];
|
||||
/* reconstruct freq tree */
|
||||
COUNT freq[T + 1]; /* cumulative freq table */
|
||||
/*
|
||||
* pointing parent nodes.
|
||||
* area [T..(T + N_CHAR - 1)] are pointers for leaves
|
||||
*/
|
||||
COUNT prnt[T + N_CHAR];
|
||||
/* pointing children nodes (son[], son[] + 1)*/
|
||||
COUNT son[T];
|
||||
UWORD workbuf;
|
||||
BYTE workbuflen;
|
||||
|
||||
STREAM_TYPE StreamType;
|
||||
|
||||
void *Stream;
|
||||
DWORD StreamIndex, StreamLength;
|
||||
|
||||
STREAM_MODE StreamMode;
|
||||
PVOIDFUNC CleanupFunc;
|
||||
};
|
||||
|
||||
typedef struct _LZHCODE_DESC LZHCODE_DESC;
|
||||
typedef LZHCODE_DESC *PLZHCODE_DESC;
|
||||
|
||||
#define InChar() (_StreamType == FILE_STREAM ? \
|
||||
GetResFileChar ((uio_Stream *)_Stream) : \
|
||||
(int)*_Stream++)
|
||||
#define OutChar(c) (_StreamType == FILE_STREAM ? \
|
||||
PutResFileChar ((c), (uio_Stream *)_Stream) : \
|
||||
(*_Stream++ = (BYTE)(c)))
|
||||
|
||||
|
||||
#define AllocCodeDesc() HCalloc (sizeof (LZHCODE_DESC))
|
||||
#define FreeCodeDesc HFree
|
||||
|
||||
extern void _update (COUNT c);
|
||||
extern void StartHuff (void);
|
||||
|
||||
extern PLZHCODE_DESC _lpCurCodeDesc;
|
||||
extern STREAM_TYPE _StreamType;
|
||||
extern BYTE* _Stream;
|
||||
extern UWORD _workbuf;
|
||||
extern BYTE _workbuflen;
|
||||
|
||||
#endif /* _LZH_H */
|
||||
|
||||
115
project/jni/application/sc2/src/libs/decomp/update.c
Normal file
115
project/jni/application/sc2/src/libs/decomp/update.c
Normal file
@@ -0,0 +1,115 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "lzh.h"
|
||||
|
||||
static void
|
||||
reconst (void)
|
||||
{
|
||||
COUNT i, j;
|
||||
|
||||
/* halven cumulative freq for leaf nodes */
|
||||
j = 0;
|
||||
for (i = 0; i < T; i++)
|
||||
{
|
||||
if (_lpCurCodeDesc->son[i] >= T)
|
||||
{
|
||||
_lpCurCodeDesc->freq[j] = (_lpCurCodeDesc->freq[i] + 1) >> 1;
|
||||
_lpCurCodeDesc->son[j] = _lpCurCodeDesc->son[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
/* make a tree : first, connect children nodes */
|
||||
for (i = 0, j = N_CHAR; j < T; i += 2, j++)
|
||||
{
|
||||
SWORD k;
|
||||
UWORD f, l;
|
||||
|
||||
k = i + 1;
|
||||
f = _lpCurCodeDesc->freq[j] = _lpCurCodeDesc->freq[i] + _lpCurCodeDesc->freq[k];
|
||||
for (k = j - 1; f < _lpCurCodeDesc->freq[k]; k--)
|
||||
;
|
||||
k++;
|
||||
l = (j - k);
|
||||
|
||||
memmove (_lpCurCodeDesc->freq + k + 1, _lpCurCodeDesc->freq + k,
|
||||
sizeof(_lpCurCodeDesc->freq[0]) * l);
|
||||
_lpCurCodeDesc->freq[k] = f;
|
||||
memmove (_lpCurCodeDesc->son + k + 1, _lpCurCodeDesc->son + k,
|
||||
sizeof(_lpCurCodeDesc->son[0]) * l);
|
||||
_lpCurCodeDesc->son[k] = i;
|
||||
}
|
||||
/* connect parent nodes */
|
||||
for (i = 0; i < T; i++)
|
||||
{
|
||||
if ((j = _lpCurCodeDesc->son[i]) >= T)
|
||||
_lpCurCodeDesc->prnt[j] = i;
|
||||
else
|
||||
_lpCurCodeDesc->prnt[j] = _lpCurCodeDesc->prnt[j + 1] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* update freq tree */
|
||||
|
||||
void
|
||||
_update (COUNT c)
|
||||
{
|
||||
PLZHCODE_DESC lpCD;
|
||||
|
||||
if ((lpCD = _lpCurCodeDesc)->freq[R] == MAX_FREQ)
|
||||
reconst ();
|
||||
|
||||
c = lpCD->prnt[c];
|
||||
do
|
||||
{
|
||||
COUNT i, l;
|
||||
|
||||
i = ++lpCD->freq[c];
|
||||
|
||||
/* swap nodes to keep the tree freq-ordered */
|
||||
if (i > lpCD->freq[l = c + 1])
|
||||
{
|
||||
COUNT j;
|
||||
|
||||
while (i > lpCD->freq[++l])
|
||||
;
|
||||
l--;
|
||||
lpCD->freq[c] = lpCD->freq[l];
|
||||
lpCD->freq[l] = i;
|
||||
|
||||
i = lpCD->son[c];
|
||||
j = lpCD->son[l];
|
||||
lpCD->son[l] = i;
|
||||
lpCD->son[c] = j;
|
||||
|
||||
lpCD->prnt[i] = l;
|
||||
if (i < T)
|
||||
lpCD->prnt[i + 1] = l;
|
||||
|
||||
lpCD->prnt[j] = c;
|
||||
if (j < T)
|
||||
lpCD->prnt[j + 1] = c;
|
||||
|
||||
c = l;
|
||||
}
|
||||
} while ((c = lpCD->prnt[c]) != 0); /* do it until reaching the root */
|
||||
}
|
||||
|
||||
|
||||
87
project/jni/application/sc2/src/libs/file.h
Normal file
87
project/jni/application/sc2/src/libs/file.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Contains file handling code
|
||||
|
||||
#ifndef _FILE_H
|
||||
#define _FILE_H
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/uio.h"
|
||||
|
||||
// for bool
|
||||
#include "types.h"
|
||||
|
||||
#if 0
|
||||
// from temp.h
|
||||
void initTempDir (void);
|
||||
void unInitTempDir (void);
|
||||
char *tempFilePath (const char *filename);
|
||||
extern uio_DirHandle *tempDir;
|
||||
#endif
|
||||
|
||||
|
||||
// from dirs.h
|
||||
int mkdirhier (const char *path);
|
||||
const char *getHomeDir (void);
|
||||
int createDirectory (const char *dir, int mode);
|
||||
|
||||
int expandPath (char *dest, size_t len, const char *src, int what);
|
||||
// values for 'what':
|
||||
#define EP_HOME 1
|
||||
// Expand '~' for home dirs.
|
||||
#define EP_ABSOLUTE 2
|
||||
// Make paths absolute
|
||||
#define EP_ENVVARS 4
|
||||
// Expand environment variables.
|
||||
#define EP_DOTS 8
|
||||
// Process ".." and "."
|
||||
#define EP_SLASHES 16
|
||||
// Consider backslashes as path component separators.
|
||||
// They will be replaced by slashes. Windows UNC paths will always
|
||||
// start with "\\server\share", with backslashes.
|
||||
#define EP_SINGLESEP 32
|
||||
// Replace multiple consecutive path separators by a single one.
|
||||
#define EP_ALL (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | EP_SLASHES \
|
||||
EP_SINGLESEP)
|
||||
// Everything
|
||||
// Everything except Windows style backslashes on Unix Systems:
|
||||
#ifdef WIN32
|
||||
# define EP_ALL_SYSTEM (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | \
|
||||
EP_SLASHES | EP_SINGLESEP)
|
||||
#else
|
||||
# define EP_ALL_SYSTEM (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | \
|
||||
EP_SINGLESEP)
|
||||
#endif
|
||||
|
||||
// from files.h
|
||||
int copyFile (uio_DirHandle *srcDir, const char *srcName,
|
||||
uio_DirHandle *dstDir, const char *newName);
|
||||
bool fileExists (const char *name);
|
||||
bool fileExists2(uio_DirHandle *dir, const char *fileName);
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
size_t skipUNCServerShare(const char *inPath);
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
static inline int isDriveLetter(int c)
|
||||
{
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||
}
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
|
||||
#endif /* _FILE_H */
|
||||
|
||||
1
project/jni/application/sc2/src/libs/file/Makeinfo
Normal file
1
project/jni/application/sc2/src/libs/file/Makeinfo
Normal file
@@ -0,0 +1 @@
|
||||
uqm_CFILES="dirs.c files.c"
|
||||
826
project/jni/application/sc2/src/libs/file/dirs.c
Normal file
826
project/jni/application/sc2/src/libs/file/dirs.c
Normal file
@@ -0,0 +1,826 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Contains code handling directories
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "port.h"
|
||||
#include "config.h"
|
||||
#include "filintrn.h"
|
||||
#include "libs/compiler.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "libs/misc.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
# include <ctype.h>
|
||||
// For tolower()
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
#ifdef WIN32
|
||||
# include <direct.h>
|
||||
// For _getdcwd()
|
||||
#else
|
||||
# include <pwd.h>
|
||||
// For getpwuid()
|
||||
#endif
|
||||
|
||||
/* Try to find a suitable value for %APPDATA% if it isn't defined on
|
||||
* Windows.
|
||||
*/
|
||||
#define APPDATA_FALLBACK
|
||||
|
||||
|
||||
static char *expandPathAbsolute (char *dest, size_t destLen, const char *src,
|
||||
size_t *skipSrc, int what);
|
||||
static char *strrchr2(const char *start, int c, const char *end);
|
||||
|
||||
|
||||
int
|
||||
createDirectory(const char *dir, int mode)
|
||||
{
|
||||
return MKDIR(dir, mode);
|
||||
}
|
||||
|
||||
// make all components of the path if they don't exist already
|
||||
// returns 0 on success, -1 on failure.
|
||||
// on failure, some parts may still have been created.
|
||||
int
|
||||
mkdirhier (const char *path)
|
||||
{
|
||||
char *buf; // buffer
|
||||
char *ptr; // end of the string in buf
|
||||
const char *pathstart; // start of a component of path
|
||||
const char *pathend; // first char past the end of a component of path
|
||||
size_t len;
|
||||
struct stat statbuf;
|
||||
|
||||
len = strlen (path);
|
||||
buf = HMalloc (len + 2); // one extra for possibly added '/'
|
||||
|
||||
ptr = buf;
|
||||
pathstart = path;
|
||||
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if (isDriveLetter(pathstart[0]) && pathstart[1] == ':')
|
||||
{
|
||||
// Driveletter + semicolon on Windows.
|
||||
// Copy as is; don't try to create directories for it.
|
||||
*(ptr++) = *(pathstart++);
|
||||
*(ptr++) = *(pathstart++);
|
||||
|
||||
ptr[0] = '/';
|
||||
ptr[1] = '\0';
|
||||
if (stat (buf, &statbuf) == -1)
|
||||
{
|
||||
log_add (log_Error, "Can't stat \"%s\": %s", buf, strerror (errno));
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
if (pathstart[0] == '\\' && pathstart[1] == '\\')
|
||||
{
|
||||
// Universal Naming Convention path. (\\server\share\...)
|
||||
// Copy the server part as is; don't try to create directories for
|
||||
// it, or stat it. Don't create a dir for the share either.
|
||||
*(ptr++) = *(pathstart++);
|
||||
*(ptr++) = *(pathstart++);
|
||||
|
||||
// Copy the server part
|
||||
while (*pathstart != '\0' && *pathstart != '\\' && *pathstart != '/')
|
||||
*(ptr++) = *(pathstart++);
|
||||
|
||||
if (*pathstart == '\0')
|
||||
{
|
||||
log_add (log_Error, "Incomplete UNC path \"%s\"", pathstart);
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Copy the path seperator.
|
||||
*(ptr++) = *(pathstart++);
|
||||
|
||||
// Copy the share part
|
||||
while (*pathstart != '\0' && *pathstart != '\\' && *pathstart != '/')
|
||||
*(ptr++) = *(pathstart++);
|
||||
|
||||
ptr[0] = '/';
|
||||
ptr[1] = '\0';
|
||||
if (stat (buf, &statbuf) == -1)
|
||||
{
|
||||
log_add (log_Error, "Can't stat \"%s\": %s", buf, strerror (errno));
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
// Making sure that there is an 'else' case if HAVE_DRIVE_LETTERS is
|
||||
// defined.
|
||||
}
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
|
||||
if (*pathstart == '/')
|
||||
*(ptr++) = *(pathstart++);
|
||||
|
||||
if (*pathstart == '\0') {
|
||||
// path exists completely, nothing more to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
// walk through the path as long as the components exist
|
||||
while (1)
|
||||
{
|
||||
pathend = strchr (pathstart, '/');
|
||||
if (pathend == NULL)
|
||||
pathend = path + len;
|
||||
memcpy(ptr, pathstart, pathend - pathstart);
|
||||
ptr += pathend - pathstart;
|
||||
*ptr = '\0';
|
||||
|
||||
if (stat (buf, &statbuf) == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
break;
|
||||
#ifdef __SYMBIAN32__
|
||||
// XXX: HACK: If we don't have access to a directory, we can
|
||||
// still have access to the underlying entries. We don't
|
||||
// actually know whether the entry is a directory, but I know of
|
||||
// no way to find out. We just pretend that it is; if we were
|
||||
// wrong, an error will occur when we try to do something with
|
||||
// the directory. That /should/ not be a problem, as any such
|
||||
// action should have its own error checking.
|
||||
if (errno != EACCES)
|
||||
#endif
|
||||
{
|
||||
log_add (log_Error, "Can't stat \"%s\": %s", buf,
|
||||
strerror (errno));
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (*pathend == '\0')
|
||||
return 0;
|
||||
|
||||
*ptr = '/';
|
||||
ptr++;
|
||||
pathstart = pathend + 1;
|
||||
while (*pathstart == '/')
|
||||
pathstart++;
|
||||
// pathstart is the next non-slash character
|
||||
|
||||
if (*pathstart == '\0')
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create all components left
|
||||
while (1)
|
||||
{
|
||||
if (createDirectory (buf, 0777) == -1)
|
||||
{
|
||||
log_add (log_Error, "Error: Can't create %s: %s", buf,
|
||||
strerror (errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (*pathend == '\0')
|
||||
break;
|
||||
|
||||
*ptr = '/';
|
||||
ptr++;
|
||||
pathstart = pathend + 1;
|
||||
while (*pathstart == '/')
|
||||
pathstart++;
|
||||
// pathstart is the next non-slash character
|
||||
|
||||
if (*pathstart == '\0')
|
||||
break;
|
||||
|
||||
pathend = strchr (pathstart, '/');
|
||||
if (pathend == NULL)
|
||||
pathend = path + len;
|
||||
|
||||
memcpy (ptr, pathstart, pathend - pathstart);
|
||||
ptr += pathend - pathstart;
|
||||
*ptr = '\0';
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
{
|
||||
int savedErrno = errno;
|
||||
HFree (buf);
|
||||
errno = savedErrno;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get the user's home dir
|
||||
// returns a pointer to a static buffer from either getenv() or getpwuid().
|
||||
const char *
|
||||
getHomeDir (void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return getenv ("HOME");
|
||||
#else
|
||||
const char *home;
|
||||
struct passwd *pw;
|
||||
|
||||
home = getenv ("HOME");
|
||||
if (home != NULL)
|
||||
return home;
|
||||
|
||||
pw = getpwuid (getuid ());
|
||||
if (pw == NULL)
|
||||
return NULL;
|
||||
// NB: pw points to a static buffer.
|
||||
|
||||
return pw->pw_dir;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Performs various types of string expansions on a path.
|
||||
// 'what' is an OR'd compination of the folowing flags, which
|
||||
// specify what type of exmansions will be performed.
|
||||
// EP_HOME - Expand '~' for home dirs.
|
||||
// EP_ABSOLUTE - Make relative paths absolute
|
||||
// EP_ENVVARS - Expand environment variables
|
||||
// EP_DOTS - Process ".." and "."
|
||||
// EP_SLASHES - Consider backslashes as path component separators.
|
||||
// They will be replaced by slashes.
|
||||
// EP_SINGLESEP - Replace multiple consecutive path seperators (which POSIX
|
||||
// considers equivalent to a single one) by a single one.
|
||||
// Additionally, there's EP_ALL, which indicates all of the above,
|
||||
// and EP_ALL_SYSTEM, which does the same as EP_ALL, with the exception
|
||||
// of EP_SLASHES, which will only be included if the operating system
|
||||
// accepts backslashes as path terminators.
|
||||
// Returns 0 on success.
|
||||
// Returns -1 on failure, setting errno.
|
||||
int
|
||||
expandPath (char *dest, size_t len, const char *src, int what)
|
||||
{
|
||||
char *destptr, *destend;
|
||||
char *buf = NULL;
|
||||
char *bufptr, *bufend;
|
||||
const char *srcend;
|
||||
|
||||
#define CHECKLEN(bufname, n) \
|
||||
if (bufname##ptr + (n) >= bufname##end) \
|
||||
{ \
|
||||
errno = ENAMETOOLONG; \
|
||||
goto err; \
|
||||
} \
|
||||
else \
|
||||
(void) 0
|
||||
|
||||
destptr = dest;
|
||||
destend = dest + len;
|
||||
|
||||
if (what & EP_ENVVARS)
|
||||
{
|
||||
buf = HMalloc (len);
|
||||
bufptr = buf;
|
||||
bufend = buf + len;
|
||||
while (*src != '\0')
|
||||
{
|
||||
switch (*src)
|
||||
{
|
||||
#ifdef WIN32
|
||||
case '%':
|
||||
{
|
||||
/* Environment variable substitution in Windows */
|
||||
const char *end; // end of env var name in src
|
||||
const char *envVar;
|
||||
char *envName;
|
||||
size_t envNameLen, envVarLen;
|
||||
|
||||
src++;
|
||||
end = strchr (src, '%');
|
||||
if (end == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
envNameLen = end - src;
|
||||
envName = HMalloc (envNameLen + 1);
|
||||
memcpy (envName, src, envNameLen + 1);
|
||||
envName[envNameLen] = '\0';
|
||||
envVar = getenv (envName);
|
||||
HFree (envName);
|
||||
|
||||
if (envVar == NULL)
|
||||
{
|
||||
#ifdef APPDATA_FALLBACK
|
||||
if (strncmp (src, "APPDATA", envNameLen) != 0)
|
||||
{
|
||||
// Substitute an empty string
|
||||
src = end + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// fallback for when the APPDATA env var is not set
|
||||
// Using SHGetFolderPath or SHGetSpecialFolderPath
|
||||
// is problematic (not everywhere available).
|
||||
log_add (log_Warning, "Warning: %%APPDATA%% is not set. "
|
||||
"Falling back to \"%%USERPROFILE%%\\Application "
|
||||
"Data\"");
|
||||
envVar = getenv ("USERPROFILE");
|
||||
if (envVar != NULL)
|
||||
{
|
||||
#define APPDATA_STRING "\\Application Data"
|
||||
envVarLen = strlen (envVar);
|
||||
CHECKLEN (buf,
|
||||
envVarLen + sizeof (APPDATA_STRING) - 1);
|
||||
strcpy (bufptr, envVar);
|
||||
bufptr += envVarLen;
|
||||
strcpy (bufptr, APPDATA_STRING);
|
||||
bufptr += sizeof (APPDATA_STRING) - 1;
|
||||
src = end + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// fallback to "./userdata"
|
||||
#define APPDATA_FALLBACK_STRING ".\\userdata"
|
||||
log_add (log_Warning,
|
||||
"Warning: %%USERPROFILE%% is not set. "
|
||||
"Falling back to \"%s\" for %%APPDATA%%",
|
||||
APPDATA_FALLBACK_STRING);
|
||||
CHECKLEN (buf, sizeof (APPDATA_FALLBACK_STRING) - 1);
|
||||
strcpy (bufptr, APPDATA_FALLBACK_STRING);
|
||||
bufptr += sizeof (APPDATA_FALLBACK_STRING) - 1;
|
||||
src = end + 1;
|
||||
break;
|
||||
|
||||
#else /* !defined (APPDATA_FALLBACK) */
|
||||
// Substitute an empty string
|
||||
src = end + 1;
|
||||
break;
|
||||
#endif /* APPDATA_FALLBACK */
|
||||
}
|
||||
|
||||
envVarLen = strlen (envVar);
|
||||
CHECKLEN (buf, envVarLen);
|
||||
strcpy (bufptr, envVar);
|
||||
bufptr += envVarLen;
|
||||
src = end + 1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
case '$':
|
||||
{
|
||||
const char *end;
|
||||
char *envName;
|
||||
size_t envNameLen;
|
||||
const char *envVar;
|
||||
size_t envVarLen;
|
||||
|
||||
src++;
|
||||
if (*src == '{')
|
||||
{
|
||||
src++;
|
||||
end = strchr(src, '}');
|
||||
if (end == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
envNameLen = end - src;
|
||||
end++; // Skip the '}'
|
||||
}
|
||||
else
|
||||
{
|
||||
end = src;
|
||||
while ((*end >= 'A' && *end <= 'Z') ||
|
||||
(*end >= 'a' && *end <= 'z') ||
|
||||
(*end >= '0' && *end <= '9') ||
|
||||
*end == '_')
|
||||
end++;
|
||||
envNameLen = end - src;
|
||||
}
|
||||
|
||||
envName = HMalloc (envNameLen + 1);
|
||||
memcpy (envName, src, envNameLen + 1);
|
||||
envName[envNameLen] = '\0';
|
||||
envVar = getenv (envName);
|
||||
HFree (envName);
|
||||
|
||||
if (envVar != NULL)
|
||||
{
|
||||
envVarLen = strlen (envVar);
|
||||
CHECKLEN (buf, envVarLen);
|
||||
memcpy (bufptr, envVar, envVarLen);
|
||||
bufptr += envVarLen;
|
||||
}
|
||||
|
||||
src = end;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
CHECKLEN(buf, 1);
|
||||
*(bufptr++) = *(src++);
|
||||
break;
|
||||
} // switch
|
||||
} // while
|
||||
*bufptr = '\0';
|
||||
src = buf;
|
||||
srcend = bufptr;
|
||||
} // if (what & EP_ENVVARS)
|
||||
else
|
||||
srcend = src + strlen (src);
|
||||
|
||||
if (what & EP_HOME)
|
||||
{
|
||||
if (src[0] == '~')
|
||||
{
|
||||
const char *home;
|
||||
size_t homelen;
|
||||
|
||||
if (src[1] != '/')
|
||||
{
|
||||
errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
home = getHomeDir ();
|
||||
if (home == NULL)
|
||||
{
|
||||
errno = ENOENT;
|
||||
goto err;
|
||||
}
|
||||
homelen = strlen (home);
|
||||
|
||||
if (what & EP_ABSOLUTE) {
|
||||
size_t skip;
|
||||
destptr = expandPathAbsolute (dest, destend - dest,
|
||||
home, &skip, what);
|
||||
if (destptr == NULL)
|
||||
{
|
||||
// errno is set
|
||||
goto err;
|
||||
}
|
||||
home += skip;
|
||||
what &= ~EP_ABSOLUTE;
|
||||
// The part after the '~' should not be seen
|
||||
// as absolute.
|
||||
}
|
||||
|
||||
CHECKLEN (dest, homelen);
|
||||
memcpy (destptr, home, homelen);
|
||||
destptr += homelen;
|
||||
src++; /* skip the ~ */
|
||||
}
|
||||
}
|
||||
|
||||
if (what & EP_ABSOLUTE)
|
||||
{
|
||||
size_t skip;
|
||||
destptr = expandPathAbsolute (destptr, destend - destptr, src,
|
||||
&skip, what);
|
||||
if (destptr == NULL)
|
||||
{
|
||||
// errno is set
|
||||
goto err;
|
||||
}
|
||||
src += skip;
|
||||
}
|
||||
|
||||
CHECKLEN (dest, srcend - src);
|
||||
memcpy (destptr, src, srcend - src + 1);
|
||||
// The +1 is for the '\0'. It is already taken into account by
|
||||
// CHECKLEN.
|
||||
|
||||
if (what & EP_SLASHES)
|
||||
{
|
||||
/* Replacing backslashes in path by slashes. */
|
||||
destptr = dest;
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
{
|
||||
// A UNC path should always start with two backslashes
|
||||
// and have a backslash in between the server and share part.
|
||||
size_t skip = skipUNCServerShare (destptr);
|
||||
if (skip != 0)
|
||||
{
|
||||
char *slash = (char *) memchr (destptr + 2, '/', skip - 2);
|
||||
if (slash)
|
||||
*slash = '\\';
|
||||
destptr += skip;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
while (*destptr != '\0')
|
||||
{
|
||||
if (*destptr == '\\')
|
||||
*destptr = '/';
|
||||
destptr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (what & EP_DOTS) {
|
||||
// At this point backslashes are already replaced by slashes if they
|
||||
// are specified to be path seperators.
|
||||
// Note that the path can only get smaller, so no size checks
|
||||
// need to be done.
|
||||
char *pathStart;
|
||||
// Start of the first path component, after any
|
||||
// leading slashes or drive letters.
|
||||
char *startPart;
|
||||
char *endPart;
|
||||
|
||||
pathStart = dest;
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if (isDriveLetter(pathStart[0]) && (pathStart[1] == ':'))
|
||||
{
|
||||
pathStart += 2;
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
{
|
||||
// Test for a Universal Naming Convention path.
|
||||
pathStart += skipUNCServerShare(pathStart);
|
||||
}
|
||||
#else
|
||||
{
|
||||
// Making sure that there is an 'else' case if HAVE_DRIVE_LETTERS is
|
||||
// defined.
|
||||
}
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
if (pathStart[0] == '/')
|
||||
pathStart++;
|
||||
|
||||
startPart = pathStart;
|
||||
destptr = pathStart;
|
||||
for (;;)
|
||||
{
|
||||
endPart = strchr(startPart, '/');
|
||||
if (endPart == NULL)
|
||||
endPart = startPart + strlen(startPart);
|
||||
|
||||
if (endPart - startPart == 1 && startPart[0] == '.')
|
||||
{
|
||||
// Found "." as path component. Ignore this component.
|
||||
}
|
||||
else if (endPart - startPart == 2 &&
|
||||
startPart[0] == '.' && startPart[1] == '.')
|
||||
{
|
||||
// Found ".." as path component. Remove the previous
|
||||
// component, and ignore this one.
|
||||
char *lastSlash;
|
||||
lastSlash = strrchr2(pathStart, '/', destptr - 1);
|
||||
if (lastSlash == NULL)
|
||||
{
|
||||
if (destptr == pathStart)
|
||||
{
|
||||
// We ran out of path components to back out of.
|
||||
errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
destptr = pathStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
destptr = lastSlash;
|
||||
if (*endPart == '/')
|
||||
destptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// A normal path component; copy it.
|
||||
// Using memmove as source and destination may overlap.
|
||||
memmove(destptr, startPart, endPart - startPart);
|
||||
destptr += (endPart - startPart);
|
||||
if (*endPart == '/')
|
||||
{
|
||||
*destptr = '/';
|
||||
destptr++;
|
||||
}
|
||||
}
|
||||
if (*endPart == '\0')
|
||||
break;
|
||||
startPart = endPart + 1;
|
||||
}
|
||||
*destptr = '\0';
|
||||
}
|
||||
|
||||
if (what & EP_SINGLESEP)
|
||||
{
|
||||
char *srcptr;
|
||||
srcptr = dest;
|
||||
destptr = dest;
|
||||
while (*srcptr != '\0')
|
||||
{
|
||||
char ch = *srcptr;
|
||||
*(destptr++) = *(srcptr++);
|
||||
if (ch == '/')
|
||||
{
|
||||
while (*srcptr == '/')
|
||||
srcptr++;
|
||||
}
|
||||
}
|
||||
*destptr = '\0';
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (buf != NULL) {
|
||||
int savedErrno = errno;
|
||||
HFree (buf);
|
||||
errno = savedErrno;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(HAVE_DRIVE_LETTERS) && defined(HAVE_CWD_PER_DRIVE)
|
||||
// This code is only needed if we have a current working directory
|
||||
// per drive.
|
||||
// letter is 0 based: 0 = A, 1 = B, ...
|
||||
bool
|
||||
driveLetterExists(int letter)
|
||||
{
|
||||
unsigned long drives;
|
||||
|
||||
drives = _getdrives ();
|
||||
|
||||
return ((drives >> letter) & 1) != 0;
|
||||
}
|
||||
#endif /* if defined(HAVE_DRIVE_LETTERS) && defined(HAVE_CWD_PER_DRIVE) */
|
||||
|
||||
// helper for expandPath, expanding an absolute path
|
||||
// returns a pointer to the end of the filled in part of dest.
|
||||
static char *
|
||||
expandPathAbsolute (char *dest, size_t destLen, const char *src,
|
||||
size_t *skipSrc, int what)
|
||||
{
|
||||
const char *orgSrc;
|
||||
|
||||
if (src[0] == '/' || ((what & EP_SLASHES) && src[0] == '\\'))
|
||||
{
|
||||
// Path is already absolute; nothing to do
|
||||
*skipSrc = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
orgSrc = src;
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if (isDriveLetter(src[0]) && (src[1] == ':'))
|
||||
{
|
||||
int letter;
|
||||
|
||||
if (src[2] == '/' || src[2] == '\\')
|
||||
{
|
||||
// Path is already absolute (of the form "d:/"); nothing to do
|
||||
*skipSrc = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
// Path is of the form "d:path", without a (back)slash after the
|
||||
// semicolon.
|
||||
|
||||
#ifdef REJECT_DRIVE_PATH_WITHOUT_SLASH
|
||||
// We reject paths of the form "d:foo/bar".
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
#elif defined(HAVE_CWD_PER_DRIVE)
|
||||
// Paths of the form "d:foo/bar" are treated as "foo/bar" relative
|
||||
// to the working directory of d:.
|
||||
letter = tolower(src[0]) - 'a';
|
||||
|
||||
// _getdcwd() should only be called on drives that exist.
|
||||
// This is weird though, because it means a race condition
|
||||
// in between the existance check and the call to _getdcwd()
|
||||
// cannot be avoided, unless a drive still exists for Windows
|
||||
// when the physical drive is removed.
|
||||
if (!driveLetterExists (letter))
|
||||
{
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the working directory for a specific drive.
|
||||
if (_getdcwd (letter + 1, dest, destLen) == NULL)
|
||||
{
|
||||
// errno is set
|
||||
return NULL;
|
||||
}
|
||||
|
||||
src += 2;
|
||||
#else /* if !defined(HAVE_CWD_PER_DRIVE) */
|
||||
// We treat paths of the form "d:foo/bar" as "d:/foo/bar".
|
||||
if (destLen < 3) {
|
||||
errno = ERANGE;
|
||||
return NULL;
|
||||
}
|
||||
dest[0] = src[0];
|
||||
dest[1] = ':';
|
||||
dest[2] = '/';
|
||||
*skipSrc = 2;
|
||||
dest += 3;
|
||||
return dest;
|
||||
#endif /* HAVE_CWD_PER_DRIVE */
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_DRIVE_LETTERS */
|
||||
{
|
||||
// Relative dir
|
||||
if (getcwd (dest, destLen) == NULL)
|
||||
{
|
||||
// errno is set
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
size_t tempLen;
|
||||
tempLen = strlen (dest);
|
||||
if (tempLen == 0)
|
||||
{
|
||||
// getcwd() or _getdcwd() returned a 0-length string.
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
dest += tempLen;
|
||||
destLen -= tempLen;
|
||||
}
|
||||
if (dest[-1] != '/'
|
||||
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||
&& dest[-1] != '\\'
|
||||
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||
)
|
||||
{
|
||||
// Need to add a slash.
|
||||
// There's always space, as we overwrite the '\0' that getcwd()
|
||||
// always returns.
|
||||
dest[0] = '/';
|
||||
dest++;
|
||||
destLen--;
|
||||
}
|
||||
|
||||
*skipSrc = (size_t) (src - orgSrc);
|
||||
return dest;
|
||||
}
|
||||
|
||||
// As strrchr, but starts searching from the indicated end of the string.
|
||||
static char *
|
||||
strrchr2(const char *start, int c, const char *end) {
|
||||
for (;;) {
|
||||
end--;
|
||||
if (end < start)
|
||||
return (char *) NULL;
|
||||
if (*end == c)
|
||||
return (char *) unconst(end);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
// returns 0 if the path is not a valid UNC path.
|
||||
// Does not skip trailing slashes.
|
||||
size_t
|
||||
skipUNCServerShare(const char *inPath) {
|
||||
const char *path = inPath;
|
||||
|
||||
// Skip the initial two backslashes.
|
||||
if (path[0] != '\\' || path[1] != '\\')
|
||||
return (size_t) 0;
|
||||
path += 2;
|
||||
|
||||
// Skip the server part.
|
||||
while (*path != '\\' && *path != '/') {
|
||||
if (*path == '\0')
|
||||
return (size_t) 0;
|
||||
path++;
|
||||
}
|
||||
|
||||
// Skip the seperator.
|
||||
path++;
|
||||
|
||||
// Skip the share part.
|
||||
while (*path != '\0' && *path != '\\' && *path != '/')
|
||||
path++;
|
||||
|
||||
return (size_t) (path - inPath);
|
||||
}
|
||||
#endif /* HAVE_UNC_PATHS */
|
||||
|
||||
|
||||
165
project/jni/application/sc2/src/libs/file/files.c
Normal file
165
project/jni/application/sc2/src/libs/file/files.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Contains code handling files
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "port.h"
|
||||
#include "libs/uio.h"
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "filintrn.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
static int copyError(uio_Handle *srcHandle, uio_Handle *dstHandle,
|
||||
uio_DirHandle *unlinkHandle, const char *unlinkPath, uint8 *buf);
|
||||
|
||||
bool
|
||||
fileExists (const char *name)
|
||||
{
|
||||
return access (name, F_OK) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
fileExists2(uio_DirHandle *dir, const char *fileName)
|
||||
{
|
||||
uio_Stream *stream;
|
||||
|
||||
stream = uio_fopen (dir, fileName, "rb");
|
||||
if (stream == NULL)
|
||||
return 0;
|
||||
|
||||
uio_fclose (stream);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a file with path srcName to a file with name newName.
|
||||
* If the destination already exists, the operation fails.
|
||||
* Links are followed.
|
||||
* Special files (fifos, char devices, block devices, etc) will be
|
||||
* read as long as there is data available and the destination will be
|
||||
* a regular file with that data.
|
||||
* The new file will have the same permissions as the old.
|
||||
* If an error occurs during copying, an attempt will be made to
|
||||
* remove the copy.
|
||||
*/
|
||||
int
|
||||
copyFile (uio_DirHandle *srcDir, const char *srcName,
|
||||
uio_DirHandle *dstDir, const char *newName)
|
||||
{
|
||||
uio_Handle *src, *dst;
|
||||
struct stat sb;
|
||||
#define BUFSIZE 65536
|
||||
uint8 *buf, *bufPtr;
|
||||
ssize_t numInBuf, numWritten;
|
||||
|
||||
src = uio_open (srcDir, srcName, O_RDONLY
|
||||
#ifdef WIN32
|
||||
| O_BINARY
|
||||
#endif
|
||||
, 0);
|
||||
if (src == NULL)
|
||||
return -1;
|
||||
|
||||
if (uio_fstat (src, &sb) == -1)
|
||||
return copyError (src, NULL, NULL, NULL, NULL);
|
||||
|
||||
dst = uio_open (dstDir, newName, O_WRONLY | O_CREAT | O_EXCL
|
||||
#ifdef WIN32
|
||||
| O_BINARY
|
||||
#endif
|
||||
, sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
||||
if (dst == NULL)
|
||||
return copyError (src, NULL, NULL, NULL, NULL);
|
||||
|
||||
buf = HMalloc(BUFSIZE);
|
||||
// This was originally a statically allocated buffer,
|
||||
// but as this function might be run from a thread with
|
||||
// a small Stack, this is better.
|
||||
while (1)
|
||||
{
|
||||
numInBuf = uio_read (src, buf, BUFSIZE);
|
||||
if (numInBuf == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return copyError (src, dst, dstDir, newName, buf);
|
||||
}
|
||||
if (numInBuf == 0)
|
||||
break;
|
||||
|
||||
bufPtr = buf;
|
||||
do
|
||||
{
|
||||
numWritten = uio_write (dst, bufPtr, numInBuf);
|
||||
if (numWritten == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return copyError (src, dst, dstDir, newName, buf);
|
||||
}
|
||||
numInBuf -= numWritten;
|
||||
bufPtr += numWritten;
|
||||
} while (numInBuf > 0);
|
||||
}
|
||||
|
||||
HFree (buf);
|
||||
uio_close (src);
|
||||
uio_close (dst);
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes srcHandle if it's not -1.
|
||||
* Closes dstHandle if it's not -1.
|
||||
* Removes unlinkpath from the unlinkHandle dir if it's not NULL.
|
||||
* Frees 'buf' if not NULL.
|
||||
* Always returns -1.
|
||||
* errno is what was before the call.
|
||||
*/
|
||||
static int
|
||||
copyError(uio_Handle *srcHandle, uio_Handle *dstHandle,
|
||||
uio_DirHandle *unlinkHandle, const char *unlinkPath, uint8 *buf)
|
||||
{
|
||||
int savedErrno;
|
||||
|
||||
savedErrno = errno;
|
||||
|
||||
log_add (log_Debug, "Error while copying: %s", strerror (errno));
|
||||
|
||||
if (srcHandle != NULL)
|
||||
uio_close (srcHandle);
|
||||
|
||||
if (dstHandle != NULL)
|
||||
uio_close (dstHandle);
|
||||
|
||||
if (unlinkPath != NULL)
|
||||
uio_unlink (unlinkHandle, unlinkPath);
|
||||
|
||||
if (buf != NULL)
|
||||
HFree(buf);
|
||||
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
24
project/jni/application/sc2/src/libs/file/filintrn.h
Normal file
24
project/jni/application/sc2/src/libs/file/filintrn.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Contains code handling temporary files and dirs
|
||||
|
||||
#ifndef _FILEINTRN_H
|
||||
|
||||
#include "../file.h"
|
||||
|
||||
#endif /* _FILEINTRN_H */
|
||||
|
||||
199
project/jni/application/sc2/src/libs/file/temp.c
Normal file
199
project/jni/application/sc2/src/libs/file/temp.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Contains code handling temporary files and dirs
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "filintrn.h"
|
||||
#include "libs/timelib.h"
|
||||
#include "port.h"
|
||||
#include "libs/compiler.h"
|
||||
#include "libs/log.h"
|
||||
#include "libs/memlib.h"
|
||||
|
||||
static char *tempDirName;
|
||||
uio_DirHandle *tempDir;
|
||||
|
||||
static void
|
||||
removeTempDir (void)
|
||||
{
|
||||
rmdir (tempDirName);
|
||||
}
|
||||
|
||||
// Try if the null-terminated path 'dir' to a directory is valid
|
||||
// as temp path.
|
||||
// On success, 'buf' will be filled with the path, with a trailing /,
|
||||
// null-terminated, and 0 is returned.
|
||||
// On failure, EINVAL, ENAMETOOLONG, or one of the errors access() can return
|
||||
// is returned, and the contents of buf is unspecified.
|
||||
static int
|
||||
tryTempDir (char *buf, size_t buflen, const char *dir)
|
||||
{
|
||||
size_t len;
|
||||
int haveSlash;
|
||||
|
||||
if (dir == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if (dir[0] == '\0')
|
||||
return EINVAL;
|
||||
|
||||
len = strlen (dir);
|
||||
haveSlash = (dir[len - 1] == '/'
|
||||
#ifdef WIN32
|
||||
|| dir[len - 1] == '\\'
|
||||
#endif
|
||||
);
|
||||
if ((haveSlash ? len : len + 1) >= buflen)
|
||||
return ENAMETOOLONG;
|
||||
|
||||
strcpy (buf, dir);
|
||||
#if 0
|
||||
//def WIN32
|
||||
{
|
||||
char *bufPtr;
|
||||
for (bufPtr = buf; *bufPtr != '\0'; bufPtr++)
|
||||
{
|
||||
if (*bufPtr == '\\')
|
||||
*bufPtr = '/';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!haveSlash)
|
||||
{
|
||||
buf[len] = '/';
|
||||
len++;
|
||||
buf[len] = '\0';
|
||||
}
|
||||
if (access (buf, R_OK | W_OK) == -1)
|
||||
return errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
getTempDir (char *buf, size_t buflen) {
|
||||
char cwd[PATH_MAX];
|
||||
|
||||
if (tryTempDir (buf, buflen, getenv("TMP")) &&
|
||||
tryTempDir (buf, buflen, getenv("TEMP")) &&
|
||||
#if !defined(WIN32) || defined (__CYGWIN__)
|
||||
tryTempDir (buf, buflen, "/tmp/") &&
|
||||
tryTempDir (buf, buflen, "/var/tmp/") &&
|
||||
#endif
|
||||
tryTempDir (buf, buflen, getcwd (cwd, sizeof cwd)))
|
||||
{
|
||||
log_add (log_Fatal, "Fatal Error: Cannot find a suitable location "
|
||||
"to store temporary files.");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the global var 'tempDir'
|
||||
static int
|
||||
mountTempDir(const char *name) {
|
||||
static uio_AutoMount *autoMount[] = { NULL };
|
||||
uio_MountHandle *tempHandle;
|
||||
extern uio_Repository *repository;
|
||||
|
||||
tempHandle = uio_mountDir (repository, "/tmp/",
|
||||
uio_FSTYPE_STDIO, NULL, NULL, name, autoMount,
|
||||
uio_MOUNT_TOP, NULL);
|
||||
if (tempHandle == NULL) {
|
||||
int saveErrno = errno;
|
||||
log_add (log_Fatal, "Fatal error: Couldn't mount temp dir '%s': "
|
||||
"%s", name, strerror (errno));
|
||||
errno = saveErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tempDir = uio_openDir (repository, "/tmp", 0);
|
||||
if (tempDir == NULL) {
|
||||
int saveErrno = errno;
|
||||
log_add (log_Fatal, "Fatal error: Could not open temp dir: %s",
|
||||
strerror (errno));
|
||||
errno = saveErrno;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define NUM_TEMP_RETRIES 16
|
||||
// Number of files to try to open before giving up.
|
||||
void
|
||||
initTempDir (void) {
|
||||
size_t len;
|
||||
DWORD num;
|
||||
int i;
|
||||
char *tempPtr;
|
||||
// Pointer to the location in the tempDirName string where the
|
||||
// path to the temp dir ends and the dir starts.
|
||||
|
||||
tempDirName = HMalloc (PATH_MAX);
|
||||
getTempDir (tempDirName, PATH_MAX - 21);
|
||||
// reserve 8 chars for dirname, 1 for slash, and 12 for filename
|
||||
len = strlen(tempDirName);
|
||||
|
||||
num = ((DWORD) time (NULL));
|
||||
// num = GetTimeCounter () % 0xffffffff;
|
||||
tempPtr = tempDirName + len;
|
||||
for (i = 0; i < NUM_TEMP_RETRIES; i++)
|
||||
{
|
||||
sprintf (tempPtr, "%08x", num + i);
|
||||
if (createDirectory (tempDirName, 0700) == -1)
|
||||
continue;
|
||||
|
||||
// Success, we've got a temp dir.
|
||||
tempDirName = HRealloc (tempDirName, len + 9);
|
||||
atexit (removeTempDir);
|
||||
if (mountTempDir (tempDirName) == -1)
|
||||
exit (EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Failure, could not make a temporary directory.
|
||||
log_add (log_Fatal, "Fatal error: Cannot get a name for a temporary "
|
||||
"directory.");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void
|
||||
unInitTempDir (void) {
|
||||
uio_closeDir(tempDir);
|
||||
// the removing of the dir is handled via atexit
|
||||
}
|
||||
|
||||
// return the path to a file in the temp dir with the specified filename.
|
||||
// returns a pointer to a static buffer.
|
||||
char *
|
||||
tempFilePath (const char *filename) {
|
||||
static char file[PATH_MAX];
|
||||
|
||||
if (snprintf (file, PATH_MAX, "%s/%s", tempDirName, filename) == -1) {
|
||||
log_add (log_Fatal, "Path to temp file too long.");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
457
project/jni/application/sc2/src/libs/gfxlib.h
Normal file
457
project/jni/application/sc2/src/libs/gfxlib.h
Normal file
@@ -0,0 +1,457 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _GFXLIB_H
|
||||
#define _GFXLIB_H
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/compiler.h"
|
||||
|
||||
typedef struct Color Color;
|
||||
struct Color {
|
||||
BYTE r;
|
||||
BYTE g;
|
||||
BYTE b;
|
||||
BYTE a;
|
||||
};
|
||||
|
||||
#include "libs/reslib.h"
|
||||
|
||||
typedef struct context_desc CONTEXT_DESC;
|
||||
typedef struct frame_desc FRAME_DESC;
|
||||
typedef struct font_desc FONT_DESC;
|
||||
typedef struct drawable_desc DRAWABLE_DESC;
|
||||
|
||||
typedef CONTEXT_DESC *CONTEXT;
|
||||
typedef FRAME_DESC *FRAME;
|
||||
typedef FONT_DESC *FONT;
|
||||
typedef DRAWABLE_DESC *DRAWABLE;
|
||||
|
||||
typedef UWORD TIME_VALUE;
|
||||
|
||||
#define TIME_SHIFT 8
|
||||
#define MAX_TIME_VALUE ((1 << TIME_SHIFT) + 1)
|
||||
|
||||
typedef SWORD COORD;
|
||||
|
||||
static inline bool
|
||||
sameColor(Color c1, Color c2)
|
||||
{
|
||||
return c1.r == c2.r &&
|
||||
c1.g == c2.g &&
|
||||
c1.b == c2.b &&
|
||||
c1.a == c2.a;
|
||||
}
|
||||
|
||||
// Transform a 5-bits color component to an 8-bits color component.
|
||||
// Form 1, calculates '(r5 / 31.0) * 255.0, highest value is 0xff:
|
||||
#define CC5TO8(c) (((c) << 3) | ((c) >> 2))
|
||||
// Form 2, calculates '(r5 / 32.0) * 256.0, highest value is 0xf8:
|
||||
//#define CC5TO8(c) ((c) << 3)
|
||||
|
||||
#define BUILD_COLOR(col, c256) col
|
||||
// BUILD_COLOR used to combine a 15-bit RGB color tripple with a
|
||||
// destination VGA palette index into a 32-bit value.
|
||||
// Now, it is an empty wrapper which returns the first argument,
|
||||
// which is of type Color, and ignores the second argument,
|
||||
// the palette index.
|
||||
//
|
||||
// It is a remnant of 8bpp hardware paletted display (VGA).
|
||||
// The palette index would be overwritten with the RGB value
|
||||
// and the drawing op would use this index on screen.
|
||||
// The palette indices 0-15, as used in DOS SC2, are unchanged
|
||||
// from the standard VGA palette and are identical to 16-color EGA.
|
||||
// Various frames, borders, menus, etc. frequently refer to these
|
||||
// first 16 colors and normally do not change the RGB values from
|
||||
// the standard ones (see colors.h; most likely unchanged from SC1)
|
||||
// The palette index is meaningless in UQM for the most part.
|
||||
// New code should just use index 0.
|
||||
|
||||
// Turn a 15 bits color into a 24-bits color.
|
||||
// r, g, and b are each 5-bits color components.
|
||||
static inline Color
|
||||
colorFromRgb15 (BYTE r, BYTE g, BYTE b)
|
||||
{
|
||||
Color c;
|
||||
c.r = CC5TO8 (r);
|
||||
c.g = CC5TO8 (g);
|
||||
c.b = CC5TO8 (b);
|
||||
c.a = 0xff;
|
||||
|
||||
return c;
|
||||
}
|
||||
#define MAKE_RGB15(r, g, b) colorFromRgb15 ((r), (g), (b))
|
||||
|
||||
#ifdef NOTYET /* Need C'99 support */
|
||||
#define MAKE_RGB15(r, g, b) (Color) { \
|
||||
.r = CC5TO8 (r), \
|
||||
.g = CC5TO8 (g), \
|
||||
.b = CC5TO8 (b), \
|
||||
.a = 0xff \
|
||||
}
|
||||
#endif
|
||||
|
||||
// Temporary, until we can use C'99 features. Then MAKE_RGB15 will be usable
|
||||
// anywhere.
|
||||
// This define is intended for global initialisations, where the
|
||||
// expression must be constant.
|
||||
#define MAKE_RGB15_INIT(r, g, b) { \
|
||||
CC5TO8 (r), \
|
||||
CC5TO8 (g), \
|
||||
CC5TO8 (b), \
|
||||
0xff \
|
||||
}
|
||||
|
||||
static inline Color
|
||||
buildColorRgba (BYTE r, BYTE g, BYTE b, BYTE a)
|
||||
{
|
||||
Color c;
|
||||
c.r = r;
|
||||
c.g = g;
|
||||
c.b = b;
|
||||
c.a = a;
|
||||
|
||||
return c;
|
||||
}
|
||||
#define BUILD_COLOR_RGBA(r, g, b, a) \
|
||||
buildColorRgba ((r), (g), (b), (a))
|
||||
|
||||
|
||||
typedef BYTE CREATE_FLAGS;
|
||||
// WANT_MASK is deprecated (and non-functional). It used to generate a bitmap
|
||||
// of changed pixels for a target DRAWABLE, so that DRAW_SUBTRACTIVE could
|
||||
// paint background pixels over them, i.e. a revert draw. The backgrounds
|
||||
// are fully erased now instead.
|
||||
#define WANT_MASK (CREATE_FLAGS)(1 << 0)
|
||||
#define WANT_PIXMAP (CREATE_FLAGS)(1 << 1)
|
||||
// MAPPED_TO_DISPLAY is deprecated but still checked by LoadDisplayPixmap().
|
||||
// Its former use was to indicate a pre-scaled graphic for the display.
|
||||
#define MAPPED_TO_DISPLAY (CREATE_FLAGS)(1 << 2)
|
||||
#define WANT_ALPHA (CREATE_FLAGS)(1 << 3)
|
||||
|
||||
typedef struct extent
|
||||
{
|
||||
COORD width, height;
|
||||
} EXTENT;
|
||||
|
||||
typedef struct point
|
||||
{
|
||||
COORD x, y;
|
||||
} POINT;
|
||||
|
||||
typedef struct stamp
|
||||
{
|
||||
POINT origin;
|
||||
FRAME frame;
|
||||
} STAMP;
|
||||
|
||||
typedef struct rect
|
||||
{
|
||||
POINT corner;
|
||||
EXTENT extent;
|
||||
} RECT;
|
||||
|
||||
typedef struct line
|
||||
{
|
||||
POINT first, second;
|
||||
} LINE;
|
||||
|
||||
static inline POINT
|
||||
MAKE_POINT (COORD x, COORD y)
|
||||
{
|
||||
POINT pt = {x, y};
|
||||
return pt;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pointsEqual (POINT p1, POINT p2)
|
||||
{
|
||||
return p1.x == p2.x && p1.y == p2.y;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
extentsEqual (EXTENT e1, EXTENT e2)
|
||||
{
|
||||
return e1.width == e2.width && e1.height == e2.height;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
rectsEqual (RECT r1, RECT r2)
|
||||
{
|
||||
return pointsEqual (r1.corner, r2.corner)
|
||||
&& extentsEqual (r1.extent, r2.extent);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pointWithinRect (RECT r, POINT p)
|
||||
{
|
||||
return p.x >= r.corner.x && p.y >= r.corner.y
|
||||
&& p.x < r.corner.x + r.extent.width
|
||||
&& p.y < r.corner.y + r.extent.height;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ALIGN_LEFT,
|
||||
ALIGN_CENTER,
|
||||
ALIGN_RIGHT
|
||||
} TEXT_ALIGN;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VALIGN_TOP,
|
||||
VALIGN_MIDDLE,
|
||||
VALIGN_BOTTOM
|
||||
} TEXT_VALIGN;
|
||||
|
||||
typedef struct text
|
||||
{
|
||||
POINT baseline;
|
||||
const UNICODE *pStr;
|
||||
TEXT_ALIGN align;
|
||||
COUNT CharCount;
|
||||
} TEXT;
|
||||
|
||||
#include "libs/strlib.h"
|
||||
|
||||
typedef STRING_TABLE COLORMAP_REF;
|
||||
typedef STRING COLORMAP;
|
||||
// COLORMAPPTR is really a pointer to colortable entry structure
|
||||
// which is documented in doc/devel/strtab, .ct files section
|
||||
typedef void *COLORMAPPTR;
|
||||
|
||||
#include "graphics/prim.h"
|
||||
|
||||
typedef BYTE BATCH_FLAGS;
|
||||
// This flag is currently unused but it might make sense to restore it
|
||||
#define BATCH_BUILD_PAGE (BATCH_FLAGS)(1 << 0)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TIME_VALUE last_time_val;
|
||||
POINT EndPoint;
|
||||
STAMP IntersectStamp;
|
||||
} INTERSECT_CONTROL;
|
||||
|
||||
typedef BYTE INTERSECT_CODE;
|
||||
|
||||
#define INTERSECT_LEFT (INTERSECT_CODE)(1 << 0)
|
||||
#define INTERSECT_TOP (INTERSECT_CODE)(1 << 1)
|
||||
#define INTERSECT_RIGHT (INTERSECT_CODE)(1 << 2)
|
||||
#define INTERSECT_BOTTOM (INTERSECT_CODE)(1 << 3)
|
||||
#define INTERSECT_NOCLIP (INTERSECT_CODE)(1 << 7)
|
||||
#define INTERSECT_ALL_SIDES (INTERSECT_CODE)(INTERSECT_LEFT | \
|
||||
INTERSECT_TOP | \
|
||||
INTERSECT_RIGHT | \
|
||||
INTERSECT_BOTTOM)
|
||||
|
||||
typedef POINT HOT_SPOT;
|
||||
|
||||
extern HOT_SPOT MAKE_HOT_SPOT (COORD, COORD);
|
||||
|
||||
extern INTERSECT_CODE BoxIntersect (RECT *pr1, RECT *pr2, RECT *printer);
|
||||
extern void BoxUnion (RECT *pr1, RECT *pr2, RECT *punion);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FadeAllToWhite = 250,
|
||||
FadeSomeToWhite,
|
||||
FadeAllToBlack,
|
||||
FadeAllToColor,
|
||||
FadeSomeToBlack,
|
||||
FadeSomeToColor
|
||||
} ScreenFadeType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DRAW_REPLACE = 0,
|
||||
// Pixels in the target FRAME are replaced entirely.
|
||||
// Non-stamp primitives with Color.a < 255 to RGB targets are
|
||||
// equivalent to DRAW_ALPHA with (DrawMode.factor = Color.a),
|
||||
// except the Text primitives.
|
||||
// DrawMode.factor: ignored
|
||||
// Text: supported (except DRAW_ALPHA via Color.a)
|
||||
// RGBA sources (WANT_ALPHA): per-pixel alpha blending performed
|
||||
// RGBA targets (WANT_ALPHA): replace directly supported
|
||||
DRAW_ADDITIVE,
|
||||
// Pixel channels of the source FRAME or Color channels of
|
||||
// a primitive are modulated by (DrawMode.factor / 255) and added
|
||||
// to the pixel channels of the target FRAME.
|
||||
// DrawMode.factor range: -32767..32767 (negative values make
|
||||
// draw subtractive); 255 = 1:1 ratio
|
||||
// Text: not yet supported
|
||||
// RGBA sources (WANT_ALPHA): alpha channel ignored
|
||||
// RGBA targets (WANT_ALPHA): not yet supported
|
||||
DRAW_ALPHA,
|
||||
// Pixel channels of the source FRAME or Color channels of
|
||||
// a primitive are modulated by (DrawMode.factor / 255) and added
|
||||
// to the pixel channels of the target FRAME, modulated by
|
||||
// (1 - DrawMode.factor / 255)
|
||||
// DrawMode.factor range: 0..255; 255 = fully opaque
|
||||
// Text: supported
|
||||
// RGBA sources (WANT_ALPHA): alpha channel ignored
|
||||
// RGBA targets (WANT_ALPHA): not yet supported
|
||||
|
||||
DRAW_DEFAULT = DRAW_REPLACE,
|
||||
} DrawKind;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE kind;
|
||||
SWORD factor;
|
||||
} DrawMode;
|
||||
|
||||
#define DRAW_REPLACE_MODE MAKE_DRAW_MODE (DRAW_REPLACE, 0)
|
||||
#define DRAW_FACTOR_1 0xff
|
||||
|
||||
static inline DrawMode
|
||||
MAKE_DRAW_MODE (DrawKind kind, SWORD factor)
|
||||
{
|
||||
DrawMode mode;
|
||||
mode.kind = kind;
|
||||
mode.factor = factor;
|
||||
return mode;
|
||||
}
|
||||
|
||||
extern CONTEXT SetContext (CONTEXT Context);
|
||||
extern Color SetContextForeGroundColor (Color Color);
|
||||
extern Color GetContextForeGroundColor (void);
|
||||
extern Color SetContextBackGroundColor (Color Color);
|
||||
extern Color GetContextBackGroundColor (void);
|
||||
extern FRAME SetContextFGFrame (FRAME Frame);
|
||||
extern FRAME GetContextFGFrame (void);
|
||||
// Context cliprect defines the drawing bounds. Additionally, all
|
||||
// drawing positions (x,y) are relative to the cliprect corner.
|
||||
extern BOOLEAN SetContextClipRect (RECT *pRect);
|
||||
// The returned rect is always filled in. If the context cliprect
|
||||
// is undefined, the returned rect has foreground frame dimensions.
|
||||
extern BOOLEAN GetContextClipRect (RECT *pRect);
|
||||
// The actual origin will be orgOffset + context ClipRect.corner
|
||||
extern POINT SetContextOrigin (POINT orgOffset);
|
||||
extern DrawMode SetContextDrawMode (DrawMode);
|
||||
extern DrawMode GetContextDrawMode (void);
|
||||
// 'area' may be NULL to copy the entire CONTEXT cliprect
|
||||
// 'area' is relative to the CONTEXT cliprect
|
||||
extern DRAWABLE CopyContextRect (const RECT* area);
|
||||
|
||||
extern TIME_VALUE DrawablesIntersect (INTERSECT_CONTROL *pControl0,
|
||||
INTERSECT_CONTROL *pControl1, TIME_VALUE max_time_val);
|
||||
extern void DrawStamp (STAMP *pStamp);
|
||||
extern void DrawFilledStamp (STAMP *pStamp);
|
||||
extern void DrawPoint (POINT *pPoint);
|
||||
extern void DrawRectangle (RECT *pRect);
|
||||
extern void DrawFilledRectangle (RECT *pRect);
|
||||
extern void DrawLine (LINE *pLine);
|
||||
extern void font_DrawText (TEXT *pText);
|
||||
extern void font_DrawTracedText (TEXT *pText, Color text, Color trace);
|
||||
extern void DrawBatch (PRIMITIVE *pBasePrim, PRIM_LINKS PrimLinks,
|
||||
BATCH_FLAGS BatchFlags);
|
||||
extern void BatchGraphics (void);
|
||||
extern void UnbatchGraphics (void);
|
||||
extern void FlushGraphics (void);
|
||||
extern void ClearDrawable (void);
|
||||
#ifdef DEBUG
|
||||
extern CONTEXT CreateContextAux (const char *name);
|
||||
#define CreateContext(name) CreateContextAux((name))
|
||||
#else /* if !defined(DEBUG) */
|
||||
extern CONTEXT CreateContextAux (void);
|
||||
#define CreateContext(name) CreateContextAux()
|
||||
#endif /* !defined(DEBUG) */
|
||||
extern BOOLEAN DestroyContext (CONTEXT ContextRef);
|
||||
extern DRAWABLE CreateDisplay (CREATE_FLAGS CreateFlags, SIZE *pwidth,
|
||||
SIZE *pheight);
|
||||
extern DRAWABLE CreateDrawable (CREATE_FLAGS CreateFlags, SIZE width,
|
||||
SIZE height, COUNT num_frames);
|
||||
extern BOOLEAN DestroyDrawable (DRAWABLE Drawable);
|
||||
extern BOOLEAN GetFrameRect (FRAME Frame, RECT *pRect);
|
||||
#ifdef DEBUG
|
||||
extern const char *GetContextName (CONTEXT context);
|
||||
extern CONTEXT GetFirstContext (void);
|
||||
extern CONTEXT GetNextContext (CONTEXT context);
|
||||
extern size_t GetContextCount (void);
|
||||
#endif /* DEBUG */
|
||||
|
||||
extern HOT_SPOT SetFrameHot (FRAME Frame, HOT_SPOT HotSpot);
|
||||
extern HOT_SPOT GetFrameHot (FRAME Frame);
|
||||
extern BOOLEAN InstallGraphicResTypes (void);
|
||||
extern DRAWABLE LoadGraphicFile (const char *pStr);
|
||||
extern FONT LoadFontFile (const char *pStr);
|
||||
extern void *LoadGraphicInstance (RESOURCE res);
|
||||
extern DRAWABLE LoadDisplayPixmap (const RECT *area, FRAME frame);
|
||||
extern FRAME SetContextFontEffect (FRAME EffectFrame);
|
||||
extern FONT SetContextFont (FONT Font);
|
||||
extern BOOLEAN DestroyFont (FONT FontRef);
|
||||
// The returned pRect is relative to the context drawing origin
|
||||
extern BOOLEAN TextRect (TEXT *pText, RECT *pRect, BYTE *pdelta);
|
||||
extern BOOLEAN GetContextFontLeading (SIZE *pheight);
|
||||
extern BOOLEAN GetContextFontLeadingWidth (SIZE *pwidth);
|
||||
extern COUNT GetFrameCount (FRAME Frame);
|
||||
extern COUNT GetFrameIndex (FRAME Frame);
|
||||
extern FRAME SetAbsFrameIndex (FRAME Frame, COUNT FrameIndex);
|
||||
extern FRAME SetRelFrameIndex (FRAME Frame, SIZE FrameOffs);
|
||||
extern FRAME SetEquFrameIndex (FRAME DstFrame, FRAME SrcFrame);
|
||||
extern FRAME IncFrameIndex (FRAME Frame);
|
||||
extern FRAME DecFrameIndex (FRAME Frame);
|
||||
extern DRAWABLE CopyFrameRect (FRAME Frame, const RECT *area);
|
||||
extern DRAWABLE CloneFrame (FRAME Frame);
|
||||
extern DRAWABLE RotateFrame (FRAME Frame, int angle_deg);
|
||||
extern DRAWABLE RescaleFrame (FRAME, int width, int height);
|
||||
// This pair works for both paletted and trucolor frames
|
||||
extern BOOLEAN ReadFramePixelColors (FRAME frame, Color *pixels,
|
||||
int width, int height);
|
||||
extern BOOLEAN WriteFramePixelColors (FRAME frame, const Color *pixels,
|
||||
int width, int height);
|
||||
// This pair only works for paletted frames
|
||||
extern BOOLEAN ReadFramePixelIndexes (FRAME frame, BYTE *pixels,
|
||||
int width, int height);
|
||||
extern BOOLEAN WriteFramePixelIndexes (FRAME frame, const BYTE *pixels,
|
||||
int width, int height);
|
||||
extern void SetFrameTransparentColor (FRAME, Color);
|
||||
|
||||
// If the frame is an active SCREEN_DRAWABLE, this call must be
|
||||
// preceeded by FlushGraphics() for draw commands to have taken effect
|
||||
extern Color GetFramePixel (FRAME, POINT pixelPt);
|
||||
|
||||
extern FRAME CaptureDrawable (DRAWABLE Drawable);
|
||||
extern DRAWABLE ReleaseDrawable (FRAME Frame);
|
||||
|
||||
extern DRAWABLE GetFrameParentDrawable (FRAME Frame);
|
||||
|
||||
extern BOOLEAN SetColorMap (COLORMAPPTR ColorMapPtr);
|
||||
extern DWORD XFormColorMap (COLORMAPPTR ColorMapPtr, SIZE TimeInterval);
|
||||
extern DWORD FadeScreen (ScreenFadeType fadeType, SIZE TimeInterval);
|
||||
extern void FlushColorXForms (void);
|
||||
#define InitColorMapResources InitStringTableResources
|
||||
#define LoadColorMapFile LoadStringTableFile
|
||||
#define LoadColorMapInstance LoadStringTableInstance
|
||||
#define CaptureColorMap CaptureStringTable
|
||||
#define ReleaseColorMap ReleaseStringTable
|
||||
#define DestroyColorMap DestroyStringTable
|
||||
#define GetColorMapRef GetStringTable
|
||||
#define GetColorMapCount GetStringTableCount
|
||||
#define GetColorMapIndex GetStringTableIndex
|
||||
#define SetAbsColorMapIndex SetAbsStringTableIndex
|
||||
#define SetRelColorMapIndex SetRelStringTableIndex
|
||||
#define GetColorMapLength GetStringLengthBin
|
||||
|
||||
extern COLORMAPPTR GetColorMapAddress (COLORMAP);
|
||||
|
||||
void SetSystemRect (const RECT *pRect);
|
||||
void ClearSystemRect (void);
|
||||
|
||||
#endif /* _GFXLIB_H */
|
||||
9
project/jni/application/sc2/src/libs/graphics/Makeinfo
Normal file
9
project/jni/application/sc2/src/libs/graphics/Makeinfo
Normal file
@@ -0,0 +1,9 @@
|
||||
if [ "$uqm_GFXMODULE" = "sdl" ]; then
|
||||
uqm_SUBDIRS="sdl"
|
||||
fi
|
||||
|
||||
uqm_CFILES="boxint.c clipline.c cmap.c context.c drawable.c filegfx.c
|
||||
bbox.c dcqueue.c gfxload.c
|
||||
font.c frame.c gfx_common.c intersec.c loaddisp.c
|
||||
pixmap.c resgfx.c tfb_draw.c tfb_prim.c widgets.c"
|
||||
|
||||
133
project/jni/application/sc2/src/libs/graphics/bbox.c
Normal file
133
project/jni/application/sc2/src/libs/graphics/bbox.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/graphics/bbox.h"
|
||||
|
||||
TFB_BoundingBox TFB_BBox;
|
||||
int maxWidth;
|
||||
int maxHeight;
|
||||
|
||||
void
|
||||
TFB_BBox_Init (int width, int height)
|
||||
{
|
||||
maxWidth = width;
|
||||
maxHeight = height;
|
||||
TFB_BBox.clip.extent.width = width;
|
||||
TFB_BBox.clip.extent.height = height;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_BBox_Reset (void)
|
||||
{
|
||||
TFB_BBox.valid = 0;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_BBox_SetClipRect (const RECT *r)
|
||||
{
|
||||
if (!r)
|
||||
{ /* No clipping -- full rect */
|
||||
TFB_BBox.clip.corner.x = 0;
|
||||
TFB_BBox.clip.corner.y = 0;
|
||||
TFB_BBox.clip.extent.width = maxWidth;
|
||||
TFB_BBox.clip.extent.height = maxHeight;
|
||||
return;
|
||||
}
|
||||
|
||||
TFB_BBox.clip = *r;
|
||||
|
||||
/* Make sure the cliprect is sane */
|
||||
if (TFB_BBox.clip.corner.x < 0)
|
||||
TFB_BBox.clip.corner.x = 0;
|
||||
|
||||
if (TFB_BBox.clip.corner.y < 0)
|
||||
TFB_BBox.clip.corner.y = 0;
|
||||
|
||||
if (TFB_BBox.clip.corner.x + TFB_BBox.clip.extent.width > maxWidth)
|
||||
TFB_BBox.clip.extent.width = maxWidth - TFB_BBox.clip.corner.x;
|
||||
|
||||
if (TFB_BBox.clip.corner.y + TFB_BBox.clip.extent.height > maxHeight)
|
||||
TFB_BBox.clip.extent.height = maxHeight - TFB_BBox.clip.corner.y;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_BBox_RegisterPoint (int x, int y)
|
||||
{
|
||||
int x1 = TFB_BBox.clip.corner.x;
|
||||
int y1 = TFB_BBox.clip.corner.y;
|
||||
int x2 = TFB_BBox.clip.corner.x + TFB_BBox.clip.extent.width - 1;
|
||||
int y2 = TFB_BBox.clip.corner.y + TFB_BBox.clip.extent.height - 1;
|
||||
|
||||
/* Constrain coordinates */
|
||||
if (x < x1) x = x1;
|
||||
if (x >= x2) x = x2;
|
||||
if (y < y1) y = y1;
|
||||
if (y >= y2) y = y2;
|
||||
|
||||
/* Is this the first point? If so, set a pixel-region and return. */
|
||||
if (!TFB_BBox.valid)
|
||||
{
|
||||
TFB_BBox.valid = 1;
|
||||
TFB_BBox.region.corner.x = x;
|
||||
TFB_BBox.region.corner.y = y;
|
||||
TFB_BBox.region.extent.width = 1;
|
||||
TFB_BBox.region.extent.height = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise expand the rectangle if necessary. */
|
||||
x1 = TFB_BBox.region.corner.x;
|
||||
y1 = TFB_BBox.region.corner.y;
|
||||
x2 = TFB_BBox.region.corner.x + TFB_BBox.region.extent.width - 1;
|
||||
y2 = TFB_BBox.region.corner.y + TFB_BBox.region.extent.height - 1;
|
||||
|
||||
if (x < x1) {
|
||||
TFB_BBox.region.corner.x = x;
|
||||
TFB_BBox.region.extent.width += x1 - x;
|
||||
}
|
||||
if (y < y1) {
|
||||
TFB_BBox.region.corner.y = y;
|
||||
TFB_BBox.region.extent.height += y1 - y;
|
||||
}
|
||||
if (x > x2) {
|
||||
TFB_BBox.region.extent.width += x - x2;
|
||||
}
|
||||
if (y > y2) {
|
||||
TFB_BBox.region.extent.height += y - y2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFB_BBox_RegisterRect (const RECT *r)
|
||||
{
|
||||
/* RECT will still register as a corner point of the cliprect even
|
||||
* if it does not intersect with the cliprect at all. This is not
|
||||
* a problem, as more is not less. */
|
||||
TFB_BBox_RegisterPoint (r->corner.x, r->corner.y);
|
||||
TFB_BBox_RegisterPoint (r->corner.x + r->extent.width - 1,
|
||||
r->corner.y + r->extent.height - 1);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_BBox_RegisterCanvas (TFB_Canvas c, int x, int y)
|
||||
{
|
||||
RECT r;
|
||||
r.corner.x = x;
|
||||
r.corner.y = y;
|
||||
TFB_DrawCanvas_GetExtent (c, &r.extent);
|
||||
TFB_BBox_RegisterRect (&r);
|
||||
}
|
||||
46
project/jni/application/sc2/src/libs/graphics/bbox.h
Normal file
46
project/jni/application/sc2/src/libs/graphics/bbox.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef BBOX_H_INCL__
|
||||
#define BBOX_H_INCL__
|
||||
|
||||
#include "libs/gfxlib.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
|
||||
/* Bounding Box operations. These operations are NOT synchronized.
|
||||
* However, they should only be accessed by TFB_FlushGraphics and
|
||||
* TFB_SwapBuffers, or the routines that they exclusively call -- all
|
||||
* of which are only callable by the thread that is permitted to touch
|
||||
* the screen. No explicit locks should therefore be required. */
|
||||
|
||||
typedef struct {
|
||||
int valid; // If zero, the next point registered becomes the region
|
||||
RECT region; // The actual modified rectangle
|
||||
RECT clip; // Points outside of this rectangle are pushed to
|
||||
// the closest border point
|
||||
} TFB_BoundingBox;
|
||||
|
||||
extern TFB_BoundingBox TFB_BBox;
|
||||
|
||||
void TFB_BBox_RegisterPoint (int x, int y);
|
||||
void TFB_BBox_RegisterRect (const RECT *r);
|
||||
void TFB_BBox_RegisterCanvas (TFB_Canvas c, int x, int y);
|
||||
|
||||
void TFB_BBox_Init (int width, int height);
|
||||
void TFB_BBox_Reset (void);
|
||||
void TFB_BBox_SetClipRect (const RECT *r);
|
||||
|
||||
#endif /* BBOX_H_INCL__ */
|
||||
183
project/jni/application/sc2/src/libs/graphics/boxint.c
Normal file
183
project/jni/application/sc2/src/libs/graphics/boxint.c
Normal file
@@ -0,0 +1,183 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
|
||||
#undef MAX
|
||||
#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
|
||||
|
||||
INTERSECT_CODE
|
||||
BoxIntersect (RECT *pr1, RECT *pr2, RECT *pinter)
|
||||
{
|
||||
INTERSECT_CODE intersect_code;
|
||||
COORD x1;
|
||||
SIZE w1, w2, delta;
|
||||
|
||||
intersect_code = INTERSECT_NOCLIP;
|
||||
|
||||
x1 = pr1->corner.x - pr2->corner.x;
|
||||
|
||||
w1 = pr1->extent.width;
|
||||
w2 = pr2->extent.width;
|
||||
if ((delta = w2 - x1) <= w1)
|
||||
{
|
||||
if (delta != w1)
|
||||
{
|
||||
w1 = delta;
|
||||
intersect_code &= ~INTERSECT_NOCLIP;
|
||||
}
|
||||
intersect_code |= INTERSECT_RIGHT;
|
||||
}
|
||||
if (x1 <= 0)
|
||||
{
|
||||
if (x1 < 0)
|
||||
{
|
||||
w1 += x1;
|
||||
x1 = 0;
|
||||
intersect_code &= ~INTERSECT_NOCLIP;
|
||||
}
|
||||
intersect_code |= INTERSECT_LEFT;
|
||||
}
|
||||
|
||||
if (w1 > 0)
|
||||
{
|
||||
#define h2 w2
|
||||
COORD y1;
|
||||
SIZE h1;
|
||||
|
||||
y1 = pr1->corner.y - pr2->corner.y;
|
||||
|
||||
h1 = pr1->extent.height;
|
||||
h2 = pr2->extent.height;
|
||||
if ((delta = h2 - y1) <= h1)
|
||||
{
|
||||
if (delta != h1)
|
||||
{
|
||||
h1 = delta;
|
||||
intersect_code &= ~INTERSECT_NOCLIP;
|
||||
}
|
||||
intersect_code |= INTERSECT_BOTTOM;
|
||||
}
|
||||
if (y1 <= 0)
|
||||
{
|
||||
if (y1 < 0)
|
||||
{
|
||||
h1 += y1;
|
||||
y1 = 0;
|
||||
intersect_code &= ~INTERSECT_NOCLIP;
|
||||
}
|
||||
intersect_code |= INTERSECT_TOP;
|
||||
}
|
||||
|
||||
if (h1 > 0)
|
||||
{
|
||||
pinter->corner.x = x1 + pr2->corner.x;
|
||||
pinter->corner.y = y1 + pr2->corner.y;
|
||||
pinter->extent.width = w1;
|
||||
pinter->extent.height = h1;
|
||||
|
||||
return (intersect_code);
|
||||
}
|
||||
#undef h2
|
||||
}
|
||||
|
||||
return ((INTERSECT_CODE)0);
|
||||
}
|
||||
|
||||
void
|
||||
BoxUnion (RECT *pr1, RECT *pr2, RECT *punion)
|
||||
{
|
||||
#if NEVER // Part of lower FIXME.
|
||||
COORD x2, y2, w2, h2;
|
||||
#endif // NEVER
|
||||
|
||||
// Union is A AND B, put together, correct? Returns a bigger box that
|
||||
// encompasses the two.
|
||||
punion->corner.x = MIN(pr1->corner.x, pr2->corner.x);
|
||||
punion->corner.y = MIN(pr1->corner.y, pr2->corner.y);
|
||||
|
||||
punion->extent.width = MAX(pr1->corner.x + pr1->extent.width,
|
||||
pr2->corner.x + pr2->extent.width) - punion->corner.x;
|
||||
punion->extent.height = MAX(pr1->corner.y + pr1->extent.height,
|
||||
pr2->corner.y + pr2->extent.height) - punion->corner.y;
|
||||
|
||||
|
||||
#if NEVER // FIXME - I think this is broken, but keeping it around for reference
|
||||
// FIXME - just in case.
|
||||
|
||||
#if 1 /* alter based on 0 widths */
|
||||
|
||||
x2 =
|
||||
(pr1->corner.x < pr2->corner.x)? pr1->corner.x : pr2->corner.x;
|
||||
|
||||
y2 =
|
||||
(pr1->corner.y < pr2->corner.y)? pr1->corner.y : pr2->corner.y;
|
||||
|
||||
w2 = (
|
||||
((pr1->corner.x + pr1->extent.width) > (pr2->corner.x + pr2->extent.width))?
|
||||
(pr1->corner.x + pr1->extent.width) : (pr2->corner.x + pr2->extent.width)
|
||||
) - punion->corner.x;
|
||||
|
||||
h2 = (
|
||||
((pr1->corner.y + pr1->extent.height) > (pr2->corner.y + pr2->extent.height))?
|
||||
(pr1->corner.y + pr1->extent.height) : (pr2->corner.y + pr2->extent.height)
|
||||
) - punion->corner.y;
|
||||
#else
|
||||
SIZE delta;
|
||||
COORD x1, y1, w1, h1;
|
||||
|
||||
x1 = pr1->corner.x;
|
||||
w1 = pr1->extent.width;
|
||||
x2 = pr2->corner.x;
|
||||
w2 = pr2->extent.width;
|
||||
if ((delta = x1 - x2) >= 0)
|
||||
w1 += delta;
|
||||
else
|
||||
{
|
||||
w2 -= delta;
|
||||
x2 += delta;
|
||||
}
|
||||
|
||||
y1 = pr1->corner.y;
|
||||
h1 = pr1->extent.height;
|
||||
y2 = pr2->corner.y;
|
||||
h2 = pr2->extent.height;
|
||||
if ((delta = y1 - y2) >= 0)
|
||||
h1 += delta;
|
||||
else
|
||||
{
|
||||
h2 -= delta;
|
||||
y2 += delta;
|
||||
}
|
||||
|
||||
if ((delta = w1 - w2) > 0)
|
||||
w2 += delta;
|
||||
if ((delta = h1 - h2) > 0)
|
||||
h2 += delta;
|
||||
#endif
|
||||
|
||||
punion->corner.x = x2;
|
||||
punion->corner.y = y2;
|
||||
punion->extent.width = w2;
|
||||
punion->extent.height = h2;
|
||||
|
||||
#endif // NEVER
|
||||
}
|
||||
|
||||
241
project/jni/application/sc2/src/libs/graphics/clipline.c
Normal file
241
project/jni/application/sc2/src/libs/graphics/clipline.c
Normal file
@@ -0,0 +1,241 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
|
||||
INTERSECT_CODE
|
||||
_clip_line (const RECT *pClipRect, BRESENHAM_LINE *pLine)
|
||||
{
|
||||
COORD p;
|
||||
COORD x0, y0, xmin, ymin, xmax, ymax;
|
||||
SIZE abs_delta_x, abs_delta_y;
|
||||
INTERSECT_CODE intersect_code;
|
||||
|
||||
xmin = pClipRect->corner.x;
|
||||
ymin = pClipRect->corner.y;
|
||||
xmax = pClipRect->corner.x + pClipRect->extent.width - 1;
|
||||
ymax = pClipRect->corner.y + pClipRect->extent.height - 1;
|
||||
if (pLine->first.x <= pLine->second.x)
|
||||
pLine->end_points_exchanged = FALSE;
|
||||
else
|
||||
{
|
||||
p = pLine->first.x;
|
||||
pLine->first.x = pLine->second.x;
|
||||
pLine->second.x = p;
|
||||
|
||||
p = pLine->first.y;
|
||||
pLine->first.y = pLine->second.y;
|
||||
pLine->second.y = p;
|
||||
|
||||
pLine->end_points_exchanged = TRUE;
|
||||
}
|
||||
|
||||
if (pLine->first.x > xmax || pLine->second.x < xmin ||
|
||||
(pLine->first.y > ymax && pLine->second.y > ymax) ||
|
||||
(pLine->first.y < ymin && pLine->second.y < ymin))
|
||||
return ((INTERSECT_CODE)0);
|
||||
|
||||
intersect_code = INTERSECT_NOCLIP;
|
||||
x0 = y0 = 0;
|
||||
abs_delta_x = (pLine->second.x - pLine->first.x) << 1;
|
||||
abs_delta_y = (pLine->second.y - pLine->first.y) << 1;
|
||||
pLine->abs_delta_x = abs_delta_x;
|
||||
pLine->abs_delta_y = abs_delta_y;
|
||||
if (abs_delta_y == 0)
|
||||
{
|
||||
if (pLine->first.x < xmin)
|
||||
{
|
||||
pLine->first.x = xmin;
|
||||
intersect_code |= INTERSECT_LEFT;
|
||||
}
|
||||
if (pLine->second.x > xmax)
|
||||
{
|
||||
pLine->second.x = xmax;
|
||||
intersect_code |= INTERSECT_RIGHT;
|
||||
}
|
||||
}
|
||||
else if (abs_delta_x == 0)
|
||||
{
|
||||
if (abs_delta_y < 0)
|
||||
{
|
||||
p = pLine->first.y;
|
||||
pLine->first.y = pLine->second.y;
|
||||
pLine->second.y = p;
|
||||
|
||||
pLine->abs_delta_y =
|
||||
abs_delta_y = -abs_delta_y;
|
||||
}
|
||||
|
||||
if (pLine->first.y < ymin)
|
||||
{
|
||||
pLine->first.y = ymin;
|
||||
intersect_code |= INTERSECT_TOP;
|
||||
}
|
||||
if (pLine->second.y > ymax)
|
||||
{
|
||||
pLine->second.y = ymax;
|
||||
intersect_code |= INTERSECT_BOTTOM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
COORD x1, y1;
|
||||
|
||||
p = pLine->first.x;
|
||||
x1 = pLine->second.x - p;
|
||||
xmin = xmin - p;
|
||||
xmax = xmax - p;
|
||||
|
||||
p = pLine->first.y;
|
||||
if (abs_delta_y > 0)
|
||||
{
|
||||
y1 = pLine->second.y - p;
|
||||
ymin = ymin - p;
|
||||
ymax = ymax - p;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1 = p - pLine->second.y;
|
||||
ymin = p - ymin;
|
||||
ymax = p - ymax;
|
||||
|
||||
p = ymin;
|
||||
ymin = ymax;
|
||||
ymax = p;
|
||||
abs_delta_y = -abs_delta_y;
|
||||
}
|
||||
|
||||
if (abs_delta_x > abs_delta_y)
|
||||
{
|
||||
SIZE half_dx;
|
||||
|
||||
half_dx = abs_delta_x >> 1;
|
||||
if (x0 < xmin)
|
||||
{
|
||||
if ((y0 = (COORD)(((long)abs_delta_y *
|
||||
(x0 = xmin) + half_dx) / abs_delta_x)) > ymax)
|
||||
return ((INTERSECT_CODE)0);
|
||||
intersect_code |= INTERSECT_LEFT;
|
||||
}
|
||||
if (x1 > xmax)
|
||||
{
|
||||
if ((y1 = (COORD)(((long)abs_delta_y *
|
||||
(x1 = xmax) + half_dx) / abs_delta_x)) < ymin)
|
||||
return ((INTERSECT_CODE)0);
|
||||
intersect_code |= INTERSECT_RIGHT;
|
||||
}
|
||||
if (y0 < ymin)
|
||||
{
|
||||
if ((x0 = (COORD)(((long)abs_delta_x *
|
||||
(y0 = ymin) - half_dx + (abs_delta_y - 1)) /
|
||||
abs_delta_y)) > xmax)
|
||||
return ((INTERSECT_CODE)0);
|
||||
intersect_code |= INTERSECT_TOP;
|
||||
intersect_code &= ~INTERSECT_LEFT;
|
||||
}
|
||||
if (y1 > ymax)
|
||||
{
|
||||
if ((x1 = (COORD)(((long)abs_delta_x *
|
||||
((y1 = ymax) + 1) - half_dx + (abs_delta_y - 1)) /
|
||||
abs_delta_y) - 1) < xmin)
|
||||
return ((INTERSECT_CODE)0);
|
||||
intersect_code |= INTERSECT_BOTTOM;
|
||||
intersect_code &= ~INTERSECT_RIGHT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SIZE half_dy;
|
||||
|
||||
half_dy = abs_delta_y >> 1;
|
||||
if (y0 < ymin)
|
||||
{
|
||||
if ((x0 = (COORD)(((long)abs_delta_x *
|
||||
(y0 = ymin) + half_dy) / abs_delta_y)) > xmax)
|
||||
return ((INTERSECT_CODE)0);
|
||||
intersect_code |= INTERSECT_TOP;
|
||||
}
|
||||
if (y1 > ymax)
|
||||
{
|
||||
if ((x1 = (COORD)(((long)abs_delta_x *
|
||||
(y1 = ymax) + half_dy) / abs_delta_y)) < xmin)
|
||||
return ((INTERSECT_CODE)0);
|
||||
intersect_code |= INTERSECT_BOTTOM;
|
||||
}
|
||||
if (x0 < xmin)
|
||||
{
|
||||
if ((y0 = (COORD)(((long)abs_delta_y *
|
||||
(x0 = xmin) - half_dy + (abs_delta_x - 1)) /
|
||||
abs_delta_x)) > ymax)
|
||||
return ((INTERSECT_CODE)0);
|
||||
intersect_code |= INTERSECT_LEFT;
|
||||
intersect_code &= ~INTERSECT_TOP;
|
||||
}
|
||||
if (x1 > xmax)
|
||||
{
|
||||
if ((y1 = (COORD)(((long)abs_delta_y *
|
||||
((x1 = xmax) + 1) - half_dy + (abs_delta_x - 1)) /
|
||||
abs_delta_x) - 1) < ymin)
|
||||
return ((INTERSECT_CODE)0);
|
||||
intersect_code |= INTERSECT_RIGHT;
|
||||
intersect_code &= ~INTERSECT_BOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
pLine->second.x = pLine->first.x + x1;
|
||||
pLine->first.x += x0;
|
||||
if (pLine->abs_delta_y > 0)
|
||||
{
|
||||
pLine->second.y = pLine->first.y + y1;
|
||||
pLine->first.y += y0;
|
||||
}
|
||||
else
|
||||
{
|
||||
INTERSECT_CODE y_code;
|
||||
|
||||
pLine->second.y = pLine->first.y - y1;
|
||||
pLine->first.y -= y0;
|
||||
|
||||
y_code = (INTERSECT_CODE)(intersect_code
|
||||
& (INTERSECT_TOP | INTERSECT_BOTTOM));
|
||||
if (y_code && y_code != (INTERSECT_TOP | INTERSECT_BOTTOM))
|
||||
intersect_code ^= (INTERSECT_TOP | INTERSECT_BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(intersect_code & INTERSECT_ALL_SIDES))
|
||||
{
|
||||
if (abs_delta_x > abs_delta_y)
|
||||
pLine->error_term = -(SIZE)(abs_delta_x >> 1);
|
||||
else
|
||||
pLine->error_term = -(SIZE)(abs_delta_y >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
intersect_code &= ~INTERSECT_NOCLIP;
|
||||
if (abs_delta_x > abs_delta_y)
|
||||
pLine->error_term = (SIZE)((x0 * (long)abs_delta_y) -
|
||||
(y0 * (long)abs_delta_x)) - (abs_delta_x >> 1);
|
||||
else
|
||||
pLine->error_term = (SIZE)((y0 * (long)abs_delta_x) -
|
||||
(x0 * (long)abs_delta_y)) - (abs_delta_y >> 1);
|
||||
}
|
||||
|
||||
return (pLine->intersect_code = intersect_code);
|
||||
}
|
||||
|
||||
639
project/jni/application/sc2/src/libs/graphics/cmap.c
Normal file
639
project/jni/application/sc2/src/libs/graphics/cmap.c
Normal file
@@ -0,0 +1,639 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libs/graphics/cmap.h"
|
||||
#include "libs/threadlib.h"
|
||||
#include "libs/timelib.h"
|
||||
#include "libs/inplib.h"
|
||||
#include "libs/strlib.h"
|
||||
// for GetStringAddress()
|
||||
#include "libs/log.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
typedef struct xform_control
|
||||
{
|
||||
int CMapIndex; // -1 means unused
|
||||
COLORMAPPTR CMapPtr;
|
||||
SIZE Ticks;
|
||||
DWORD StartTime;
|
||||
DWORD EndTime;
|
||||
Color OldCMap[NUMBER_OF_PLUTVALS];
|
||||
} XFORM_CONTROL;
|
||||
|
||||
#define MAX_XFORMS 16
|
||||
static struct
|
||||
{
|
||||
XFORM_CONTROL TaskControl[MAX_XFORMS];
|
||||
volatile int Highest;
|
||||
// 'pending' is Highest >= 0
|
||||
Mutex Lock;
|
||||
} XFormControl;
|
||||
|
||||
static int fadeAmount = FADE_NORMAL_INTENSITY;
|
||||
static int fadeDelta;
|
||||
static TimeCount fadeStartTime;
|
||||
static sint32 fadeInterval;
|
||||
|
||||
#define SPARE_COLORMAPS 20
|
||||
|
||||
// Colormaps are rapidly replaced in some parts of the game, so
|
||||
// it pays to have some spares on hand
|
||||
static TFB_ColorMap *poolhead;
|
||||
static int poolcount;
|
||||
|
||||
static TFB_ColorMap * colormaps[MAX_COLORMAPS];
|
||||
static int mapcount;
|
||||
Mutex maplock;
|
||||
|
||||
|
||||
void
|
||||
InitColorMaps (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// init colormaps
|
||||
maplock = CreateMutex ("Colormaps Lock", SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
||||
|
||||
// init xform control
|
||||
XFormControl.Highest = -1;
|
||||
XFormControl.Lock = CreateMutex ("Transform Lock", SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
||||
for (i = 0; i < MAX_XFORMS; ++i)
|
||||
XFormControl.TaskControl[i].CMapIndex = -1;
|
||||
}
|
||||
|
||||
void
|
||||
UninitColorMaps (void)
|
||||
{
|
||||
TFB_ColorMap *next;
|
||||
|
||||
// free spares
|
||||
for ( ; poolhead; poolhead = next)
|
||||
{
|
||||
next = poolhead->next;
|
||||
HFree (poolhead);
|
||||
}
|
||||
|
||||
// uninit xform control
|
||||
DestroyMutex (XFormControl.Lock);
|
||||
|
||||
// uninit colormaps
|
||||
DestroyMutex (maplock);
|
||||
}
|
||||
|
||||
static inline TFB_ColorMap *
|
||||
alloc_colormap (void)
|
||||
// returns an addrefed object
|
||||
{
|
||||
TFB_ColorMap *map;
|
||||
|
||||
if (poolhead)
|
||||
{ // have some spares
|
||||
map = poolhead;
|
||||
poolhead = map->next;
|
||||
--poolcount;
|
||||
}
|
||||
else
|
||||
{ // no spares, need a new one
|
||||
map = HMalloc (sizeof (*map));
|
||||
map->palette = AllocNativePalette ();
|
||||
if (!map->palette)
|
||||
{
|
||||
HFree (map);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
map->next = NULL;
|
||||
map->index = -1;
|
||||
map->refcount = 1;
|
||||
map->version = 0;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static TFB_ColorMap *
|
||||
clone_colormap (TFB_ColorMap *from, int index)
|
||||
// returns an addrefed object
|
||||
{
|
||||
TFB_ColorMap *map;
|
||||
|
||||
map = alloc_colormap ();
|
||||
if (!map)
|
||||
{
|
||||
log_add (log_Warning, "FATAL: clone_colormap(): "
|
||||
"could not allocate a map");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
{ // fresh new map
|
||||
map->index = index;
|
||||
if (from)
|
||||
map->version = from->version;
|
||||
}
|
||||
map->version++;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_colormap (TFB_ColorMap *map)
|
||||
{
|
||||
if (!map)
|
||||
{
|
||||
log_add (log_Warning, "free_colormap(): tried to free a NULL map");
|
||||
return;
|
||||
}
|
||||
|
||||
if (poolcount < SPARE_COLORMAPS)
|
||||
{ // return to the spare pool
|
||||
map->next = poolhead;
|
||||
poolhead = map;
|
||||
++poolcount;
|
||||
}
|
||||
else
|
||||
{ // don't need any more spares
|
||||
FreeNativePalette (map->palette);
|
||||
HFree (map);
|
||||
}
|
||||
}
|
||||
|
||||
static inline TFB_ColorMap *
|
||||
get_colormap (int index)
|
||||
{
|
||||
TFB_ColorMap *map;
|
||||
|
||||
map = colormaps[index];
|
||||
if (!map)
|
||||
{
|
||||
log_add (log_Fatal, "BUG: get_colormap(): map not present");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
map->refcount++;
|
||||
return map;
|
||||
}
|
||||
|
||||
static inline void
|
||||
release_colormap (TFB_ColorMap *map)
|
||||
{
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
if (map->refcount <= 0)
|
||||
{
|
||||
log_add (log_Warning, "BUG: release_colormap(): refcount not >0");
|
||||
return;
|
||||
}
|
||||
|
||||
map->refcount--;
|
||||
if (map->refcount == 0)
|
||||
free_colormap (map);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_ReturnColorMap (TFB_ColorMap *map)
|
||||
{
|
||||
LockMutex (maplock);
|
||||
release_colormap (map);
|
||||
UnlockMutex (maplock);
|
||||
}
|
||||
|
||||
TFB_ColorMap *
|
||||
TFB_GetColorMap (int index)
|
||||
{
|
||||
TFB_ColorMap *map;
|
||||
|
||||
LockMutex (maplock);
|
||||
map = get_colormap (index);
|
||||
UnlockMutex (maplock);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
void
|
||||
GetColorMapColors (Color *colors, TFB_ColorMap *map)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
for (i = 0; i < NUMBER_OF_PLUTVALS; ++i)
|
||||
colors[i] = GetNativePaletteColor (map->palette, i);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SetColorMap (COLORMAPPTR map)
|
||||
{
|
||||
int start, end;
|
||||
int total_size;
|
||||
UBYTE *colors = (UBYTE*)map;
|
||||
TFB_ColorMap **mpp;
|
||||
|
||||
if (!map)
|
||||
return TRUE;
|
||||
|
||||
start = *colors++;
|
||||
end = *colors++;
|
||||
if (start > end)
|
||||
{
|
||||
log_add (log_Warning, "ERROR: SetColorMap(): "
|
||||
"starting map (%d) not less or eq ending (%d)",
|
||||
start, end);
|
||||
return FALSE;
|
||||
}
|
||||
if (start >= MAX_COLORMAPS)
|
||||
{
|
||||
log_add (log_Warning, "ERROR: SetColorMap(): "
|
||||
"starting map (%d) beyond range (0-%d)",
|
||||
start, (int)MAX_COLORMAPS - 1);
|
||||
return FALSE;
|
||||
}
|
||||
if (end >= MAX_COLORMAPS)
|
||||
{
|
||||
log_add (log_Warning, "SetColorMap(): "
|
||||
"ending map (%d) beyond range (0-%d)\n",
|
||||
end, (int)MAX_COLORMAPS - 1);
|
||||
end = MAX_COLORMAPS - 1;
|
||||
}
|
||||
|
||||
total_size = end + 1;
|
||||
|
||||
LockMutex (maplock);
|
||||
|
||||
if (total_size > mapcount)
|
||||
mapcount = total_size;
|
||||
|
||||
// parse the supplied PLUTs into our colormaps
|
||||
for (mpp = colormaps + start; start <= end; ++start, ++mpp)
|
||||
{
|
||||
int i;
|
||||
TFB_ColorMap *newmap;
|
||||
TFB_ColorMap *oldmap;
|
||||
|
||||
oldmap = *mpp;
|
||||
newmap = clone_colormap (oldmap, start);
|
||||
|
||||
for (i = 0; i < NUMBER_OF_PLUTVALS; ++i, colors += PLUTVAL_BYTE_SIZE)
|
||||
{
|
||||
Color color;
|
||||
|
||||
color.a = 0xff;
|
||||
color.r = colors[PLUTVAL_RED];
|
||||
color.g = colors[PLUTVAL_GREEN];
|
||||
color.b = colors[PLUTVAL_BLUE];
|
||||
SetNativePaletteColor (newmap->palette, i, color);
|
||||
}
|
||||
|
||||
*mpp = newmap;
|
||||
release_colormap (oldmap);
|
||||
}
|
||||
|
||||
UnlockMutex (maplock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Fade Transforms */
|
||||
|
||||
int
|
||||
GetFadeAmount (void)
|
||||
{
|
||||
int newAmount;
|
||||
|
||||
LockMutex (XFormControl.Lock);
|
||||
|
||||
if (fadeInterval)
|
||||
{ // have a pending fade
|
||||
TimeCount Now = GetTimeCounter ();
|
||||
sint32 elapsed;
|
||||
|
||||
elapsed = Now - fadeStartTime;
|
||||
if (elapsed > fadeInterval)
|
||||
elapsed = fadeInterval;
|
||||
|
||||
newAmount = fadeAmount + (long)fadeDelta * elapsed / fadeInterval;
|
||||
|
||||
if (elapsed >= fadeInterval)
|
||||
{ // fade is over
|
||||
fadeAmount = newAmount;
|
||||
fadeInterval = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // no fade pending, return the current
|
||||
newAmount = fadeAmount;
|
||||
}
|
||||
|
||||
UnlockMutex (XFormControl.Lock);
|
||||
|
||||
return newAmount;
|
||||
}
|
||||
|
||||
static void
|
||||
finishPendingFade (void)
|
||||
{
|
||||
if (fadeInterval)
|
||||
{ // end the fade immediately
|
||||
fadeAmount += fadeDelta;
|
||||
fadeInterval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FlushFadeXForms (void)
|
||||
{
|
||||
LockMutex (XFormControl.Lock);
|
||||
finishPendingFade ();
|
||||
UnlockMutex (XFormControl.Lock);
|
||||
}
|
||||
|
||||
DWORD
|
||||
FadeScreen (ScreenFadeType fadeType, SIZE TimeInterval)
|
||||
{
|
||||
TimeCount TimeOut;
|
||||
int FadeEnd;
|
||||
|
||||
switch (fadeType)
|
||||
{
|
||||
case FadeAllToBlack:
|
||||
case FadeSomeToBlack:
|
||||
FadeEnd = FADE_NO_INTENSITY;
|
||||
break;
|
||||
case FadeAllToColor:
|
||||
case FadeSomeToColor:
|
||||
FadeEnd = FADE_NORMAL_INTENSITY;
|
||||
break;
|
||||
case FadeAllToWhite:
|
||||
case FadeSomeToWhite:
|
||||
FadeEnd = FADE_FULL_INTENSITY;
|
||||
break;
|
||||
default:
|
||||
return (GetTimeCounter ());
|
||||
}
|
||||
|
||||
// Don't make users wait for fades
|
||||
if (QuitPosted)
|
||||
TimeInterval = 0;
|
||||
|
||||
LockMutex (XFormControl.Lock);
|
||||
|
||||
finishPendingFade ();
|
||||
|
||||
if (TimeInterval <= 0)
|
||||
{ // end the fade immediately
|
||||
fadeAmount = FadeEnd;
|
||||
// cancel any pending fades
|
||||
fadeInterval = 0;
|
||||
TimeOut = GetTimeCounter ();
|
||||
}
|
||||
else
|
||||
{
|
||||
fadeInterval = TimeInterval;
|
||||
fadeDelta = FadeEnd - fadeAmount;
|
||||
fadeStartTime = GetTimeCounter ();
|
||||
TimeOut = fadeStartTime + TimeInterval + 1;
|
||||
}
|
||||
|
||||
UnlockMutex (XFormControl.Lock);
|
||||
|
||||
return TimeOut;
|
||||
}
|
||||
|
||||
/* Colormap Transforms */
|
||||
|
||||
static void
|
||||
finish_colormap_xform (int which)
|
||||
{
|
||||
SetColorMap (XFormControl.TaskControl[which].CMapPtr);
|
||||
XFormControl.TaskControl[which].CMapIndex = -1;
|
||||
// check Highest ptr
|
||||
if (which == XFormControl.Highest)
|
||||
{
|
||||
do
|
||||
--which;
|
||||
while (which >= 0 && XFormControl.TaskControl[which].CMapIndex == -1);
|
||||
|
||||
XFormControl.Highest = which;
|
||||
}
|
||||
}
|
||||
|
||||
static inline BYTE
|
||||
blendChan (BYTE c1, BYTE c2, int weight, int scale)
|
||||
{
|
||||
return c1 + ((int)c2 - c1) * weight / scale;
|
||||
}
|
||||
|
||||
/* This gives the XFormColorMap task a timeslice to do its thing
|
||||
* Only one thread should ever be allowed to be calling this at any time
|
||||
*/
|
||||
BOOLEAN
|
||||
XFormColorMap_step (void)
|
||||
{
|
||||
BOOLEAN Changed = FALSE;
|
||||
int x;
|
||||
DWORD Now = GetTimeCounter ();
|
||||
|
||||
LockMutex (XFormControl.Lock);
|
||||
|
||||
for (x = 0; x <= XFormControl.Highest; ++x)
|
||||
{
|
||||
XFORM_CONTROL *control = &XFormControl.TaskControl[x];
|
||||
int index = control->CMapIndex;
|
||||
int TicksLeft = control->EndTime - Now;
|
||||
TFB_ColorMap *curmap;
|
||||
|
||||
if (index < 0)
|
||||
continue; // unused slot
|
||||
|
||||
LockMutex (maplock);
|
||||
|
||||
curmap = colormaps[index];
|
||||
if (!curmap)
|
||||
{
|
||||
UnlockMutex (maplock);
|
||||
log_add (log_Error, "BUG: XFormColorMap_step(): no current map");
|
||||
finish_colormap_xform (x);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TicksLeft > 0)
|
||||
{
|
||||
#define XFORM_SCALE 0x10000
|
||||
TFB_ColorMap *newmap = NULL;
|
||||
UBYTE *newClr;
|
||||
Color *oldClr;
|
||||
int frac;
|
||||
int i;
|
||||
|
||||
newmap = clone_colormap (curmap, index);
|
||||
|
||||
oldClr = control->OldCMap;
|
||||
newClr = (UBYTE*)control->CMapPtr + 2;
|
||||
|
||||
frac = (int)(control->Ticks - TicksLeft) * XFORM_SCALE
|
||||
/ control->Ticks;
|
||||
|
||||
for (i = 0; i < NUMBER_OF_PLUTVALS; ++i, ++oldClr,
|
||||
newClr += PLUTVAL_BYTE_SIZE)
|
||||
{
|
||||
Color color;
|
||||
|
||||
color.a = 0xff;
|
||||
color.r = blendChan (oldClr->r, newClr[PLUTVAL_RED],
|
||||
frac, XFORM_SCALE);
|
||||
color.g = blendChan (oldClr->g, newClr[PLUTVAL_GREEN],
|
||||
frac, XFORM_SCALE);
|
||||
color.b = blendChan (oldClr->b, newClr[PLUTVAL_BLUE],
|
||||
frac, XFORM_SCALE);
|
||||
SetNativePaletteColor (newmap->palette, i, color);
|
||||
}
|
||||
|
||||
colormaps[index] = newmap;
|
||||
release_colormap (curmap);
|
||||
}
|
||||
|
||||
UnlockMutex (maplock);
|
||||
|
||||
if (TicksLeft <= 0)
|
||||
{ // asked for immediate xform or already done
|
||||
finish_colormap_xform (x);
|
||||
}
|
||||
|
||||
Changed = TRUE;
|
||||
}
|
||||
|
||||
UnlockMutex (XFormControl.Lock);
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
static void
|
||||
FlushPLUTXForms (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
LockMutex (XFormControl.Lock);
|
||||
|
||||
for (i = 0; i <= XFormControl.Highest; ++i)
|
||||
{
|
||||
if (XFormControl.TaskControl[i].CMapIndex >= 0)
|
||||
finish_colormap_xform (i);
|
||||
}
|
||||
XFormControl.Highest = -1; // all gone
|
||||
|
||||
UnlockMutex (XFormControl.Lock);
|
||||
}
|
||||
|
||||
static DWORD
|
||||
XFormPLUT (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
|
||||
{
|
||||
TFB_ColorMap *map;
|
||||
XFORM_CONTROL *control;
|
||||
int index;
|
||||
int x;
|
||||
int first_avail = -1;
|
||||
DWORD EndTime;
|
||||
DWORD Now;
|
||||
|
||||
Now = GetTimeCounter ();
|
||||
index = *(UBYTE*)ColorMapPtr;
|
||||
|
||||
LockMutex (XFormControl.Lock);
|
||||
// Find an available slot, or reuse if required
|
||||
for (x = 0; x <= XFormControl.Highest
|
||||
&& index != XFormControl.TaskControl[x].CMapIndex;
|
||||
++x)
|
||||
{
|
||||
if (first_avail == -1 && XFormControl.TaskControl[x].CMapIndex == -1)
|
||||
first_avail = x;
|
||||
}
|
||||
|
||||
if (index == XFormControl.TaskControl[x].CMapIndex)
|
||||
{ // already xforming this colormap -- cancel and reuse slot
|
||||
finish_colormap_xform (x);
|
||||
}
|
||||
else if (first_avail >= 0)
|
||||
{ // picked up a slot along the way
|
||||
x = first_avail;
|
||||
}
|
||||
else if (x >= MAX_XFORMS)
|
||||
{ // flush some xforms if the queue is full
|
||||
log_add (log_Debug, "WARNING: XFormPLUT(): no slots available");
|
||||
x = XFormControl.Highest;
|
||||
finish_colormap_xform (x);
|
||||
}
|
||||
// take next unused one
|
||||
control = &XFormControl.TaskControl[x];
|
||||
if (x > XFormControl.Highest)
|
||||
XFormControl.Highest = x;
|
||||
|
||||
// make a copy of the current map
|
||||
LockMutex (maplock);
|
||||
map = colormaps[index];
|
||||
if (!map)
|
||||
{
|
||||
UnlockMutex (maplock);
|
||||
UnlockMutex (XFormControl.Lock);
|
||||
log_add (log_Warning, "BUG: XFormPLUT(): no current map");
|
||||
return (0);
|
||||
}
|
||||
GetColorMapColors (control->OldCMap, map);
|
||||
UnlockMutex (maplock);
|
||||
|
||||
control->CMapIndex = index;
|
||||
control->CMapPtr = ColorMapPtr;
|
||||
control->Ticks = TimeInterval;
|
||||
if (control->Ticks < 0)
|
||||
control->Ticks = 0; /* prevent negative fade */
|
||||
control->StartTime = Now;
|
||||
control->EndTime = EndTime = Now + control->Ticks;
|
||||
|
||||
UnlockMutex (XFormControl.Lock);
|
||||
|
||||
return (EndTime);
|
||||
}
|
||||
|
||||
DWORD
|
||||
XFormColorMap (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
|
||||
{
|
||||
if (!ColorMapPtr)
|
||||
return (0);
|
||||
|
||||
// Don't make users wait for transforms
|
||||
if (QuitPosted)
|
||||
TimeInterval = 0;
|
||||
|
||||
return XFormPLUT (ColorMapPtr, TimeInterval);
|
||||
}
|
||||
|
||||
void
|
||||
FlushColorXForms (void)
|
||||
{
|
||||
FlushFadeXForms ();
|
||||
FlushPLUTXForms ();
|
||||
}
|
||||
|
||||
// The type conversions are implicit and will generate errors
|
||||
// or warnings if types change imcompatibly
|
||||
COLORMAPPTR
|
||||
GetColorMapAddress (COLORMAP colormap)
|
||||
{
|
||||
return GetStringAddress (colormap);
|
||||
}
|
||||
77
project/jni/application/sc2/src/libs/graphics/cmap.h
Normal file
77
project/jni/application/sc2/src/libs/graphics/cmap.h
Normal file
@@ -0,0 +1,77 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef CMAP_H
|
||||
#define CMAP_H
|
||||
|
||||
#include "libs/gfxlib.h"
|
||||
|
||||
#define MAX_COLORMAPS 250
|
||||
|
||||
// These are pertinent to colortable file format
|
||||
// We load colormaps as binary and parse them when needed
|
||||
#define PLUTVAL_BYTE_SIZE 3
|
||||
// Channel order in colormap tables
|
||||
#define PLUTVAL_RED 0
|
||||
#define PLUTVAL_GREEN 1
|
||||
#define PLUTVAL_BLUE 2
|
||||
|
||||
#define NUMBER_OF_PLUTVALS 256
|
||||
// Size of the colormap in a colortable file
|
||||
#define PLUT_BYTE_SIZE (PLUTVAL_BYTE_SIZE * NUMBER_OF_PLUTVALS)
|
||||
|
||||
#define FADE_NO_INTENSITY 0
|
||||
#define FADE_NORMAL_INTENSITY 255
|
||||
#define FADE_FULL_INTENSITY 510
|
||||
|
||||
typedef struct NativePalette NativePalette;
|
||||
|
||||
typedef struct tfb_colormap
|
||||
{
|
||||
int index;
|
||||
// Colormap index as the game sees it
|
||||
int version;
|
||||
// Version goes up every time the colormap changes. This may
|
||||
// be due to SetColorMap() or at every transformation step
|
||||
// of XFormColorMap(). Paletted TFB_Images track the last
|
||||
// colormap version they were drawn with for optimization.
|
||||
int refcount;
|
||||
struct tfb_colormap *next;
|
||||
// for spares linking
|
||||
NativePalette *palette;
|
||||
} TFB_ColorMap;
|
||||
|
||||
extern int GetFadeAmount (void);
|
||||
|
||||
extern void InitColorMaps (void);
|
||||
extern void UninitColorMaps (void);
|
||||
|
||||
extern void GetColorMapColors (Color *colors, TFB_ColorMap *);
|
||||
|
||||
extern TFB_ColorMap * TFB_GetColorMap (int index);
|
||||
extern void TFB_ReturnColorMap (TFB_ColorMap *map);
|
||||
|
||||
extern BOOLEAN XFormColorMap_step (void);
|
||||
|
||||
// Native
|
||||
NativePalette* AllocNativePalette (void);
|
||||
void FreeNativePalette (NativePalette *);
|
||||
void SetNativePaletteColor (NativePalette *, int index, Color);
|
||||
Color GetNativePaletteColor (NativePalette *, int index);
|
||||
|
||||
#endif /* CMAP_H */
|
||||
398
project/jni/application/sc2/src/libs/graphics/context.c
Normal file
398
project/jni/application/sc2/src/libs/graphics/context.c
Normal file
@@ -0,0 +1,398 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
|
||||
GRAPHICS_STATUS _GraphicsStatusFlags;
|
||||
CONTEXT _pCurContext;
|
||||
|
||||
#ifdef DEBUG
|
||||
// We keep track of all contexts
|
||||
CONTEXT firstContext;
|
||||
// The first one in the list.
|
||||
CONTEXT *contextEnd = &firstContext;
|
||||
// Where to put the next context.
|
||||
#endif
|
||||
|
||||
PRIMITIVE _locPrim;
|
||||
|
||||
FONT _CurFontPtr;
|
||||
|
||||
#define DEFAULT_FORE_COLOR BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)
|
||||
#define DEFAULT_BACK_COLOR BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00)
|
||||
|
||||
#define DEFAULT_DRAW_MODE MAKE_DRAW_MODE (DRAW_DEFAULT, 255)
|
||||
|
||||
CONTEXT
|
||||
SetContext (CONTEXT Context)
|
||||
{
|
||||
CONTEXT LastContext;
|
||||
|
||||
LastContext = _pCurContext;
|
||||
if (Context != LastContext)
|
||||
{
|
||||
if (LastContext)
|
||||
{
|
||||
UnsetContextFlags (
|
||||
MAKE_WORD (0, GRAPHICS_ACTIVE | DRAWABLE_ACTIVE));
|
||||
SetContextFlags (
|
||||
MAKE_WORD (0, _GraphicsStatusFlags
|
||||
& (GRAPHICS_ACTIVE | DRAWABLE_ACTIVE)));
|
||||
|
||||
DeactivateContext ();
|
||||
}
|
||||
|
||||
_pCurContext = Context;
|
||||
if (_pCurContext)
|
||||
{
|
||||
ActivateContext ();
|
||||
|
||||
_GraphicsStatusFlags &= ~(GRAPHICS_ACTIVE | DRAWABLE_ACTIVE);
|
||||
_GraphicsStatusFlags |= HIBYTE (_get_context_flags ());
|
||||
|
||||
SetPrimColor (&_locPrim, _get_context_fg_color ());
|
||||
|
||||
_CurFramePtr = _get_context_fg_frame ();
|
||||
_CurFontPtr = _get_context_font ();
|
||||
}
|
||||
}
|
||||
|
||||
return (LastContext);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
CONTEXT
|
||||
CreateContextAux (const char *name)
|
||||
#else /* if !defined(DEBUG) */
|
||||
CONTEXT
|
||||
CreateContextAux (void)
|
||||
#endif /* !defined(DEBUG) */
|
||||
{
|
||||
CONTEXT NewContext;
|
||||
|
||||
NewContext = AllocContext ();
|
||||
if (NewContext)
|
||||
{
|
||||
/* initialize context */
|
||||
#ifdef DEBUG
|
||||
NewContext->name = name;
|
||||
NewContext->next = NULL;
|
||||
*contextEnd = NewContext;
|
||||
contextEnd = &NewContext->next;
|
||||
#endif /* DEBUG */
|
||||
|
||||
NewContext->Mode = DEFAULT_DRAW_MODE;
|
||||
NewContext->ForeGroundColor = DEFAULT_FORE_COLOR;
|
||||
NewContext->BackGroundColor = DEFAULT_BACK_COLOR;
|
||||
}
|
||||
|
||||
return NewContext;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Loop through the list of context to the pointer which points to the
|
||||
// specified context. This is either 'firstContext' or the address of
|
||||
// the 'next' field of some other context.
|
||||
static CONTEXT *
|
||||
FindContextPtr (CONTEXT context) {
|
||||
CONTEXT *ptr;
|
||||
|
||||
for (ptr = &firstContext; *ptr != NULL; ptr = &(*ptr)->next) {
|
||||
if (*ptr == context)
|
||||
break;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
BOOLEAN
|
||||
DestroyContext (CONTEXT ContextRef)
|
||||
{
|
||||
if (ContextRef == 0)
|
||||
return (FALSE);
|
||||
|
||||
if (_pCurContext && _pCurContext == ContextRef)
|
||||
SetContext ((CONTEXT)0);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Unlink the context.
|
||||
{
|
||||
CONTEXT *contextPtr = FindContextPtr (ContextRef);
|
||||
if (contextEnd == &ContextRef->next)
|
||||
contextEnd = contextPtr;
|
||||
*contextPtr = ContextRef->next;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
FreeContext (ContextRef);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Color
|
||||
SetContextForeGroundColor (Color color)
|
||||
{
|
||||
Color oldColor;
|
||||
|
||||
if (!ContextActive ())
|
||||
return DEFAULT_FORE_COLOR;
|
||||
|
||||
oldColor = _get_context_fg_color ();
|
||||
if (!sameColor(oldColor, color))
|
||||
{
|
||||
SwitchContextForeGroundColor (color);
|
||||
|
||||
if (!(_get_context_fbk_flags () & FBK_IMAGE))
|
||||
{
|
||||
SetContextFBkFlags (FBK_DIRTY);
|
||||
}
|
||||
}
|
||||
SetPrimColor (&_locPrim, color);
|
||||
|
||||
return (oldColor);
|
||||
}
|
||||
|
||||
Color
|
||||
GetContextForeGroundColor (void)
|
||||
{
|
||||
if (!ContextActive ())
|
||||
return DEFAULT_FORE_COLOR;
|
||||
|
||||
return _get_context_fg_color ();
|
||||
}
|
||||
|
||||
Color
|
||||
SetContextBackGroundColor (Color color)
|
||||
{
|
||||
Color oldColor;
|
||||
|
||||
if (!ContextActive ())
|
||||
return DEFAULT_BACK_COLOR;
|
||||
|
||||
oldColor = _get_context_bg_color ();
|
||||
if (!sameColor(oldColor, color))
|
||||
SwitchContextBackGroundColor (color);
|
||||
|
||||
return oldColor;
|
||||
}
|
||||
|
||||
Color
|
||||
GetContextBackGroundColor (void)
|
||||
{
|
||||
if (!ContextActive ())
|
||||
return DEFAULT_BACK_COLOR;
|
||||
|
||||
return _get_context_bg_color ();
|
||||
}
|
||||
|
||||
DrawMode
|
||||
SetContextDrawMode (DrawMode mode)
|
||||
{
|
||||
DrawMode oldMode;
|
||||
|
||||
if (!ContextActive ())
|
||||
return DEFAULT_DRAW_MODE;
|
||||
|
||||
oldMode = _get_context_draw_mode ();
|
||||
SwitchContextDrawMode (mode);
|
||||
|
||||
return oldMode;
|
||||
}
|
||||
|
||||
DrawMode
|
||||
GetContextDrawMode (void)
|
||||
{
|
||||
if (!ContextActive ())
|
||||
return DEFAULT_DRAW_MODE;
|
||||
|
||||
return _get_context_draw_mode ();
|
||||
}
|
||||
|
||||
// Returns a rect based at 0,0 and the size of context foreground frame
|
||||
static inline RECT
|
||||
_get_context_fg_rect (void)
|
||||
{
|
||||
RECT r = { {0, 0}, {0, 0} };
|
||||
if (_CurFramePtr)
|
||||
r.extent = GetFrameBounds (_CurFramePtr);
|
||||
return r;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SetContextClipRect (RECT *lpRect)
|
||||
{
|
||||
if (!ContextActive ())
|
||||
return (FALSE);
|
||||
|
||||
if (lpRect)
|
||||
{
|
||||
if (rectsEqual (*lpRect, _get_context_fg_rect ()))
|
||||
{ // Cliprect is undefined to mirror GetContextClipRect()
|
||||
_pCurContext->ClipRect.extent.width = 0;
|
||||
}
|
||||
else
|
||||
{ // We have a cliprect
|
||||
_pCurContext->ClipRect = *lpRect;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Set cliprect as undefined
|
||||
_pCurContext->ClipRect.extent.width = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
GetContextClipRect (RECT *lpRect)
|
||||
{
|
||||
if (!ContextActive ())
|
||||
return (FALSE);
|
||||
|
||||
*lpRect = _pCurContext->ClipRect;
|
||||
if (!_pCurContext->ClipRect.extent.width)
|
||||
{ // Though the cliprect is undefined, drawing will be clipped
|
||||
// to the extent of the foreground frame
|
||||
*lpRect = _get_context_fg_rect ();
|
||||
}
|
||||
|
||||
return (_pCurContext->ClipRect.extent.width != 0);
|
||||
}
|
||||
|
||||
POINT
|
||||
SetContextOrigin (POINT orgOffset)
|
||||
{
|
||||
// XXX: This is a hack, kind of. But that's what the original did.
|
||||
return SetFrameHot (_CurFramePtr, orgOffset);
|
||||
}
|
||||
|
||||
FRAME
|
||||
SetContextFontEffect (FRAME EffectFrame)
|
||||
{
|
||||
FRAME LastEffect;
|
||||
|
||||
if (!ContextActive ())
|
||||
return (NULL);
|
||||
|
||||
LastEffect = _get_context_fonteff ();
|
||||
if (EffectFrame != LastEffect)
|
||||
{
|
||||
SwitchContextFontEffect (EffectFrame);
|
||||
|
||||
if (EffectFrame != 0)
|
||||
{
|
||||
SetContextFBkFlags (FBK_IMAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnsetContextFBkFlags (FBK_IMAGE);
|
||||
}
|
||||
}
|
||||
|
||||
return LastEffect;
|
||||
}
|
||||
|
||||
void
|
||||
FixContextFontEffect (void)
|
||||
{
|
||||
SIZE w, h;
|
||||
TFB_Image* img;
|
||||
|
||||
if (!ContextActive () || (_get_context_font_backing () != 0
|
||||
&& !(_get_context_fbk_flags () & FBK_DIRTY)))
|
||||
return;
|
||||
|
||||
if (!GetContextFontLeading (&h) || !GetContextFontLeadingWidth (&w))
|
||||
return;
|
||||
|
||||
img = _pCurContext->FontBacking;
|
||||
if (img)
|
||||
TFB_DrawScreen_DeleteImage (img);
|
||||
|
||||
img = TFB_DrawImage_CreateForScreen (w, h, TRUE);
|
||||
if (_get_context_fbk_flags () & FBK_IMAGE)
|
||||
{ // image pattern backing
|
||||
FRAME EffectFrame = _get_context_fonteff ();
|
||||
|
||||
TFB_DrawImage_Image (EffectFrame->image,
|
||||
-EffectFrame->HotSpot.x, -EffectFrame->HotSpot.y,
|
||||
0, 0, NULL, DRAW_REPLACE_MODE, img);
|
||||
}
|
||||
else
|
||||
{ // solid color backing
|
||||
RECT r = { {0, 0}, {w, h} };
|
||||
Color color = _get_context_fg_color ();
|
||||
|
||||
TFB_DrawImage_Rect (&r, color, DRAW_REPLACE_MODE, img);
|
||||
}
|
||||
|
||||
_pCurContext->FontBacking = img;
|
||||
UnsetContextFBkFlags (FBK_DIRTY);
|
||||
}
|
||||
|
||||
// 'area' may be NULL to copy the entire CONTEXT cliprect
|
||||
// 'area' is relative to the CONTEXT cliprect
|
||||
DRAWABLE
|
||||
CopyContextRect (const RECT* area)
|
||||
{
|
||||
RECT clipRect;
|
||||
RECT fgRect;
|
||||
RECT r;
|
||||
|
||||
if (!ContextActive () || !_CurFramePtr)
|
||||
return NULL;
|
||||
|
||||
fgRect = _get_context_fg_rect ();
|
||||
GetContextClipRect (&clipRect);
|
||||
r = clipRect;
|
||||
if (area)
|
||||
{ // a portion of the context
|
||||
r.corner.x += area->corner.x;
|
||||
r.corner.y += area->corner.y;
|
||||
r.extent = area->extent;
|
||||
}
|
||||
// TODO: Should this take CONTEXT origin into account too?
|
||||
// validate the rect
|
||||
if (!BoxIntersect (&r, &fgRect, &r))
|
||||
return NULL;
|
||||
|
||||
if (_CurFramePtr->Type == SCREEN_DRAWABLE)
|
||||
return LoadDisplayPixmap (&r, NULL);
|
||||
else
|
||||
return CopyFrameRect (_CurFramePtr, &r);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
const char *
|
||||
GetContextName (CONTEXT context)
|
||||
{
|
||||
return context->name;
|
||||
}
|
||||
|
||||
CONTEXT
|
||||
GetFirstContext (void)
|
||||
{
|
||||
return firstContext;
|
||||
}
|
||||
|
||||
CONTEXT
|
||||
GetNextContext (CONTEXT context)
|
||||
{
|
||||
return context->next;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
147
project/jni/application/sc2/src/libs/graphics/context.h
Normal file
147
project/jni/application/sc2/src/libs/graphics/context.h
Normal file
@@ -0,0 +1,147 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _CONTEXT_H
|
||||
#define _CONTEXT_H
|
||||
|
||||
#include "tfb_draw.h"
|
||||
#include "libs/memlib.h"
|
||||
|
||||
typedef UWORD FBK_FLAGS;
|
||||
#define FBK_DIRTY (1 << 0)
|
||||
#define FBK_IMAGE (1 << 1)
|
||||
|
||||
struct context_desc
|
||||
{
|
||||
UWORD Flags;
|
||||
// Low nibble currently unused
|
||||
// High nibble contains GRAPHICS_STATUS
|
||||
|
||||
Color ForeGroundColor, BackGroundColor;
|
||||
DrawMode Mode;
|
||||
FRAME ForeGroundFrame;
|
||||
FONT Font;
|
||||
|
||||
RECT ClipRect;
|
||||
|
||||
FRAME FontEffect;
|
||||
TFB_Image *FontBacking;
|
||||
FBK_FLAGS BackingFlags;
|
||||
|
||||
#ifdef DEBUG
|
||||
const char *name;
|
||||
CONTEXT next;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define AllocContext() HCalloc (sizeof (CONTEXT_DESC))
|
||||
#define FreeContext HFree
|
||||
|
||||
extern CONTEXT _pCurContext;
|
||||
extern PRIMITIVE _locPrim;
|
||||
|
||||
#define _get_context_fg_color() (_pCurContext->ForeGroundColor)
|
||||
#define _get_context_bg_color() (_pCurContext->BackGroundColor)
|
||||
#define _get_context_flags() (_pCurContext->Flags)
|
||||
#define _get_context_fg_frame() (_pCurContext->ForeGroundFrame)
|
||||
#define _get_context_font() (_pCurContext->Font)
|
||||
#define _get_context_fbk_flags() (_pCurContext->BackingFlags)
|
||||
#define _get_context_fonteff() (_pCurContext->FontEffect)
|
||||
#define _get_context_font_backing() (_pCurContext->FontBacking)
|
||||
#define _get_context_draw_mode() (_pCurContext->Mode)
|
||||
|
||||
#define SwitchContextDrawMode(m) \
|
||||
{ \
|
||||
_pCurContext->Mode = (m); \
|
||||
}
|
||||
#define SwitchContextForeGroundColor(c) \
|
||||
{ \
|
||||
_pCurContext->ForeGroundColor = (c); \
|
||||
}
|
||||
#define SwitchContextBackGroundColor(c) \
|
||||
{ \
|
||||
_pCurContext->BackGroundColor = (c); \
|
||||
}
|
||||
#define SetContextFlags(f) \
|
||||
{ \
|
||||
_pCurContext->Flags |= (f); \
|
||||
}
|
||||
#define UnsetContextFlags(f) \
|
||||
{ \
|
||||
_pCurContext->Flags &= ~(f); \
|
||||
}
|
||||
#define SwitchContextFGFrame(f) \
|
||||
{ \
|
||||
_pCurContext->ForeGroundFrame = (f); \
|
||||
}
|
||||
#define SwitchContextFont(f) \
|
||||
{ \
|
||||
_pCurContext->Font = (f); \
|
||||
SetContextFBkFlags (FBK_DIRTY); \
|
||||
}
|
||||
#define SwitchContextBGFunc(f) \
|
||||
{ \
|
||||
_pCurContext->BackGroundFunc = (f); \
|
||||
}
|
||||
#define SetContextFBkFlags(f) \
|
||||
{ \
|
||||
_pCurContext->BackingFlags |= (f); \
|
||||
}
|
||||
#define UnsetContextFBkFlags(f) \
|
||||
{ \
|
||||
_pCurContext->BackingFlags &= ~(f); \
|
||||
}
|
||||
#define SwitchContextFontEffect(f) \
|
||||
{ \
|
||||
_pCurContext->FontEffect = (f); \
|
||||
SetContextFBkFlags (FBK_DIRTY); \
|
||||
}
|
||||
|
||||
typedef BYTE GRAPHICS_STATUS;
|
||||
|
||||
extern GRAPHICS_STATUS _GraphicsStatusFlags;
|
||||
#define GRAPHICS_ACTIVE (GRAPHICS_STATUS)(1 << 0)
|
||||
#define GRAPHICS_VISIBLE (GRAPHICS_STATUS)(1 << 1)
|
||||
#define CONTEXT_ACTIVE (GRAPHICS_STATUS)(1 << 2)
|
||||
#define DRAWABLE_ACTIVE (GRAPHICS_STATUS)(1 << 3)
|
||||
#define DeactivateGraphics() (_GraphicsStatusFlags &= ~GRAPHICS_ACTIVE)
|
||||
#define ActivateGraphics() (_GraphicsStatusFlags |= GRAPHICS_ACTIVE)
|
||||
#define GraphicsActive() (_GraphicsStatusFlags & GRAPHICS_ACTIVE)
|
||||
#define DeactivateVisible() (_GraphicsStatusFlags &= ~GRAPHICS_VISIBLE)
|
||||
#define ActivateVisible() (_GraphicsStatusFlags |= GRAPHICS_VISIBLE)
|
||||
#define DeactivateContext() (_GraphicsStatusFlags &= ~CONTEXT_ACTIVE)
|
||||
#define ActivateContext() (_GraphicsStatusFlags |= CONTEXT_ACTIVE)
|
||||
#define ContextActive() (_GraphicsStatusFlags & CONTEXT_ACTIVE)
|
||||
#define DeactivateDrawable() (_GraphicsStatusFlags &= ~DRAWABLE_ACTIVE)
|
||||
#define ActivateDrawable() (_GraphicsStatusFlags |= DRAWABLE_ACTIVE)
|
||||
#define DrawableActive() (_GraphicsStatusFlags & DRAWABLE_ACTIVE)
|
||||
|
||||
#define SYSTEM_ACTIVE (GRAPHICS_STATUS)(CONTEXT_ACTIVE | DRAWABLE_ACTIVE)
|
||||
|
||||
#define GraphicsSystemActive() \
|
||||
((_GraphicsStatusFlags & SYSTEM_ACTIVE) == SYSTEM_ACTIVE)
|
||||
#define GraphicsStatus() \
|
||||
(_GraphicsStatusFlags & (GRAPHICS_STATUS)(GRAPHICS_ACTIVE \
|
||||
| GRAPHICS_VISIBLE))
|
||||
|
||||
// pValidRect or origin may be NULL
|
||||
BOOLEAN GetContextValidRect (RECT *pValidRect, POINT *origin);
|
||||
extern void FixContextFontEffect (void);
|
||||
|
||||
#endif /* _CONTEXT_H */
|
||||
|
||||
589
project/jni/application/sc2/src/libs/graphics/dcqueue.c
Normal file
589
project/jni/application/sc2/src/libs/graphics/dcqueue.c
Normal file
@@ -0,0 +1,589 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/threadlib.h"
|
||||
#include "libs/graphics/drawcmd.h"
|
||||
#include "libs/graphics/drawable.h"
|
||||
#include "libs/graphics/context.h"
|
||||
#include "libs/graphics/dcqueue.h"
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/graphics/bbox.h"
|
||||
#include "libs/timelib.h"
|
||||
#include "libs/log.h"
|
||||
#include "libs/misc.h"
|
||||
// for TFB_DEBUG_HALT
|
||||
|
||||
|
||||
static RecursiveMutex DCQ_Mutex;
|
||||
|
||||
CondVar RenderingCond;
|
||||
|
||||
TFB_DrawCommand DCQ[DCQ_MAX];
|
||||
|
||||
TFB_DrawCommandQueue DrawCommandQueue;
|
||||
|
||||
#define FPS_PERIOD (ONE_SECOND / 100)
|
||||
int RenderedFrames = 0;
|
||||
|
||||
|
||||
// Wait for the queue to be emptied.
|
||||
static void
|
||||
TFB_WaitForSpace (int requested_slots)
|
||||
{
|
||||
int old_depth, i;
|
||||
log_add (log_Debug, "DCQ overload (Size = %d, FullSize = %d, "
|
||||
"Requested = %d). Sleeping until renderer is done.",
|
||||
DrawCommandQueue.Size, DrawCommandQueue.FullSize,
|
||||
requested_slots);
|
||||
// Restore the DCQ locking level. I *think* this is
|
||||
// always 1, but...
|
||||
TFB_BatchReset ();
|
||||
old_depth = GetRecursiveMutexDepth (DCQ_Mutex);
|
||||
for (i = 0; i < old_depth; i++)
|
||||
UnlockRecursiveMutex (DCQ_Mutex);
|
||||
WaitCondVar (RenderingCond);
|
||||
for (i = 0; i < old_depth; i++)
|
||||
LockRecursiveMutex (DCQ_Mutex);
|
||||
log_add (log_Debug, "DCQ clear (Size = %d, FullSize = %d). Continuing.",
|
||||
DrawCommandQueue.Size, DrawCommandQueue.FullSize);
|
||||
}
|
||||
|
||||
void
|
||||
Lock_DCQ (int slots)
|
||||
{
|
||||
LockRecursiveMutex (DCQ_Mutex);
|
||||
while (DrawCommandQueue.FullSize >= DCQ_MAX - slots)
|
||||
{
|
||||
TFB_WaitForSpace (slots);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Unlock_DCQ (void)
|
||||
{
|
||||
UnlockRecursiveMutex (DCQ_Mutex);
|
||||
}
|
||||
|
||||
// Always have the DCQ locked when calling this.
|
||||
static void
|
||||
Synchronize_DCQ (void)
|
||||
{
|
||||
if (!DrawCommandQueue.Batching)
|
||||
{
|
||||
int front = DrawCommandQueue.Front;
|
||||
int back = DrawCommandQueue.InsertionPoint;
|
||||
DrawCommandQueue.Back = DrawCommandQueue.InsertionPoint;
|
||||
if (front <= back)
|
||||
{
|
||||
DrawCommandQueue.Size = (back - front);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCommandQueue.Size = (back + DCQ_MAX - front);
|
||||
}
|
||||
DrawCommandQueue.FullSize = DrawCommandQueue.Size;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFB_BatchGraphics (void)
|
||||
{
|
||||
LockRecursiveMutex (DCQ_Mutex);
|
||||
DrawCommandQueue.Batching++;
|
||||
UnlockRecursiveMutex (DCQ_Mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_UnbatchGraphics (void)
|
||||
{
|
||||
LockRecursiveMutex (DCQ_Mutex);
|
||||
if (DrawCommandQueue.Batching)
|
||||
{
|
||||
DrawCommandQueue.Batching--;
|
||||
}
|
||||
Synchronize_DCQ ();
|
||||
UnlockRecursiveMutex (DCQ_Mutex);
|
||||
}
|
||||
|
||||
// Cancel all pending batch operations, making them unbatched. This will
|
||||
// cause a small amount of flicker when invoked, but prevents
|
||||
// batching problems from freezing the game.
|
||||
void
|
||||
TFB_BatchReset (void)
|
||||
{
|
||||
LockRecursiveMutex (DCQ_Mutex);
|
||||
DrawCommandQueue.Batching = 0;
|
||||
Synchronize_DCQ ();
|
||||
UnlockRecursiveMutex (DCQ_Mutex);
|
||||
}
|
||||
|
||||
|
||||
// Draw Command Queue Stuff
|
||||
|
||||
void
|
||||
Init_DrawCommandQueue (void)
|
||||
{
|
||||
DrawCommandQueue.Back = 0;
|
||||
DrawCommandQueue.Front = 0;
|
||||
DrawCommandQueue.InsertionPoint = 0;
|
||||
DrawCommandQueue.Batching = 0;
|
||||
DrawCommandQueue.FullSize = 0;
|
||||
DrawCommandQueue.Size = 0;
|
||||
|
||||
TFB_BBox_Init (ScreenWidth, ScreenHeight);
|
||||
|
||||
DCQ_Mutex = CreateRecursiveMutex ("DCQ",
|
||||
SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
||||
|
||||
RenderingCond = CreateCondVar ("DCQ empty",
|
||||
SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
||||
}
|
||||
|
||||
void
|
||||
Uninit_DrawCommandQueue (void)
|
||||
{
|
||||
DestroyCondVar (RenderingCond);
|
||||
DestroyRecursiveMutex (DCQ_Mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command)
|
||||
{
|
||||
Lock_DCQ (1);
|
||||
DCQ[DrawCommandQueue.InsertionPoint] = *Command;
|
||||
DrawCommandQueue.InsertionPoint = (DrawCommandQueue.InsertionPoint + 1)
|
||||
% DCQ_MAX;
|
||||
DrawCommandQueue.FullSize++;
|
||||
Synchronize_DCQ ();
|
||||
Unlock_DCQ ();
|
||||
}
|
||||
|
||||
int
|
||||
TFB_DrawCommandQueue_Pop (TFB_DrawCommand *target)
|
||||
{
|
||||
LockRecursiveMutex (DCQ_Mutex);
|
||||
|
||||
if (DrawCommandQueue.Size == 0)
|
||||
{
|
||||
Unlock_DCQ ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (DrawCommandQueue.Front == DrawCommandQueue.Back &&
|
||||
DrawCommandQueue.Size != DCQ_MAX)
|
||||
{
|
||||
log_add (log_Debug, "Augh! Assertion failure in DCQ! "
|
||||
"Front == Back, Size != DCQ_MAX");
|
||||
DrawCommandQueue.Size = 0;
|
||||
Unlock_DCQ ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
*target = DCQ[DrawCommandQueue.Front];
|
||||
DrawCommandQueue.Front = (DrawCommandQueue.Front + 1) % DCQ_MAX;
|
||||
|
||||
DrawCommandQueue.Size--;
|
||||
DrawCommandQueue.FullSize--;
|
||||
UnlockRecursiveMutex (DCQ_Mutex);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawCommandQueue_Clear ()
|
||||
{
|
||||
LockRecursiveMutex (DCQ_Mutex);
|
||||
DrawCommandQueue.Size = 0;
|
||||
DrawCommandQueue.Front = 0;
|
||||
DrawCommandQueue.Back = 0;
|
||||
DrawCommandQueue.Batching = 0;
|
||||
DrawCommandQueue.FullSize = 0;
|
||||
DrawCommandQueue.InsertionPoint = 0;
|
||||
UnlockRecursiveMutex (DCQ_Mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
|
||||
{
|
||||
if (TFB_DEBUG_HALT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (DrawCommand->Type <= TFB_DRAWCOMMANDTYPE_COPYTOIMAGE
|
||||
&& _CurFramePtr->Type == SCREEN_DRAWABLE)
|
||||
{
|
||||
static RECT scissor_rect;
|
||||
|
||||
// Set the clipping region.
|
||||
// We allow drawing with no current context set, so the whole screen
|
||||
if ((_pCurContext && !rectsEqual (scissor_rect, _pCurContext->ClipRect))
|
||||
|| (!_pCurContext && scissor_rect.extent.width != 0))
|
||||
{
|
||||
// Enqueue command to set the glScissor spec
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
if (_pCurContext)
|
||||
scissor_rect = _pCurContext->ClipRect;
|
||||
else
|
||||
scissor_rect.extent.width = 0;
|
||||
|
||||
if (scissor_rect.extent.width)
|
||||
{
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_SCISSORENABLE;
|
||||
DC.data.scissor.rect = scissor_rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_SCISSORDISABLE;
|
||||
}
|
||||
|
||||
TFB_EnqueueDrawCommand(&DC);
|
||||
}
|
||||
}
|
||||
|
||||
TFB_DrawCommandQueue_Push (DrawCommand);
|
||||
}
|
||||
|
||||
static void
|
||||
computeFPS (void)
|
||||
{
|
||||
static TimeCount last_time;
|
||||
static TimePeriod fps_counter;
|
||||
TimeCount current_time;
|
||||
TimePeriod delta_time;
|
||||
|
||||
current_time = GetTimeCounter ();
|
||||
delta_time = current_time - last_time;
|
||||
last_time = current_time;
|
||||
|
||||
fps_counter += delta_time;
|
||||
if (fps_counter > FPS_PERIOD)
|
||||
{
|
||||
log_add (log_User, "fps %.2f, effective %.2f",
|
||||
(float)ONE_SECOND / delta_time,
|
||||
(float)ONE_SECOND * RenderedFrames / fps_counter);
|
||||
|
||||
fps_counter = 0;
|
||||
RenderedFrames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Only call from main() thread!!
|
||||
void
|
||||
TFB_FlushGraphics (void)
|
||||
{
|
||||
int commands_handled;
|
||||
BOOLEAN livelock_deterrence;
|
||||
|
||||
// This is technically a locking violation on DrawCommandQueue.Size,
|
||||
// but it is likely to not be very destructive.
|
||||
if (DrawCommandQueue.Size == 0)
|
||||
{
|
||||
static int last_fade = 255;
|
||||
static int last_transition = 255;
|
||||
int current_fade = GetFadeAmount ();
|
||||
int current_transition = TransitionAmount;
|
||||
|
||||
if ((current_fade != 255 && current_fade != last_fade) ||
|
||||
(current_transition != 255 &&
|
||||
current_transition != last_transition) ||
|
||||
(current_fade == 255 && last_fade != 255) ||
|
||||
(current_transition == 255 && last_transition != 255))
|
||||
{
|
||||
TFB_SwapBuffers (TFB_REDRAW_FADING);
|
||||
// if fading, redraw every frame
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskSwitch ();
|
||||
}
|
||||
|
||||
last_fade = current_fade;
|
||||
last_transition = current_transition;
|
||||
BroadcastCondVar (RenderingCond);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GfxFlags & TFB_GFXFLAGS_SHOWFPS)
|
||||
computeFPS ();
|
||||
|
||||
commands_handled = 0;
|
||||
livelock_deterrence = FALSE;
|
||||
|
||||
if (DrawCommandQueue.FullSize > DCQ_FORCE_BREAK_SIZE)
|
||||
{
|
||||
TFB_BatchReset ();
|
||||
}
|
||||
|
||||
if (DrawCommandQueue.Size > DCQ_FORCE_SLOWDOWN_SIZE)
|
||||
{
|
||||
Lock_DCQ (-1);
|
||||
livelock_deterrence = TRUE;
|
||||
}
|
||||
|
||||
TFB_BBox_Reset ();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
if (!TFB_DrawCommandQueue_Pop (&DC))
|
||||
{
|
||||
// the Queue is now empty.
|
||||
break;
|
||||
}
|
||||
|
||||
++commands_handled;
|
||||
if (!livelock_deterrence && commands_handled + DrawCommandQueue.Size
|
||||
> DCQ_LIVELOCK_MAX)
|
||||
{
|
||||
// log_add (log_Debug, "Initiating livelock deterrence!");
|
||||
livelock_deterrence = TRUE;
|
||||
|
||||
Lock_DCQ (-1);
|
||||
}
|
||||
|
||||
switch (DC.Type)
|
||||
{
|
||||
case TFB_DRAWCOMMANDTYPE_SETMIPMAP:
|
||||
{
|
||||
TFB_DrawCommand_SetMipmap *cmd = &DC.data.setmipmap;
|
||||
TFB_DrawImage_SetMipmap (cmd->image, cmd->mipmap,
|
||||
cmd->hotx, cmd->hoty);
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_IMAGE:
|
||||
{
|
||||
TFB_DrawCommand_Image *cmd = &DC.data.image;
|
||||
TFB_Image *DC_image = cmd->image;
|
||||
const int x = cmd->x;
|
||||
const int y = cmd->y;
|
||||
|
||||
TFB_DrawCanvas_Image (DC_image, x, y,
|
||||
cmd->scale, cmd->scaleMode, cmd->colormap,
|
||||
cmd->drawMode,
|
||||
TFB_GetScreenCanvas (cmd->destBuffer));
|
||||
|
||||
if (cmd->destBuffer == TFB_SCREEN_MAIN)
|
||||
{
|
||||
LockMutex (DC_image->mutex);
|
||||
if (cmd->scale)
|
||||
TFB_BBox_RegisterCanvas (DC_image->ScaledImg,
|
||||
x - DC_image->last_scale_hs.x,
|
||||
y - DC_image->last_scale_hs.y);
|
||||
else
|
||||
TFB_BBox_RegisterCanvas (DC_image->NormalImg,
|
||||
x - DC_image->NormalHs.x,
|
||||
y - DC_image->NormalHs.y);
|
||||
UnlockMutex (DC_image->mutex);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_FILLEDIMAGE:
|
||||
{
|
||||
TFB_DrawCommand_FilledImage *cmd = &DC.data.filledimage;
|
||||
TFB_Image *DC_image = cmd->image;
|
||||
const int x = cmd->x;
|
||||
const int y = cmd->y;
|
||||
|
||||
TFB_DrawCanvas_FilledImage (DC_image, x, y,
|
||||
cmd->scale, cmd->scaleMode, cmd->color,
|
||||
cmd->drawMode,
|
||||
TFB_GetScreenCanvas (cmd->destBuffer));
|
||||
|
||||
if (cmd->destBuffer == TFB_SCREEN_MAIN)
|
||||
{
|
||||
LockMutex (DC_image->mutex);
|
||||
if (cmd->scale)
|
||||
TFB_BBox_RegisterCanvas (DC_image->ScaledImg,
|
||||
x - DC_image->last_scale_hs.x,
|
||||
y - DC_image->last_scale_hs.y);
|
||||
else
|
||||
TFB_BBox_RegisterCanvas (DC_image->NormalImg,
|
||||
x - DC_image->NormalHs.x,
|
||||
y - DC_image->NormalHs.y);
|
||||
UnlockMutex (DC_image->mutex);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_FONTCHAR:
|
||||
{
|
||||
TFB_DrawCommand_FontChar *cmd = &DC.data.fontchar;
|
||||
TFB_Char *DC_char = cmd->fontchar;
|
||||
const int x = cmd->x;
|
||||
const int y = cmd->y;
|
||||
|
||||
TFB_DrawCanvas_FontChar (DC_char, cmd->backing, x, y,
|
||||
cmd->drawMode, TFB_GetScreenCanvas (cmd->destBuffer));
|
||||
|
||||
if (cmd->destBuffer == TFB_SCREEN_MAIN)
|
||||
{
|
||||
RECT r;
|
||||
|
||||
r.corner.x = x - DC_char->HotSpot.x;
|
||||
r.corner.y = y - DC_char->HotSpot.y;
|
||||
r.extent.width = DC_char->extent.width;
|
||||
r.extent.height = DC_char->extent.height;
|
||||
|
||||
TFB_BBox_RegisterRect (&r);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_LINE:
|
||||
{
|
||||
TFB_DrawCommand_Line *cmd = &DC.data.line;
|
||||
|
||||
if (cmd->destBuffer == TFB_SCREEN_MAIN)
|
||||
{
|
||||
TFB_BBox_RegisterPoint (cmd->x1, cmd->y1);
|
||||
TFB_BBox_RegisterPoint (cmd->x2, cmd->y2);
|
||||
}
|
||||
TFB_DrawCanvas_Line (cmd->x1, cmd->y1, cmd->x2, cmd->y2,
|
||||
cmd->color, cmd->drawMode,
|
||||
TFB_GetScreenCanvas (cmd->destBuffer));
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_RECTANGLE:
|
||||
{
|
||||
TFB_DrawCommand_Rect *cmd = &DC.data.rect;
|
||||
|
||||
if (cmd->destBuffer == TFB_SCREEN_MAIN)
|
||||
TFB_BBox_RegisterRect (&cmd->rect);
|
||||
TFB_DrawCanvas_Rect (&cmd->rect, cmd->color, cmd->drawMode,
|
||||
TFB_GetScreenCanvas (cmd->destBuffer));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_SCISSORENABLE:
|
||||
{
|
||||
TFB_DrawCommand_Scissor *cmd = &DC.data.scissor;
|
||||
|
||||
TFB_DrawCanvas_SetClipRect (
|
||||
TFB_GetScreenCanvas (TFB_SCREEN_MAIN), &cmd->rect);
|
||||
TFB_BBox_SetClipRect (&DC.data.scissor.rect);
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_SCISSORDISABLE:
|
||||
TFB_DrawCanvas_SetClipRect (
|
||||
TFB_GetScreenCanvas (TFB_SCREEN_MAIN), NULL);
|
||||
TFB_BBox_SetClipRect (NULL);
|
||||
break;
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_COPYTOIMAGE:
|
||||
{
|
||||
TFB_DrawCommand_CopyToImage *cmd = &DC.data.copytoimage;
|
||||
TFB_Image *DC_image = cmd->image;
|
||||
const POINT dstPt = {0, 0};
|
||||
|
||||
if (DC_image == 0)
|
||||
{
|
||||
log_add (log_Debug, "DCQ ERROR: COPYTOIMAGE passed null "
|
||||
"image ptr");
|
||||
break;
|
||||
}
|
||||
LockMutex (DC_image->mutex);
|
||||
TFB_DrawCanvas_CopyRect (
|
||||
TFB_GetScreenCanvas (cmd->srcBuffer), &cmd->rect,
|
||||
DC_image->NormalImg, dstPt);
|
||||
UnlockMutex (DC_image->mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_COPY:
|
||||
{
|
||||
TFB_DrawCommand_Copy *cmd = &DC.data.copy;
|
||||
const RECT r = cmd->rect;
|
||||
|
||||
if (cmd->destBuffer == TFB_SCREEN_MAIN)
|
||||
TFB_BBox_RegisterRect (&cmd->rect);
|
||||
|
||||
TFB_DrawCanvas_CopyRect (
|
||||
TFB_GetScreenCanvas (cmd->srcBuffer), &r,
|
||||
TFB_GetScreenCanvas (cmd->destBuffer), r.corner);
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_DELETEIMAGE:
|
||||
{
|
||||
TFB_Image *DC_image = DC.data.deleteimage.image;
|
||||
TFB_DrawImage_Delete (DC_image);
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_DELETEDATA:
|
||||
{
|
||||
void *data = DC.data.deletedata.data;
|
||||
HFree (data);
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_SENDSIGNAL:
|
||||
ClearSemaphore (DC.data.sendsignal.sem);
|
||||
break;
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_REINITVIDEO:
|
||||
{
|
||||
TFB_DrawCommand_ReinitVideo *cmd = &DC.data.reinitvideo;
|
||||
int oldDriver = GraphicsDriver;
|
||||
int oldFlags = GfxFlags;
|
||||
int oldWidth = ScreenWidthActual;
|
||||
int oldHeight = ScreenHeightActual;
|
||||
if (TFB_ReInitGraphics (cmd->driver, cmd->flags,
|
||||
cmd->width, cmd->height))
|
||||
{
|
||||
log_add (log_Error, "Could not provide requested mode: "
|
||||
"reverting to last known driver.");
|
||||
// We don't know what exactly failed, so roll it all back
|
||||
if (TFB_ReInitGraphics (oldDriver, oldFlags,
|
||||
oldWidth, oldHeight))
|
||||
{
|
||||
log_add (log_Fatal,
|
||||
"Couldn't reinit at that point either. "
|
||||
"Your video has been somehow tied in knots.");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
TFB_SwapBuffers (TFB_REDRAW_YES);
|
||||
break;
|
||||
}
|
||||
|
||||
case TFB_DRAWCOMMANDTYPE_CALLBACK:
|
||||
{
|
||||
DC.data.callback.callback (DC.data.callback.arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (livelock_deterrence)
|
||||
Unlock_DCQ ();
|
||||
|
||||
TFB_SwapBuffers (TFB_REDRAW_NO);
|
||||
RenderedFrames++;
|
||||
BroadcastCondVar (RenderingCond);
|
||||
}
|
||||
55
project/jni/application/sc2/src/libs/graphics/dcqueue.h
Normal file
55
project/jni/application/sc2/src/libs/graphics/dcqueue.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef DCQUEUE_H
|
||||
#define DCQUEUE_H
|
||||
|
||||
// Maximum size of the DCQ. The larger the DCQ, the larger frameskips
|
||||
// become tolerable before initiating livelock deterrence and game
|
||||
// slowdown. Other constants for controlling the frameskip/slowdown
|
||||
// balance may be found in sdl_common.c near TFB_FlushGraphics.
|
||||
|
||||
// Livelock deterrance constants. Because the entire screen is rarely
|
||||
// refreshed, we may not drop draw commands on the floor with abandon.
|
||||
// Furthermore, if the main program is queuing commands at a speed
|
||||
// comparable to our processing of the commands, we never finish and
|
||||
// the game freezes. Thus, if the queue starts out larger than
|
||||
// DCQ_FORCE_SLOWDOWN_SIZE, or DCQ_LIVELOCK_MAX commands find
|
||||
// themselves being processed in one go, livelock deterrence is
|
||||
// enabled, and TFB_FlushGraphics locks the DCQ until it has processed
|
||||
// all entries. If batched but pending commands exceed DCQ_FORCE_BREAK_SIZE,
|
||||
// a continuity break is performed. This will effectively slow down the
|
||||
// game logic, a fate we seek to avoid - however, it seems to be unavoidable
|
||||
// on slower machines. Even there, it's seems nonexistent outside of
|
||||
// communications screens. --Michael
|
||||
|
||||
#ifdef DCQ_OF_DOOM
|
||||
#define DCQ_MAX 512
|
||||
#define DCQ_FORCE_SLOWDOWN_SIZE 128
|
||||
#define DCQ_FORCE_BREAK_SIZE 512
|
||||
#define DCQ_LIVELOCK_MAX 256
|
||||
#else
|
||||
#define DCQ_MAX 16384
|
||||
#define DCQ_FORCE_SLOWDOWN_SIZE 4096
|
||||
#define DCQ_FORCE_BREAK_SIZE 16384
|
||||
#define DCQ_LIVELOCK_MAX 4096
|
||||
#endif
|
||||
|
||||
extern CondVar RenderingCond;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
501
project/jni/application/sc2/src/libs/graphics/drawable.c
Normal file
501
project/jni/application/sc2/src/libs/graphics/drawable.c
Normal file
@@ -0,0 +1,501 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libs/gfxlib.h"
|
||||
#include "libs/graphics/context.h"
|
||||
#include "libs/graphics/drawable.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "tfb_draw.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
FRAME _CurFramePtr;
|
||||
|
||||
FRAME
|
||||
SetContextFGFrame (FRAME Frame)
|
||||
{
|
||||
FRAME LastFrame;
|
||||
|
||||
if (Frame != (LastFrame = (FRAME)_CurFramePtr))
|
||||
{
|
||||
if (LastFrame)
|
||||
DeactivateDrawable ();
|
||||
|
||||
_CurFramePtr = Frame;
|
||||
if (_CurFramePtr)
|
||||
ActivateDrawable ();
|
||||
|
||||
if (ContextActive ())
|
||||
{
|
||||
SwitchContextFGFrame (Frame);
|
||||
}
|
||||
}
|
||||
|
||||
return (LastFrame);
|
||||
}
|
||||
|
||||
FRAME
|
||||
GetContextFGFrame (void)
|
||||
{
|
||||
return _CurFramePtr;
|
||||
}
|
||||
|
||||
static DRAWABLE
|
||||
request_drawable (COUNT NumFrames, DRAWABLE_TYPE DrawableType,
|
||||
CREATE_FLAGS flags, SIZE width, SIZE height)
|
||||
{
|
||||
DRAWABLE Drawable;
|
||||
COUNT i;
|
||||
|
||||
Drawable = AllocDrawable (NumFrames);
|
||||
if (!Drawable)
|
||||
return NULL;
|
||||
|
||||
Drawable->Flags = flags;
|
||||
Drawable->MaxIndex = NumFrames - 1;
|
||||
|
||||
for (i = 0; i < NumFrames; ++i)
|
||||
{
|
||||
FRAME FramePtr = &Drawable->Frame[i];
|
||||
|
||||
if (DrawableType == RAM_DRAWABLE && width > 0 && height > 0)
|
||||
{
|
||||
FramePtr->image = TFB_DrawImage_New (TFB_DrawCanvas_New_TrueColor (
|
||||
width, height, (flags & WANT_ALPHA) ? TRUE : FALSE));
|
||||
}
|
||||
|
||||
FramePtr->Type = DrawableType;
|
||||
FramePtr->Index = i;
|
||||
SetFrameBounds (FramePtr, width, height);
|
||||
}
|
||||
|
||||
return Drawable;
|
||||
}
|
||||
|
||||
DRAWABLE
|
||||
CreateDisplay (CREATE_FLAGS CreateFlags, SIZE *pwidth, SIZE *pheight)
|
||||
{
|
||||
DRAWABLE Drawable;
|
||||
|
||||
// TODO: ScreenWidth and ScreenHeight should be passed in
|
||||
// instead of returned.
|
||||
Drawable = request_drawable (1, SCREEN_DRAWABLE,
|
||||
(CreateFlags & (WANT_PIXMAP | WANT_MASK)),
|
||||
ScreenWidth, ScreenHeight);
|
||||
if (Drawable)
|
||||
{
|
||||
FRAME F;
|
||||
|
||||
F = CaptureDrawable (Drawable);
|
||||
if (F == 0)
|
||||
DestroyDrawable (Drawable);
|
||||
else
|
||||
{
|
||||
*pwidth = GetFrameWidth (F);
|
||||
*pheight = GetFrameHeight (F);
|
||||
|
||||
ReleaseDrawable (F);
|
||||
return (Drawable);
|
||||
}
|
||||
}
|
||||
|
||||
*pwidth = *pheight = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
DRAWABLE
|
||||
AllocDrawable (COUNT n)
|
||||
{
|
||||
DRAWABLE Drawable;
|
||||
Drawable = (DRAWABLE) HCalloc(sizeof (DRAWABLE_DESC));
|
||||
if (Drawable)
|
||||
{
|
||||
int i;
|
||||
Drawable->Frame = (FRAME)HMalloc (sizeof (FRAME_DESC) * n);
|
||||
if (Drawable->Frame == NULL)
|
||||
{
|
||||
HFree (Drawable);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Zero out the newly allocated frames, since HMalloc doesn't have
|
||||
* MEM_ZEROINIT. */
|
||||
for (i = 0; i < n; i++) {
|
||||
FRAME F;
|
||||
F = &Drawable->Frame[i];
|
||||
F->parent = Drawable;
|
||||
F->Type = 0;
|
||||
F->Index = 0;
|
||||
F->image = 0;
|
||||
F->Bounds.width = 0;
|
||||
F->Bounds.height = 0;
|
||||
F->HotSpot.x = 0;
|
||||
F->HotSpot.y = 0;
|
||||
}
|
||||
}
|
||||
return Drawable;
|
||||
}
|
||||
|
||||
DRAWABLE
|
||||
CreateDrawable (CREATE_FLAGS CreateFlags, SIZE width, SIZE height, COUNT
|
||||
num_frames)
|
||||
{
|
||||
DRAWABLE Drawable;
|
||||
|
||||
Drawable = request_drawable (num_frames, RAM_DRAWABLE,
|
||||
(CreateFlags & (WANT_MASK | WANT_PIXMAP
|
||||
| WANT_ALPHA | MAPPED_TO_DISPLAY)),
|
||||
width, height);
|
||||
if (Drawable)
|
||||
{
|
||||
FRAME F;
|
||||
|
||||
F = CaptureDrawable (Drawable);
|
||||
if (F)
|
||||
{
|
||||
ReleaseDrawable (F);
|
||||
|
||||
return (Drawable);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DestroyDrawable (DRAWABLE Drawable)
|
||||
{
|
||||
if (_CurFramePtr && (Drawable == _CurFramePtr->parent))
|
||||
SetContextFGFrame ((FRAME)NULL);
|
||||
|
||||
if (Drawable)
|
||||
{
|
||||
FreeDrawable (Drawable);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
GetFrameRect (FRAME FramePtr, RECT *pRect)
|
||||
{
|
||||
if (FramePtr)
|
||||
{
|
||||
pRect->corner.x = -FramePtr->HotSpot.x;
|
||||
pRect->corner.y = -FramePtr->HotSpot.y;
|
||||
pRect->extent = GetFrameBounds (FramePtr);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
HOT_SPOT
|
||||
SetFrameHot (FRAME FramePtr, HOT_SPOT HotSpot)
|
||||
{
|
||||
if (FramePtr)
|
||||
{
|
||||
HOT_SPOT OldHot;
|
||||
|
||||
OldHot = FramePtr->HotSpot;
|
||||
FramePtr->HotSpot = HotSpot;
|
||||
|
||||
return (OldHot);
|
||||
}
|
||||
|
||||
return (MAKE_HOT_SPOT (0, 0));
|
||||
}
|
||||
|
||||
HOT_SPOT
|
||||
GetFrameHot (FRAME FramePtr)
|
||||
{
|
||||
if (FramePtr)
|
||||
{
|
||||
return FramePtr->HotSpot;
|
||||
}
|
||||
|
||||
return (MAKE_HOT_SPOT (0, 0));
|
||||
}
|
||||
|
||||
DRAWABLE
|
||||
RotateFrame (FRAME Frame, int angle_deg)
|
||||
{
|
||||
DRAWABLE Drawable;
|
||||
FRAME RotFramePtr;
|
||||
double dx, dy;
|
||||
double d;
|
||||
double angle = angle_deg * M_PI / 180;
|
||||
|
||||
if (!Frame)
|
||||
return NULL;
|
||||
|
||||
assert (Frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
Drawable = request_drawable (1, RAM_DRAWABLE, WANT_PIXMAP, 0, 0);
|
||||
if (!Drawable)
|
||||
return 0;
|
||||
RotFramePtr = CaptureDrawable (Drawable);
|
||||
if (!RotFramePtr)
|
||||
{
|
||||
FreeDrawable (Drawable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RotFramePtr->image = TFB_DrawImage_New_Rotated (
|
||||
Frame->image, angle_deg);
|
||||
SetFrameBounds (RotFramePtr, RotFramePtr->image->extent.width,
|
||||
RotFramePtr->image->extent.height);
|
||||
|
||||
/* now we need to rotate the hot-spot, eww */
|
||||
dx = Frame->HotSpot.x - (GetFrameWidth (Frame) / 2);
|
||||
dy = Frame->HotSpot.y - (GetFrameHeight (Frame) / 2);
|
||||
d = sqrt ((double)dx*dx + (double)dy*dy);
|
||||
if ((int)d != 0)
|
||||
{
|
||||
double organg = atan2 (-dy, dx);
|
||||
dx = cos (organg + angle) * d;
|
||||
dy = -sin (organg + angle) * d;
|
||||
}
|
||||
RotFramePtr->HotSpot.x = (GetFrameWidth (RotFramePtr) / 2) + (int)dx;
|
||||
RotFramePtr->HotSpot.y = (GetFrameHeight (RotFramePtr) / 2) + (int)dy;
|
||||
|
||||
ReleaseDrawable (RotFramePtr);
|
||||
|
||||
return Drawable;
|
||||
}
|
||||
|
||||
// color.a is ignored
|
||||
void
|
||||
SetFrameTransparentColor (FRAME frame, Color color)
|
||||
{
|
||||
TFB_Image *img;
|
||||
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
img = frame->image;
|
||||
LockMutex (img->mutex);
|
||||
|
||||
// TODO: This should defer to TFB_DrawImage instead
|
||||
TFB_DrawCanvas_SetTransparentColor (img->NormalImg, color, FALSE);
|
||||
|
||||
UnlockMutex (img->mutex);
|
||||
}
|
||||
|
||||
Color
|
||||
GetFramePixel (FRAME frame, POINT pixelPt)
|
||||
{
|
||||
TFB_Image *img;
|
||||
Color ret;
|
||||
|
||||
if (!frame)
|
||||
return BUILD_COLOR_RGBA (0, 0, 0, 0);
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
img = frame->image;
|
||||
LockMutex (img->mutex);
|
||||
|
||||
// TODO: This should defer to TFB_DrawImage instead
|
||||
ret = TFB_DrawCanvas_GetPixel (img->NormalImg, pixelPt.x, pixelPt.y);
|
||||
|
||||
UnlockMutex (img->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static FRAME
|
||||
makeMatchingFrame (FRAME frame, int width, int height)
|
||||
{
|
||||
DRAWABLE drawable;
|
||||
FRAME newFrame;
|
||||
CREATE_FLAGS flags;
|
||||
|
||||
flags = GetFrameParentDrawable (frame)->Flags;
|
||||
drawable = CreateDrawable (flags, width, height, 1);
|
||||
if (!drawable)
|
||||
return NULL;
|
||||
newFrame = CaptureDrawable (drawable);
|
||||
if (!newFrame)
|
||||
{
|
||||
FreeDrawable (drawable);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newFrame;
|
||||
}
|
||||
|
||||
// Creates an new DRAWABLE containing a copy of specified FRAME's rect
|
||||
// Source FRAME must not be a SCREEN_DRAWABLE
|
||||
DRAWABLE
|
||||
CopyFrameRect (FRAME frame, const RECT *area)
|
||||
{
|
||||
FRAME newFrame;
|
||||
POINT nullPt = MAKE_POINT (0, 0);
|
||||
|
||||
if (!frame)
|
||||
return NULL;
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
newFrame = makeMatchingFrame (frame, area->extent.width,
|
||||
area->extent.height);
|
||||
if (!newFrame)
|
||||
return NULL;
|
||||
|
||||
TFB_DrawImage_CopyRect (frame->image, area, newFrame->image, nullPt);
|
||||
|
||||
return ReleaseDrawable (newFrame);
|
||||
}
|
||||
|
||||
// Creates an new DRAWABLE mostly identical to specified FRAME
|
||||
// Source FRAME must not be a SCREEN_DRAWABLE
|
||||
DRAWABLE
|
||||
CloneFrame (FRAME frame)
|
||||
{
|
||||
FRAME newFrame;
|
||||
RECT r;
|
||||
|
||||
if (!frame)
|
||||
return NULL;
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
GetFrameRect (frame, &r);
|
||||
r.corner.x = 0;
|
||||
r.corner.y = 0;
|
||||
|
||||
newFrame = CaptureDrawable (CopyFrameRect (frame, &r));
|
||||
if (!newFrame)
|
||||
return NULL;
|
||||
|
||||
// copy the hot-spot
|
||||
newFrame->HotSpot = frame->HotSpot;
|
||||
|
||||
return ReleaseDrawable (newFrame);
|
||||
}
|
||||
|
||||
// Creates a new DRAWABLE of specified size and scales the passed
|
||||
// frame onto it. The aspect ratio is not preserved.
|
||||
DRAWABLE
|
||||
RescaleFrame (FRAME frame, int width, int height)
|
||||
{
|
||||
FRAME newFrame;
|
||||
TFB_Image *img;
|
||||
TFB_Canvas src, dst;
|
||||
|
||||
if (!frame)
|
||||
return NULL;
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
newFrame = makeMatchingFrame (frame, width, height);
|
||||
if (!newFrame)
|
||||
return NULL;
|
||||
|
||||
// scale the hot-spot
|
||||
newFrame->HotSpot.x = frame->HotSpot.x * width / frame->Bounds.width;
|
||||
newFrame->HotSpot.y = frame->HotSpot.y * height / frame->Bounds.height;
|
||||
|
||||
img = frame->image;
|
||||
LockMutex (img->mutex);
|
||||
// NOTE: We do not lock the target image because nothing has a
|
||||
// reference to it yet!
|
||||
src = img->NormalImg;
|
||||
dst = newFrame->image->NormalImg;
|
||||
TFB_DrawCanvas_Rescale_Nearest (src, dst, -1, NULL, NULL, NULL);
|
||||
|
||||
UnlockMutex (img->mutex);
|
||||
|
||||
return ReleaseDrawable (newFrame);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ReadFramePixelColors (FRAME frame, Color *pixels, int width, int height)
|
||||
{
|
||||
TFB_Image *img;
|
||||
|
||||
if (!frame)
|
||||
return FALSE;
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
// TODO: Do we need to lock the img->mutex here?
|
||||
img = frame->image;
|
||||
return TFB_DrawCanvas_GetPixelColors (img->NormalImg, pixels,
|
||||
width, height);
|
||||
}
|
||||
|
||||
// Warning: this functions bypasses DCQ, which is why it is not a DrawXXX
|
||||
BOOLEAN
|
||||
WriteFramePixelColors (FRAME frame, const Color *pixels, int width, int height)
|
||||
{
|
||||
TFB_Image *img;
|
||||
|
||||
if (!frame)
|
||||
return FALSE;
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
// TODO: Do we need to lock the img->mutex here?
|
||||
img = frame->image;
|
||||
return TFB_DrawCanvas_SetPixelColors (img->NormalImg, pixels,
|
||||
width, height);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ReadFramePixelIndexes (FRAME frame, BYTE *pixels, int width, int height)
|
||||
{
|
||||
TFB_Image *img;
|
||||
|
||||
if (!frame)
|
||||
return FALSE;
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
// TODO: Do we need to lock the img->mutex here?
|
||||
img = frame->image;
|
||||
return TFB_DrawCanvas_GetPixelIndexes (img->NormalImg, pixels,
|
||||
width, height);
|
||||
}
|
||||
|
||||
// Warning: this functions bypasses DCQ, which is why it is not a DrawXXX
|
||||
BOOLEAN
|
||||
WriteFramePixelIndexes (FRAME frame, const BYTE *pixels, int width, int height)
|
||||
{
|
||||
TFB_Image *img;
|
||||
|
||||
if (!frame)
|
||||
return FALSE;
|
||||
|
||||
assert (frame->Type != SCREEN_DRAWABLE);
|
||||
|
||||
// TODO: Do we need to lock the img->mutex here?
|
||||
img = frame->image;
|
||||
return TFB_DrawCanvas_SetPixelIndexes (img->NormalImg, pixels,
|
||||
width, height);
|
||||
}
|
||||
88
project/jni/application/sc2/src/libs/graphics/drawable.h
Normal file
88
project/jni/application/sc2/src/libs/graphics/drawable.h
Normal file
@@ -0,0 +1,88 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DRAWABLE_H
|
||||
#define _DRAWABLE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tfb_draw.h"
|
||||
|
||||
#define ValidPrimType(pt) ((pt)<NUM_PRIMS)
|
||||
|
||||
typedef struct bresenham_line
|
||||
{
|
||||
POINT first, second;
|
||||
SIZE abs_delta_x, abs_delta_y;
|
||||
SIZE error_term;
|
||||
BOOLEAN end_points_exchanged;
|
||||
INTERSECT_CODE intersect_code;
|
||||
} BRESENHAM_LINE;
|
||||
|
||||
typedef UWORD DRAWABLE_TYPE;
|
||||
#define ROM_DRAWABLE 0
|
||||
#define RAM_DRAWABLE 1
|
||||
#define SCREEN_DRAWABLE 2
|
||||
|
||||
struct frame_desc
|
||||
{
|
||||
DRAWABLE_TYPE Type;
|
||||
UWORD Index;
|
||||
HOT_SPOT HotSpot;
|
||||
EXTENT Bounds;
|
||||
TFB_Image *image;
|
||||
struct drawable_desc *parent;
|
||||
};
|
||||
|
||||
struct drawable_desc
|
||||
{
|
||||
CREATE_FLAGS Flags;
|
||||
UWORD MaxIndex;
|
||||
FRAME_DESC *Frame;
|
||||
};
|
||||
|
||||
#define GetFrameWidth(f) ((f)->Bounds.width)
|
||||
#define GetFrameHeight(f) ((f)->Bounds.height)
|
||||
#define GetFrameBounds(f) ((f)->Bounds)
|
||||
#define SetFrameBounds(f,w,h) \
|
||||
((f)->Bounds.width=(w), \
|
||||
((f))->Bounds.height=(h))
|
||||
|
||||
#define DRAWABLE_PRIORITY DEFAULT_MEM_PRIORITY
|
||||
|
||||
extern DRAWABLE AllocDrawable (COUNT num_frames);
|
||||
#define FreeDrawable(D) _ReleaseCelData (D)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RECT Box;
|
||||
FRAME FramePtr;
|
||||
} IMAGE_BOX;
|
||||
|
||||
extern INTERSECT_CODE _clip_line (const RECT *pClipRect,
|
||||
BRESENHAM_LINE *pLine);
|
||||
|
||||
extern void *_GetCelData (uio_Stream *fp, DWORD length);
|
||||
extern BOOLEAN _ReleaseCelData (void *handle);
|
||||
|
||||
extern FRAME _CurFramePtr;
|
||||
|
||||
// ClipRect is relative to ctxOrigin
|
||||
extern void _text_blt (RECT *pClipRect, TEXT *TextPtr, POINT ctxOrigin);
|
||||
|
||||
#endif /* _DRAWABLE_H */
|
||||
|
||||
202
project/jni/application/sc2/src/libs/graphics/drawcmd.h
Normal file
202
project/jni/application/sc2/src/libs/graphics/drawcmd.h
Normal file
@@ -0,0 +1,202 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef DRAWCMD_H
|
||||
#define DRAWCMD_H
|
||||
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
|
||||
enum
|
||||
{
|
||||
TFB_DRAWCOMMANDTYPE_LINE,
|
||||
TFB_DRAWCOMMANDTYPE_RECTANGLE,
|
||||
TFB_DRAWCOMMANDTYPE_IMAGE,
|
||||
TFB_DRAWCOMMANDTYPE_FILLEDIMAGE,
|
||||
TFB_DRAWCOMMANDTYPE_FONTCHAR,
|
||||
|
||||
TFB_DRAWCOMMANDTYPE_COPY,
|
||||
TFB_DRAWCOMMANDTYPE_COPYTOIMAGE,
|
||||
|
||||
TFB_DRAWCOMMANDTYPE_SCISSORENABLE,
|
||||
TFB_DRAWCOMMANDTYPE_SCISSORDISABLE,
|
||||
|
||||
TFB_DRAWCOMMANDTYPE_SETMIPMAP,
|
||||
TFB_DRAWCOMMANDTYPE_DELETEIMAGE,
|
||||
TFB_DRAWCOMMANDTYPE_DELETEDATA,
|
||||
TFB_DRAWCOMMANDTYPE_SENDSIGNAL,
|
||||
TFB_DRAWCOMMANDTYPE_REINITVIDEO,
|
||||
TFB_DRAWCOMMANDTYPE_CALLBACK,
|
||||
};
|
||||
|
||||
typedef struct tfb_dc_line
|
||||
{
|
||||
int x1, y1, x2, y2;
|
||||
Color color;
|
||||
DrawMode drawMode;
|
||||
SCREEN destBuffer;
|
||||
} TFB_DrawCommand_Line;
|
||||
|
||||
typedef struct tfb_dc_rect
|
||||
{
|
||||
RECT rect;
|
||||
Color color;
|
||||
DrawMode drawMode;
|
||||
SCREEN destBuffer;
|
||||
} TFB_DrawCommand_Rect;
|
||||
|
||||
typedef struct tfb_dc_img
|
||||
{
|
||||
TFB_Image *image;
|
||||
int x, y;
|
||||
SCREEN destBuffer;
|
||||
TFB_ColorMap *colormap;
|
||||
DrawMode drawMode;
|
||||
int scale;
|
||||
int scaleMode;
|
||||
} TFB_DrawCommand_Image;
|
||||
|
||||
typedef struct tfb_dc_filledimg
|
||||
{
|
||||
TFB_Image *image;
|
||||
int x, y;
|
||||
Color color;
|
||||
SCREEN destBuffer;
|
||||
DrawMode drawMode;
|
||||
int scale;
|
||||
int scaleMode;
|
||||
} TFB_DrawCommand_FilledImage;
|
||||
|
||||
typedef struct tfb_dc_fontchar
|
||||
{
|
||||
TFB_Char *fontchar;
|
||||
TFB_Image *backing;
|
||||
int x, y;
|
||||
DrawMode drawMode;
|
||||
SCREEN destBuffer;
|
||||
} TFB_DrawCommand_FontChar;
|
||||
|
||||
typedef struct tfb_dc_copy
|
||||
{
|
||||
RECT rect;
|
||||
SCREEN srcBuffer, destBuffer;
|
||||
} TFB_DrawCommand_Copy;
|
||||
|
||||
typedef struct tfb_dc_copyimg
|
||||
{
|
||||
TFB_Image *image;
|
||||
RECT rect;
|
||||
SCREEN srcBuffer;
|
||||
} TFB_DrawCommand_CopyToImage;
|
||||
|
||||
typedef struct tfb_dc_scissor
|
||||
{
|
||||
RECT rect;
|
||||
} TFB_DrawCommand_Scissor;
|
||||
|
||||
typedef struct tfb_dc_setmip
|
||||
{
|
||||
TFB_Image *image;
|
||||
TFB_Image *mipmap;
|
||||
int hotx, hoty;
|
||||
} TFB_DrawCommand_SetMipmap;
|
||||
|
||||
typedef struct tfb_dc_delimg
|
||||
{
|
||||
TFB_Image *image;
|
||||
} TFB_DrawCommand_DeleteImage;
|
||||
|
||||
typedef struct tfb_dc_deldata
|
||||
{
|
||||
void *data;
|
||||
// data must be a result of HXalloc() call
|
||||
} TFB_DrawCommand_DeleteData;
|
||||
|
||||
typedef struct tfb_dc_signal
|
||||
{
|
||||
Semaphore sem;
|
||||
} TFB_DrawCommand_SendSignal;
|
||||
|
||||
typedef struct tfb_dc_reinit_video
|
||||
{
|
||||
int driver, flags, width, height;
|
||||
} TFB_DrawCommand_ReinitVideo;
|
||||
|
||||
typedef struct tfb_dc_callback
|
||||
{
|
||||
void (*callback)(void *arg);
|
||||
void *arg;
|
||||
} TFB_DrawCommand_Callback;
|
||||
|
||||
typedef struct tfb_drawcommand
|
||||
{
|
||||
int Type;
|
||||
union {
|
||||
TFB_DrawCommand_Line line;
|
||||
TFB_DrawCommand_Rect rect;
|
||||
TFB_DrawCommand_Image image;
|
||||
TFB_DrawCommand_FilledImage filledimage;
|
||||
TFB_DrawCommand_FontChar fontchar;
|
||||
TFB_DrawCommand_Copy copy;
|
||||
TFB_DrawCommand_CopyToImage copytoimage;
|
||||
TFB_DrawCommand_Scissor scissor;
|
||||
TFB_DrawCommand_SetMipmap setmipmap;
|
||||
TFB_DrawCommand_DeleteImage deleteimage;
|
||||
TFB_DrawCommand_DeleteData deletedata;
|
||||
TFB_DrawCommand_SendSignal sendsignal;
|
||||
TFB_DrawCommand_ReinitVideo reinitvideo;
|
||||
TFB_DrawCommand_Callback callback;
|
||||
} data;
|
||||
} TFB_DrawCommand;
|
||||
|
||||
// Queue Stuff
|
||||
|
||||
typedef struct tfb_drawcommandqueue
|
||||
{
|
||||
int Front;
|
||||
int Back;
|
||||
int InsertionPoint;
|
||||
int Batching;
|
||||
volatile int FullSize;
|
||||
volatile int Size;
|
||||
} TFB_DrawCommandQueue;
|
||||
|
||||
void Init_DrawCommandQueue (void);
|
||||
|
||||
void Uninit_DrawCommandQueue (void);
|
||||
|
||||
void TFB_BatchGraphics (void);
|
||||
|
||||
void TFB_UnbatchGraphics (void);
|
||||
|
||||
void TFB_BatchReset (void);
|
||||
|
||||
void TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command);
|
||||
|
||||
int TFB_DrawCommandQueue_Pop (TFB_DrawCommand* Command);
|
||||
|
||||
void TFB_DrawCommandQueue_Clear (void);
|
||||
|
||||
extern TFB_DrawCommandQueue DrawCommandQueue;
|
||||
|
||||
void TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand);
|
||||
|
||||
void Lock_DCQ (int slots);
|
||||
|
||||
void Unlock_DCQ (void);
|
||||
|
||||
#endif
|
||||
72
project/jni/application/sc2/src/libs/graphics/filegfx.c
Normal file
72
project/jni/application/sc2/src/libs/graphics/filegfx.c
Normal file
@@ -0,0 +1,72 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
#include "options.h"
|
||||
#include "libs/reslib.h"
|
||||
|
||||
|
||||
DRAWABLE
|
||||
LoadGraphicFile (const char *pStr)
|
||||
{
|
||||
uio_Stream *fp;
|
||||
|
||||
// FIXME: this theoretically needs a mechanism to prevent races
|
||||
if (_cur_resfile_name)
|
||||
// something else is loading resources atm
|
||||
return 0;
|
||||
|
||||
fp = res_OpenResFile (contentDir, pStr, "rb");
|
||||
if (fp != NULL)
|
||||
{
|
||||
DRAWABLE hData;
|
||||
|
||||
_cur_resfile_name = pStr;
|
||||
hData = (DRAWABLE)_GetCelData (fp, LengthResFile (fp));
|
||||
_cur_resfile_name = 0;
|
||||
res_CloseResFile (fp);
|
||||
return hData;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
FONT
|
||||
LoadFontFile (const char *pStr)
|
||||
{
|
||||
uio_Stream *fp;
|
||||
|
||||
// FIXME: this theoretically needs a mechanism to prevent races
|
||||
if (_cur_resfile_name)
|
||||
// something else is loading resources atm
|
||||
return 0;
|
||||
|
||||
fp = res_OpenResFile (contentDir, pStr, "rb");
|
||||
if (fp != NULL)
|
||||
{
|
||||
FONT hData;
|
||||
|
||||
_cur_resfile_name = pStr;
|
||||
hData = (FONT)_GetFontData (fp, LengthResFile (fp));
|
||||
_cur_resfile_name = 0;
|
||||
res_CloseResFile (fp);
|
||||
return hData;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
334
project/jni/application/sc2/src/libs/graphics/font.c
Normal file
334
project/jni/application/sc2/src/libs/graphics/font.c
Normal file
@@ -0,0 +1,334 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
#include "tfb_prim.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
static inline TFB_Char *getCharFrame (FONT_DESC *fontPtr, UniChar ch);
|
||||
|
||||
|
||||
FONT
|
||||
SetContextFont (FONT Font)
|
||||
{
|
||||
FONT LastFont;
|
||||
|
||||
LastFont = _CurFontPtr;
|
||||
_CurFontPtr = Font;
|
||||
if (ContextActive ())
|
||||
SwitchContextFont (Font);
|
||||
|
||||
return (LastFont);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DestroyFont (FONT FontRef)
|
||||
{
|
||||
if (FontRef == NULL)
|
||||
return (FALSE);
|
||||
|
||||
if (_CurFontPtr && _CurFontPtr == FontRef)
|
||||
SetContextFont ((FONT)NULL);
|
||||
|
||||
return (FreeFont (FontRef));
|
||||
}
|
||||
|
||||
// XXX: Should be in frame.c (renamed to something decent?)
|
||||
void
|
||||
font_DrawText (TEXT *lpText)
|
||||
{
|
||||
RECT ClipRect;
|
||||
POINT origin;
|
||||
TEXT text;
|
||||
|
||||
FixContextFontEffect ();
|
||||
if (!GraphicsSystemActive () || !GetContextValidRect (NULL, &origin))
|
||||
return;
|
||||
|
||||
// TextRect() clobbers TEXT.CharCount so we have to make a copy
|
||||
text = *lpText;
|
||||
if (!TextRect (&text, &ClipRect, NULL))
|
||||
return;
|
||||
// ClipRect is relative to origin
|
||||
_text_blt (&ClipRect, &text, origin);
|
||||
}
|
||||
|
||||
/* Draw the stroke by drawing the same text in the
|
||||
* background color one pixel shifted to all 4 directions.
|
||||
*/
|
||||
void
|
||||
font_DrawTracedText (TEXT *pText, Color text, Color trace)
|
||||
{
|
||||
// Preserve current foreground color for full correctness
|
||||
Color oldfg = SetContextForeGroundColor (trace);
|
||||
pText->baseline.x--;
|
||||
font_DrawText (pText);
|
||||
pText->baseline.x += 2;
|
||||
font_DrawText (pText);
|
||||
pText->baseline.x--;
|
||||
pText->baseline.y--;
|
||||
font_DrawText (pText);
|
||||
pText->baseline.y += 2;
|
||||
font_DrawText (pText);
|
||||
pText->baseline.y--;
|
||||
SetContextForeGroundColor (text);
|
||||
font_DrawText (pText);
|
||||
SetContextForeGroundColor (oldfg);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
GetContextFontLeading (SIZE *pheight)
|
||||
{
|
||||
if (_CurFontPtr != 0)
|
||||
{
|
||||
*pheight = (SIZE)_CurFontPtr->Leading;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
*pheight = 0;
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
GetContextFontLeadingWidth (SIZE *pwidth)
|
||||
{
|
||||
if (_CurFontPtr != 0)
|
||||
{
|
||||
*pwidth = (SIZE)_CurFontPtr->LeadingWidth;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
*pwidth = 0;
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
TextRect (TEXT *lpText, RECT *pRect, BYTE *pdelta)
|
||||
{
|
||||
BYTE char_delta_array[MAX_DELTAS];
|
||||
FONT FontPtr;
|
||||
|
||||
FontPtr = _CurFontPtr;
|
||||
if (FontPtr != 0 && lpText->CharCount != 0)
|
||||
{
|
||||
COORD top_y, bot_y;
|
||||
SIZE width;
|
||||
UniChar next_ch = 0;
|
||||
const char *pStr;
|
||||
COUNT num_chars;
|
||||
|
||||
num_chars = lpText->CharCount;
|
||||
/* At this point lpText->CharCount contains the *maximum* number of
|
||||
* characters that lpText->pStr may contain.
|
||||
* After the while loop below, it will contain the actual number.
|
||||
*/
|
||||
if (pdelta == 0)
|
||||
{
|
||||
pdelta = char_delta_array;
|
||||
if (num_chars > MAX_DELTAS)
|
||||
{
|
||||
num_chars = MAX_DELTAS;
|
||||
lpText->CharCount = MAX_DELTAS;
|
||||
}
|
||||
}
|
||||
|
||||
top_y = 0;
|
||||
bot_y = 0;
|
||||
width = 0;
|
||||
pStr = lpText->pStr;
|
||||
if (num_chars > 0)
|
||||
{
|
||||
next_ch = getCharFromString (&pStr);
|
||||
if (next_ch == '\0')
|
||||
num_chars = 0;
|
||||
}
|
||||
while (num_chars--)
|
||||
{
|
||||
UniChar ch;
|
||||
SIZE last_width;
|
||||
TFB_Char *charFrame;
|
||||
|
||||
last_width = width;
|
||||
|
||||
ch = next_ch;
|
||||
if (num_chars > 0)
|
||||
{
|
||||
next_ch = getCharFromString (&pStr);
|
||||
if (next_ch == '\0')
|
||||
{
|
||||
lpText->CharCount -= num_chars;
|
||||
num_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
charFrame = getCharFrame (FontPtr, ch);
|
||||
if (charFrame != NULL && charFrame->disp.width)
|
||||
{
|
||||
COORD y;
|
||||
|
||||
y = -charFrame->HotSpot.y;
|
||||
if (y < top_y)
|
||||
top_y = y;
|
||||
y += charFrame->disp.height;
|
||||
if (y > bot_y)
|
||||
bot_y = y;
|
||||
|
||||
width += charFrame->disp.width;
|
||||
#if 0
|
||||
if (num_chars && next_ch < (UNICODE) MAX_CHARS
|
||||
&& !(FontPtr->KernTab[ch]
|
||||
& (FontPtr->KernTab[next_ch] >> 2)))
|
||||
width -= FontPtr->KernAmount;
|
||||
#endif
|
||||
}
|
||||
|
||||
*pdelta++ = (BYTE)(width - last_width);
|
||||
}
|
||||
|
||||
if (width > 0 && (bot_y -= top_y) > 0)
|
||||
{
|
||||
/* subtract off default character spacing */
|
||||
if (pdelta[-1] > 0)
|
||||
{
|
||||
--pdelta[-1];
|
||||
--width;
|
||||
}
|
||||
|
||||
if (lpText->align == ALIGN_LEFT)
|
||||
pRect->corner.x = 0;
|
||||
else if (lpText->align == ALIGN_CENTER)
|
||||
pRect->corner.x = -(width >> 1);
|
||||
else
|
||||
pRect->corner.x = -width;
|
||||
pRect->corner.y = top_y;
|
||||
pRect->extent.width = width;
|
||||
pRect->extent.height = bot_y;
|
||||
|
||||
pRect->corner.x += lpText->baseline.x;
|
||||
pRect->corner.y += lpText->baseline.y;
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
pRect->corner = lpText->baseline;
|
||||
pRect->extent.width = 0;
|
||||
pRect->extent.height = 0;
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
_text_blt (RECT *pClipRect, TEXT *TextPtr, POINT ctxOrigin)
|
||||
{
|
||||
FONT FontPtr;
|
||||
COUNT num_chars;
|
||||
UniChar next_ch;
|
||||
const char *pStr;
|
||||
POINT origin;
|
||||
TFB_Image *backing;
|
||||
DrawMode mode = _get_context_draw_mode ();
|
||||
|
||||
FontPtr = _CurFontPtr;
|
||||
if (FontPtr == NULL)
|
||||
return;
|
||||
backing = _get_context_font_backing ();
|
||||
if (!backing)
|
||||
return;
|
||||
|
||||
origin.x = pClipRect->corner.x;
|
||||
origin.y = TextPtr->baseline.y;
|
||||
num_chars = TextPtr->CharCount;
|
||||
if (num_chars == 0)
|
||||
return;
|
||||
|
||||
pStr = TextPtr->pStr;
|
||||
|
||||
next_ch = getCharFromString (&pStr);
|
||||
if (next_ch == '\0')
|
||||
num_chars = 0;
|
||||
while (num_chars--)
|
||||
{
|
||||
UniChar ch;
|
||||
TFB_Char* fontChar;
|
||||
|
||||
ch = next_ch;
|
||||
if (num_chars > 0)
|
||||
{
|
||||
next_ch = getCharFromString (&pStr);
|
||||
if (next_ch == '\0')
|
||||
num_chars = 0;
|
||||
}
|
||||
|
||||
fontChar = getCharFrame (FontPtr, ch);
|
||||
if (fontChar != NULL && fontChar->disp.width)
|
||||
{
|
||||
RECT r;
|
||||
|
||||
r.corner.x = origin.x - fontChar->HotSpot.x;
|
||||
r.corner.y = origin.y - fontChar->HotSpot.y;
|
||||
r.extent.width = fontChar->disp.width;
|
||||
r.extent.height = fontChar->disp.height;
|
||||
if (BoxIntersect (&r, pClipRect, &r))
|
||||
{
|
||||
TFB_Prim_FontChar (origin, fontChar, backing, mode,
|
||||
ctxOrigin);
|
||||
}
|
||||
|
||||
origin.x += fontChar->disp.width;
|
||||
#if 0
|
||||
if (num_chars && next_ch < (UNICODE) MAX_CHARS
|
||||
&& !(FontPtr->KernTab[ch]
|
||||
& (FontPtr->KernTab[next_ch] >> 2)))
|
||||
origin.x -= FontPtr->KernAmount;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline TFB_Char *
|
||||
getCharFrame (FONT_DESC *fontPtr, UniChar ch)
|
||||
{
|
||||
UniChar pageStart = ch & CHARACTER_PAGE_MASK;
|
||||
size_t charIndex;
|
||||
|
||||
FONT_PAGE *page = fontPtr->fontPages;
|
||||
for (;;)
|
||||
{
|
||||
if (page == NULL)
|
||||
return NULL;
|
||||
|
||||
if (page->pageStart == pageStart)
|
||||
break;
|
||||
|
||||
page = page->next;
|
||||
}
|
||||
|
||||
charIndex = ch - page->firstChar;
|
||||
if (ch >= page->firstChar && charIndex < page->numChars
|
||||
&& page->charDesc[charIndex].data)
|
||||
{
|
||||
return &page->charDesc[charIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
//log_add (log_Debug, "Character %u not present", (unsigned int) ch);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
71
project/jni/application/sc2/src/libs/graphics/font.h
Normal file
71
project/jni/application/sc2/src/libs/graphics/font.h
Normal file
@@ -0,0 +1,71 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _FONT_H
|
||||
#define _FONT_H
|
||||
|
||||
#include "libs/memlib.h"
|
||||
|
||||
#define MAX_DELTAS 100
|
||||
|
||||
typedef struct FontPage
|
||||
{
|
||||
struct FontPage *next;
|
||||
UniChar pageStart;
|
||||
#define CHARACTER_PAGE_MASK 0xfffff800
|
||||
UniChar firstChar;
|
||||
size_t numChars;
|
||||
TFB_Char *charDesc;
|
||||
} FONT_PAGE;
|
||||
|
||||
static inline FONT_PAGE *
|
||||
AllocFontPage (int numChars)
|
||||
{
|
||||
FONT_PAGE *result = HMalloc (sizeof (FONT_PAGE));
|
||||
result->charDesc = HCalloc (numChars * sizeof *result->charDesc);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void
|
||||
FreeFontPage (FONT_PAGE *page)
|
||||
{
|
||||
HFree (page->charDesc);
|
||||
HFree (page);
|
||||
}
|
||||
|
||||
struct font_desc
|
||||
{
|
||||
UWORD Leading;
|
||||
UWORD LeadingWidth;
|
||||
FONT_PAGE *fontPages;
|
||||
};
|
||||
|
||||
#define CHAR_DESCPTR PCHAR_DESC
|
||||
|
||||
#define FONT_PRIORITY DEFAULT_MEM_PRIORITY
|
||||
|
||||
#define AllocFont(size) (FONT)HCalloc (sizeof (FONT_DESC) + (size))
|
||||
#define FreeFont _ReleaseFontData
|
||||
|
||||
extern FONT _CurFontPtr;
|
||||
|
||||
extern void *_GetFontData (uio_Stream *fp, DWORD length);
|
||||
extern BOOLEAN _ReleaseFontData (void *handle);
|
||||
|
||||
#endif /* _FONT_H */
|
||||
|
||||
266
project/jni/application/sc2/src/libs/graphics/frame.c
Normal file
266
project/jni/application/sc2/src/libs/graphics/frame.c
Normal file
@@ -0,0 +1,266 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
#include "gfx_common.h"
|
||||
#include "tfb_draw.h"
|
||||
#include "tfb_prim.h"
|
||||
|
||||
HOT_SPOT
|
||||
MAKE_HOT_SPOT (COORD x, COORD y)
|
||||
{
|
||||
HOT_SPOT hs;
|
||||
hs.x = x;
|
||||
hs.y = y;
|
||||
return hs;
|
||||
}
|
||||
|
||||
// XXX: INTERNAL_PRIMITIVE and INTERNAL_PRIM_DESC are not used
|
||||
typedef union
|
||||
{
|
||||
POINT Point;
|
||||
STAMP Stamp;
|
||||
BRESENHAM_LINE Line;
|
||||
TEXT Text;
|
||||
RECT Rect;
|
||||
} INTERNAL_PRIM_DESC;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PRIM_LINKS Links;
|
||||
GRAPHICS_PRIM Type;
|
||||
Color Color;
|
||||
INTERNAL_PRIM_DESC Object;
|
||||
} INTERNAL_PRIMITIVE;
|
||||
|
||||
|
||||
// pValidRect or origin may be NULL
|
||||
BOOLEAN
|
||||
GetContextValidRect (RECT *pValidRect, POINT *origin)
|
||||
{
|
||||
RECT tempRect;
|
||||
POINT tempPt;
|
||||
|
||||
if (!pValidRect)
|
||||
pValidRect = &tempRect;
|
||||
if (!origin)
|
||||
origin = &tempPt;
|
||||
|
||||
// Start with a rect the size of foreground frame
|
||||
pValidRect->corner.x = 0;
|
||||
pValidRect->corner.y = 0;
|
||||
pValidRect->extent = GetFrameBounds (_CurFramePtr);
|
||||
*origin = _CurFramePtr->HotSpot;
|
||||
|
||||
if (_pCurContext->ClipRect.extent.width)
|
||||
{
|
||||
// If the cliprect is completely outside of the valid frame
|
||||
// bounds we have nothing to draw
|
||||
if (!BoxIntersect (&_pCurContext->ClipRect,
|
||||
pValidRect, pValidRect))
|
||||
return (FALSE);
|
||||
|
||||
// Foreground frame hotspot defines a drawing position offset
|
||||
// WRT the context cliprect
|
||||
origin->x += _pCurContext->ClipRect.corner.x;
|
||||
origin->y += _pCurContext->ClipRect.corner.y;
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
ClearBackGround (RECT *pClipRect)
|
||||
{
|
||||
RECT clearRect;
|
||||
Color color = _get_context_bg_color ();
|
||||
clearRect.corner.x = 0;
|
||||
clearRect.corner.y = 0;
|
||||
clearRect.extent = pClipRect->extent;
|
||||
TFB_Prim_FillRect (&clearRect, color, DRAW_REPLACE_MODE,
|
||||
pClipRect->corner);
|
||||
}
|
||||
|
||||
void
|
||||
DrawBatch (PRIMITIVE *lpBasePrim, PRIM_LINKS PrimLinks,
|
||||
BATCH_FLAGS BatchFlags)
|
||||
{
|
||||
RECT ValidRect;
|
||||
POINT origin;
|
||||
|
||||
if (GraphicsSystemActive () && GetContextValidRect (&ValidRect, &origin))
|
||||
{
|
||||
COUNT CurIndex;
|
||||
PRIMITIVE *lpPrim;
|
||||
DrawMode mode = _get_context_draw_mode ();
|
||||
|
||||
BatchGraphics ();
|
||||
|
||||
if (BatchFlags & BATCH_BUILD_PAGE)
|
||||
{
|
||||
ClearBackGround (&ValidRect);
|
||||
}
|
||||
|
||||
CurIndex = GetPredLink (PrimLinks);
|
||||
|
||||
for (; CurIndex != END_OF_LIST;
|
||||
CurIndex = GetSuccLink (GetPrimLinks (lpPrim)))
|
||||
{
|
||||
GRAPHICS_PRIM PrimType;
|
||||
PRIMITIVE *lpWorkPrim;
|
||||
RECT ClipRect;
|
||||
Color color;
|
||||
|
||||
lpPrim = &lpBasePrim[CurIndex];
|
||||
PrimType = GetPrimType (lpPrim);
|
||||
if (!ValidPrimType (PrimType))
|
||||
continue;
|
||||
|
||||
lpWorkPrim = lpPrim;
|
||||
|
||||
switch (PrimType)
|
||||
{
|
||||
case POINT_PRIM:
|
||||
color = GetPrimColor (lpWorkPrim);
|
||||
TFB_Prim_Point (&lpWorkPrim->Object.Point, color,
|
||||
mode, origin);
|
||||
break;
|
||||
case STAMP_PRIM:
|
||||
TFB_Prim_Stamp (&lpWorkPrim->Object.Stamp, mode, origin);
|
||||
break;
|
||||
case STAMPFILL_PRIM:
|
||||
color = GetPrimColor (lpWorkPrim);
|
||||
TFB_Prim_StampFill (&lpWorkPrim->Object.Stamp, color,
|
||||
mode, origin);
|
||||
break;
|
||||
case LINE_PRIM:
|
||||
color = GetPrimColor (lpWorkPrim);
|
||||
TFB_Prim_Line (&lpWorkPrim->Object.Line, color,
|
||||
mode, origin);
|
||||
break;
|
||||
case TEXT_PRIM:
|
||||
if (!TextRect (&lpWorkPrim->Object.Text, &ClipRect, NULL))
|
||||
continue;
|
||||
// ClipRect is relative to origin
|
||||
_text_blt (&ClipRect, &lpWorkPrim->Object.Text, origin);
|
||||
break;
|
||||
case RECT_PRIM:
|
||||
color = GetPrimColor (lpWorkPrim);
|
||||
TFB_Prim_Rect (&lpWorkPrim->Object.Rect, color,
|
||||
mode, origin);
|
||||
break;
|
||||
case RECTFILL_PRIM:
|
||||
color = GetPrimColor (lpWorkPrim);
|
||||
TFB_Prim_FillRect (&lpWorkPrim->Object.Rect, color,
|
||||
mode, origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UnbatchGraphics ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClearDrawable (void)
|
||||
{
|
||||
RECT ValidRect;
|
||||
|
||||
if (GraphicsSystemActive () && GetContextValidRect (&ValidRect, NULL))
|
||||
{
|
||||
ClearBackGround (&ValidRect);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawPoint (POINT *lpPoint)
|
||||
{
|
||||
POINT origin;
|
||||
|
||||
if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
|
||||
{
|
||||
Color color = GetPrimColor (&_locPrim);
|
||||
DrawMode mode = _get_context_draw_mode ();
|
||||
TFB_Prim_Point (lpPoint, color, mode, origin);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawRectangle (RECT *lpRect)
|
||||
{
|
||||
POINT origin;
|
||||
|
||||
if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
|
||||
{
|
||||
Color color = GetPrimColor (&_locPrim);
|
||||
DrawMode mode = _get_context_draw_mode ();
|
||||
TFB_Prim_Rect (lpRect, color, mode, origin);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawFilledRectangle (RECT *lpRect)
|
||||
{
|
||||
POINT origin;
|
||||
|
||||
if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
|
||||
{
|
||||
Color color = GetPrimColor (&_locPrim);
|
||||
DrawMode mode = _get_context_draw_mode ();
|
||||
TFB_Prim_FillRect (lpRect, color, mode, origin);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawLine (LINE *lpLine)
|
||||
{
|
||||
POINT origin;
|
||||
|
||||
if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
|
||||
{
|
||||
Color color = GetPrimColor (&_locPrim);
|
||||
DrawMode mode = _get_context_draw_mode ();
|
||||
TFB_Prim_Line (lpLine, color, mode, origin);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawStamp (STAMP *stmp)
|
||||
{
|
||||
POINT origin;
|
||||
|
||||
if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
|
||||
{
|
||||
DrawMode mode = _get_context_draw_mode ();
|
||||
TFB_Prim_Stamp (stmp, mode, origin);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawFilledStamp (STAMP *stmp)
|
||||
{
|
||||
POINT origin;
|
||||
|
||||
if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
|
||||
{
|
||||
Color color = GetPrimColor (&_locPrim);
|
||||
DrawMode mode = _get_context_draw_mode ();
|
||||
TFB_Prim_StampFill (stmp, color, mode, origin);
|
||||
}
|
||||
}
|
||||
|
||||
196
project/jni/application/sc2/src/libs/graphics/gfx_common.c
Normal file
196
project/jni/application/sc2/src/libs/graphics/gfx_common.c
Normal file
@@ -0,0 +1,196 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/graphics/drawcmd.h"
|
||||
#include "libs/timelib.h"
|
||||
#include "libs/misc.h"
|
||||
// for TFB_DEBUG_HALT
|
||||
|
||||
|
||||
int ScreenWidth;
|
||||
int ScreenHeight;
|
||||
int ScreenWidthActual;
|
||||
int ScreenHeightActual;
|
||||
int ScreenColorDepth;
|
||||
int GraphicsDriver;
|
||||
int TFB_DEBUG_HALT = 0;
|
||||
|
||||
volatile int TransitionAmount = 255;
|
||||
RECT TransitionClipRect;
|
||||
|
||||
static int gscale = GSCALE_IDENTITY;
|
||||
static int gscale_mode = TFB_SCALE_NEAREST;
|
||||
|
||||
void
|
||||
DrawFromExtraScreen (RECT *r)
|
||||
{
|
||||
TFB_DrawScreen_Copy(r, TFB_SCREEN_EXTRA, TFB_SCREEN_MAIN);
|
||||
}
|
||||
|
||||
void
|
||||
LoadIntoExtraScreen (RECT *r)
|
||||
{
|
||||
TFB_DrawScreen_Copy(r, TFB_SCREEN_MAIN, TFB_SCREEN_EXTRA);
|
||||
}
|
||||
|
||||
int
|
||||
SetGraphicScale (int scale)
|
||||
{
|
||||
int old_scale = gscale;
|
||||
gscale = (scale ? scale : GSCALE_IDENTITY);
|
||||
return old_scale;
|
||||
}
|
||||
|
||||
int
|
||||
GetGraphicScale (void)
|
||||
{
|
||||
return gscale;
|
||||
}
|
||||
|
||||
int
|
||||
SetGraphicScaleMode (int mode)
|
||||
{
|
||||
int old_mode = gscale_mode;
|
||||
assert (mode >= TFB_SCALE_NEAREST && mode <= TFB_SCALE_TRILINEAR);
|
||||
gscale_mode = mode;
|
||||
return old_mode;
|
||||
}
|
||||
|
||||
int
|
||||
GetGraphicScaleMode (void)
|
||||
{
|
||||
return gscale_mode;
|
||||
}
|
||||
|
||||
/* Batching and Unbatching functions. A "Batch" is a collection of
|
||||
DrawCommands that will never be flipped to the screen half-rendered.
|
||||
BatchGraphics and UnbatchGraphics function vaguely like a non-blocking
|
||||
recursive lock to do this respect. */
|
||||
void
|
||||
BatchGraphics (void)
|
||||
{
|
||||
TFB_BatchGraphics ();
|
||||
}
|
||||
|
||||
void
|
||||
UnbatchGraphics (void)
|
||||
{
|
||||
TFB_UnbatchGraphics ();
|
||||
}
|
||||
|
||||
/* Sleeps this thread until all Draw Commands queued by that thread have
|
||||
been processed. */
|
||||
|
||||
void
|
||||
FlushGraphics ()
|
||||
{
|
||||
TFB_DrawScreen_WaitForSignal ();
|
||||
}
|
||||
|
||||
static void
|
||||
ExpandRect (RECT *rect, int expansion)
|
||||
{
|
||||
if (rect->corner.x - expansion >= 0)
|
||||
{
|
||||
rect->extent.width += expansion;
|
||||
rect->corner.x -= expansion;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect->extent.width += rect->corner.x;
|
||||
rect->corner.x = 0;
|
||||
}
|
||||
|
||||
if (rect->corner.y - expansion >= 0)
|
||||
{
|
||||
rect->extent.height += expansion;
|
||||
rect->corner.y -= expansion;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect->extent.height += rect->corner.y;
|
||||
rect->corner.y = 0;
|
||||
}
|
||||
|
||||
if (rect->corner.x + rect->extent.width + expansion <= ScreenWidth)
|
||||
rect->extent.width += expansion;
|
||||
else
|
||||
rect->extent.width = ScreenWidth - rect->corner.x;
|
||||
|
||||
if (rect->corner.y + rect->extent.height + expansion <= ScreenHeight)
|
||||
rect->extent.height += expansion;
|
||||
else
|
||||
rect->extent.height = ScreenHeight - rect->corner.y;
|
||||
}
|
||||
|
||||
void
|
||||
SetTransitionSource (const RECT *pRect)
|
||||
{
|
||||
RECT ActualRect;
|
||||
|
||||
if (pRect)
|
||||
{ /* expand the rect to accomodate scalers in OpenGL mode */
|
||||
ActualRect = *pRect;
|
||||
pRect = &ActualRect;
|
||||
ExpandRect (&ActualRect, 2);
|
||||
}
|
||||
TFB_DrawScreen_Copy (pRect, TFB_SCREEN_MAIN, TFB_SCREEN_TRANSITION);
|
||||
}
|
||||
|
||||
// ScreenTransition() is synchronous (does not return until transition done)
|
||||
void
|
||||
ScreenTransition (int TransType, const RECT *pRect)
|
||||
{
|
||||
const TimePeriod DURATION = ONE_SECOND * 31 / 60;
|
||||
TimeCount startTime;
|
||||
(void) TransType; /* dodge compiler warning */
|
||||
|
||||
if (pRect)
|
||||
{
|
||||
TransitionClipRect = *pRect;
|
||||
}
|
||||
else
|
||||
{
|
||||
TransitionClipRect.corner.x = 0;
|
||||
TransitionClipRect.corner.y = 0;
|
||||
TransitionClipRect.extent.width = ScreenWidth;
|
||||
TransitionClipRect.extent.height = ScreenHeight;
|
||||
}
|
||||
|
||||
TFB_UploadTransitionScreen ();
|
||||
|
||||
TransitionAmount = 0;
|
||||
FlushGraphics ();
|
||||
startTime = GetTimeCounter ();
|
||||
while (TransitionAmount < 255)
|
||||
{
|
||||
TimePeriod deltaT;
|
||||
int newAmount;
|
||||
|
||||
SleepThread (ONE_SECOND / 100);
|
||||
|
||||
deltaT = GetTimeCounter () - startTime;
|
||||
newAmount = deltaT * 255 / DURATION;
|
||||
if (newAmount > 255)
|
||||
newAmount = 255;
|
||||
|
||||
TransitionAmount = newAmount;
|
||||
}
|
||||
}
|
||||
109
project/jni/application/sc2/src/libs/graphics/gfx_common.h
Normal file
109
project/jni/application/sc2/src/libs/graphics/gfx_common.h
Normal file
@@ -0,0 +1,109 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef GFX_COMMON_H
|
||||
#define GFX_COMMON_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libs/gfxlib.h"
|
||||
|
||||
// driver for TFB_InitGraphics
|
||||
enum
|
||||
{
|
||||
TFB_GFXDRIVER_SDL_OPENGL,
|
||||
TFB_GFXDRIVER_SDL_PURE,
|
||||
};
|
||||
|
||||
// forced redraw
|
||||
enum
|
||||
{
|
||||
TFB_REDRAW_NO = 0,
|
||||
TFB_REDRAW_FADING,
|
||||
TFB_REDRAW_EXPOSE,
|
||||
TFB_REDRAW_YES
|
||||
};
|
||||
|
||||
// flags for TFB_InitGraphics
|
||||
#define TFB_GFXFLAGS_FULLSCREEN (1<<0)
|
||||
#define TFB_GFXFLAGS_SHOWFPS (1<<1)
|
||||
#define TFB_GFXFLAGS_SCANLINES (1<<2)
|
||||
#define TFB_GFXFLAGS_SCALE_BILINEAR (1<<3)
|
||||
#define TFB_GFXFLAGS_SCALE_BIADAPT (1<<4)
|
||||
#define TFB_GFXFLAGS_SCALE_BIADAPTADV (1<<5)
|
||||
#define TFB_GFXFLAGS_SCALE_TRISCAN (1<<6)
|
||||
#define TFB_GFXFLAGS_SCALE_HQXX (1<<7)
|
||||
#define TFB_GFXFLAGS_SCALE_ANY \
|
||||
( TFB_GFXFLAGS_SCALE_BILINEAR | \
|
||||
TFB_GFXFLAGS_SCALE_BIADAPT | \
|
||||
TFB_GFXFLAGS_SCALE_BIADAPTADV | \
|
||||
TFB_GFXFLAGS_SCALE_TRISCAN | \
|
||||
TFB_GFXFLAGS_SCALE_HQXX )
|
||||
#define TFB_GFXFLAGS_SCALE_SOFT_ONLY \
|
||||
( TFB_GFXFLAGS_SCALE_ANY & ~TFB_GFXFLAGS_SCALE_BILINEAR )
|
||||
|
||||
// The flag variable itself
|
||||
extern int GfxFlags;
|
||||
|
||||
// The following functions are driver-defined
|
||||
void TFB_PreInit (void);
|
||||
int TFB_InitGraphics (int driver, int flags, int width, int height);
|
||||
int TFB_ReInitGraphics (int driver, int flags, int width, int height);
|
||||
void TFB_UninitGraphics (void);
|
||||
void TFB_ProcessEvents (void);
|
||||
void TFB_SetGamma (float gamma);
|
||||
void TFB_UploadTransitionScreen (void);
|
||||
// This function should not be called directly
|
||||
void TFB_SwapBuffers (int force_full_redraw);
|
||||
|
||||
#define GSCALE_IDENTITY 256
|
||||
|
||||
typedef enum {
|
||||
TFB_SCALE_STEP, /* not really a scaler */
|
||||
TFB_SCALE_NEAREST,
|
||||
TFB_SCALE_BILINEAR,
|
||||
TFB_SCALE_TRILINEAR
|
||||
} SCALE;
|
||||
|
||||
void LoadIntoExtraScreen (RECT *r);
|
||||
void DrawFromExtraScreen (RECT *r);
|
||||
int SetGraphicScale (int scale);
|
||||
int GetGraphicScale (void);
|
||||
int SetGraphicScaleMode (int mode /* enum SCALE */);
|
||||
int GetGraphicScaleMode (void);
|
||||
void SetTransitionSource (const RECT *pRect);
|
||||
void ScreenTransition (int transition, const RECT *pRect);
|
||||
|
||||
// TODO: there should be accessor functions for these
|
||||
extern volatile int TransitionAmount;
|
||||
extern RECT TransitionClipRect;
|
||||
|
||||
extern float FrameRate;
|
||||
extern int FrameRateTickBase;
|
||||
|
||||
void TFB_FlushGraphics (void); // Only call from main thread!!
|
||||
|
||||
extern int ScreenWidth;
|
||||
extern int ScreenHeight;
|
||||
extern int ScreenWidthActual;
|
||||
extern int ScreenHeightActual;
|
||||
extern int ScreenColorDepth;
|
||||
extern int GraphicsDriver;
|
||||
|
||||
#endif
|
||||
32
project/jni/application/sc2/src/libs/graphics/gfxintrn.h
Normal file
32
project/jni/application/sc2/src/libs/graphics/gfxintrn.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _GFXINTRN_H
|
||||
#define _GFXINTRN_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libs/gfxlib.h"
|
||||
#include "libs/reslib.h"
|
||||
#include "context.h"
|
||||
#include "drawable.h"
|
||||
#include "font.h"
|
||||
|
||||
#endif /* _GFXINTRN_H */
|
||||
|
||||
605
project/jni/application/sc2/src/libs/graphics/gfxload.c
Normal file
605
project/jni/application/sc2/src/libs/graphics/gfxload.c
Normal file
@@ -0,0 +1,605 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "port.h"
|
||||
#include "libs/uio.h"
|
||||
#include "libs/reslib.h"
|
||||
// for _cur_resfile_name
|
||||
#include "libs/log.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "libs/graphics/drawable.h"
|
||||
#include "libs/graphics/font.h"
|
||||
|
||||
|
||||
typedef struct anidata
|
||||
{
|
||||
int transparent_color;
|
||||
int colormap_index;
|
||||
int hotspot_x;
|
||||
int hotspot_y;
|
||||
} AniData;
|
||||
|
||||
extern uio_Repository *repository;
|
||||
static uio_AutoMount *autoMount[] = { NULL };
|
||||
|
||||
static void
|
||||
process_image (FRAME FramePtr, TFB_Canvas img[], AniData *ani, int cel_ct)
|
||||
{
|
||||
TFB_Image *tfbimg;
|
||||
int hx, hy;
|
||||
|
||||
FramePtr->Type = ROM_DRAWABLE;
|
||||
FramePtr->Index = cel_ct;
|
||||
|
||||
// handle transparency cases
|
||||
if (TFB_DrawCanvas_IsPaletted (img[cel_ct]))
|
||||
{ // indexed color image
|
||||
if (ani[cel_ct].transparent_color >= 0)
|
||||
{
|
||||
TFB_DrawCanvas_SetTransparentIndex (img[cel_ct],
|
||||
ani[cel_ct].transparent_color, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // special transparency cases for truecolor images
|
||||
if (ani[cel_ct].transparent_color == 0)
|
||||
{ // make RGB=0,0,0 transparent
|
||||
Color color = {0, 0, 0, 0};
|
||||
TFB_DrawCanvas_SetTransparentColor (img[cel_ct], color, FALSE);
|
||||
}
|
||||
}
|
||||
if (ani[cel_ct].transparent_color == -1)
|
||||
{ // enforce -1 to mean 'no transparency'
|
||||
TFB_DrawCanvas_SetTransparentIndex (img[cel_ct], -1, FALSE);
|
||||
// set transparent_color == -2 to use PNG tRNS transparency
|
||||
}
|
||||
|
||||
hx = ani[cel_ct].hotspot_x;
|
||||
hy = ani[cel_ct].hotspot_y;
|
||||
|
||||
FramePtr->image = TFB_DrawImage_New (img[cel_ct]);
|
||||
|
||||
tfbimg = FramePtr->image;
|
||||
tfbimg->colormap_index = ani[cel_ct].colormap_index;
|
||||
img[cel_ct] = tfbimg->NormalImg;
|
||||
|
||||
FramePtr->HotSpot = MAKE_HOT_SPOT (hx, hy);
|
||||
SetFrameBounds (FramePtr, tfbimg->extent.width, tfbimg->extent.height);
|
||||
|
||||
#ifdef CLIPDEBUG
|
||||
{
|
||||
/* for debugging clipping:
|
||||
draws white (or most matching color from palette) pixels to
|
||||
every corner of the image
|
||||
*/
|
||||
Color color = {0xff, 0xff, 0xff, 0xff};
|
||||
RECT r = {{0, 0}, {1, 1}};
|
||||
if (tfbimg->extent.width > 2 && tfbimg->extent.height > 2)
|
||||
{
|
||||
TFB_DrawImage_Rect (&r, color, tfbimg);
|
||||
r.corner.x = tfbimg->extent.width - 1;
|
||||
TFB_DrawImage_Rect (&r, color, tfbimg);
|
||||
r.corner.y = tfbimg->extent.height - 1;
|
||||
TFB_DrawImage_Rect (&r, color, tfbimg);
|
||||
r.corner.x = 0;
|
||||
TFB_DrawImage_Rect (&r, color, tfbimg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
processFontChar (TFB_Char* CharPtr, TFB_Canvas canvas)
|
||||
{
|
||||
BYTE* newdata;
|
||||
size_t dpitch;
|
||||
|
||||
TFB_DrawCanvas_GetExtent (canvas, &CharPtr->extent);
|
||||
|
||||
// Currently, each font char has its own separate data
|
||||
// but that can change to common mem area
|
||||
dpitch = CharPtr->extent.width;
|
||||
newdata = HMalloc (dpitch * CharPtr->extent.height * sizeof (BYTE));
|
||||
TFB_DrawCanvas_GetFontCharData (canvas, newdata, dpitch);
|
||||
|
||||
CharPtr->data = newdata;
|
||||
CharPtr->pitch = dpitch;
|
||||
CharPtr->disp.width = CharPtr->extent.width + 1;
|
||||
CharPtr->disp.height = CharPtr->extent.height + 1;
|
||||
// XXX: why the +1?
|
||||
// I brought it into this function from the only calling
|
||||
// function, but I don't know why it was there in the first
|
||||
// place.
|
||||
// XXX: the +1 appears to be for character and line spacing
|
||||
// text_blt just adds the frame width to move to the next char
|
||||
|
||||
{
|
||||
// This tunes the font positioning to be about what it should
|
||||
// TODO: prolly needs a little tweaking still
|
||||
|
||||
int tune_amount = 0;
|
||||
|
||||
if (CharPtr->extent.height == 8)
|
||||
tune_amount = -1;
|
||||
else if (CharPtr->extent.height == 9)
|
||||
tune_amount = -2;
|
||||
else if (CharPtr->extent.height > 9)
|
||||
tune_amount = -3;
|
||||
|
||||
CharPtr->HotSpot = MAKE_HOT_SPOT (0,
|
||||
CharPtr->extent.height + tune_amount);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
_GetCelData (uio_Stream *fp, DWORD length)
|
||||
{
|
||||
int cel_total, cel_index, n;
|
||||
DWORD opos;
|
||||
char CurrentLine[1024], filename[PATH_MAX];
|
||||
TFB_Canvas *img;
|
||||
AniData *ani;
|
||||
DRAWABLE Drawable;
|
||||
uio_MountHandle *aniMount = 0;
|
||||
uio_DirHandle *aniDir = 0;
|
||||
uio_Stream *aniFile = 0;
|
||||
|
||||
opos = uio_ftell (fp);
|
||||
|
||||
{
|
||||
char *s1, *s2;
|
||||
char aniDirName[PATH_MAX];
|
||||
const char *aniFileName;
|
||||
uint8 buf[4] = { 0, 0, 0, 0 };
|
||||
uint32 header;
|
||||
|
||||
if (_cur_resfile_name == 0
|
||||
|| (((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0)
|
||||
&& (s2 = strrchr (_cur_resfile_name, '\\')) == 0))
|
||||
{
|
||||
n = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s2 > s1)
|
||||
s1 = s2;
|
||||
n = s1 - _cur_resfile_name + 1;
|
||||
}
|
||||
|
||||
uio_fread(buf, 4, 1, fp);
|
||||
header = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||
if (_cur_resfile_name && header == 0x04034b50)
|
||||
{
|
||||
// zipped ani file
|
||||
if (n)
|
||||
{
|
||||
strncpy (aniDirName, _cur_resfile_name, n - 1);
|
||||
aniDirName[n - 1] = 0;
|
||||
aniFileName = _cur_resfile_name + n;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(aniDirName, ".");
|
||||
aniFileName = _cur_resfile_name;
|
||||
}
|
||||
aniDir = uio_openDir (repository, aniDirName, 0);
|
||||
aniMount = uio_mountDir (repository, aniDirName, uio_FSTYPE_ZIP,
|
||||
aniDir, aniFileName, "/", autoMount,
|
||||
uio_MOUNT_RDONLY | uio_MOUNT_TOP,
|
||||
NULL);
|
||||
aniFile = uio_fopen (aniDir, aniFileName, "r");
|
||||
opos = 0;
|
||||
n = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unpacked ani file
|
||||
strncpy (filename, _cur_resfile_name, n);
|
||||
aniFile = fp;
|
||||
aniDir = contentDir;
|
||||
}
|
||||
}
|
||||
|
||||
cel_total = 0;
|
||||
uio_fseek (aniFile, opos, SEEK_SET);
|
||||
while (uio_fgets (CurrentLine, sizeof (CurrentLine), aniFile))
|
||||
{
|
||||
++cel_total;
|
||||
}
|
||||
|
||||
img = HMalloc (sizeof (TFB_Canvas) * cel_total);
|
||||
ani = HMalloc (sizeof (AniData) * cel_total);
|
||||
if (!img || !ani)
|
||||
{
|
||||
log_add (log_Warning, "Couldn't allocate space for '%s'", _cur_resfile_name);
|
||||
if (aniMount)
|
||||
{
|
||||
uio_fclose(aniFile);
|
||||
uio_closeDir(aniDir);
|
||||
uio_unmountDir(aniMount);
|
||||
}
|
||||
HFree (img);
|
||||
HFree (ani);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cel_index = 0;
|
||||
uio_fseek (aniFile, opos, SEEK_SET);
|
||||
while (uio_fgets (CurrentLine, sizeof (CurrentLine), aniFile) && cel_index < cel_total)
|
||||
{
|
||||
sscanf (CurrentLine, "%s %d %d %d %d", &filename[n],
|
||||
&ani[cel_index].transparent_color, &ani[cel_index].colormap_index,
|
||||
&ani[cel_index].hotspot_x, &ani[cel_index].hotspot_y);
|
||||
|
||||
img[cel_index] = TFB_DrawCanvas_LoadFromFile (aniDir, filename);
|
||||
if (img[cel_index] == NULL)
|
||||
{
|
||||
const char *err;
|
||||
|
||||
err = TFB_DrawCanvas_GetError ();
|
||||
log_add (log_Warning, "_GetCelData: Unable to load image!");
|
||||
if (err != NULL)
|
||||
log_add (log_Warning, "Gfx Driver reports: %s", err);
|
||||
}
|
||||
else
|
||||
{
|
||||
++cel_index;
|
||||
}
|
||||
|
||||
if ((int)uio_ftell (aniFile) - (int)opos >= (int)length)
|
||||
break;
|
||||
}
|
||||
|
||||
Drawable = NULL;
|
||||
if (cel_index && (Drawable = AllocDrawable (cel_index)))
|
||||
{
|
||||
if (!Drawable)
|
||||
{
|
||||
while (cel_index--)
|
||||
TFB_DrawCanvas_Delete (img[cel_index]);
|
||||
|
||||
HFree (Drawable);
|
||||
Drawable = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
FRAME FramePtr;
|
||||
|
||||
Drawable->Flags = WANT_PIXMAP;
|
||||
Drawable->MaxIndex = cel_index - 1;
|
||||
|
||||
FramePtr = &Drawable->Frame[cel_index];
|
||||
while (--FramePtr, cel_index--)
|
||||
process_image (FramePtr, img, ani, cel_index);
|
||||
}
|
||||
}
|
||||
|
||||
if (Drawable == NULL)
|
||||
log_add (log_Warning, "Couldn't get cel data for '%s'",
|
||||
_cur_resfile_name);
|
||||
|
||||
if (aniMount)
|
||||
{
|
||||
uio_fclose(aniFile);
|
||||
uio_closeDir(aniDir);
|
||||
uio_unmountDir(aniMount);
|
||||
}
|
||||
|
||||
HFree (img);
|
||||
HFree (ani);
|
||||
return Drawable;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
_ReleaseCelData (void *handle)
|
||||
{
|
||||
DRAWABLE DrawablePtr;
|
||||
int cel_ct;
|
||||
FRAME FramePtr = NULL;
|
||||
|
||||
if ((DrawablePtr = handle) == 0)
|
||||
return (FALSE);
|
||||
|
||||
cel_ct = DrawablePtr->MaxIndex + 1;
|
||||
|
||||
if (DrawablePtr->Frame)
|
||||
{
|
||||
FramePtr = DrawablePtr->Frame;
|
||||
if (FramePtr->Type == SCREEN_DRAWABLE)
|
||||
{
|
||||
FramePtr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HFree (handle);
|
||||
if (FramePtr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < cel_ct; i++)
|
||||
{
|
||||
TFB_Image *img = FramePtr[i].image;
|
||||
if (img)
|
||||
{
|
||||
FramePtr[i].image = NULL;
|
||||
TFB_DrawScreen_DeleteImage (img);
|
||||
}
|
||||
}
|
||||
HFree (FramePtr);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
typedef struct BuildCharDesc
|
||||
{
|
||||
TFB_Canvas canvas;
|
||||
UniChar index;
|
||||
} BuildCharDesc;
|
||||
|
||||
static int
|
||||
compareBCDIndex (const void *arg1, const void *arg2)
|
||||
{
|
||||
const BuildCharDesc *bcd1 = (const BuildCharDesc *) arg1;
|
||||
const BuildCharDesc *bcd2 = (const BuildCharDesc *) arg2;
|
||||
|
||||
return (int) bcd1->index - (int) bcd2->index;
|
||||
}
|
||||
|
||||
void *
|
||||
_GetFontData (uio_Stream *fp, DWORD length)
|
||||
{
|
||||
COUNT numDirEntries;
|
||||
DIRENTRY fontDir = NULL;
|
||||
BuildCharDesc *bcds = NULL;
|
||||
size_t numBCDs = 0;
|
||||
int dirEntryI;
|
||||
uio_DirHandle *fontDirHandle = NULL;
|
||||
uio_MountHandle *fontMount = NULL;
|
||||
FONT fontPtr = NULL;
|
||||
|
||||
if (_cur_resfile_name == 0)
|
||||
goto err;
|
||||
|
||||
if (fp != (uio_Stream*)~0)
|
||||
{
|
||||
// font is zipped instead of being in a directory
|
||||
|
||||
char *s1, *s2;
|
||||
int n;
|
||||
const char *fontZipName;
|
||||
char fontDirName[PATH_MAX];
|
||||
|
||||
if ((((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0)
|
||||
&& (s2 = strrchr (_cur_resfile_name, '\\')) == 0))
|
||||
{
|
||||
strcpy(fontDirName, ".");
|
||||
fontZipName = _cur_resfile_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s2 > s1)
|
||||
s1 = s2;
|
||||
n = s1 - _cur_resfile_name + 1;
|
||||
strncpy (fontDirName, _cur_resfile_name, n - 1);
|
||||
fontDirName[n - 1] = 0;
|
||||
fontZipName = _cur_resfile_name + n;
|
||||
}
|
||||
|
||||
fontDirHandle = uio_openDir (repository, fontDirName, 0);
|
||||
fontMount = uio_mountDir (repository, _cur_resfile_name, uio_FSTYPE_ZIP,
|
||||
fontDirHandle, fontZipName, "/", autoMount,
|
||||
uio_MOUNT_RDONLY | uio_MOUNT_TOP,
|
||||
NULL);
|
||||
uio_closeDir (fontDirHandle);
|
||||
}
|
||||
|
||||
fontDir = CaptureDirEntryTable (LoadDirEntryTable (contentDir,
|
||||
_cur_resfile_name, ".", match_MATCH_SUBSTRING));
|
||||
if (fontDir == 0)
|
||||
goto err;
|
||||
numDirEntries = GetDirEntryTableCount (fontDir);
|
||||
|
||||
fontDirHandle = uio_openDirRelative (contentDir, _cur_resfile_name, 0);
|
||||
if (fontDirHandle == NULL)
|
||||
goto err;
|
||||
|
||||
bcds = HMalloc (numDirEntries * sizeof (BuildCharDesc));
|
||||
if (bcds == NULL)
|
||||
goto err;
|
||||
|
||||
// Load the surfaces for all dir Entries
|
||||
for (dirEntryI = 0; dirEntryI < numDirEntries; dirEntryI++)
|
||||
{
|
||||
char *char_name;
|
||||
unsigned int charIndex;
|
||||
TFB_Canvas canvas;
|
||||
EXTENT size;
|
||||
|
||||
char_name = GetDirEntryAddress (SetAbsDirEntryTableIndex (
|
||||
fontDir, dirEntryI));
|
||||
if (sscanf (char_name, "%x.", &charIndex) != 1)
|
||||
continue;
|
||||
|
||||
if (charIndex > 0xffff)
|
||||
continue;
|
||||
|
||||
canvas = TFB_DrawCanvas_LoadFromFile (fontDirHandle, char_name);
|
||||
if (canvas == NULL)
|
||||
continue;
|
||||
|
||||
TFB_DrawCanvas_GetExtent (canvas, &size);
|
||||
if (size.width == 0 || size.height == 0)
|
||||
{
|
||||
TFB_DrawCanvas_Delete (canvas);
|
||||
continue;
|
||||
}
|
||||
|
||||
bcds[numBCDs].canvas = canvas;
|
||||
bcds[numBCDs].index = charIndex;
|
||||
numBCDs++;
|
||||
}
|
||||
uio_closeDir (fontDirHandle);
|
||||
DestroyDirEntryTable (ReleaseDirEntryTable (fontDir));
|
||||
if (fontMount != 0)
|
||||
uio_unmountDir(fontMount);
|
||||
|
||||
#if 0
|
||||
if (numBCDs == 0)
|
||||
goto err;
|
||||
#endif
|
||||
|
||||
// sort on the character index
|
||||
qsort (bcds, numBCDs, sizeof (BuildCharDesc), compareBCDIndex);
|
||||
|
||||
fontPtr = AllocFont (0);
|
||||
if (fontPtr == NULL)
|
||||
goto err;
|
||||
|
||||
fontPtr->Leading = 0;
|
||||
fontPtr->LeadingWidth = 0;
|
||||
|
||||
{
|
||||
size_t startBCD = 0;
|
||||
UniChar pageStart;
|
||||
FONT_PAGE **pageEndPtr = &fontPtr->fontPages;
|
||||
while (startBCD < numBCDs)
|
||||
{
|
||||
// Process one character page.
|
||||
size_t endBCD;
|
||||
pageStart = bcds[startBCD].index & CHARACTER_PAGE_MASK;
|
||||
|
||||
endBCD = startBCD;
|
||||
while (endBCD < numBCDs &&
|
||||
(bcds[endBCD].index & CHARACTER_PAGE_MASK) == pageStart)
|
||||
endBCD++;
|
||||
|
||||
{
|
||||
size_t bcdI;
|
||||
int numChars = bcds[endBCD - 1].index + 1
|
||||
- bcds[startBCD].index;
|
||||
FONT_PAGE *page = AllocFontPage (numChars);
|
||||
page->pageStart = pageStart;
|
||||
page->firstChar = bcds[startBCD].index;
|
||||
page->numChars = numChars;
|
||||
*pageEndPtr = page;
|
||||
pageEndPtr = &page->next;
|
||||
|
||||
for (bcdI = startBCD; bcdI < endBCD; bcdI++)
|
||||
{
|
||||
// Process one character.
|
||||
BuildCharDesc *bcd = &bcds[bcdI];
|
||||
TFB_Char *destChar =
|
||||
&page->charDesc[bcd->index - page->firstChar];
|
||||
|
||||
if (destChar->data != NULL)
|
||||
{
|
||||
// There's already an image for this character.
|
||||
log_add (log_Debug, "Duplicate image for character %d "
|
||||
"for font %s.", (int) bcd->index,
|
||||
_cur_resfile_name);
|
||||
TFB_DrawCanvas_Delete (bcd->canvas);
|
||||
continue;
|
||||
}
|
||||
|
||||
processFontChar (destChar, bcd->canvas);
|
||||
TFB_DrawCanvas_Delete (bcd->canvas);
|
||||
|
||||
if (destChar->disp.height > fontPtr->Leading)
|
||||
fontPtr->Leading = destChar->disp.height;
|
||||
if (destChar->disp.width > fontPtr->LeadingWidth)
|
||||
fontPtr->LeadingWidth = destChar->disp.width;
|
||||
}
|
||||
}
|
||||
|
||||
startBCD = endBCD;
|
||||
}
|
||||
*pageEndPtr = NULL;
|
||||
}
|
||||
|
||||
fontPtr->Leading++;
|
||||
|
||||
HFree (bcds);
|
||||
|
||||
(void) fp; /* Satisfying compiler (unused parameter) */
|
||||
(void) length; /* Satisfying compiler (unused parameter) */
|
||||
return fontPtr;
|
||||
|
||||
err:
|
||||
if (fontPtr != 0)
|
||||
HFree (fontPtr);
|
||||
|
||||
if (bcds != NULL)
|
||||
{
|
||||
size_t bcdI;
|
||||
for (bcdI = 0; bcdI < numBCDs; bcdI++)
|
||||
TFB_DrawCanvas_Delete (bcds[bcdI].canvas);
|
||||
HFree (bcds);
|
||||
}
|
||||
|
||||
if (fontDirHandle != NULL)
|
||||
uio_closeDir (fontDirHandle);
|
||||
|
||||
if (fontDir != 0)
|
||||
DestroyDirEntryTable (ReleaseDirEntryTable (fontDir));
|
||||
|
||||
if (fontMount != 0)
|
||||
uio_unmountDir(fontMount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
_ReleaseFontData (void *handle)
|
||||
{
|
||||
FONT font = (FONT) handle;
|
||||
if (font == NULL)
|
||||
return FALSE;
|
||||
|
||||
{
|
||||
FONT_PAGE *page;
|
||||
FONT_PAGE *nextPage;
|
||||
|
||||
for (page = font->fontPages; page != NULL; page = nextPage)
|
||||
{
|
||||
size_t charI;
|
||||
for (charI = 0; charI < page->numChars; charI++)
|
||||
{
|
||||
TFB_Char *c = &page->charDesc[charI];
|
||||
|
||||
if (c->data == NULL)
|
||||
continue;
|
||||
|
||||
// XXX: fix this if fonts get per-page data
|
||||
// rather than per-char
|
||||
TFB_DrawScreen_DeleteData (c->data);
|
||||
}
|
||||
|
||||
nextPage = page->next;
|
||||
FreeFontPage (page);
|
||||
}
|
||||
}
|
||||
|
||||
HFree (font);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
415
project/jni/application/sc2/src/libs/graphics/intersec.c
Normal file
415
project/jni/application/sc2/src/libs/graphics/intersec.c
Normal file
@@ -0,0 +1,415 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libs/graphics/context.h"
|
||||
#include "libs/graphics/drawable.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
//#define DEBUG_INTERSEC
|
||||
|
||||
static inline BOOLEAN
|
||||
images_intersect (IMAGE_BOX *box1, IMAGE_BOX *box2, const RECT *rect)
|
||||
{
|
||||
return TFB_DrawImage_Intersect (box1->FramePtr->image, box1->Box.corner,
|
||||
box2->FramePtr->image, box2->Box.corner, rect);
|
||||
}
|
||||
|
||||
static TIME_VALUE
|
||||
frame_intersect (INTERSECT_CONTROL *pControl0, RECT *pr0,
|
||||
INTERSECT_CONTROL *pControl1, RECT *pr1, TIME_VALUE t0,
|
||||
TIME_VALUE t1)
|
||||
{
|
||||
SIZE time_error0, time_error1;
|
||||
SIZE cycle0, cycle1;
|
||||
SIZE dx_0, dy_0, dx_1, dy_1;
|
||||
SIZE xincr0, yincr0, xincr1, yincr1;
|
||||
SIZE xerror0, xerror1, yerror0, yerror1;
|
||||
RECT r_intersect;
|
||||
IMAGE_BOX IB0, IB1;
|
||||
BOOLEAN check0, check1;
|
||||
|
||||
IB0.FramePtr = pControl0->IntersectStamp.frame;
|
||||
IB0.Box.corner = pr0->corner;
|
||||
IB0.Box.extent.width = GetFrameWidth (IB0.FramePtr);
|
||||
IB0.Box.extent.height = GetFrameHeight (IB0.FramePtr);
|
||||
IB1.FramePtr = pControl1->IntersectStamp.frame;
|
||||
IB1.Box.corner = pr1->corner;
|
||||
IB1.Box.extent.width = GetFrameWidth (IB1.FramePtr);
|
||||
IB1.Box.extent.height = GetFrameHeight (IB1.FramePtr);
|
||||
|
||||
dx_0 = pr0->extent.width;
|
||||
dy_0 = pr0->extent.height;
|
||||
if (dx_0 >= 0)
|
||||
xincr0 = 1;
|
||||
else
|
||||
{
|
||||
xincr0 = -1;
|
||||
dx_0 = -dx_0;
|
||||
}
|
||||
if (dy_0 >= 0)
|
||||
yincr0 = 1;
|
||||
else
|
||||
{
|
||||
yincr0 = -1;
|
||||
dy_0 = -dy_0;
|
||||
}
|
||||
if (dx_0 >= dy_0)
|
||||
cycle0 = dx_0;
|
||||
else
|
||||
cycle0 = dy_0;
|
||||
xerror0 = yerror0 = cycle0;
|
||||
|
||||
dx_1 = pr1->extent.width;
|
||||
dy_1 = pr1->extent.height;
|
||||
if (dx_1 >= 0)
|
||||
xincr1 = 1;
|
||||
else
|
||||
{
|
||||
xincr1 = -1;
|
||||
dx_1 = -dx_1;
|
||||
}
|
||||
if (dy_1 >= 0)
|
||||
yincr1 = 1;
|
||||
else
|
||||
{
|
||||
yincr1 = -1;
|
||||
dy_1 = -dy_1;
|
||||
}
|
||||
if (dx_1 >= dy_1)
|
||||
cycle1 = dx_1;
|
||||
else
|
||||
cycle1 = dy_1;
|
||||
xerror1 = yerror1 = cycle1;
|
||||
|
||||
check0 = check1 = FALSE;
|
||||
if (t0 <= 1)
|
||||
{
|
||||
time_error0 = time_error1 = 0;
|
||||
if (t0 == 0)
|
||||
{
|
||||
++t0;
|
||||
goto CheckFirstIntersection;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SIZE delta;
|
||||
COUNT start;
|
||||
long error;
|
||||
|
||||
start = (COUNT)cycle0 * (COUNT)(t0 - 1);
|
||||
time_error0 = start & ((1 << TIME_SHIFT) - 1);
|
||||
if ((start >>= (COUNT)TIME_SHIFT) > 0)
|
||||
{
|
||||
if ((error = (long)xerror0
|
||||
- (long)dx_0 * (long)start) > 0)
|
||||
xerror0 = (SIZE)error;
|
||||
else
|
||||
{
|
||||
delta = -(SIZE)(error / (long)cycle0) + 1;
|
||||
IB0.Box.corner.x += xincr0 * delta;
|
||||
xerror0 = (SIZE)(error + (long)cycle0 * (long)delta);
|
||||
}
|
||||
if ((error = (long)yerror0
|
||||
- (long)dy_0 * (long)start) > 0)
|
||||
yerror0 = (SIZE)error;
|
||||
else
|
||||
{
|
||||
delta = -(SIZE)(error / (long)cycle0) + 1;
|
||||
IB0.Box.corner.y += yincr0 * delta;
|
||||
yerror0 = (SIZE)(error + (long)cycle0 * (long)delta);
|
||||
}
|
||||
pr0->corner = IB0.Box.corner;
|
||||
}
|
||||
|
||||
start = (COUNT)cycle1 * (COUNT)(t0 - 1);
|
||||
time_error1 = start & ((1 << TIME_SHIFT) - 1);
|
||||
if ((start >>= (COUNT)TIME_SHIFT) > 0)
|
||||
{
|
||||
if ((error = (long)xerror1
|
||||
- (long)dx_1 * (long)start) > 0)
|
||||
xerror1 = (SIZE)error;
|
||||
else
|
||||
{
|
||||
delta = -(SIZE)(error / (long)cycle1) + 1;
|
||||
IB1.Box.corner.x += xincr1 * delta;
|
||||
xerror1 = (SIZE)(error + (long)cycle1 * (long)delta);
|
||||
}
|
||||
if ((error = (long)yerror1
|
||||
- (long)dy_1 * (long)start) > 0)
|
||||
yerror1 = (SIZE)error;
|
||||
else
|
||||
{
|
||||
delta = -(SIZE)(error / (long)cycle1) + 1;
|
||||
IB1.Box.corner.y += yincr1 * delta;
|
||||
yerror1 = (SIZE)(error + (long)cycle1 * (long)delta);
|
||||
}
|
||||
pr1->corner = IB1.Box.corner;
|
||||
}
|
||||
}
|
||||
|
||||
pControl0->last_time_val = pControl1->last_time_val = t0;
|
||||
do
|
||||
{
|
||||
++t0;
|
||||
if ((time_error0 += cycle0) >= (1 << TIME_SHIFT))
|
||||
{
|
||||
if ((xerror0 -= dx_0) <= 0)
|
||||
{
|
||||
IB0.Box.corner.x += xincr0;
|
||||
xerror0 += cycle0;
|
||||
}
|
||||
if ((yerror0 -= dy_0) <= 0)
|
||||
{
|
||||
IB0.Box.corner.y += yincr0;
|
||||
yerror0 += cycle0;
|
||||
}
|
||||
|
||||
check0 = TRUE;
|
||||
time_error0 -= (1 << TIME_SHIFT);
|
||||
}
|
||||
|
||||
if ((time_error1 += cycle1) >= (1 << TIME_SHIFT))
|
||||
{
|
||||
if ((xerror1 -= dx_1) <= 0)
|
||||
{
|
||||
IB1.Box.corner.x += xincr1;
|
||||
xerror1 += cycle1;
|
||||
}
|
||||
if ((yerror1 -= dy_1) <= 0)
|
||||
{
|
||||
IB1.Box.corner.y += yincr1;
|
||||
yerror1 += cycle1;
|
||||
}
|
||||
|
||||
check1 = TRUE;
|
||||
time_error1 -= (1 << TIME_SHIFT);
|
||||
}
|
||||
|
||||
if (check0 || check1)
|
||||
{ /* if check0 && check1, this may not be quite right --
|
||||
* if shapes had a pixel's separation to begin with
|
||||
* and both moved toward each other, you would actually
|
||||
* get a pixel overlap but since the last positions were
|
||||
* separated by a pixel, the shapes wouldn't be touching
|
||||
* each other.
|
||||
*/
|
||||
CheckFirstIntersection:
|
||||
if (BoxIntersect (&IB0.Box, &IB1.Box, &r_intersect)
|
||||
&& images_intersect (&IB0, &IB1, &r_intersect))
|
||||
return (t0);
|
||||
|
||||
if (check0)
|
||||
{
|
||||
pr0->corner = IB0.Box.corner;
|
||||
pControl0->last_time_val = t0;
|
||||
check0 = FALSE;
|
||||
}
|
||||
if (check1)
|
||||
{
|
||||
pr1->corner = IB1.Box.corner;
|
||||
pControl1->last_time_val = t0;
|
||||
check1 = FALSE;
|
||||
}
|
||||
}
|
||||
} while (t0 <= t1);
|
||||
|
||||
return ((TIME_VALUE)0);
|
||||
}
|
||||
|
||||
TIME_VALUE
|
||||
DrawablesIntersect (INTERSECT_CONTROL *pControl0,
|
||||
INTERSECT_CONTROL *pControl1, TIME_VALUE max_time_val)
|
||||
{
|
||||
SIZE dy;
|
||||
SIZE time_y_0, time_y_1;
|
||||
RECT r0, r1;
|
||||
FRAME FramePtr0, FramePtr1;
|
||||
|
||||
if (!ContextActive () || max_time_val == 0)
|
||||
return ((TIME_VALUE)0);
|
||||
else if (max_time_val > MAX_TIME_VALUE)
|
||||
max_time_val = MAX_TIME_VALUE;
|
||||
|
||||
pControl0->last_time_val = pControl1->last_time_val = 0;
|
||||
|
||||
r0.corner = pControl0->IntersectStamp.origin;
|
||||
r1.corner = pControl1->IntersectStamp.origin;
|
||||
|
||||
r0.extent.width = pControl0->EndPoint.x - r0.corner.x;
|
||||
r0.extent.height = pControl0->EndPoint.y - r0.corner.y;
|
||||
r1.extent.width = pControl1->EndPoint.x - r1.corner.x;
|
||||
r1.extent.height = pControl1->EndPoint.y - r1.corner.y;
|
||||
|
||||
FramePtr0 = pControl0->IntersectStamp.frame;
|
||||
if (FramePtr0 == 0)
|
||||
return(0);
|
||||
r0.corner.x -= FramePtr0->HotSpot.x;
|
||||
r0.corner.y -= FramePtr0->HotSpot.y;
|
||||
|
||||
FramePtr1 = pControl1->IntersectStamp.frame;
|
||||
if (FramePtr1 == 0)
|
||||
return(0);
|
||||
r1.corner.x -= FramePtr1->HotSpot.x;
|
||||
r1.corner.y -= FramePtr1->HotSpot.y;
|
||||
|
||||
dy = r1.corner.y - r0.corner.y;
|
||||
time_y_0 = dy - GetFrameHeight (FramePtr0) + 1;
|
||||
time_y_1 = dy + GetFrameHeight (FramePtr1) - 1;
|
||||
dy = r0.extent.height - r1.extent.height;
|
||||
|
||||
if ((time_y_0 <= 0 && time_y_1 >= 0)
|
||||
|| (time_y_0 > 0 && dy >= time_y_0)
|
||||
|| (time_y_1 < 0 && dy <= time_y_1))
|
||||
{
|
||||
SIZE dx;
|
||||
SIZE time_x_0, time_x_1;
|
||||
|
||||
dx = r1.corner.x - r0.corner.x;
|
||||
time_x_0 = dx - GetFrameWidth (FramePtr0) + 1;
|
||||
time_x_1 = dx + GetFrameWidth (FramePtr1) - 1;
|
||||
dx = r0.extent.width - r1.extent.width;
|
||||
|
||||
if ((time_x_0 <= 0 && time_x_1 >= 0)
|
||||
|| (time_x_0 > 0 && dx >= time_x_0)
|
||||
|| (time_x_1 < 0 && dx <= time_x_1))
|
||||
{
|
||||
TIME_VALUE intersect_time;
|
||||
|
||||
if (dx == 0 && dy == 0)
|
||||
time_y_0 = time_y_1 = 0;
|
||||
else
|
||||
{
|
||||
SIZE t;
|
||||
long time_beg, time_end, fract;
|
||||
|
||||
if (time_y_1 < 0)
|
||||
{
|
||||
t = time_y_0;
|
||||
time_y_0 = -time_y_1;
|
||||
time_y_1 = -t;
|
||||
}
|
||||
else if (time_y_0 <= 0)
|
||||
{
|
||||
if (dy < 0)
|
||||
time_y_1 = -time_y_0;
|
||||
time_y_0 = 0;
|
||||
}
|
||||
if (dy < 0)
|
||||
dy = -dy;
|
||||
if (dy < time_y_1)
|
||||
time_y_1 = dy;
|
||||
/* just to be safe, widen search area */
|
||||
--time_y_0;
|
||||
++time_y_1;
|
||||
|
||||
if (time_x_1 < 0)
|
||||
{
|
||||
t = time_x_0;
|
||||
time_x_0 = -time_x_1;
|
||||
time_x_1 = -t;
|
||||
}
|
||||
else if (time_x_0 <= 0)
|
||||
{
|
||||
if (dx < 0)
|
||||
time_x_1 = -time_x_0;
|
||||
time_x_0 = 0;
|
||||
}
|
||||
if (dx < 0)
|
||||
dx = -dx;
|
||||
if (dx < time_x_1)
|
||||
time_x_1 = dx;
|
||||
/* just to be safe, widen search area */
|
||||
--time_x_0;
|
||||
++time_x_1;
|
||||
|
||||
#ifdef DEBUG_INTERSEC
|
||||
log_add (log_Debug, "FramePtr0<%d, %d> --> <%d, %d>",
|
||||
GetFrameWidth (FramePtr0), GetFrameHeight (FramePtr0),
|
||||
r0.corner.x, r0.corner.y);
|
||||
log_add (log_Debug, "FramePtr1<%d, %d> --> <%d, %d>",
|
||||
GetFrameWidth (FramePtr1), GetFrameHeight (FramePtr1),
|
||||
r1.corner.x, r1.corner.y);
|
||||
log_add (log_Debug, "time_x(%d, %d)-%d, time_y(%d, %d)-%d",
|
||||
time_x_0, time_x_1, dx, time_y_0, time_y_1, dy);
|
||||
#endif /* DEBUG_INTERSEC */
|
||||
if (dx == 0)
|
||||
{
|
||||
time_beg = time_y_0;
|
||||
time_end = time_y_1;
|
||||
fract = dy;
|
||||
}
|
||||
else if (dy == 0)
|
||||
{
|
||||
time_beg = time_x_0;
|
||||
time_end = time_x_1;
|
||||
fract = dx;
|
||||
}
|
||||
else
|
||||
{
|
||||
long time_x, time_y;
|
||||
|
||||
time_x = (long)time_x_0 * (long)dy;
|
||||
time_y = (long)time_y_0 * (long)dx;
|
||||
time_beg = time_x < time_y ? time_y : time_x;
|
||||
|
||||
time_x = (long)time_x_1 * (long)dy;
|
||||
time_y = (long)time_y_1 * (long)dx;
|
||||
time_end = time_x > time_y ? time_y : time_x;
|
||||
|
||||
fract = (long)dx * (long)dy;
|
||||
}
|
||||
|
||||
if ((time_beg <<= TIME_SHIFT) < fract)
|
||||
time_y_0 = 0;
|
||||
else
|
||||
time_y_0 = (SIZE)(time_beg / fract);
|
||||
|
||||
if (time_end >= fract /* just in case of overflow */
|
||||
|| (time_end <<= TIME_SHIFT) >=
|
||||
fract * (long)max_time_val)
|
||||
time_y_1 = max_time_val - 1;
|
||||
else
|
||||
time_y_1 = (SIZE)((time_end + fract - 1) / fract) - 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_INTERSEC
|
||||
log_add (log_Debug, "start_time = %d, end_time = %d",
|
||||
time_y_0, time_y_1);
|
||||
#endif /* DEBUG_INTERSEC */
|
||||
if (time_y_0 <= time_y_1
|
||||
&& (intersect_time = frame_intersect (
|
||||
pControl0, &r0, pControl1, &r1,
|
||||
(TIME_VALUE)time_y_0, (TIME_VALUE)time_y_1)))
|
||||
{
|
||||
FramePtr0 = pControl0->IntersectStamp.frame;
|
||||
pControl0->EndPoint.x = r0.corner.x + FramePtr0->HotSpot.x;
|
||||
pControl0->EndPoint.y = r0.corner.y + FramePtr0->HotSpot.y;
|
||||
FramePtr1 = pControl1->IntersectStamp.frame;
|
||||
pControl1->EndPoint.x = r1.corner.x + FramePtr1->HotSpot.x;
|
||||
pControl1->EndPoint.y = r1.corner.y + FramePtr1->HotSpot.y;
|
||||
|
||||
return (intersect_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ((TIME_VALUE)0);
|
||||
}
|
||||
|
||||
65
project/jni/application/sc2/src/libs/graphics/loaddisp.c
Normal file
65
project/jni/application/sc2/src/libs/graphics/loaddisp.c
Normal file
@@ -0,0 +1,65 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libs/gfxlib.h"
|
||||
#include "libs/graphics/drawable.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
|
||||
// Reads a piece of screen into a passed FRAME or a newly created one
|
||||
DRAWABLE
|
||||
LoadDisplayPixmap (const RECT *area, FRAME frame)
|
||||
{
|
||||
// TODO: This should just return a FRAME instead of DRAWABLE
|
||||
DRAWABLE buffer = GetFrameParentDrawable (frame);
|
||||
COUNT index;
|
||||
|
||||
if (!buffer)
|
||||
{ // asked to create a new DRAWABLE instead
|
||||
buffer = CreateDrawable (WANT_PIXMAP | MAPPED_TO_DISPLAY,
|
||||
area->extent.width, area->extent.height, 1);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = GetFrameIndex (frame);
|
||||
}
|
||||
|
||||
frame = SetAbsFrameIndex (CaptureDrawable (buffer), index);
|
||||
|
||||
if (_CurFramePtr->Type != SCREEN_DRAWABLE
|
||||
|| frame->Type == SCREEN_DRAWABLE
|
||||
|| !(GetFrameParentDrawable (frame)->Flags & MAPPED_TO_DISPLAY))
|
||||
{
|
||||
log_add (log_Warning, "Unimplemented function activated: "
|
||||
"LoadDisplayPixmap()");
|
||||
}
|
||||
else
|
||||
{
|
||||
TFB_Image *img = frame->image;
|
||||
TFB_DrawScreen_CopyToImage (img, area, TFB_SCREEN_MAIN);
|
||||
}
|
||||
|
||||
ReleaseDrawable (frame);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
170
project/jni/application/sc2/src/libs/graphics/pixmap.c
Normal file
170
project/jni/application/sc2/src/libs/graphics/pixmap.c
Normal file
@@ -0,0 +1,170 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
DRAWABLE
|
||||
GetFrameParentDrawable (FRAME f)
|
||||
{
|
||||
if (f != NULL)
|
||||
{
|
||||
return f->parent;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FRAME
|
||||
CaptureDrawable (DRAWABLE DrawablePtr)
|
||||
{
|
||||
if (DrawablePtr)
|
||||
{
|
||||
return &DrawablePtr->Frame[0];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DRAWABLE
|
||||
ReleaseDrawable (FRAME FramePtr)
|
||||
{
|
||||
if (FramePtr != 0)
|
||||
{
|
||||
DRAWABLE Drawable;
|
||||
|
||||
Drawable = GetFrameParentDrawable (FramePtr);
|
||||
|
||||
return (Drawable);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
COUNT
|
||||
GetFrameCount (FRAME FramePtr)
|
||||
{
|
||||
DRAWABLE_DESC *DrawablePtr;
|
||||
|
||||
if (FramePtr == 0)
|
||||
return (0);
|
||||
|
||||
DrawablePtr = GetFrameParentDrawable (FramePtr);
|
||||
return DrawablePtr->MaxIndex + 1;
|
||||
}
|
||||
|
||||
COUNT
|
||||
GetFrameIndex (FRAME FramePtr)
|
||||
{
|
||||
if (FramePtr == 0)
|
||||
return (0);
|
||||
|
||||
return FramePtr->Index;
|
||||
}
|
||||
|
||||
FRAME
|
||||
SetAbsFrameIndex (FRAME FramePtr, COUNT FrameIndex)
|
||||
{
|
||||
if (FramePtr != 0)
|
||||
{
|
||||
DRAWABLE_DESC *DrawablePtr;
|
||||
|
||||
DrawablePtr = GetFrameParentDrawable (FramePtr);
|
||||
|
||||
FrameIndex = FrameIndex % (DrawablePtr->MaxIndex + 1);
|
||||
FramePtr = &DrawablePtr->Frame[FrameIndex];
|
||||
}
|
||||
|
||||
return FramePtr;
|
||||
}
|
||||
|
||||
FRAME
|
||||
SetRelFrameIndex (FRAME FramePtr, SIZE FrameOffs)
|
||||
{
|
||||
if (FramePtr != 0)
|
||||
{
|
||||
COUNT num_frames;
|
||||
DRAWABLE_DESC *DrawablePtr;
|
||||
|
||||
DrawablePtr = GetFrameParentDrawable (FramePtr);
|
||||
num_frames = DrawablePtr->MaxIndex + 1;
|
||||
if (FrameOffs < 0)
|
||||
{
|
||||
while ((FrameOffs += num_frames) < 0)
|
||||
;
|
||||
}
|
||||
|
||||
FrameOffs = ((SWORD)FramePtr->Index + FrameOffs) % num_frames;
|
||||
FramePtr = &DrawablePtr->Frame[FrameOffs];
|
||||
}
|
||||
|
||||
return FramePtr;
|
||||
}
|
||||
|
||||
FRAME
|
||||
SetEquFrameIndex (FRAME DstFramePtr, FRAME SrcFramePtr)
|
||||
{
|
||||
COUNT Index;
|
||||
|
||||
if (!DstFramePtr || !SrcFramePtr)
|
||||
return 0;
|
||||
|
||||
Index = GetFrameIndex (SrcFramePtr);
|
||||
#ifdef DEBUG
|
||||
{
|
||||
DRAWABLE_DESC *DrawablePtr = GetFrameParentDrawable (DstFramePtr);
|
||||
if (Index > DrawablePtr->MaxIndex)
|
||||
log_add (log_Debug, "SetEquFrameIndex: source index (%d) beyond "
|
||||
"destination range (%d)", (int)Index,
|
||||
(int)DrawablePtr->MaxIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
return SetAbsFrameIndex (DstFramePtr, Index);
|
||||
}
|
||||
|
||||
FRAME
|
||||
IncFrameIndex (FRAME FramePtr)
|
||||
{
|
||||
DRAWABLE_DESC *DrawablePtr;
|
||||
|
||||
if (FramePtr == 0)
|
||||
return (0);
|
||||
|
||||
DrawablePtr = GetFrameParentDrawable (FramePtr);
|
||||
if (FramePtr->Index < DrawablePtr->MaxIndex)
|
||||
return ++FramePtr;
|
||||
else
|
||||
return DrawablePtr->Frame;
|
||||
}
|
||||
|
||||
FRAME
|
||||
DecFrameIndex (FRAME FramePtr)
|
||||
{
|
||||
if (FramePtr == 0)
|
||||
return (0);
|
||||
|
||||
if (FramePtr->Index > 0)
|
||||
return --FramePtr;
|
||||
else
|
||||
{
|
||||
DRAWABLE_DESC *DrawablePtr;
|
||||
|
||||
DrawablePtr = GetFrameParentDrawable (FramePtr);
|
||||
return &DrawablePtr->Frame[DrawablePtr->MaxIndex];
|
||||
}
|
||||
}
|
||||
80
project/jni/application/sc2/src/libs/graphics/prim.h
Normal file
80
project/jni/application/sc2/src/libs/graphics/prim.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef _PRIM_H
|
||||
#define _PRIM_H
|
||||
|
||||
enum gfx_object
|
||||
{
|
||||
POINT_PRIM = 0,
|
||||
STAMP_PRIM,
|
||||
STAMPFILL_PRIM,
|
||||
LINE_PRIM,
|
||||
TEXT_PRIM,
|
||||
RECT_PRIM,
|
||||
RECTFILL_PRIM,
|
||||
|
||||
NUM_PRIMS
|
||||
};
|
||||
typedef BYTE GRAPHICS_PRIM;
|
||||
|
||||
typedef union
|
||||
{
|
||||
POINT Point;
|
||||
STAMP Stamp;
|
||||
LINE Line;
|
||||
TEXT Text;
|
||||
RECT Rect;
|
||||
} PRIM_DESC;
|
||||
|
||||
typedef DWORD PRIM_LINKS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PRIM_LINKS Links;
|
||||
GRAPHICS_PRIM Type;
|
||||
Color color;
|
||||
PRIM_DESC Object;
|
||||
} PRIMITIVE;
|
||||
|
||||
#define END_OF_LIST ((COUNT)0xFFFF)
|
||||
|
||||
#define GetPredLink(l) LOWORD(l)
|
||||
#define GetSuccLink(l) HIWORD(l)
|
||||
#define MakeLinks MAKE_DWORD
|
||||
#define SetPrimLinks(pPrim,p,s) ((pPrim)->Links = MakeLinks (p, s))
|
||||
#define GetPrimLinks(pPrim) ((pPrim)->Links)
|
||||
#define SetPrimType(pPrim,t) ((pPrim)->Type = t)
|
||||
#define GetPrimType(pPrim) ((pPrim)->Type)
|
||||
#define SetPrimColor(pPrim,c) ((pPrim)->color = c)
|
||||
#define GetPrimColor(pPrim) ((pPrim)->color)
|
||||
|
||||
static inline void
|
||||
SetPrimNextLink (PRIMITIVE *pPrim, COUNT Link)
|
||||
{
|
||||
SetPrimLinks (pPrim, END_OF_LIST, Link);
|
||||
}
|
||||
|
||||
|
||||
static inline COUNT
|
||||
GetPrimNextLink (PRIMITIVE *pPrim)
|
||||
{
|
||||
return GetSuccLink (GetPrimLinks (pPrim));
|
||||
}
|
||||
|
||||
|
||||
#endif /* PRIM_H */
|
||||
|
||||
|
||||
54
project/jni/application/sc2/src/libs/graphics/resgfx.c
Normal file
54
project/jni/application/sc2/src/libs/graphics/resgfx.c
Normal file
@@ -0,0 +1,54 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gfxintrn.h"
|
||||
|
||||
static void
|
||||
GetCelFileData (const char *pathname, RESOURCE_DATA *resdata)
|
||||
{
|
||||
resdata->ptr = LoadResourceFromPath (pathname, _GetCelData);
|
||||
}
|
||||
|
||||
static void
|
||||
GetFontFileData (const char *pathname, RESOURCE_DATA *resdata)
|
||||
{
|
||||
resdata->ptr = LoadResourceFromPath (pathname, _GetFontData);
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
InstallGraphicResTypes (void)
|
||||
{
|
||||
InstallResTypeVectors ("GFXRES", GetCelFileData, _ReleaseCelData, NULL);
|
||||
InstallResTypeVectors ("FONTRES", GetFontFileData, _ReleaseFontData, NULL);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* Needs to be void * because it could be either a DRAWABLE or a FONT. */
|
||||
void *
|
||||
LoadGraphicInstance (RESOURCE res)
|
||||
{
|
||||
void *hData;
|
||||
|
||||
hData = res_GetResource (res);
|
||||
if (hData)
|
||||
res_DetachResource (res);
|
||||
|
||||
return (hData);
|
||||
}
|
||||
|
||||
260
project/jni/application/sc2/src/libs/graphics/sdl/2xscalers.c
Normal file
260
project/jni/application/sc2/src/libs/graphics/sdl/2xscalers.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
|
||||
|
||||
// Scaler function lookup table
|
||||
//
|
||||
const Scale_FuncDef_t
|
||||
Scale_C_Functions[] =
|
||||
{
|
||||
{TFB_GFXFLAGS_SCALE_BILINEAR, Scale_BilinearFilter},
|
||||
{TFB_GFXFLAGS_SCALE_BIADAPT, Scale_BiAdaptFilter},
|
||||
{TFB_GFXFLAGS_SCALE_BIADAPTADV, Scale_BiAdaptAdvFilter},
|
||||
{TFB_GFXFLAGS_SCALE_TRISCAN, Scale_TriScanFilter},
|
||||
{TFB_GFXFLAGS_SCALE_HQXX, Scale_HqFilter},
|
||||
// Default
|
||||
{0, Scale_Nearest}
|
||||
};
|
||||
|
||||
// See
|
||||
// nearest2x.c -- Nearest Neighboor scaling
|
||||
// bilinear2x.c -- Bilinear scaling
|
||||
// biadv2x.c -- Advanced Biadapt scaling
|
||||
// triscan2x.c -- Triscan scaling
|
||||
|
||||
// Biadapt scaling to 2x
|
||||
void
|
||||
SCALE_(BiAdaptFilter) (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r)
|
||||
{
|
||||
int x, y;
|
||||
const int w = src->w, h = src->h;
|
||||
int xend, yend;
|
||||
int dsrc, ddst;
|
||||
SDL_Rect *region = r;
|
||||
SDL_Rect limits;
|
||||
SDL_PixelFormat *fmt = dst->format;
|
||||
const int sp = src->pitch, dp = dst->pitch;
|
||||
const int bpp = fmt->BytesPerPixel;
|
||||
const int slen = sp / bpp, dlen = dp / bpp;
|
||||
Uint32 *src_p = (Uint32 *)src->pixels;
|
||||
Uint32 *dst_p = (Uint32 *)dst->pixels;
|
||||
Uint32 pixval_tl, pixval_tr, pixval_bl, pixval_br;
|
||||
|
||||
// these macros are for clarity; they make the current pixel (0,0)
|
||||
// and allow to access pixels in all directions
|
||||
#define SRC(x, y) (src_p + (x) + ((y) * slen))
|
||||
|
||||
SCALE_(PlatInit) ();
|
||||
|
||||
// expand updated region if necessary
|
||||
// pixels neighbooring the updated region may
|
||||
// change as a result of updates
|
||||
limits.x = 0;
|
||||
limits.y = 0;
|
||||
limits.w = src->w;
|
||||
limits.h = src->h;
|
||||
Scale_ExpandRect (region, 2, &limits);
|
||||
|
||||
xend = region->x + region->w;
|
||||
yend = region->y + region->h;
|
||||
dsrc = slen - region->w;
|
||||
ddst = (dlen - region->w) * 2;
|
||||
|
||||
// move ptrs to the first updated pixel
|
||||
src_p += slen * region->y + region->x;
|
||||
dst_p += (dlen * region->y + region->x) * 2;
|
||||
|
||||
for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc)
|
||||
{
|
||||
for (x = region->x; x < xend; ++x, ++src_p, ++dst_p)
|
||||
{
|
||||
pixval_tl = SCALE_GETPIX (SRC (0, 0));
|
||||
|
||||
SCALE_SETPIX (dst_p, pixval_tl);
|
||||
|
||||
if (y + 1 < h)
|
||||
{
|
||||
// check pixel below the current one
|
||||
pixval_bl = SCALE_GETPIX (SRC (0, 1));
|
||||
|
||||
if (pixval_tl == pixval_bl)
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tl);
|
||||
else
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
pixval_tl, pixval_bl)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// last pixel in column - propagate
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tl);
|
||||
pixval_bl = pixval_tl;
|
||||
}
|
||||
++dst_p;
|
||||
|
||||
if (x + 1 >= w)
|
||||
{
|
||||
// last pixel in row - propagate
|
||||
SCALE_SETPIX (dst_p, pixval_tl);
|
||||
|
||||
if (pixval_tl == pixval_bl)
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tl);
|
||||
else
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
pixval_tl, pixval_bl)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// check pixel to the right from the current one
|
||||
pixval_tr = SCALE_GETPIX (SRC (1, 0));
|
||||
|
||||
if (pixval_tl == pixval_tr)
|
||||
SCALE_SETPIX (dst_p, pixval_tr);
|
||||
else
|
||||
SCALE_SETPIX (dst_p, Scale_Blend_11 (
|
||||
pixval_tl, pixval_tr)
|
||||
);
|
||||
|
||||
if (y + 1 >= h)
|
||||
{
|
||||
// last pixel in column - propagate
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tl);
|
||||
continue;
|
||||
}
|
||||
|
||||
// check pixel to the bottom-right
|
||||
pixval_br = SCALE_GETPIX (SRC (1, 1));
|
||||
|
||||
if (pixval_tl == pixval_br && pixval_tr == pixval_bl)
|
||||
{
|
||||
int cl, cr;
|
||||
Uint32 clr;
|
||||
|
||||
if (pixval_tl == pixval_tr)
|
||||
{
|
||||
// all 4 are equal - propagate
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tl);
|
||||
continue;
|
||||
}
|
||||
|
||||
// both pairs are equal, have to resolve the pixel
|
||||
// race; we try detecting which color is
|
||||
// the background by looking for a line or an edge
|
||||
// examine 8 pixels surrounding the current quad
|
||||
|
||||
cl = cr = 1;
|
||||
|
||||
if (x > 0)
|
||||
{
|
||||
clr = SCALE_GETPIX (SRC (-1, 0));
|
||||
if (clr == pixval_tl)
|
||||
cl++;
|
||||
else if (clr == pixval_tr)
|
||||
cr++;
|
||||
|
||||
clr = SCALE_GETPIX (SRC (-1, 1));
|
||||
if (clr == pixval_tl)
|
||||
cl++;
|
||||
else if (clr == pixval_tr)
|
||||
cr++;
|
||||
}
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
clr = SCALE_GETPIX (SRC (0, -1));
|
||||
if (clr == pixval_tl)
|
||||
cl++;
|
||||
else if (clr == pixval_tr)
|
||||
cr++;
|
||||
|
||||
clr = SCALE_GETPIX (SRC (1, -1));
|
||||
if (clr == pixval_tl)
|
||||
cl++;
|
||||
else if (clr == pixval_tr)
|
||||
cr++;
|
||||
}
|
||||
|
||||
if (x + 2 < w)
|
||||
{
|
||||
clr = SCALE_GETPIX (SRC (2, 0));
|
||||
if (clr == pixval_tl)
|
||||
cl++;
|
||||
else if (clr == pixval_tr)
|
||||
cr++;
|
||||
|
||||
clr = SCALE_GETPIX (SRC (2, 1));
|
||||
if (clr == pixval_tl)
|
||||
cl++;
|
||||
else if (clr == pixval_tr)
|
||||
cr++;
|
||||
}
|
||||
|
||||
if (y + 2 < h)
|
||||
{
|
||||
clr = SCALE_GETPIX (SRC (0, 2));
|
||||
if (clr == pixval_tl)
|
||||
cl++;
|
||||
else if (clr == pixval_tr)
|
||||
cr++;
|
||||
|
||||
clr = SCALE_GETPIX (SRC (1, 2));
|
||||
if (clr == pixval_tl)
|
||||
cl++;
|
||||
else if (clr == pixval_tr)
|
||||
cr++;
|
||||
}
|
||||
|
||||
// least count wins
|
||||
if (cl > cr)
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tr);
|
||||
else if (cr > cl)
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tl);
|
||||
else
|
||||
SCALE_SETPIX (dst_p + dlen,
|
||||
Scale_Blend_11 (pixval_tl, pixval_tr));
|
||||
}
|
||||
else if (pixval_tl == pixval_br)
|
||||
{
|
||||
// main diagonal is same color
|
||||
// use its value
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tl);
|
||||
}
|
||||
else if (pixval_tr == pixval_bl)
|
||||
{
|
||||
// 2nd diagonal is same color
|
||||
// use its value
|
||||
SCALE_SETPIX (dst_p + dlen, pixval_tr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// blend all 4
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_1111 (
|
||||
pixval_tl, pixval_bl, pixval_tr, pixval_br
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCALE_(PlatDone) ();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _2XSCALERS_H_
|
||||
#define _2XSCALERS_H_
|
||||
|
||||
void Scale_Nearest (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_BilinearFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_BiAdaptFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_BiAdaptAdvFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_TriScanFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_HqFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
|
||||
extern const Scale_FuncDef_t Scale_C_Functions[];
|
||||
|
||||
|
||||
#endif /* _2XSCALERS_H_ */
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/platform.h"
|
||||
|
||||
#if defined(MMX_ASM)
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
#include "2xscalers_mmx.h"
|
||||
|
||||
// 3DNow! name for all functions
|
||||
#undef SCALE_
|
||||
#define SCALE_(name) Scale ## _3DNow_ ## name
|
||||
|
||||
// Tell them which opcodes we want to support
|
||||
#undef USE_MOVNTQ
|
||||
#define USE_PREFETCH AMD_PREFETCH
|
||||
#undef USE_PSADBW
|
||||
// Bring in inline asm functions
|
||||
#include "scalemmx.h"
|
||||
|
||||
|
||||
// Scaler function lookup table
|
||||
//
|
||||
const Scale_FuncDef_t
|
||||
Scale_3DNow_Functions[] =
|
||||
{
|
||||
{TFB_GFXFLAGS_SCALE_BILINEAR, Scale_3DNow_BilinearFilter},
|
||||
{TFB_GFXFLAGS_SCALE_BIADAPT, Scale_BiAdaptFilter},
|
||||
{TFB_GFXFLAGS_SCALE_BIADAPTADV, Scale_MMX_BiAdaptAdvFilter},
|
||||
{TFB_GFXFLAGS_SCALE_TRISCAN, Scale_MMX_TriScanFilter},
|
||||
{TFB_GFXFLAGS_SCALE_HQXX, Scale_MMX_HqFilter},
|
||||
// Default
|
||||
{0, Scale_3DNow_Nearest}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
Scale_3DNow_PrepPlatform (const SDL_PixelFormat* fmt)
|
||||
{
|
||||
Scale_MMX_PrepPlatform (fmt);
|
||||
}
|
||||
|
||||
// Nearest Neighbor scaling to 2x
|
||||
// void Scale_3DNow_Nearest (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "nearest2x.c"
|
||||
|
||||
|
||||
// Bilinear scaling to 2x
|
||||
// void Scale_3DNow_BilinearFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "bilinear2x.c"
|
||||
|
||||
|
||||
#if 0 && NO_IMPROVEMENT
|
||||
|
||||
// Advanced Biadapt scaling to 2x
|
||||
// void Scale_3DNow_BiAdaptAdvFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "biadv2x.c"
|
||||
|
||||
|
||||
// Triscan scaling to 2x
|
||||
// derivative of scale2x -- scale2x.sf.net
|
||||
// void Scale_3DNow_TriScanFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "triscan2x.c"
|
||||
|
||||
// Hq2x scaling
|
||||
// (adapted from 'hq2x' by Maxim Stepin -- www.hiend3d.com/hq2x.html)
|
||||
// void Scale_3DNow_HqFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "hq2x.c"
|
||||
|
||||
#endif /* NO_IMPROVEMENT */
|
||||
|
||||
#endif /* MMX_ASM */
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/platform.h"
|
||||
|
||||
#if defined(MMX_ASM)
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
#include "2xscalers_mmx.h"
|
||||
|
||||
// MMX name for all functions
|
||||
#undef SCALE_
|
||||
#define SCALE_(name) Scale ## _MMX_ ## name
|
||||
|
||||
// Tell them which opcodes we want to support
|
||||
#undef USE_MOVNTQ
|
||||
#undef USE_PREFETCH
|
||||
#undef USE_PSADBW
|
||||
// And Bring in inline asm functions
|
||||
#include "scalemmx.h"
|
||||
|
||||
|
||||
// Scaler function lookup table
|
||||
//
|
||||
const Scale_FuncDef_t
|
||||
Scale_MMX_Functions[] =
|
||||
{
|
||||
{TFB_GFXFLAGS_SCALE_BILINEAR, Scale_MMX_BilinearFilter},
|
||||
{TFB_GFXFLAGS_SCALE_BIADAPT, Scale_BiAdaptFilter},
|
||||
{TFB_GFXFLAGS_SCALE_BIADAPTADV, Scale_MMX_BiAdaptAdvFilter},
|
||||
{TFB_GFXFLAGS_SCALE_TRISCAN, Scale_MMX_TriScanFilter},
|
||||
{TFB_GFXFLAGS_SCALE_HQXX, Scale_MMX_HqFilter},
|
||||
// Default
|
||||
{0, Scale_MMX_Nearest}
|
||||
};
|
||||
|
||||
// MMX transformation multipliers
|
||||
Uint64 mmx_888to555_mult;
|
||||
Uint64 mmx_Y_mult;
|
||||
Uint64 mmx_U_mult;
|
||||
Uint64 mmx_V_mult;
|
||||
// Uint64 mmx_YUV_threshold = 0x00300706; original hq2x threshold
|
||||
//Uint64 mmx_YUV_threshold = 0x0030100e;
|
||||
Uint64 mmx_YUV_threshold = 0x0040120c;
|
||||
|
||||
void
|
||||
Scale_MMX_PrepPlatform (const SDL_PixelFormat* fmt)
|
||||
{
|
||||
// prepare the channel-shuffle multiplier
|
||||
mmx_888to555_mult = ((Uint64)0x0400) << (fmt->Rshift * 2)
|
||||
| ((Uint64)0x0020) << (fmt->Gshift * 2)
|
||||
| ((Uint64)0x0001) << (fmt->Bshift * 2);
|
||||
|
||||
// prepare the RGB->YUV multipliers
|
||||
mmx_Y_mult = ((Uint64)(uint16)YUV_matrix[YUV_XFORM_R][YUV_XFORM_Y])
|
||||
<< (fmt->Rshift * 2)
|
||||
| ((Uint64)(uint16)YUV_matrix[YUV_XFORM_G][YUV_XFORM_Y])
|
||||
<< (fmt->Gshift * 2)
|
||||
| ((Uint64)(uint16)YUV_matrix[YUV_XFORM_B][YUV_XFORM_Y])
|
||||
<< (fmt->Bshift * 2);
|
||||
|
||||
mmx_U_mult = ((Uint64)(uint16)YUV_matrix[YUV_XFORM_R][YUV_XFORM_U])
|
||||
<< (fmt->Rshift * 2)
|
||||
| ((Uint64)(uint16)YUV_matrix[YUV_XFORM_G][YUV_XFORM_U])
|
||||
<< (fmt->Gshift * 2)
|
||||
| ((Uint64)(uint16)YUV_matrix[YUV_XFORM_B][YUV_XFORM_U])
|
||||
<< (fmt->Bshift * 2);
|
||||
|
||||
mmx_V_mult = ((Uint64)(uint16)YUV_matrix[YUV_XFORM_R][YUV_XFORM_V])
|
||||
<< (fmt->Rshift * 2)
|
||||
| ((Uint64)(uint16)YUV_matrix[YUV_XFORM_G][YUV_XFORM_V])
|
||||
<< (fmt->Gshift * 2)
|
||||
| ((Uint64)(uint16)YUV_matrix[YUV_XFORM_B][YUV_XFORM_V])
|
||||
<< (fmt->Bshift * 2);
|
||||
|
||||
mmx_YUV_threshold = (SCALE_DIFFYUV_TY << 16) | (SCALE_DIFFYUV_TU << 8)
|
||||
| SCALE_DIFFYUV_TV;
|
||||
}
|
||||
|
||||
|
||||
// Nearest Neighbor scaling to 2x
|
||||
// void Scale_MMX_Nearest (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "nearest2x.c"
|
||||
|
||||
|
||||
// Bilinear scaling to 2x
|
||||
// void Scale_MMX_BilinearFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "bilinear2x.c"
|
||||
|
||||
|
||||
// Advanced Biadapt scaling to 2x
|
||||
// void Scale_MMX_BiAdaptAdvFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "biadv2x.c"
|
||||
|
||||
|
||||
// Triscan scaling to 2x
|
||||
// derivative of 'scale2x' -- scale2x.sf.net
|
||||
// void Scale_MMX_TriScanFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "triscan2x.c"
|
||||
|
||||
// Hq2x scaling
|
||||
// (adapted from 'hq2x' by Maxim Stepin -- www.hiend3d.com/hq2x.html)
|
||||
// void Scale_MMX_HqFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "hq2x.c"
|
||||
|
||||
|
||||
#endif /* MMX_ASM */
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _2XSCALERS_MMX_H_
|
||||
#define _2XSCALERS_MMX_H_
|
||||
|
||||
// MMX versions
|
||||
void Scale_MMX_PrepPlatform (const SDL_PixelFormat* fmt);
|
||||
|
||||
void Scale_MMX_Nearest (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_MMX_BilinearFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_MMX_BiAdaptAdvFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_MMX_TriScanFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_MMX_HqFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
|
||||
extern const Scale_FuncDef_t Scale_MMX_Functions[];
|
||||
|
||||
|
||||
// SSE (Intel)/MMX Ext (Athlon) versions
|
||||
void Scale_SSE_PrepPlatform (const SDL_PixelFormat* fmt);
|
||||
|
||||
void Scale_SSE_Nearest (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_SSE_BilinearFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_SSE_BiAdaptAdvFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_SSE_TriScanFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_SSE_HqFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
|
||||
extern const Scale_FuncDef_t Scale_SSE_Functions[];
|
||||
|
||||
|
||||
// 3DNow (AMD K6/Athlon) versions
|
||||
void Scale_3DNow_PrepPlatform (const SDL_PixelFormat* fmt);
|
||||
|
||||
void Scale_3DNow_Nearest (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_3DNow_BilinearFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_3DNow_BiAdaptAdvFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_3DNow_TriScanFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
void Scale_3DNow_HqFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r);
|
||||
|
||||
extern const Scale_FuncDef_t Scale_3DNow_Functions[];
|
||||
|
||||
|
||||
#endif /* _2XSCALERS_MMX_H_ */
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/platform.h"
|
||||
|
||||
#if defined(MMX_ASM)
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
#include "2xscalers_mmx.h"
|
||||
|
||||
// SSE name for all functions
|
||||
#undef SCALE_
|
||||
#define SCALE_(name) Scale ## _SSE_ ## name
|
||||
|
||||
// Tell them which opcodes we want to support
|
||||
#define USE_MOVNTQ
|
||||
#define USE_PREFETCH INTEL_PREFETCH
|
||||
#define USE_PSADBW
|
||||
// Bring in inline asm functions
|
||||
#include "scalemmx.h"
|
||||
|
||||
|
||||
// Scaler function lookup table
|
||||
//
|
||||
const Scale_FuncDef_t
|
||||
Scale_SSE_Functions[] =
|
||||
{
|
||||
{TFB_GFXFLAGS_SCALE_BILINEAR, Scale_SSE_BilinearFilter},
|
||||
{TFB_GFXFLAGS_SCALE_BIADAPT, Scale_BiAdaptFilter},
|
||||
{TFB_GFXFLAGS_SCALE_BIADAPTADV, Scale_SSE_BiAdaptAdvFilter},
|
||||
{TFB_GFXFLAGS_SCALE_TRISCAN, Scale_SSE_TriScanFilter},
|
||||
{TFB_GFXFLAGS_SCALE_HQXX, Scale_MMX_HqFilter},
|
||||
// Default
|
||||
{0, Scale_SSE_Nearest}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
Scale_SSE_PrepPlatform (const SDL_PixelFormat* fmt)
|
||||
{
|
||||
Scale_MMX_PrepPlatform (fmt);
|
||||
}
|
||||
|
||||
// Nearest Neighbor scaling to 2x
|
||||
// void Scale_SSE_Nearest (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "nearest2x.c"
|
||||
|
||||
|
||||
// Bilinear scaling to 2x
|
||||
// void Scale_SSE_BilinearFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "bilinear2x.c"
|
||||
|
||||
|
||||
// Advanced Biadapt scaling to 2x
|
||||
// void Scale_SSE_BiAdaptAdvFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "biadv2x.c"
|
||||
|
||||
|
||||
// Triscan scaling to 2x
|
||||
// derivative of scale2x -- scale2x.sf.net
|
||||
// void Scale_SSE_TriScanFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "triscan2x.c"
|
||||
|
||||
#if 0 && NO_IMPROVEMENT
|
||||
// Hq2x scaling
|
||||
// (adapted from 'hq2x' by Maxim Stepin -- www.hiend3d.com/hq2x.html)
|
||||
// void Scale_SSE_HqFilter (SDL_Surface *src,
|
||||
// SDL_Surface *dst, SDL_Rect *r)
|
||||
|
||||
#include "hq2x.c"
|
||||
#endif
|
||||
|
||||
#endif /* MMX_ASM */
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
uqm_CFILES="opengl.c palette.c primitives.c pure.c sdl_common.c
|
||||
scalers.c 2xscalers.c
|
||||
2xscalers_mmx.c 2xscalers_sse.c 2xscalers_3dnow.c
|
||||
nearest2x.c bilinear2x.c biadv2x.c triscan2x.c hq2x.c
|
||||
canvas.c sdluio.c rotozoom.c"
|
||||
532
project/jni/application/sc2/src/libs/graphics/sdl/biadv2x.c
Normal file
532
project/jni/application/sc2/src/libs/graphics/sdl/biadv2x.c
Normal file
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Portions Copyright (C) 2003-2005 Alex Volkov (codepro@usa.net)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Core algorithm of the Advanced BiAdaptive screen scaler
|
||||
// Template
|
||||
// When this file is built standalone is produces a plain C version
|
||||
// Also #included by 2xscalers_mmx.c for an MMX version
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
|
||||
|
||||
// Advanced biadapt scaling to 2x
|
||||
// The name expands to either
|
||||
// Scale_BiAdaptAdvFilter (for plain C) or
|
||||
// Scale_MMX_BiAdaptAdvFilter (for MMX)
|
||||
// [others when platforms are added]
|
||||
void
|
||||
SCALE_(BiAdaptAdvFilter) (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r)
|
||||
{
|
||||
int x, y;
|
||||
const int w = src->w, h = src->h;
|
||||
int xend, yend;
|
||||
int dsrc, ddst;
|
||||
SDL_Rect *region = r;
|
||||
SDL_Rect limits;
|
||||
SDL_PixelFormat *fmt = dst->format;
|
||||
const int sp = src->pitch, dp = dst->pitch;
|
||||
const int bpp = fmt->BytesPerPixel;
|
||||
const int slen = sp / bpp, dlen = dp / bpp;
|
||||
// for clarity purposes, the 'pixels' array here is transposed
|
||||
Uint32 pixels[4][4];
|
||||
static int resolve_coord[][2] =
|
||||
{
|
||||
{0, -1}, {1, -1}, { 2, 0}, { 2, 1},
|
||||
{1, 2}, {0, 2}, {-1, 1}, {-1, 0},
|
||||
{100, 100} // term
|
||||
};
|
||||
Uint32 *src_p = (Uint32 *)src->pixels;
|
||||
Uint32 *dst_p = (Uint32 *)dst->pixels;
|
||||
|
||||
// these macros are for clarity; they make the current pixel (0,0)
|
||||
// and allow to access pixels in all directions
|
||||
#define PIX(x, y) (pixels[1 + (x)][1 + (y)])
|
||||
#define SRC(x, y) (src_p + (x) + ((y) * slen))
|
||||
// commonly used operations, for clarity also
|
||||
// others are defined at their respective bpp levels
|
||||
#define BIADAPT_RGBHIGH 8000
|
||||
#define BIADAPT_YUVLOW 30
|
||||
#define BIADAPT_YUVMED 70
|
||||
#define BIADAPT_YUVHIGH 130
|
||||
|
||||
// high tolerance pixel comparison
|
||||
#define BIADAPT_CMPRGB_HIGH(p1, p2) \
|
||||
(p1 == p2 || SCALE_CMPRGB (p1, p2) <= BIADAPT_RGBHIGH)
|
||||
|
||||
// low tolerance pixel comparison
|
||||
#define BIADAPT_CMPYUV_LOW(p1, p2) \
|
||||
(p1 == p2 || SCALE_CMPYUV (p1, p2, BIADAPT_YUVLOW))
|
||||
// medium tolerance pixel comparison
|
||||
#define BIADAPT_CMPYUV_MED(p1, p2) \
|
||||
(p1 == p2 || SCALE_CMPYUV (p1, p2, BIADAPT_YUVMED))
|
||||
// high tolerance pixel comparison
|
||||
#define BIADAPT_CMPYUV_HIGH(p1, p2) \
|
||||
(p1 == p2 || SCALE_CMPYUV (p1, p2, BIADAPT_YUVHIGH))
|
||||
|
||||
SCALE_(PlatInit) ();
|
||||
|
||||
// expand updated region if necessary
|
||||
// pixels neighbooring the updated region may
|
||||
// change as a result of updates
|
||||
limits.x = 0;
|
||||
limits.y = 0;
|
||||
limits.w = src->w;
|
||||
limits.h = src->h;
|
||||
Scale_ExpandRect (region, 2, &limits);
|
||||
|
||||
xend = region->x + region->w;
|
||||
yend = region->y + region->h;
|
||||
dsrc = slen - region->w;
|
||||
ddst = (dlen - region->w) * 2;
|
||||
|
||||
#define SCALE_GETPIX(p) ( *(Uint32 *)(p) )
|
||||
#define SCALE_SETPIX(p, c) ( *(Uint32 *)(p) = (c) )
|
||||
|
||||
// move ptrs to the first updated pixel
|
||||
src_p += slen * region->y + region->x;
|
||||
dst_p += (dlen * region->y + region->x) * 2;
|
||||
|
||||
for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc)
|
||||
{
|
||||
for (x = region->x; x < xend; ++x, ++src_p, ++dst_p)
|
||||
{
|
||||
// pixel equality counter
|
||||
int cmatch;
|
||||
|
||||
// most pixels will fall into 'all 4 equal'
|
||||
// pattern, so we check it first
|
||||
cmatch = 0;
|
||||
|
||||
PIX (0, 0) = SCALE_GETPIX (SRC (0, 0));
|
||||
|
||||
SCALE_SETPIX (dst_p, PIX (0, 0));
|
||||
|
||||
if (y + 1 < h)
|
||||
{
|
||||
// check pixel below the current one
|
||||
PIX (0, 1) = SCALE_GETPIX (SRC (0, 1));
|
||||
|
||||
if (PIX (0, 0) == PIX (0, 1))
|
||||
{
|
||||
SCALE_SETPIX (dst_p + dlen, PIX (0, 0));
|
||||
cmatch |= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// last pixel in column - propagate
|
||||
PIX (0, 1) = PIX (0, 0);
|
||||
SCALE_SETPIX (dst_p + dlen, PIX (0, 0));
|
||||
cmatch |= 1;
|
||||
|
||||
}
|
||||
|
||||
if (x + 1 < w)
|
||||
{
|
||||
// check pixel to the right from the current one
|
||||
PIX (1, 0) = SCALE_GETPIX (SRC (1, 0));
|
||||
|
||||
if (PIX (0, 0) == PIX (1, 0))
|
||||
{
|
||||
SCALE_SETPIX (dst_p + 1, PIX (0, 0));
|
||||
cmatch |= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// last pixel in row - propagate
|
||||
PIX (1, 0) = PIX (0, 0);
|
||||
SCALE_SETPIX (dst_p + 1, PIX (0, 0));
|
||||
cmatch |= 2;
|
||||
}
|
||||
|
||||
if (cmatch == 3)
|
||||
{
|
||||
if (y + 1 >= h || x + 1 >= w)
|
||||
{
|
||||
// last pixel in row/column and nearest
|
||||
// neighboor is identical
|
||||
dst_p++;
|
||||
SCALE_SETPIX (dst_p + dlen, PIX (0, 0));
|
||||
continue;
|
||||
}
|
||||
|
||||
// check pixel to the bottom-right
|
||||
PIX (1, 1) = SCALE_GETPIX (SRC (1, 1));
|
||||
|
||||
if (PIX (0, 0) == PIX (1, 1))
|
||||
{
|
||||
// all 4 are equal - propagate
|
||||
dst_p++;
|
||||
SCALE_SETPIX (dst_p + dlen, PIX (0, 0));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// some neighboors are different, lets check them
|
||||
|
||||
if (x > 0)
|
||||
PIX (-1, 0) = SCALE_GETPIX (SRC (-1, 0));
|
||||
else
|
||||
PIX (-1, 0) = PIX (0, 0);
|
||||
|
||||
if (x + 2 < w)
|
||||
PIX (2, 0) = SCALE_GETPIX (SRC (2, 0));
|
||||
else
|
||||
PIX (2, 0) = PIX (1, 0);
|
||||
|
||||
if (y + 1 < h)
|
||||
{
|
||||
if (x > 0)
|
||||
PIX (-1, 1) = SCALE_GETPIX (SRC (-1, 1));
|
||||
else
|
||||
PIX (-1, 1) = PIX (0, 1);
|
||||
|
||||
if (x + 2 < w)
|
||||
{
|
||||
PIX (1, 1) = SCALE_GETPIX (SRC (1, 1));
|
||||
PIX (2, 1) = SCALE_GETPIX (SRC (2, 1));
|
||||
}
|
||||
else if (x + 1 < w)
|
||||
{
|
||||
PIX (1, 1) = SCALE_GETPIX (SRC (1, 1));
|
||||
PIX (2, 1) = PIX (1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
PIX (1, 1) = PIX (0, 1);
|
||||
PIX (2, 1) = PIX (0, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// last pixel in column
|
||||
PIX (-1, 1) = PIX (-1, 0);
|
||||
PIX (1, 1) = PIX (1, 0);
|
||||
PIX (2, 1) = PIX (2, 0);
|
||||
}
|
||||
|
||||
if (y + 2 < h)
|
||||
{
|
||||
PIX (0, 2) = SCALE_GETPIX (SRC (0, 2));
|
||||
|
||||
if (x > 0)
|
||||
PIX (-1, 2) = SCALE_GETPIX (SRC (-1, 2));
|
||||
else
|
||||
PIX (-1, 2) = PIX (0, 2);
|
||||
|
||||
if (x + 2 < w)
|
||||
{
|
||||
PIX (1, 2) = SCALE_GETPIX (SRC (1, 2));
|
||||
PIX (2, 2) = SCALE_GETPIX (SRC (2, 2));
|
||||
}
|
||||
else if (x + 1 < w)
|
||||
{
|
||||
PIX (1, 2) = SCALE_GETPIX (SRC (1, 2));
|
||||
PIX (2, 2) = PIX (1, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
PIX (1, 2) = PIX (0, 2);
|
||||
PIX (2, 2) = PIX (0, 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// last pixel in column
|
||||
PIX (-1, 2) = PIX (-1, 1);
|
||||
PIX (0, 2) = PIX (0, 1);
|
||||
PIX (1, 2) = PIX (1, 1);
|
||||
PIX (2, 2) = PIX (2, 1);
|
||||
}
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
PIX (0, -1) = SCALE_GETPIX (SRC (0, -1));
|
||||
|
||||
if (x > 0)
|
||||
PIX (-1, -1) = SCALE_GETPIX (SRC (-1, -1));
|
||||
else
|
||||
PIX (-1, -1) = PIX (0, -1);
|
||||
|
||||
if (x + 2 < w)
|
||||
{
|
||||
PIX (1, -1) = SCALE_GETPIX (SRC (1, -1));
|
||||
PIX (2, -1) = SCALE_GETPIX (SRC (2, -1));
|
||||
}
|
||||
else if (x + 1 < w)
|
||||
{
|
||||
PIX (1, -1) = SCALE_GETPIX (SRC (1, -1));
|
||||
PIX (2, -1) = PIX (1, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
PIX (1, -1) = PIX (0, -1);
|
||||
PIX (2, -1) = PIX (0, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PIX (-1, -1) = PIX (-1, 0);
|
||||
PIX (0, -1) = PIX (0, 0);
|
||||
PIX (1, -1) = PIX (1, 0);
|
||||
PIX (2, -1) = PIX (2, 0);
|
||||
}
|
||||
|
||||
// check pixel below the current one
|
||||
if (!(cmatch & 1))
|
||||
{
|
||||
if (SCALE_CMPYUV (PIX (0, 0), PIX (0, 1), BIADAPT_YUVLOW))
|
||||
{
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
PIX (0, 0), PIX (0, 1))
|
||||
);
|
||||
cmatch |= 1;
|
||||
}
|
||||
// detect a 2:1 line going across the current pixel
|
||||
else if ( (PIX (0, 0) == PIX (-1, 0)
|
||||
&& PIX (0, 0) == PIX (1, 1)
|
||||
&& PIX (0, 0) == PIX (2, 1) &&
|
||||
|
||||
((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 0))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 0))) ||
|
||||
(!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 2))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 2))))) ||
|
||||
|
||||
(PIX (0, 0) == PIX (1, 0)
|
||||
&& PIX (0, 0) == PIX (-1, 1)
|
||||
&& PIX (0, 0) == PIX (2, -1) &&
|
||||
|
||||
((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, -1))) ||
|
||||
(!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 2))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 0))))) )
|
||||
{
|
||||
SCALE_SETPIX (dst_p + dlen, PIX (0, 0));
|
||||
}
|
||||
// detect a 2:1 line going across the pixel below current
|
||||
else if ( (PIX (0, 1) == PIX (-1, 0)
|
||||
&& PIX (0, 1) == PIX (1, 1)
|
||||
&& PIX (0, 1) == PIX (2, 2) &&
|
||||
|
||||
((!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 0))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, 1))) ||
|
||||
(!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (0, 2))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 2))))) ||
|
||||
|
||||
(PIX (0, 1) == PIX (1, 0)
|
||||
&& PIX (0, 1) == PIX (-1, 1)
|
||||
&& PIX (0, 1) == PIX (2, 0) &&
|
||||
|
||||
((!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 0))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, -1))) ||
|
||||
(!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 2))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (0, 2))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, 1))))) )
|
||||
{
|
||||
SCALE_SETPIX (dst_p + dlen, PIX (0, 1));
|
||||
}
|
||||
else
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
PIX (0, 0), PIX (0, 1))
|
||||
);
|
||||
}
|
||||
|
||||
dst_p++;
|
||||
|
||||
// check pixel to the right from the current one
|
||||
if (!(cmatch & 2))
|
||||
{
|
||||
if (SCALE_CMPYUV (PIX (0, 0), PIX (1, 0), BIADAPT_YUVLOW))
|
||||
{
|
||||
SCALE_SETPIX (dst_p, Scale_Blend_11 (
|
||||
PIX (0, 0), PIX (1, 0))
|
||||
);
|
||||
cmatch |= 2;
|
||||
}
|
||||
// detect a 1:2 line going across the current pixel
|
||||
else if ( (PIX (0, 0) == PIX (1, -1)
|
||||
&& PIX (0, 0) == PIX (0, 1)
|
||||
&& PIX (0, 0) == PIX (-1, 2) &&
|
||||
|
||||
((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 1))) ||
|
||||
(!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 2))))) ||
|
||||
|
||||
(PIX (0, 0) == PIX (0, -1)
|
||||
&& PIX (0, 0) == PIX (1, 1)
|
||||
&& PIX (0, 0) == PIX (1, 2) &&
|
||||
|
||||
((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 2))) ||
|
||||
(!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 2))))) )
|
||||
|
||||
{
|
||||
SCALE_SETPIX (dst_p, PIX (0, 0));
|
||||
}
|
||||
// detect a 1:2 line going across the pixel to the right
|
||||
else if ( (PIX (1, 0) == PIX (1, -1)
|
||||
&& PIX (1, 0) == PIX (0, 1)
|
||||
&& PIX (1, 0) == PIX (0, 2) &&
|
||||
|
||||
((!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (0, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, 2))) ||
|
||||
(!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 0))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 2))))) ||
|
||||
|
||||
(PIX (1, 0) == PIX (0, -1)
|
||||
&& PIX (1, 0) == PIX (1, 1)
|
||||
&& PIX (1, 0) == PIX (2, 2) &&
|
||||
|
||||
((!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (0, 1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 2))) ||
|
||||
(!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, -1))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 0))
|
||||
&& !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 1))))) )
|
||||
{
|
||||
SCALE_SETPIX (dst_p, PIX (1, 0));
|
||||
}
|
||||
else
|
||||
SCALE_SETPIX (dst_p, Scale_Blend_11 (
|
||||
PIX (0, 0), PIX (1, 0))
|
||||
);
|
||||
}
|
||||
|
||||
if (PIX (0, 0) == PIX (1, 1) && PIX (1, 0) == PIX (0, 1))
|
||||
{
|
||||
// diagonals are equal
|
||||
int *coord;
|
||||
int cl, cr;
|
||||
Uint32 clr;
|
||||
|
||||
// both pairs are equal, have to resolve the pixel
|
||||
// race; we try detecting which color is
|
||||
// the background by looking for a line or an edge
|
||||
// examine 8 pixels surrounding the current quad
|
||||
|
||||
cl = cr = 2;
|
||||
for (coord = resolve_coord[0]; *coord < 100; coord += 2)
|
||||
{
|
||||
clr = PIX (coord[0], coord[1]);
|
||||
|
||||
if (BIADAPT_CMPYUV_MED (clr, PIX (0, 0)))
|
||||
cl++;
|
||||
else if (BIADAPT_CMPYUV_MED (clr, PIX (1, 0)))
|
||||
cr++;
|
||||
}
|
||||
|
||||
// least count wins
|
||||
if (cl > cr)
|
||||
clr = PIX (1, 0);
|
||||
else if (cr > cl)
|
||||
clr = PIX (0, 0);
|
||||
else
|
||||
clr = Scale_Blend_11 (PIX (0, 0), PIX (1, 0));
|
||||
|
||||
SCALE_SETPIX (dst_p + dlen, clr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cmatch == 3
|
||||
|| (BIADAPT_CMPYUV_LOW (PIX (1, 0), PIX (0, 1))
|
||||
&& BIADAPT_CMPYUV_LOW (PIX (1, 0), PIX (1, 1))))
|
||||
{
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
PIX (0, 1), PIX (1, 0))
|
||||
);
|
||||
continue;
|
||||
}
|
||||
else if (cmatch && BIADAPT_CMPYUV_LOW (PIX (0, 0), PIX (1, 1)))
|
||||
{
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
PIX (0, 0), PIX (1, 1))
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// check pixel to the bottom-right
|
||||
if (BIADAPT_CMPYUV_HIGH (PIX (0, 0), PIX (1, 1))
|
||||
&& BIADAPT_CMPYUV_HIGH (PIX (1, 0), PIX (0, 1)))
|
||||
{
|
||||
if (SCALE_GETY (PIX (0, 0)) > SCALE_GETY (PIX (1, 0)))
|
||||
{
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
PIX (0, 0), PIX (1, 1))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
PIX (1, 0), PIX (0, 1))
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (BIADAPT_CMPYUV_HIGH (PIX (0, 0), PIX (1, 1)))
|
||||
{
|
||||
// main diagonal is same color
|
||||
// use its value
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
PIX (0, 0), PIX (1, 1))
|
||||
);
|
||||
}
|
||||
else if (BIADAPT_CMPYUV_HIGH (PIX (1, 0), PIX (0, 1)))
|
||||
{
|
||||
// 2nd diagonal is same color
|
||||
// use its value
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 (
|
||||
PIX (1, 0), PIX (0, 1))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// blend all 4
|
||||
SCALE_SETPIX (dst_p + dlen, Scale_Blend_1111 (
|
||||
PIX (0, 0), PIX (0, 1),
|
||||
PIX (1, 0), PIX (1, 1)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCALE_(PlatDone) ();
|
||||
}
|
||||
|
||||
112
project/jni/application/sc2/src/libs/graphics/sdl/bilinear2x.c
Normal file
112
project/jni/application/sc2/src/libs/graphics/sdl/bilinear2x.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Core algorithm of the BiLinear screen scaler
|
||||
// Template
|
||||
// When this file is built standalone is produces a plain C version
|
||||
// Also #included by 2xscalers_mmx.c for an MMX version
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
|
||||
|
||||
// Bilinear scaling to 2x
|
||||
// The name expands to either
|
||||
// Scale_BilinearFilter (for plain C) or
|
||||
// Scale_MMX_BilinearFilter (for MMX)
|
||||
// Scale_SSE_BilinearFilter (for SSE)
|
||||
// [others when platforms are added]
|
||||
void
|
||||
SCALE_(BilinearFilter) (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r)
|
||||
{
|
||||
int x, y;
|
||||
const int w = src->w, h = src->h;
|
||||
int xend, yend;
|
||||
int dsrc, ddst;
|
||||
SDL_Rect *region = r;
|
||||
SDL_Rect limits;
|
||||
SDL_PixelFormat *fmt = dst->format;
|
||||
const int pitch = src->pitch, dp = dst->pitch;
|
||||
const int bpp = fmt->BytesPerPixel;
|
||||
const int len = pitch / bpp, dlen = dp / bpp;
|
||||
Uint32 p[4]; // influential pixels array
|
||||
Uint32 *srow0 = (Uint32 *) src->pixels;
|
||||
Uint32 *dst_p = (Uint32 *) dst->pixels;
|
||||
|
||||
SCALE_(PlatInit) ();
|
||||
|
||||
// expand updated region if necessary
|
||||
// pixels neighbooring the updated region may
|
||||
// change as a result of updates
|
||||
limits.x = 0;
|
||||
limits.y = 0;
|
||||
limits.w = w;
|
||||
limits.h = h;
|
||||
Scale_ExpandRect (region, 1, &limits);
|
||||
|
||||
xend = region->x + region->w;
|
||||
yend = region->y + region->h;
|
||||
dsrc = len - region->w;
|
||||
ddst = (dlen - region->w) * 2;
|
||||
|
||||
// move ptrs to the first updated pixel
|
||||
srow0 += len * region->y + region->x;
|
||||
dst_p += (dlen * region->y + region->x) * 2;
|
||||
|
||||
for (y = region->y; y < yend; ++y, dst_p += ddst, srow0 += dsrc)
|
||||
{
|
||||
Uint32 *srow1;
|
||||
|
||||
SCALE_(Prefetch) (srow0 + 16);
|
||||
SCALE_(Prefetch) (srow0 + 32);
|
||||
|
||||
if (y < h - 1)
|
||||
srow1 = srow0 + len;
|
||||
else
|
||||
srow1 = srow0;
|
||||
|
||||
SCALE_(Prefetch) (srow1 + 16);
|
||||
SCALE_(Prefetch) (srow1 + 32);
|
||||
|
||||
for (x = region->x; x < xend; ++x, ++srow0, ++srow1, dst_p += 2)
|
||||
{
|
||||
if (x < w - 1)
|
||||
{ // can blend directly from pixels
|
||||
SCALE_BILINEAR_BLEND4 (srow0, srow1, dst_p, dlen);
|
||||
}
|
||||
else
|
||||
{ // need to make temp pixel rows
|
||||
p[0] = srow0[0];
|
||||
p[1] = p[0];
|
||||
p[2] = srow1[0];
|
||||
p[3] = p[2];
|
||||
|
||||
SCALE_BILINEAR_BLEND4 (&p[0], &p[2], dst_p, dlen);
|
||||
}
|
||||
}
|
||||
|
||||
SCALE_(Prefetch) (srow0 + dsrc);
|
||||
SCALE_(Prefetch) (srow0 + dsrc + 16);
|
||||
SCALE_(Prefetch) (srow1 + dsrc);
|
||||
SCALE_(Prefetch) (srow1 + dsrc + 16);
|
||||
}
|
||||
|
||||
SCALE_(PlatDone) ();
|
||||
}
|
||||
|
||||
2171
project/jni/application/sc2/src/libs/graphics/sdl/canvas.c
Normal file
2171
project/jni/application/sc2/src/libs/graphics/sdl/canvas.c
Normal file
File diff suppressed because it is too large
Load Diff
2888
project/jni/application/sc2/src/libs/graphics/sdl/hq2x.c
Normal file
2888
project/jni/application/sc2/src/libs/graphics/sdl/hq2x.c
Normal file
File diff suppressed because it is too large
Load Diff
207
project/jni/application/sc2/src/libs/graphics/sdl/nearest2x.c
Normal file
207
project/jni/application/sc2/src/libs/graphics/sdl/nearest2x.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Core algorithm of the BiLinear screen scaler
|
||||
// Template
|
||||
// When this file is built standalone is produces a plain C version
|
||||
// Also #included by 2xscalers_mmx.c for an MMX version
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
|
||||
// Nearest Neighbor scaling to 2x
|
||||
// The name expands to
|
||||
// Scale_Nearest (for plain C)
|
||||
// Scale_MMX_Nearest (for MMX)
|
||||
// Scale_SSE_Nearest (for SSE)
|
||||
// [others when platforms are added]
|
||||
void
|
||||
SCALE_(Nearest) (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r)
|
||||
{
|
||||
int y;
|
||||
const int rw = r->w, rh = r->h;
|
||||
const int sp = src->pitch, dp = dst->pitch;
|
||||
const int bpp = dst->format->BytesPerPixel;
|
||||
const int slen = sp / bpp, dlen = dp / bpp;
|
||||
const int dsrc = slen-rw, ddst = (dlen-rw) * 2;
|
||||
|
||||
Uint32 *src_p = (Uint32 *)src->pixels;
|
||||
Uint32 *dst_p = (Uint32 *)dst->pixels;
|
||||
|
||||
// guard asm code against such atrocities
|
||||
if (rw == 0 || rh == 0)
|
||||
return;
|
||||
|
||||
SCALE_(PlatInit) ();
|
||||
|
||||
// move ptrs to the first updated pixel
|
||||
src_p += slen * r->y + r->x;
|
||||
dst_p += (dlen * r->y + r->x) * 2;
|
||||
|
||||
#if defined(MMX_ASM) && defined(MSVC_ASM)
|
||||
// Just about everything has to be done in asm for MSVC
|
||||
// to actually take advantage of asm here
|
||||
// MSVC does not support beautiful GCC-like asm templates
|
||||
|
||||
y = rh;
|
||||
__asm
|
||||
{
|
||||
// setup vars
|
||||
mov esi, src_p
|
||||
mov edi, dst_p
|
||||
|
||||
PREFETCH (esi + 0x40)
|
||||
PREFETCH (esi + 0x80)
|
||||
PREFETCH (esi + 0xc0)
|
||||
|
||||
mov edx, dlen
|
||||
lea edx, [edx * 4]
|
||||
mov eax, dsrc
|
||||
lea eax, [eax * 4]
|
||||
mov ebx, ddst
|
||||
lea ebx, [ebx * 4]
|
||||
|
||||
mov ecx, rw
|
||||
loop_y:
|
||||
test ecx, 1
|
||||
jz even_x
|
||||
|
||||
// one-pixel transfer
|
||||
movd mm1, [esi]
|
||||
punpckldq mm1, mm1 // pix1 | pix1 -> mm1
|
||||
add esi, 4
|
||||
MOVNTQ (edi, mm1)
|
||||
add edi, 8
|
||||
MOVNTQ (edi - 8 + edx, mm1)
|
||||
|
||||
even_x:
|
||||
shr ecx, 1 // x = rw / 2
|
||||
jz end_x // rw was 1
|
||||
|
||||
loop_x:
|
||||
// two-pixel transfer
|
||||
movq mm1, [esi]
|
||||
movq mm2, mm1
|
||||
PREFETCH (esi + 0x100)
|
||||
punpckldq mm1, mm1 // pix1 | pix1 -> mm1
|
||||
add esi, 8
|
||||
MOVNTQ (edi, mm1)
|
||||
punpckhdq mm2, mm2 // pix2 | pix2 -> mm2
|
||||
MOVNTQ (edi + edx, mm1)
|
||||
add edi, 16
|
||||
MOVNTQ (edi - 8, mm2)
|
||||
MOVNTQ (edi - 8 + edx, mm2)
|
||||
|
||||
dec ecx
|
||||
jnz loop_x
|
||||
|
||||
end_x:
|
||||
// try to prefetch as early as possible to have it on time
|
||||
PREFETCH (esi + eax)
|
||||
|
||||
mov ecx, rw
|
||||
add esi, eax
|
||||
|
||||
PREFETCH (esi + 0x40)
|
||||
PREFETCH (esi + 0x80)
|
||||
PREFETCH (esi + 0xc0)
|
||||
|
||||
add edi, ebx
|
||||
|
||||
dec y
|
||||
jnz loop_y
|
||||
}
|
||||
|
||||
#elif defined(MMX_ASM) && defined(GCC_ASM)
|
||||
|
||||
SCALE_(Prefetch) (src_p + 16);
|
||||
SCALE_(Prefetch) (src_p + 32);
|
||||
SCALE_(Prefetch) (src_p + 48);
|
||||
|
||||
for (y = rh; y; --y)
|
||||
{
|
||||
int x = rw;
|
||||
|
||||
if (x & 1)
|
||||
{ // one-pixel transfer
|
||||
__asm__ (
|
||||
"movd (%0), %%mm1 \n\t"
|
||||
"punpckldq %%mm1, %%mm1 \n\t"
|
||||
MOVNTQ (%%mm1, (%1)) "\n\t"
|
||||
MOVNTQ (%%mm1, (%1,%2)) "\n\t"
|
||||
|
||||
: /* nothing */
|
||||
: /*0*/"r" (src_p), /*1*/"r" (dst_p), /*2*/"r" (dlen*sizeof(Uint32))
|
||||
);
|
||||
|
||||
++src_p;
|
||||
dst_p += 2;
|
||||
--x;
|
||||
}
|
||||
|
||||
for (x >>= 1; x; --x, src_p += 2, dst_p += 4)
|
||||
{ // two-pixel transfer
|
||||
__asm__ (
|
||||
"movq (%0), %%mm1 \n\t"
|
||||
"movq %%mm1, %%mm2 \n\t"
|
||||
PREFETCH (0x100(%0)) "\n\t"
|
||||
"punpckldq %%mm1, %%mm1 \n\t"
|
||||
MOVNTQ (%%mm1, (%1)) "\n\t"
|
||||
MOVNTQ (%%mm1, (%1,%2)) "\n\t"
|
||||
"punpckhdq %%mm2, %%mm2 \n\t"
|
||||
MOVNTQ (%%mm2, 8(%1)) "\n\t"
|
||||
MOVNTQ (%%mm2, 8(%1,%2)) "\n\t"
|
||||
|
||||
: /* nothing */
|
||||
: /*0*/"r" (src_p), /*1*/"r" (dst_p), /*2*/"r" (dlen*sizeof(Uint32))
|
||||
);
|
||||
}
|
||||
|
||||
src_p += dsrc;
|
||||
// try to prefetch as early as possible to have it on time
|
||||
SCALE_(Prefetch) (src_p);
|
||||
|
||||
dst_p += ddst;
|
||||
|
||||
SCALE_(Prefetch) (src_p + 16);
|
||||
SCALE_(Prefetch) (src_p + 32);
|
||||
SCALE_(Prefetch) (src_p + 48);
|
||||
}
|
||||
|
||||
#else
|
||||
// Plain C version
|
||||
for (y = 0; y < rh; ++y)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < rw; ++x, ++src_p, dst_p += 2)
|
||||
{
|
||||
Uint32 pix = *src_p;
|
||||
dst_p[0] = pix;
|
||||
dst_p[1] = pix;
|
||||
dst_p[dlen] = pix;
|
||||
dst_p[dlen + 1] = pix;
|
||||
}
|
||||
dst_p += ddst;
|
||||
src_p += dsrc;
|
||||
}
|
||||
#endif
|
||||
|
||||
SCALE_(PlatDone) ();
|
||||
}
|
||||
|
||||
581
project/jni/application/sc2/src/libs/graphics/sdl/opengl.c
Normal file
581
project/jni/application/sc2/src/libs/graphics/sdl/opengl.c
Normal file
@@ -0,0 +1,581 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
|
||||
#include "libs/graphics/sdl/opengl.h"
|
||||
#include "libs/graphics/bbox.h"
|
||||
#include "scalers.h"
|
||||
#include "options.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
typedef struct _gl_screeninfo {
|
||||
SDL_Surface *scaled;
|
||||
GLuint texture;
|
||||
BOOLEAN dirty, active;
|
||||
SDL_Rect updated;
|
||||
} TFB_GL_SCREENINFO;
|
||||
|
||||
static TFB_GL_SCREENINFO GL_Screens[TFB_GFX_NUMSCREENS];
|
||||
|
||||
static int ScreenFilterMode;
|
||||
|
||||
static TFB_ScaleFunc scaler = NULL;
|
||||
static BOOLEAN first_init = TRUE;
|
||||
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
#define R_MASK 0xff000000
|
||||
#define G_MASK 0x00ff0000
|
||||
#define B_MASK 0x0000ff00
|
||||
#define A_MASK 0x000000ff
|
||||
#else
|
||||
#define R_MASK 0x000000ff
|
||||
#define G_MASK 0x0000ff00
|
||||
#define B_MASK 0x00ff0000
|
||||
#define A_MASK 0xff000000
|
||||
#endif
|
||||
|
||||
static void TFB_GL_Preprocess (int force_full_redraw, int transition_amount, int fade_amount);
|
||||
static void TFB_GL_Postprocess (void);
|
||||
static void TFB_GL_Scaled_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect);
|
||||
static void TFB_GL_Unscaled_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect);
|
||||
static void TFB_GL_ColorLayer (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect);
|
||||
|
||||
static TFB_GRAPHICS_BACKEND opengl_scaled_backend = {
|
||||
TFB_GL_Preprocess,
|
||||
TFB_GL_Postprocess,
|
||||
TFB_GL_Scaled_ScreenLayer,
|
||||
TFB_GL_ColorLayer };
|
||||
|
||||
static TFB_GRAPHICS_BACKEND opengl_unscaled_backend = {
|
||||
TFB_GL_Preprocess,
|
||||
TFB_GL_Postprocess,
|
||||
TFB_GL_Unscaled_ScreenLayer,
|
||||
TFB_GL_ColorLayer };
|
||||
|
||||
|
||||
static SDL_Surface *
|
||||
Create_Screen (SDL_Surface *template, int w, int h)
|
||||
{
|
||||
SDL_Surface *newsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,
|
||||
template->format->BitsPerPixel,
|
||||
template->format->Rmask, template->format->Gmask,
|
||||
template->format->Bmask, 0);
|
||||
if (newsurf == 0) {
|
||||
log_add (log_Error, "Couldn't create screen buffers: %s",
|
||||
SDL_GetError());
|
||||
}
|
||||
return newsurf;
|
||||
}
|
||||
|
||||
static int
|
||||
ReInit_Screen (SDL_Surface **screen, SDL_Surface *template, int w, int h)
|
||||
{
|
||||
if (*screen)
|
||||
SDL_FreeSurface (*screen);
|
||||
*screen = Create_Screen (template, w, h);
|
||||
|
||||
return *screen == 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
AttemptColorDepth (int flags, int width, int height, int bpp)
|
||||
{
|
||||
int videomode_flags;
|
||||
ScreenColorDepth = bpp;
|
||||
ScreenWidthActual = width;
|
||||
ScreenHeightActual = height;
|
||||
|
||||
switch (bpp) {
|
||||
case 15:
|
||||
SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
|
||||
SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
|
||||
SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
|
||||
SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 6);
|
||||
SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
|
||||
break;
|
||||
|
||||
case 24:
|
||||
SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 8);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0);
|
||||
SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
videomode_flags = SDL_OPENGL;
|
||||
if (flags & TFB_GFXFLAGS_FULLSCREEN)
|
||||
videomode_flags |= SDL_FULLSCREEN;
|
||||
videomode_flags |= SDL_ANYFORMAT;
|
||||
|
||||
SDL_Video = SDL_SetVideoMode (ScreenWidthActual, ScreenHeightActual,
|
||||
bpp, videomode_flags);
|
||||
if (SDL_Video == NULL)
|
||||
{
|
||||
log_add (log_Error, "Couldn't set OpenGL %ix%ix%i video mode: %s",
|
||||
ScreenWidthActual, ScreenHeightActual, bpp,
|
||||
SDL_GetError ());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_add (log_Info, "Set the resolution to: %ix%ix%i"
|
||||
" (surface reports %ix%ix%i)",
|
||||
width, height, bpp,
|
||||
SDL_GetVideoSurface()->w, SDL_GetVideoSurface()->h,
|
||||
SDL_GetVideoSurface()->format->BitsPerPixel);
|
||||
|
||||
log_add (log_Info, "OpenGL renderer: %s version: %s",
|
||||
glGetString (GL_RENDERER), glGetString (GL_VERSION));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
TFB_GL_ConfigureVideo (int driver, int flags, int width, int height, int togglefullscreen)
|
||||
{
|
||||
int i, texture_width, texture_height;
|
||||
GraphicsDriver = driver;
|
||||
|
||||
if (AttemptColorDepth (flags, width, height, 32) &&
|
||||
AttemptColorDepth (flags, width, height, 24) &&
|
||||
AttemptColorDepth (flags, width, height, 16))
|
||||
{
|
||||
log_add (log_Error, "Couldn't set any OpenGL %ix%i video mode!",
|
||||
width, height);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!togglefullscreen)
|
||||
{
|
||||
if (format_conv_surf)
|
||||
SDL_FreeSurface (format_conv_surf);
|
||||
format_conv_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, 0, 0, 32,
|
||||
R_MASK, G_MASK, B_MASK, A_MASK);
|
||||
if (format_conv_surf == NULL)
|
||||
{
|
||||
log_add (log_Error, "Couldn't create format_conv_surf: %s",
|
||||
SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
|
||||
{
|
||||
if (0 != ReInit_Screen (&SDL_Screens[i], format_conv_surf,
|
||||
ScreenWidth, ScreenHeight))
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_Screen = SDL_Screens[0];
|
||||
TransitionScreen = SDL_Screens[2];
|
||||
|
||||
if (first_init)
|
||||
{
|
||||
for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
|
||||
{
|
||||
GL_Screens[i].scaled = NULL;
|
||||
GL_Screens[i].dirty = TRUE;
|
||||
GL_Screens[i].active = TRUE;
|
||||
}
|
||||
GL_Screens[1].active = FALSE;
|
||||
first_init = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (GfxFlags & TFB_GFXFLAGS_SCALE_SOFT_ONLY)
|
||||
{
|
||||
if (!togglefullscreen)
|
||||
{
|
||||
for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
|
||||
{
|
||||
if (!GL_Screens[i].active)
|
||||
continue;
|
||||
if (0 != ReInit_Screen (&GL_Screens[i].scaled, format_conv_surf,
|
||||
ScreenWidth * 2, ScreenHeight * 2))
|
||||
return -1;
|
||||
}
|
||||
scaler = Scale_PrepPlatform (flags, SDL_Screen->format);
|
||||
}
|
||||
|
||||
texture_width = 1024;
|
||||
texture_height = 512;
|
||||
|
||||
graphics_backend = &opengl_scaled_backend;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture_width = 512;
|
||||
texture_height = 256;
|
||||
|
||||
scaler = NULL;
|
||||
graphics_backend = &opengl_unscaled_backend;
|
||||
}
|
||||
|
||||
|
||||
if (GfxFlags & TFB_GFXFLAGS_SCALE_ANY)
|
||||
ScreenFilterMode = GL_LINEAR;
|
||||
else
|
||||
ScreenFilterMode = GL_NEAREST;
|
||||
|
||||
glViewport (0, 0, ScreenWidthActual, ScreenHeightActual);
|
||||
glClearColor (0,0,0,0);
|
||||
glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
SDL_GL_SwapBuffers ();
|
||||
glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
glDisable (GL_DITHER);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
|
||||
{
|
||||
if (!GL_Screens[i].active)
|
||||
continue;
|
||||
glGenTextures (1, &GL_Screens[i].texture);
|
||||
glBindTexture (GL_TEXTURE_2D, GL_Screens[i].texture);
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
TFB_GL_InitGraphics (int driver, int flags, int width, int height)
|
||||
{
|
||||
char VideoName[256];
|
||||
|
||||
log_add (log_Info, "Initializing SDL with OpenGL support.");
|
||||
|
||||
SDL_VideoDriverName (VideoName, sizeof (VideoName));
|
||||
log_add (log_Info, "SDL driver used: %s", VideoName);
|
||||
log_add (log_Info, "SDL initialized.");
|
||||
log_add (log_Info, "Initializing Screen.");
|
||||
|
||||
ScreenWidth = 320;
|
||||
ScreenHeight = 240;
|
||||
|
||||
if (TFB_GL_ConfigureVideo (driver, flags, width, height, 0))
|
||||
{
|
||||
log_add (log_Fatal, "Could not initialize video: "
|
||||
"no fallback at start of program!");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Initialize scalers (let them precompute whatever)
|
||||
Scale_Init ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TFB_GL_UploadTransitionScreen (void)
|
||||
{
|
||||
GL_Screens[TFB_SCREEN_TRANSITION].updated.x = 0;
|
||||
GL_Screens[TFB_SCREEN_TRANSITION].updated.y = 0;
|
||||
GL_Screens[TFB_SCREEN_TRANSITION].updated.w = ScreenWidth;
|
||||
GL_Screens[TFB_SCREEN_TRANSITION].updated.h = ScreenHeight;
|
||||
GL_Screens[TFB_SCREEN_TRANSITION].dirty = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_GL_ScanLines (void)
|
||||
{
|
||||
int y;
|
||||
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_DST_COLOR, GL_ZERO);
|
||||
glColor3f (0.85f, 0.85f, 0.85f);
|
||||
for (y = 0; y < ScreenHeightActual; y += 2)
|
||||
{
|
||||
glBegin (GL_LINES);
|
||||
glVertex2i (0, y);
|
||||
glVertex2i (ScreenWidthActual, y);
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
glBlendFunc (GL_DST_COLOR, GL_ONE);
|
||||
glColor3f (0.2f, 0.2f, 0.2f);
|
||||
for (y = 1; y < ScreenHeightActual; y += 2)
|
||||
{
|
||||
glBegin (GL_LINES);
|
||||
glVertex2i (0, y);
|
||||
glVertex2i (ScreenWidthActual, y);
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_GL_DrawQuad (SDL_Rect *r)
|
||||
{
|
||||
BOOLEAN keep_aspect_ratio = optKeepAspectRatio;
|
||||
int x1 = 0, y1 = 0, x2 = ScreenWidthActual, y2 = ScreenHeightActual;
|
||||
int sx = 0, sy = 0;
|
||||
int sw, sh;
|
||||
float sx_multiplier = 1;
|
||||
float sy_multiplier = 1;
|
||||
|
||||
if (keep_aspect_ratio)
|
||||
{
|
||||
float threshold = 0.75f;
|
||||
float ratio = ScreenHeightActual / (float)ScreenWidthActual;
|
||||
|
||||
if (ratio > threshold)
|
||||
{
|
||||
// screen is narrower than 4:3
|
||||
int height = (int)(ScreenWidthActual * threshold);
|
||||
y1 = (ScreenHeightActual - height) / 2;
|
||||
y2 = ScreenHeightActual - y1;
|
||||
|
||||
if (r != NULL)
|
||||
{
|
||||
sx_multiplier = ScreenWidthActual / (float)ScreenWidth;
|
||||
sy_multiplier = height / (float)ScreenHeight;
|
||||
sx = (int)(r->x * sx_multiplier);
|
||||
sy = (int)(((ScreenHeight - (r->y + r->h)) * sy_multiplier) + y1);
|
||||
}
|
||||
}
|
||||
else if (ratio < threshold)
|
||||
{
|
||||
// screen is wider than 4:3
|
||||
int width = (int)(ScreenHeightActual / threshold);
|
||||
x1 = (ScreenWidthActual - width) / 2;
|
||||
x2 = ScreenWidthActual - x1;
|
||||
|
||||
if (r != NULL)
|
||||
{
|
||||
sx_multiplier = width / (float)ScreenWidth;
|
||||
sy_multiplier = ScreenHeightActual / (float)ScreenHeight;
|
||||
sx = (int)((r->x * sx_multiplier) + x1);
|
||||
sy = (int)((ScreenHeight - (r->y + r->h)) * sy_multiplier);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// screen is 4:3
|
||||
keep_aspect_ratio = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (r != NULL)
|
||||
{
|
||||
if (!keep_aspect_ratio)
|
||||
{
|
||||
sx_multiplier = ScreenWidthActual / (float)ScreenWidth;
|
||||
sy_multiplier = ScreenHeightActual / (float)ScreenHeight;
|
||||
sx = (int)(r->x * sx_multiplier);
|
||||
sy = (int)((ScreenHeight - (r->y + r->h)) * sy_multiplier);
|
||||
}
|
||||
sw = (int)(r->w * sx_multiplier);
|
||||
sh = (int)(r->h * sy_multiplier);
|
||||
glScissor (sx, sy, sw, sh);
|
||||
glEnable (GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex2i (x1, y1);
|
||||
glTexCoord2f (ScreenWidth / 512.0f, 0);
|
||||
glVertex2i (x2, y1);
|
||||
glTexCoord2f (ScreenWidth / 512.0f, ScreenHeight / 256.0f);
|
||||
glVertex2i (x2, y2);
|
||||
glTexCoord2f (0, ScreenHeight / 256.0f);
|
||||
glVertex2i (x1, y2);
|
||||
glEnd ();
|
||||
if (r != NULL)
|
||||
{
|
||||
glDisable (GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_GL_Preprocess (int force_full_redraw, int transition_amount, int fade_amount)
|
||||
{
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
glOrtho (0,ScreenWidthActual,ScreenHeightActual, 0, -1, 1);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
if (optKeepAspectRatio)
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
|
||||
(void) transition_amount;
|
||||
(void) fade_amount;
|
||||
|
||||
if (force_full_redraw == TFB_REDRAW_YES)
|
||||
{
|
||||
GL_Screens[TFB_SCREEN_MAIN].updated.x = 0;
|
||||
GL_Screens[TFB_SCREEN_MAIN].updated.y = 0;
|
||||
GL_Screens[TFB_SCREEN_MAIN].updated.w = ScreenWidth;
|
||||
GL_Screens[TFB_SCREEN_MAIN].updated.h = ScreenHeight;
|
||||
GL_Screens[TFB_SCREEN_MAIN].dirty = TRUE;
|
||||
}
|
||||
else if (TFB_BBox.valid)
|
||||
{
|
||||
GL_Screens[TFB_SCREEN_MAIN].updated.x = TFB_BBox.region.corner.x;
|
||||
GL_Screens[TFB_SCREEN_MAIN].updated.y = TFB_BBox.region.corner.y;
|
||||
GL_Screens[TFB_SCREEN_MAIN].updated.w = TFB_BBox.region.extent.width;
|
||||
GL_Screens[TFB_SCREEN_MAIN].updated.h = TFB_BBox.region.extent.height;
|
||||
GL_Screens[TFB_SCREEN_MAIN].dirty = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_GL_Unscaled_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, GL_Screens[screen].texture);
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
if (GL_Screens[screen].dirty)
|
||||
{
|
||||
int PitchWords = SDL_Screens[screen]->pitch / 4;
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, PitchWords);
|
||||
/* Matrox OpenGL drivers do not handle GL_UNPACK_SKIP_*
|
||||
correctly */
|
||||
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
SDL_LockSurface (SDL_Screens[screen]);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, GL_Screens[screen].updated.x,
|
||||
GL_Screens[screen].updated.y,
|
||||
GL_Screens[screen].updated.w,
|
||||
GL_Screens[screen].updated.h,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
(Uint32 *)SDL_Screens[screen]->pixels +
|
||||
(GL_Screens[screen].updated.y * PitchWords +
|
||||
GL_Screens[screen].updated.x));
|
||||
SDL_UnlockSurface (SDL_Screens[screen]);
|
||||
GL_Screens[screen].dirty = FALSE;
|
||||
}
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ScreenFilterMode);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ScreenFilterMode);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
|
||||
if (a == 255)
|
||||
{
|
||||
glDisable (GL_BLEND);
|
||||
glColor4f (1, 1, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
float a_f = a / 255.0f;
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable (GL_BLEND);
|
||||
glColor4f (1, 1, 1, a_f);
|
||||
}
|
||||
|
||||
TFB_GL_DrawQuad (rect);
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_GL_Scaled_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, GL_Screens[screen].texture);
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
if (GL_Screens[screen].dirty)
|
||||
{
|
||||
int PitchWords = GL_Screens[screen].scaled->pitch / 4;
|
||||
scaler (SDL_Screens[screen], GL_Screens[screen].scaled, &GL_Screens[screen].updated);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, PitchWords);
|
||||
|
||||
/* Matrox OpenGL drivers do not handle GL_UNPACK_SKIP_*
|
||||
correctly */
|
||||
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
SDL_LockSurface (GL_Screens[screen].scaled);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, GL_Screens[screen].updated.x * 2,
|
||||
GL_Screens[screen].updated.y * 2,
|
||||
GL_Screens[screen].updated.w * 2,
|
||||
GL_Screens[screen].updated.h * 2,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
(Uint32 *)GL_Screens[screen].scaled->pixels +
|
||||
(GL_Screens[screen].updated.y * 2 * PitchWords +
|
||||
GL_Screens[screen].updated.x * 2));
|
||||
SDL_UnlockSurface (GL_Screens[screen].scaled);
|
||||
GL_Screens[screen].dirty = FALSE;
|
||||
}
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ScreenFilterMode);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ScreenFilterMode);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
|
||||
if (a == 255)
|
||||
{
|
||||
glDisable (GL_BLEND);
|
||||
glColor4f (1, 1, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
float a_f = a / 255.0f;
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable (GL_BLEND);
|
||||
glColor4f (1, 1, 1, a_f);
|
||||
}
|
||||
|
||||
TFB_GL_DrawQuad (rect);
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_GL_ColorLayer (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect)
|
||||
{
|
||||
float r_f = r / 255.0f;
|
||||
float g_f = g / 255.0f;
|
||||
float b_f = b / 255.0f;
|
||||
float a_f = a / 255.0f;
|
||||
glColor4f(r_f, g_f, b_f, a_f);
|
||||
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
if (a != 255)
|
||||
{
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable (GL_BLEND);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
TFB_GL_DrawQuad (rect);
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_GL_Postprocess (void)
|
||||
{
|
||||
if (GfxFlags & TFB_GFXFLAGS_SCANLINES)
|
||||
TFB_GL_ScanLines ();
|
||||
|
||||
SDL_GL_SwapBuffers ();
|
||||
}
|
||||
|
||||
#endif
|
||||
88
project/jni/application/sc2/src/libs/graphics/sdl/opengl.h
Normal file
88
project/jni/application/sc2/src/libs/graphics/sdl/opengl.h
Normal file
@@ -0,0 +1,88 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef OPENGL_H
|
||||
#define OPENGL_H
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
|
||||
int TFB_GL_InitGraphics (int driver, int flags, int width, int height);
|
||||
int TFB_GL_ConfigureVideo (int driver, int flags, int width, int height, int togglefullscreen);
|
||||
void TFB_GL_UploadTransitionScreen (void);
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
#ifdef WIN32
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment (lib, "opengl32.lib")
|
||||
#pragma comment (lib, "glu32.lib")
|
||||
#endif
|
||||
|
||||
/* To avoid including windows.h,
|
||||
Win32's <GL/gl.h> needs APIENTRY and WINGDIAPI defined properly. */
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define GLUT_APIENTRY_DEFINED
|
||||
#if __MINGW32__ || (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
|
||||
#define APIENTRY __stdcall
|
||||
#else
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WINAPI
|
||||
#define GLUT_WINAPI_DEFINED
|
||||
#if __MINGW32__ || (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
|
||||
#define WINAPI __stdcall
|
||||
#else
|
||||
#define WINAPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This is from Win32's <winnt.h> */
|
||||
#ifndef CALLBACK
|
||||
#if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
|
||||
#define CALLBACK __stdcall
|
||||
#else
|
||||
#define CALLBACK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This is from Win32's <wingdi.h> and <winnt.h> */
|
||||
#ifndef WINGDIAPI
|
||||
#define GLUT_WINGDIAPI_DEFINED
|
||||
#define WINGDIAPI __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
/* This is from Win32's <ctype.h> */
|
||||
#ifndef _WCHAR_T_DEFINED
|
||||
typedef unsigned short wchar_t;
|
||||
#define _WCHAR_T_DEFINED
|
||||
#endif
|
||||
|
||||
#include "GL/glu.h"
|
||||
|
||||
#else /* !defined(WIN32) */
|
||||
|
||||
#include "port.h"
|
||||
#include SDL_INCLUDE(SDL_opengl.h)
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* HAVE_OPENGL */
|
||||
|
||||
#endif
|
||||
47
project/jni/application/sc2/src/libs/graphics/sdl/palette.c
Normal file
47
project/jni/application/sc2/src/libs/graphics/sdl/palette.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2009 Alex Volkov <codepro@usa.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "palette.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
NativePalette *
|
||||
AllocNativePalette (void)
|
||||
{
|
||||
return HCalloc (sizeof (NativePalette));
|
||||
}
|
||||
|
||||
void
|
||||
FreeNativePalette (NativePalette *palette)
|
||||
{
|
||||
HFree (palette);
|
||||
}
|
||||
|
||||
void
|
||||
SetNativePaletteColor (NativePalette *palette, int index, Color color)
|
||||
{
|
||||
assert (index < NUMBER_OF_PLUTVALS);
|
||||
palette->colors[index] = ColorToNative (color);
|
||||
}
|
||||
|
||||
Color
|
||||
GetNativePaletteColor (NativePalette *palette, int index)
|
||||
{
|
||||
assert (index < NUMBER_OF_PLUTVALS);
|
||||
return NativeToColor (palette->colors[index]);
|
||||
}
|
||||
53
project/jni/application/sc2/src/libs/graphics/sdl/palette.h
Normal file
53
project/jni/application/sc2/src/libs/graphics/sdl/palette.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2009 Alex Volkov <codepro@usa.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef PALETTE_H_INCL__
|
||||
#define PALETTE_H_INCL__
|
||||
|
||||
#include "port.h"
|
||||
#include SDL_INCLUDE(SDL.h)
|
||||
#include "libs/graphics/cmap.h"
|
||||
|
||||
struct NativePalette
|
||||
{
|
||||
SDL_Color colors[NUMBER_OF_PLUTVALS];
|
||||
};
|
||||
|
||||
static inline Color
|
||||
NativeToColor (SDL_Color native)
|
||||
{
|
||||
Color color;
|
||||
color.r = native.r;
|
||||
color.g = native.g;
|
||||
color.b = native.b;
|
||||
color.a = 0xff; // fully opaque
|
||||
return color;
|
||||
}
|
||||
|
||||
static inline SDL_Color
|
||||
ColorToNative (Color color)
|
||||
{
|
||||
SDL_Color native;
|
||||
native.r = color.r;
|
||||
native.g = color.g;
|
||||
native.b = color.b;
|
||||
native.unused = 0;
|
||||
return native;
|
||||
}
|
||||
|
||||
#endif /* PALETTE_H_INCL__ */
|
||||
635
project/jni/application/sc2/src/libs/graphics/sdl/primitives.c
Normal file
635
project/jni/application/sc2/src/libs/graphics/sdl/primitives.c
Normal file
@@ -0,0 +1,635 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "port.h"
|
||||
#include "sdl_common.h"
|
||||
#include "primitives.h"
|
||||
|
||||
|
||||
// Pixel drawing routines
|
||||
|
||||
static Uint32
|
||||
getpixel_8(SDL_Surface *surface, int x, int y)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to retrieve */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x;
|
||||
return *p;
|
||||
}
|
||||
|
||||
static void
|
||||
putpixel_8(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to set */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 1;
|
||||
*p = pixel;
|
||||
}
|
||||
|
||||
static Uint32
|
||||
getpixel_16(SDL_Surface *surface, int x, int y)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to retrieve */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 2;
|
||||
return *(Uint16 *)p;
|
||||
}
|
||||
|
||||
static void
|
||||
putpixel_16(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to set */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 2;
|
||||
*(Uint16 *)p = pixel;
|
||||
}
|
||||
|
||||
static Uint32
|
||||
getpixel_24_be(SDL_Surface *surface, int x, int y)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to retrieve */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 3;
|
||||
return p[0] << 16 | p[1] << 8 | p[2];
|
||||
}
|
||||
|
||||
static void
|
||||
putpixel_24_be(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to set */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 3;
|
||||
p[0] = (pixel >> 16) & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = pixel & 0xff;
|
||||
}
|
||||
|
||||
static Uint32
|
||||
getpixel_24_le(SDL_Surface *surface, int x, int y)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to retrieve */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 3;
|
||||
return p[0] | p[1] << 8 | p[2] << 16;
|
||||
}
|
||||
|
||||
static void
|
||||
putpixel_24_le(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to set */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 3;
|
||||
p[0] = pixel & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = (pixel >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static Uint32
|
||||
getpixel_32(SDL_Surface *surface, int x, int y)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to retrieve */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 4;
|
||||
return *(Uint32 *)p;
|
||||
}
|
||||
|
||||
static void
|
||||
putpixel_32(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
||||
{
|
||||
/* Here p is the address to the pixel we want to set */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 4;
|
||||
*(Uint32 *)p = pixel;
|
||||
}
|
||||
|
||||
GetPixelFn
|
||||
getpixel_for(SDL_Surface *surface)
|
||||
{
|
||||
int bpp = surface->format->BytesPerPixel;
|
||||
switch (bpp) {
|
||||
case 1:
|
||||
return &getpixel_8;
|
||||
case 2:
|
||||
return &getpixel_16;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
|
||||
return &getpixel_24_be;
|
||||
} else {
|
||||
return &getpixel_24_le;
|
||||
}
|
||||
case 4:
|
||||
return &getpixel_32;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PutPixelFn
|
||||
putpixel_for(SDL_Surface *surface)
|
||||
{
|
||||
int bpp = surface->format->BytesPerPixel;
|
||||
switch (bpp) {
|
||||
case 1:
|
||||
return &putpixel_8;
|
||||
case 2:
|
||||
return &putpixel_16;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
|
||||
return &putpixel_24_be;
|
||||
} else {
|
||||
return &putpixel_24_le;
|
||||
}
|
||||
case 4:
|
||||
return &putpixel_32;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
renderpixel_replace(SDL_Surface *surface, int x, int y, Uint32 pixel,
|
||||
int factor)
|
||||
{
|
||||
(void) factor; // ignored
|
||||
putpixel_32(surface, x, y, pixel);
|
||||
}
|
||||
|
||||
static inline Uint8
|
||||
clip_channel(int c)
|
||||
{
|
||||
if (c < 0)
|
||||
c = 0;
|
||||
else if (c > 255)
|
||||
c = 255;
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline Uint8
|
||||
modulated_sum(Uint8 dc, Uint8 sc, int factor)
|
||||
{
|
||||
// We use >> 8 instead of / 255 because it is faster, but it does
|
||||
// not work 100% correctly. It should be safe because this should
|
||||
// not be called for factor==255
|
||||
int b = dc + ((sc * factor) >> 8);
|
||||
return clip_channel(b);
|
||||
}
|
||||
|
||||
static inline Uint8
|
||||
alpha_blend(Uint8 dc, Uint8 sc, int alpha)
|
||||
{
|
||||
// We use >> 8 instead of / 255 because it is faster, but it does
|
||||
// not work 100% correctly. It should be safe because this should
|
||||
// not be called for alpha==255
|
||||
// No need to clip since we should never get values outside of 0..255
|
||||
// range, unless alpha is over 255, which is not supported.
|
||||
return (((sc - dc) * alpha) >> 8) + dc;
|
||||
}
|
||||
|
||||
// Assumes 8 bits/channel, a safe assumption for 32bpp surfaces
|
||||
#define UNPACK_PIXEL_32(p, fmt, r, g, b) \
|
||||
do { \
|
||||
(r) = ((p) >> (fmt)->Rshift) & 0xff; \
|
||||
(g) = ((p) >> (fmt)->Gshift) & 0xff; \
|
||||
(b) = ((p) >> (fmt)->Bshift) & 0xff; \
|
||||
} while (0)
|
||||
|
||||
// Assumes the channels already clipped to 8 bits
|
||||
static inline Uint32
|
||||
PACK_PIXEL_32(const SDL_PixelFormat *fmt,
|
||||
Uint8 r, Uint8 g, Uint8 b)
|
||||
{
|
||||
return ((Uint32)r << fmt->Rshift) | ((Uint32)g << fmt->Gshift)
|
||||
| ((Uint32)b << fmt->Bshift);
|
||||
}
|
||||
|
||||
static void
|
||||
renderpixel_additive(SDL_Surface *surface, int x, int y, Uint32 pixel,
|
||||
int factor)
|
||||
{
|
||||
const SDL_PixelFormat *fmt = surface->format;
|
||||
Uint32 *p;
|
||||
Uint32 sp;
|
||||
Uint8 sr, sg, sb;
|
||||
int r, g, b;
|
||||
|
||||
p = (Uint32 *) ((Uint8 *)surface->pixels + y * surface->pitch + x * 4);
|
||||
sp = *p;
|
||||
UNPACK_PIXEL_32(sp, fmt, sr, sg, sb);
|
||||
UNPACK_PIXEL_32(pixel, fmt, r, g, b);
|
||||
|
||||
// TODO: We may need a special case for factor == -ADDITIVE_FACTOR_1 too,
|
||||
// but it is not important enough right now to care ;)
|
||||
if (factor == ADDITIVE_FACTOR_1)
|
||||
{ // no need to modulate the 'pixel', and modulation does not
|
||||
// work correctly with factor==255 anyway
|
||||
sr = clip_channel(sr + r);
|
||||
sg = clip_channel(sg + g);
|
||||
sb = clip_channel(sb + b);
|
||||
}
|
||||
else
|
||||
{
|
||||
sr = modulated_sum(sr, r, factor);
|
||||
sg = modulated_sum(sg, g, factor);
|
||||
sb = modulated_sum(sb, b, factor);
|
||||
}
|
||||
|
||||
*p = PACK_PIXEL_32(fmt, sr, sg, sb);
|
||||
}
|
||||
|
||||
static void
|
||||
renderpixel_alpha(SDL_Surface *surface, int x, int y, Uint32 pixel,
|
||||
int factor)
|
||||
{
|
||||
const SDL_PixelFormat *fmt = surface->format;
|
||||
Uint32 *p;
|
||||
Uint32 sp;
|
||||
Uint8 sr, sg, sb;
|
||||
int r, g, b;
|
||||
|
||||
if (factor == FULLY_OPAQUE_ALPHA)
|
||||
{ // alpha == 255 is equivalent to 'replace' and blending does not
|
||||
// work correctly anyway because we use >> 8 instead of / 255
|
||||
putpixel_32(surface, x, y, pixel);
|
||||
return;
|
||||
}
|
||||
|
||||
p = (Uint32 *) ((Uint8 *)surface->pixels + y * surface->pitch + x * 4);
|
||||
sp = *p;
|
||||
UNPACK_PIXEL_32(sp, fmt, sr, sg, sb);
|
||||
UNPACK_PIXEL_32(pixel, fmt, r, g, b);
|
||||
sr = alpha_blend(sr, r, factor);
|
||||
sg = alpha_blend(sg, g, factor);
|
||||
sb = alpha_blend(sb, b, factor);
|
||||
*p = PACK_PIXEL_32(fmt, sr, sg, sb);
|
||||
}
|
||||
|
||||
RenderPixelFn
|
||||
renderpixel_for(SDL_Surface *surface, RenderKind kind)
|
||||
{
|
||||
const SDL_PixelFormat *fmt = surface->format;
|
||||
|
||||
// The only supported rendering is to 32bpp surfaces
|
||||
if (fmt->BytesPerPixel != 4)
|
||||
return NULL;
|
||||
|
||||
// Rendering other than REPLACE is not supported on RGBA surfaces
|
||||
if (fmt->Amask != 0 && kind != renderReplace)
|
||||
return NULL;
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case renderReplace:
|
||||
return &renderpixel_replace;
|
||||
case renderAdditive:
|
||||
return &renderpixel_additive;
|
||||
case renderAlpha:
|
||||
return &renderpixel_alpha;
|
||||
}
|
||||
// should not ever get here
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Line drawing routine
|
||||
* Adapted from Paul Heckbert's implementation of Bresenham's algorithm,
|
||||
* 3 Sep 85; taken from Graphics Gems I */
|
||||
|
||||
void
|
||||
line_prim(int x1, int y1, int x2, int y2, Uint32 color, RenderPixelFn plot,
|
||||
int factor, SDL_Surface *dst)
|
||||
{
|
||||
int d, x, y, ax, ay, sx, sy, dx, dy;
|
||||
SDL_Rect clip_r;
|
||||
|
||||
SDL_GetClipRect (dst, &clip_r);
|
||||
if (!clip_line (&x1, &y1, &x2, &y2, &clip_r))
|
||||
return; // line is completely outside clipping rectangle
|
||||
|
||||
dx = x2-x1;
|
||||
ax = ((dx < 0) ? -dx : dx) << 1;
|
||||
sx = (dx < 0) ? -1 : 1;
|
||||
dy = y2-y1;
|
||||
ay = ((dy < 0) ? -dy : dy) << 1;
|
||||
sy = (dy < 0) ? -1 : 1;
|
||||
|
||||
x = x1;
|
||||
y = y1;
|
||||
if (ax > ay) {
|
||||
d = ay - (ax >> 1);
|
||||
for (;;) {
|
||||
(*plot)(dst, x, y, color, factor);
|
||||
if (x == x2)
|
||||
return;
|
||||
if (d >= 0) {
|
||||
y += sy;
|
||||
d -= ax;
|
||||
}
|
||||
x += sx;
|
||||
d += ay;
|
||||
}
|
||||
} else {
|
||||
d = ax - (ay >> 1);
|
||||
for (;;) {
|
||||
(*plot)(dst, x, y, color, factor);
|
||||
if (y == y2)
|
||||
return;
|
||||
if (d >= 0) {
|
||||
x += sx;
|
||||
d -= ay;
|
||||
}
|
||||
y += sy;
|
||||
d += ax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clips line against rectangle using Cohen-Sutherland algorithm
|
||||
|
||||
enum {C_TOP = 0x1, C_BOTTOM = 0x2, C_RIGHT = 0x4, C_LEFT = 0x8};
|
||||
|
||||
static int
|
||||
compute_code (float x, float y, float xmin, float ymin, float xmax, float ymax)
|
||||
{
|
||||
int c = 0;
|
||||
if (y > ymax)
|
||||
c |= C_TOP;
|
||||
else if (y < ymin)
|
||||
c |= C_BOTTOM;
|
||||
if (x > xmax)
|
||||
c |= C_RIGHT;
|
||||
else if (x < xmin)
|
||||
c |= C_LEFT;
|
||||
return c;
|
||||
}
|
||||
|
||||
int
|
||||
clip_line (int *lx1, int *ly1, int *lx2, int *ly2, const SDL_Rect *r)
|
||||
{
|
||||
int C0, C1, C;
|
||||
float x, y, x0, y0, x1, y1, xmin, ymin, xmax, ymax;
|
||||
|
||||
x0 = (float)*lx1;
|
||||
y0 = (float)*ly1;
|
||||
x1 = (float)*lx2;
|
||||
y1 = (float)*ly2;
|
||||
|
||||
xmin = (float)r->x;
|
||||
ymin = (float)r->y;
|
||||
xmax = (float)r->x + r->w - 1;
|
||||
ymax = (float)r->y + r->h - 1;
|
||||
|
||||
C0 = compute_code (x0, y0, xmin, ymin, xmax, ymax);
|
||||
C1 = compute_code (x1, y1, xmin, ymin, xmax, ymax);
|
||||
|
||||
for (;;) {
|
||||
/* trivial accept: both ends in rectangle */
|
||||
if ((C0 | C1) == 0)
|
||||
{
|
||||
*lx1 = (int)x0;
|
||||
*ly1 = (int)y0;
|
||||
*lx2 = (int)x1;
|
||||
*ly2 = (int)y1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* trivial reject: both ends on the external side of the rectangle */
|
||||
if ((C0 & C1) != 0)
|
||||
return 0;
|
||||
|
||||
/* normal case: clip end outside rectangle */
|
||||
C = C0 ? C0 : C1;
|
||||
if (C & C_TOP)
|
||||
{
|
||||
x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
|
||||
y = ymax;
|
||||
}
|
||||
else if (C & C_BOTTOM)
|
||||
{
|
||||
x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
|
||||
y = ymin;
|
||||
}
|
||||
else if (C & C_RIGHT)
|
||||
{
|
||||
x = xmax;
|
||||
y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = xmin;
|
||||
y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
|
||||
}
|
||||
|
||||
/* set new end point and iterate */
|
||||
if (C == C0)
|
||||
{
|
||||
x0 = x; y0 = y;
|
||||
C0 = compute_code (x0, y0, xmin, ymin, xmax, ymax);
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = x; y1 = y;
|
||||
C1 = compute_code (x1, y1, xmin, ymin, xmax, ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fillrect_prim(SDL_Rect r, Uint32 color, RenderPixelFn plot, int factor,
|
||||
SDL_Surface *dst)
|
||||
{
|
||||
int x, y;
|
||||
int x1, y1;
|
||||
SDL_Rect clip_r;
|
||||
|
||||
SDL_GetClipRect (dst, &clip_r);
|
||||
if (!clip_rect (&r, &clip_r))
|
||||
return; // rect is completely outside clipping rectangle
|
||||
|
||||
// TODO: calculate destination pointer directly instead of
|
||||
// using the plot(x,y) version
|
||||
x1 = r.x + r.w;
|
||||
y1 = r.y + r.h;
|
||||
for (y = r.y; y < y1; ++y)
|
||||
{
|
||||
for (x = r.x; x < x1; ++x)
|
||||
plot(dst, x, y, color, factor);
|
||||
}
|
||||
}
|
||||
|
||||
// clip the rectangle against the clip rectangle
|
||||
int
|
||||
clip_rect(SDL_Rect *r, const SDL_Rect *clip_r)
|
||||
{
|
||||
// NOTE: the following clipping code is copied in part
|
||||
// from SDL-1.2.4 sources
|
||||
int dx, dy;
|
||||
int w = r->w;
|
||||
int h = r->h;
|
||||
// SDL_Rect.w and .h are unsigned, we need signed
|
||||
|
||||
dx = clip_r->x - r->x;
|
||||
if (dx > 0)
|
||||
{
|
||||
w -= dx;
|
||||
r->x += dx;
|
||||
}
|
||||
dx = r->x + w - clip_r->x - clip_r->w;
|
||||
if (dx > 0)
|
||||
w -= dx;
|
||||
|
||||
dy = clip_r->y - r->y;
|
||||
if (dy > 0)
|
||||
{
|
||||
h -= dy;
|
||||
r->y += dy;
|
||||
}
|
||||
dy = r->y + h - clip_r->y - clip_r->h;
|
||||
if (dy > 0)
|
||||
h -= dy;
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
{
|
||||
r->w = 0;
|
||||
r->h = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r->w = w;
|
||||
r->h = h;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
blt_prim(SDL_Surface *src, SDL_Rect src_r, RenderPixelFn plot, int factor,
|
||||
SDL_Surface *dst, SDL_Rect dst_r)
|
||||
{
|
||||
SDL_PixelFormat *srcfmt = src->format;
|
||||
SDL_Palette *srcpal = srcfmt->palette;
|
||||
SDL_PixelFormat *dstfmt = dst->format;
|
||||
Uint32 mask = 0;
|
||||
Uint32 key = ~0;
|
||||
GetPixelFn getpix = getpixel_for(src);
|
||||
SDL_Rect clip_r;
|
||||
int x, y;
|
||||
|
||||
SDL_GetClipRect (dst, &clip_r);
|
||||
if (!clip_blt_rects (&src_r, &dst_r, &clip_r))
|
||||
return; // rect is completely outside clipping rectangle
|
||||
|
||||
if (src_r.x >= src->w || src_r.y >= src->h)
|
||||
return; // rect is completely outside source bounds
|
||||
|
||||
if (src_r.x + src_r.w > src->w)
|
||||
src_r.w = src->w - src_r.x;
|
||||
if (src_r.y + src_r.h > src->h)
|
||||
src_r.h = src->h - src_r.y;
|
||||
|
||||
// use colorkeys where appropriate
|
||||
if (srcfmt->Amask)
|
||||
{ // alpha transparency
|
||||
mask = srcfmt->Amask;
|
||||
key = 0;
|
||||
}
|
||||
else if (src->flags & SDL_SRCCOLORKEY)
|
||||
{ // colorkey transparency
|
||||
mask = ~srcfmt->Amask;
|
||||
key = srcfmt->colorkey & mask;
|
||||
}
|
||||
|
||||
// TODO: calculate the source and destination pointers directly
|
||||
// instead of using the plot(x,y) version
|
||||
for (y = 0; y < src_r.h; ++y)
|
||||
{
|
||||
for (x = 0; x < src_r.w; ++x)
|
||||
{
|
||||
Uint8 r, g, b, a;
|
||||
Uint32 p;
|
||||
|
||||
p = getpix(src, src_r.x + x, src_r.y + y);
|
||||
if (srcpal)
|
||||
{ // source is paletted, colorkey does not use mask
|
||||
if (p == key)
|
||||
continue; // transparent pixel
|
||||
}
|
||||
else
|
||||
{ // source is RGB(A), colorkey uses mask
|
||||
if ((p & mask) == key)
|
||||
continue; // transparent pixel
|
||||
}
|
||||
|
||||
// convert pixel format to destination
|
||||
SDL_GetRGBA(p, srcfmt, &r, &g, &b, &a);
|
||||
// TODO: handle source pixel alpha; plot() should probably
|
||||
// get a source alpha parameter
|
||||
p = SDL_MapRGBA(dstfmt, r, g, b, a);
|
||||
|
||||
plot(dst, dst_r.x + x, dst_r.y + y, p, factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clip the source and destination rectangles against the clip rectangle
|
||||
int
|
||||
clip_blt_rects(SDL_Rect *src_r, SDL_Rect *dst_r, const SDL_Rect *clip_r)
|
||||
{
|
||||
// NOTE: the following clipping code is copied in part
|
||||
// from SDL-1.2.4 sources
|
||||
int w, h;
|
||||
int dx, dy;
|
||||
|
||||
// clip the source rectangle to the source surface
|
||||
w = src_r->w;
|
||||
if (src_r->x < 0)
|
||||
{
|
||||
w += src_r->x;
|
||||
dst_r->x -= src_r->x;
|
||||
src_r->x = 0;
|
||||
}
|
||||
|
||||
h = src_r->h;
|
||||
if (src_r->y < 0)
|
||||
{
|
||||
h += src_r->y;
|
||||
dst_r->y -= src_r->y;
|
||||
src_r->y = 0;
|
||||
}
|
||||
|
||||
// clip the destination rectangle against the clip rectangle,
|
||||
// minding the source rectangle in the process
|
||||
dx = clip_r->x - dst_r->x;
|
||||
if (dx > 0)
|
||||
{
|
||||
w -= dx;
|
||||
dst_r->x += dx;
|
||||
src_r->x += dx;
|
||||
}
|
||||
dx = dst_r->x + w - clip_r->x - clip_r->w;
|
||||
if (dx > 0)
|
||||
w -= dx;
|
||||
|
||||
dy = clip_r->y - dst_r->y;
|
||||
if (dy > 0)
|
||||
{
|
||||
h -= dy;
|
||||
dst_r->y += dy;
|
||||
src_r->y += dy;
|
||||
}
|
||||
dy = dst_r->y + h - clip_r->y - clip_r->h;
|
||||
if (dy > 0)
|
||||
h -= dy;
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
{
|
||||
src_r->w = 0;
|
||||
src_r->h = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
src_r->w = w;
|
||||
src_r->h = h;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef PRIMITIVES_H
|
||||
#define PRIMITIVES_H
|
||||
|
||||
/* Function types for the pixel functions */
|
||||
|
||||
typedef Uint32 (*GetPixelFn)(SDL_Surface *, int x, int y);
|
||||
// 'pixel' is in destination surface format
|
||||
typedef void (*PutPixelFn)(SDL_Surface *, int x, int y, Uint32 pixel);
|
||||
|
||||
GetPixelFn getpixel_for(SDL_Surface *surface);
|
||||
PutPixelFn putpixel_for(SDL_Surface *surface);
|
||||
|
||||
// This currently matches gfxlib.h:DrawKind for simplicity
|
||||
typedef enum
|
||||
{
|
||||
renderReplace = 0,
|
||||
renderAdditive,
|
||||
renderAlpha,
|
||||
} RenderKind;
|
||||
|
||||
#define FULLY_OPAQUE_ALPHA 255
|
||||
#define ADDITIVE_FACTOR_1 255
|
||||
|
||||
// 'pixel' is in destination surface format
|
||||
// See gfxlib.h:DrawKind for 'factor' spec
|
||||
typedef void (*RenderPixelFn)(SDL_Surface *, int x, int y, Uint32 pixel,
|
||||
int factor);
|
||||
|
||||
RenderPixelFn renderpixel_for(SDL_Surface *surface, RenderKind);
|
||||
|
||||
void line_prim(int x1, int y1, int x2, int y2, Uint32 color,
|
||||
RenderPixelFn plot, int factor, SDL_Surface *dst);
|
||||
void fillrect_prim(SDL_Rect r, Uint32 color,
|
||||
RenderPixelFn plot, int factor, SDL_Surface *dst);
|
||||
void blt_prim(SDL_Surface *src, SDL_Rect src_r,
|
||||
RenderPixelFn plot, int factor,
|
||||
SDL_Surface *dst, SDL_Rect dst_r);
|
||||
|
||||
int clip_line(int *lx1, int *ly1, int *lx2, int *ly2, const SDL_Rect *clip_r);
|
||||
int clip_rect(SDL_Rect *r, const SDL_Rect *clip_r);
|
||||
int clip_blt_rects(SDL_Rect *src_r, SDL_Rect *dst_r, const SDL_Rect *clip_r);
|
||||
|
||||
|
||||
#endif /* PRIMITIVES_H */
|
||||
484
project/jni/application/sc2/src/libs/graphics/sdl/pure.c
Normal file
484
project/jni/application/sc2/src/libs/graphics/sdl/pure.c
Normal file
@@ -0,0 +1,484 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "pure.h"
|
||||
#include "libs/graphics/bbox.h"
|
||||
#include "scalers.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
static SDL_Surface *fade_color_surface = NULL;
|
||||
static SDL_Surface *fade_temp = NULL;
|
||||
static SDL_Surface *scaled_display = NULL;
|
||||
|
||||
static TFB_ScaleFunc scaler = NULL;
|
||||
|
||||
static Uint32 fade_color;
|
||||
|
||||
static void TFB_Pure_Scaled_Preprocess (int force_full_redraw, int transition_amount, int fade_amount);
|
||||
static void TFB_Pure_Scaled_Postprocess (void);
|
||||
static void TFB_Pure_Unscaled_Preprocess (int force_full_redraw, int transition_amount, int fade_amount);
|
||||
static void TFB_Pure_Unscaled_Postprocess (void);
|
||||
static void TFB_Pure_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect);
|
||||
static void TFB_Pure_ColorLayer (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect);
|
||||
|
||||
static TFB_GRAPHICS_BACKEND pure_scaled_backend = {
|
||||
TFB_Pure_Scaled_Preprocess,
|
||||
TFB_Pure_Scaled_Postprocess,
|
||||
TFB_Pure_ScreenLayer,
|
||||
TFB_Pure_ColorLayer };
|
||||
|
||||
static TFB_GRAPHICS_BACKEND pure_unscaled_backend = {
|
||||
TFB_Pure_Unscaled_Preprocess,
|
||||
TFB_Pure_Unscaled_Postprocess,
|
||||
TFB_Pure_ScreenLayer,
|
||||
TFB_Pure_ColorLayer };
|
||||
|
||||
static SDL_Surface *
|
||||
Create_Screen (SDL_Surface *template, int w, int h)
|
||||
{
|
||||
SDL_Surface *newsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,
|
||||
template->format->BitsPerPixel,
|
||||
template->format->Rmask, template->format->Gmask,
|
||||
template->format->Bmask, 0);
|
||||
if (newsurf == 0) {
|
||||
log_add (log_Error, "Couldn't create screen buffers: %s",
|
||||
SDL_GetError());
|
||||
}
|
||||
return newsurf;
|
||||
}
|
||||
|
||||
static int
|
||||
ReInit_Screen (SDL_Surface **screen, SDL_Surface *template, int w, int h)
|
||||
{
|
||||
if (*screen)
|
||||
SDL_FreeSurface (*screen);
|
||||
*screen = Create_Screen (template, w, h);
|
||||
|
||||
return *screen == 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
// We cannot rely on SDL_DisplayFormatAlpha() anymore. It can return
|
||||
// formats that we do not expect (SDL v1.2.14 on Mac OSX). Mac likes
|
||||
// ARGB surfaces, but SDL_DisplayFormatAlpha thinks that only RGBA are fast.
|
||||
// This is a generic replacement that gives what we want.
|
||||
static void
|
||||
CalcAlphaFormat (const SDL_PixelFormat* video, SDL_PixelFormat* ours)
|
||||
{
|
||||
int valid = 0;
|
||||
|
||||
// We use 32-bit surfaces internally
|
||||
ours->BitsPerPixel = 32;
|
||||
|
||||
// Try to get as close to the video format as possible
|
||||
if (video->BitsPerPixel == 15 || video->BitsPerPixel == 16)
|
||||
{ // At least match the channel order
|
||||
ours->Rshift = video->Rshift / 5 * 8;
|
||||
ours->Gshift = video->Gshift / 5 * 8;
|
||||
ours->Bshift = video->Bshift / 5 * 8;
|
||||
valid = 1;
|
||||
}
|
||||
else if (video->BitsPerPixel == 24 || video->BitsPerPixel == 32)
|
||||
{
|
||||
// We can only use channels aligned on byte boundary
|
||||
if (video->Rshift % 8 == 0 && video->Gshift % 8 == 0
|
||||
&& video->Bshift % 8 == 0)
|
||||
{ // Match RGB in video
|
||||
ours->Rshift = video->Rshift;
|
||||
ours->Gshift = video->Gshift;
|
||||
ours->Bshift = video->Bshift;
|
||||
valid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{ // For alpha, use the unoccupied byte
|
||||
ours->Ashift = 48 - (ours->Rshift + ours->Gshift + ours->Bshift);
|
||||
// Set channels according to byte positions
|
||||
ours->Rmask = 0xff << ours->Rshift;
|
||||
ours->Gmask = 0xff << ours->Gshift;
|
||||
ours->Bmask = 0xff << ours->Bshift;
|
||||
ours->Amask = 0xff << ours->Ashift;
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback case. It does not matter what we set, but SDL likes
|
||||
// Alpha to be the highest.
|
||||
ours->Rmask = 0x000000ff;
|
||||
ours->Gmask = 0x0000ff00;
|
||||
ours->Bmask = 0x00ff0000;
|
||||
ours->Amask = 0xff000000;
|
||||
}
|
||||
|
||||
int
|
||||
TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height, int togglefullscreen)
|
||||
{
|
||||
int i, videomode_flags;
|
||||
SDL_PixelFormat conv_fmt;
|
||||
int BPP = 32;
|
||||
|
||||
GraphicsDriver = driver;
|
||||
|
||||
// must use SDL_SWSURFACE, HWSURFACE doesn't work properly
|
||||
// with fades/scaling
|
||||
if (width == 320 && height == 240)
|
||||
{
|
||||
videomode_flags = SDL_SWSURFACE;
|
||||
ScreenWidthActual = 320;
|
||||
ScreenHeightActual = 240;
|
||||
graphics_backend = &pure_unscaled_backend;
|
||||
}
|
||||
else
|
||||
{
|
||||
videomode_flags = SDL_SWSURFACE;
|
||||
ScreenWidthActual = 640;
|
||||
ScreenHeightActual = 480;
|
||||
graphics_backend = &pure_scaled_backend;
|
||||
|
||||
if (width != 640 || height != 480)
|
||||
log_add (log_Error, "Screen resolution of %dx%d not supported "
|
||||
"under pure SDL, using 640x480", width, height);
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
videomode_flags = SDL_SWSURFACE;
|
||||
ScreenWidthActual = 320;
|
||||
ScreenHeightActual = 240;
|
||||
graphics_backend = &pure_unscaled_backend;
|
||||
BPP = 16;
|
||||
#endif
|
||||
|
||||
videomode_flags |= SDL_ANYFORMAT;
|
||||
if (flags & TFB_GFXFLAGS_FULLSCREEN)
|
||||
videomode_flags |= SDL_FULLSCREEN;
|
||||
|
||||
/* We'll ask for a 32bpp frame, but it doesn't really matter, because we've set
|
||||
SDL_ANYFORMAT */
|
||||
SDL_Video = SDL_SetVideoMode (ScreenWidthActual, ScreenHeightActual,
|
||||
BPP, videomode_flags);
|
||||
|
||||
if (SDL_Video == NULL)
|
||||
{
|
||||
log_add (log_Error, "Couldn't set %ix%i video mode: %s",
|
||||
ScreenWidthActual, ScreenHeightActual,
|
||||
SDL_GetError ());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const SDL_Surface *video = SDL_GetVideoSurface ();
|
||||
const SDL_PixelFormat* fmt = video->format;
|
||||
|
||||
ScreenColorDepth = fmt->BitsPerPixel;
|
||||
log_add (log_Info, "Set the resolution to: %ix%ix%i",
|
||||
video->w, video->h, ScreenColorDepth);
|
||||
log_add (log_Info, " Video: R %08x, G %08x, B %08x, A %08x",
|
||||
fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask);
|
||||
|
||||
if (togglefullscreen)
|
||||
{
|
||||
// NOTE: We cannot change the format_conv_surf now because we
|
||||
// have already loaded lots of graphics and changing it now
|
||||
// will only lead to chaos.
|
||||
// Just check if channel order has changed significantly
|
||||
CalcAlphaFormat (fmt, &conv_fmt);
|
||||
fmt = format_conv_surf->format;
|
||||
if (conv_fmt.Rmask != fmt->Rmask || conv_fmt.Bmask != fmt->Bmask)
|
||||
log_add (log_Warning, "Warning: pixel format has changed "
|
||||
"significantly. Rendering will be slow.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a 32bpp surface in a compatible format which will supply
|
||||
// the format information to all other surfaces used in the game
|
||||
if (format_conv_surf)
|
||||
{
|
||||
SDL_FreeSurface (format_conv_surf);
|
||||
format_conv_surf = NULL;
|
||||
}
|
||||
CalcAlphaFormat (SDL_Video->format, &conv_fmt);
|
||||
format_conv_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, 0, 0,
|
||||
conv_fmt.BitsPerPixel, conv_fmt.Rmask, conv_fmt.Gmask,
|
||||
conv_fmt.Bmask, conv_fmt.Amask);
|
||||
if (!format_conv_surf)
|
||||
{
|
||||
log_add (log_Error, "Couldn't create format_conv_surf: %s",
|
||||
SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const SDL_PixelFormat* fmt = format_conv_surf->format;
|
||||
log_add (log_Info, " Internal: R %08x, G %08x, B %08x, A %08x",
|
||||
fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask);
|
||||
}
|
||||
|
||||
for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
|
||||
{
|
||||
if (0 != ReInit_Screen (&SDL_Screens[i], format_conv_surf,
|
||||
ScreenWidth, ScreenHeight))
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_Screen = SDL_Screens[0];
|
||||
TransitionScreen = SDL_Screens[2];
|
||||
|
||||
if (0 != ReInit_Screen (&fade_color_surface, format_conv_surf,
|
||||
ScreenWidth, ScreenHeight))
|
||||
return -1;
|
||||
fade_color = SDL_MapRGB (fade_color_surface->format, 0, 0, 0);
|
||||
SDL_FillRect (fade_color_surface, NULL, fade_color);
|
||||
|
||||
if (0 != ReInit_Screen (&fade_temp, format_conv_surf,
|
||||
ScreenWidth, ScreenHeight))
|
||||
return -1;
|
||||
|
||||
if (ScreenWidthActual > ScreenWidth || ScreenHeightActual > ScreenHeight)
|
||||
{
|
||||
if (0 != ReInit_Screen (&scaled_display, format_conv_surf,
|
||||
ScreenWidthActual, ScreenHeightActual))
|
||||
return -1;
|
||||
|
||||
scaler = Scale_PrepPlatform (flags, SDL_Screen->format);
|
||||
}
|
||||
else
|
||||
{ // no need to scale
|
||||
scaler = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
TFB_Pure_InitGraphics (int driver, int flags, int width, int height)
|
||||
{
|
||||
char VideoName[256];
|
||||
|
||||
log_add (log_Info, "Initializing Pure-SDL graphics.");
|
||||
|
||||
SDL_VideoDriverName (VideoName, sizeof (VideoName));
|
||||
log_add (log_Info, "SDL driver used: %s", VideoName);
|
||||
// Set the environment variable SDL_VIDEODRIVER to override
|
||||
// For Linux: x11 (default), dga, fbcon, directfb, svgalib,
|
||||
// ggi, aalib
|
||||
// For Windows: directx (default), windib
|
||||
|
||||
log_add (log_Info, "SDL initialized.");
|
||||
log_add (log_Info, "Initializing Screen.");
|
||||
|
||||
ScreenWidth = 320;
|
||||
ScreenHeight = 240;
|
||||
|
||||
if (TFB_Pure_ConfigureVideo (driver, flags, width, height, 0))
|
||||
{
|
||||
log_add (log_Fatal, "Could not initialize video: "
|
||||
"no fallback at start of program!");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Initialize scalers (let them precompute whatever)
|
||||
Scale_Init ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ScanLines (SDL_Surface *dst, SDL_Rect *r)
|
||||
{
|
||||
const int rw = r->w * 2;
|
||||
const int rh = r->h * 2;
|
||||
SDL_PixelFormat *fmt = dst->format;
|
||||
const int pitch = dst->pitch;
|
||||
const int len = pitch / fmt->BytesPerPixel;
|
||||
int ddst;
|
||||
Uint32 *p = (Uint32 *) dst->pixels;
|
||||
int x, y;
|
||||
|
||||
p += len * (r->y * 2) + (r->x * 2);
|
||||
ddst = len + len - rw;
|
||||
|
||||
for (y = rh; y; y -= 2, p += ddst)
|
||||
{
|
||||
for (x = rw; x; --x, ++p)
|
||||
{
|
||||
// we ignore the lower bits as the difference
|
||||
// of 1 in 255 is negligible
|
||||
*p = ((*p >> 1) & 0x7f7f7f7f) + ((*p >> 2) & 0x3f3f3f3f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_Surface *backbuffer = NULL, *scalebuffer = NULL;
|
||||
static SDL_Rect updated;
|
||||
|
||||
static void
|
||||
TFB_Pure_Scaled_Preprocess (int force_full_redraw, int transition_amount, int fade_amount)
|
||||
{
|
||||
if (force_full_redraw != TFB_REDRAW_NO)
|
||||
{
|
||||
updated.x = updated.y = 0;
|
||||
updated.w = ScreenWidth;
|
||||
updated.h = ScreenHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
updated.x = TFB_BBox.region.corner.x;
|
||||
updated.y = TFB_BBox.region.corner.y;
|
||||
updated.w = TFB_BBox.region.extent.width;
|
||||
updated.h = TFB_BBox.region.extent.height;
|
||||
}
|
||||
|
||||
if (transition_amount == 255 && fade_amount == 255)
|
||||
backbuffer = SDL_Screens[TFB_SCREEN_MAIN];
|
||||
else
|
||||
backbuffer = fade_temp;
|
||||
|
||||
// we can scale directly onto SDL_Video if video is compatible
|
||||
if (SDL_Video->format->BitsPerPixel == SDL_Screen->format->BitsPerPixel
|
||||
&& SDL_Video->format->Rmask == SDL_Screen->format->Rmask
|
||||
&& SDL_Video->format->Bmask == SDL_Screen->format->Bmask)
|
||||
scalebuffer = SDL_Video;
|
||||
else
|
||||
scalebuffer = scaled_display;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_Pure_Unscaled_Preprocess (int force_full_redraw, int transition_amount, int fade_amount)
|
||||
{
|
||||
if (force_full_redraw != TFB_REDRAW_NO)
|
||||
{
|
||||
updated.x = updated.y = 0;
|
||||
updated.w = ScreenWidth;
|
||||
updated.h = ScreenHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
updated.x = TFB_BBox.region.corner.x;
|
||||
updated.y = TFB_BBox.region.corner.y;
|
||||
updated.w = TFB_BBox.region.extent.width;
|
||||
updated.h = TFB_BBox.region.extent.height;
|
||||
}
|
||||
|
||||
backbuffer = SDL_Video;
|
||||
(void)transition_amount;
|
||||
(void)fade_amount;
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_Pure_Scaled_Postprocess (void)
|
||||
{
|
||||
SDL_LockSurface (scalebuffer);
|
||||
SDL_LockSurface (backbuffer);
|
||||
|
||||
if (scaler)
|
||||
scaler (backbuffer, scalebuffer, &updated);
|
||||
|
||||
if (GfxFlags & TFB_GFXFLAGS_SCANLINES)
|
||||
ScanLines (scalebuffer, &updated);
|
||||
|
||||
SDL_UnlockSurface (backbuffer);
|
||||
SDL_UnlockSurface (scalebuffer);
|
||||
|
||||
updated.x *= 2;
|
||||
updated.y *= 2;
|
||||
updated.w *= 2;
|
||||
updated.h *= 2;
|
||||
if (scalebuffer != SDL_Video)
|
||||
SDL_BlitSurface (scalebuffer, &updated, SDL_Video, &updated);
|
||||
|
||||
SDL_UpdateRects (SDL_Video, 1, &updated);
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_Pure_Unscaled_Postprocess (void)
|
||||
{
|
||||
SDL_UpdateRect (SDL_Video, updated.x, updated.y,
|
||||
updated.w, updated.h);
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_Pure_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect)
|
||||
{
|
||||
if (SDL_Screens[screen] == backbuffer)
|
||||
return;
|
||||
SDL_SetAlpha (SDL_Screens[screen], SDL_SRCALPHA, a);
|
||||
SDL_BlitSurface (SDL_Screens[screen], rect, backbuffer, rect);
|
||||
}
|
||||
|
||||
static void
|
||||
TFB_Pure_ColorLayer (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect)
|
||||
{
|
||||
Uint32 col = SDL_MapRGB (fade_color_surface->format, r, g, b);
|
||||
if (col != fade_color)
|
||||
{
|
||||
fade_color = col;
|
||||
SDL_FillRect (fade_color_surface, NULL, fade_color);
|
||||
}
|
||||
SDL_SetAlpha (fade_color_surface, SDL_SRCALPHA, a);
|
||||
SDL_BlitSurface (fade_color_surface, rect, backbuffer, rect);
|
||||
}
|
||||
|
||||
void
|
||||
Scale_PerfTest (void)
|
||||
{
|
||||
TimeCount TimeStart, TimeIn;
|
||||
TimeCount Now = 0;
|
||||
SDL_Rect updated = {0, 0, ScreenWidth, ScreenHeight};
|
||||
int i;
|
||||
|
||||
if (!scaler)
|
||||
{
|
||||
log_add (log_Error, "No scaler configured! "
|
||||
"Run with larger resolution, please");
|
||||
return;
|
||||
}
|
||||
if (!scaled_display)
|
||||
{
|
||||
log_add (log_Error, "Run scaler performance tests "
|
||||
"in Pure mode, please");
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LockSurface (SDL_Screen);
|
||||
SDL_LockSurface (scaled_display);
|
||||
|
||||
TimeStart = TimeIn = SDL_GetTicks ();
|
||||
|
||||
for (i = 1; i < 1001; ++i) // run for 1000 frames
|
||||
{
|
||||
scaler (SDL_Screen, scaled_display, &updated);
|
||||
|
||||
if (GfxFlags & TFB_GFXFLAGS_SCANLINES)
|
||||
ScanLines (scaled_display, &updated);
|
||||
|
||||
if (i % 100 == 0)
|
||||
{
|
||||
Now = SDL_GetTicks ();
|
||||
log_add (log_Debug, "%03d(%04u) ", 100*1000 / (Now - TimeIn),
|
||||
Now - TimeIn);
|
||||
TimeIn = Now;
|
||||
}
|
||||
}
|
||||
|
||||
log_add (log_Debug, "Full frames scaled: %d; over %u ms; %d fps\n",
|
||||
(i - 1), Now - TimeStart, i * 1000 / (Now - TimeStart));
|
||||
|
||||
SDL_UnlockSurface (scaled_display);
|
||||
SDL_UnlockSurface (SDL_Screen);
|
||||
}
|
||||
|
||||
28
project/jni/application/sc2/src/libs/graphics/sdl/pure.h
Normal file
28
project/jni/application/sc2/src/libs/graphics/sdl/pure.h
Normal file
@@ -0,0 +1,28 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef PURE_H
|
||||
#define PURE_H
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
|
||||
int TFB_Pure_InitGraphics (int driver, int flags, int width, int height);
|
||||
int TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height, int togglefullscreen);
|
||||
void Scale_PerfTest (void);
|
||||
|
||||
#endif
|
||||
1025
project/jni/application/sc2/src/libs/graphics/sdl/rotozoom.c
Normal file
1025
project/jni/application/sc2/src/libs/graphics/sdl/rotozoom.c
Normal file
File diff suppressed because it is too large
Load Diff
96
project/jni/application/sc2/src/libs/graphics/sdl/rotozoom.h
Normal file
96
project/jni/application/sc2/src/libs/graphics/sdl/rotozoom.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
rotozoom.h - rotozoomer for 32bit or 8bit surfaces
|
||||
LGPL (c) A. Schiffler
|
||||
|
||||
Note by sc2 developers:
|
||||
Taken from SDL_gfx library and modified, original code can be downloaded
|
||||
from http://www.ferzkopp.net/Software/SDL_gfx-2.0/
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ROTOZOOM_H
|
||||
#define ROTOZOOM_H
|
||||
|
||||
#include <math.h>
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.141592654
|
||||
#endif
|
||||
|
||||
#include "port.h"
|
||||
#include SDL_INCLUDE(SDL.h)
|
||||
|
||||
|
||||
/* ---- Defines */
|
||||
|
||||
#define SMOOTHING_OFF 0
|
||||
#define SMOOTHING_ON 1
|
||||
|
||||
/* ---- Structures */
|
||||
|
||||
typedef struct tColorRGBA {
|
||||
Uint8 r;
|
||||
Uint8 g;
|
||||
Uint8 b;
|
||||
Uint8 a;
|
||||
} tColorRGBA;
|
||||
|
||||
typedef struct tColorY {
|
||||
Uint8 y;
|
||||
} tColorY;
|
||||
|
||||
|
||||
/* ---- Prototypes */
|
||||
|
||||
/*
|
||||
zoomSurfaceRGBA()
|
||||
|
||||
Zoom the src surface into dst. The zoom amount is determined
|
||||
by the dimensions of src and dst
|
||||
|
||||
*/
|
||||
int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int smooth);
|
||||
|
||||
/*
|
||||
|
||||
rotozoomSurface()
|
||||
|
||||
Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
|
||||
'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1
|
||||
then the destination 32bit surface is anti-aliased. If the surface is not 8bit
|
||||
or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
|
||||
|
||||
*/
|
||||
|
||||
SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom,
|
||||
int smooth);
|
||||
|
||||
int rotateSurface(SDL_Surface * src, SDL_Surface * dst, double angle,
|
||||
int smooth);
|
||||
|
||||
/* Returns the size of the target surface for a rotozoomSurface() call */
|
||||
|
||||
void rotozoomSurfaceSize(int width, int height, double angle, double zoom,
|
||||
int *dstwidth, int *dstheight);
|
||||
|
||||
/*
|
||||
|
||||
zoomSurface()
|
||||
|
||||
Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
|
||||
'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1
|
||||
then the destination 32bit surface is anti-aliased. If the surface is not 8bit
|
||||
or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
|
||||
|
||||
*/
|
||||
|
||||
SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy,
|
||||
int smooth);
|
||||
|
||||
/* Returns the size of the target surface for a zoomSurface() call */
|
||||
|
||||
void zoomSurfaceSize(int width, int height, double zoomx, double zoomy,
|
||||
int *dstwidth, int *dstheight);
|
||||
|
||||
#endif
|
||||
433
project/jni/application/sc2/src/libs/graphics/sdl/scaleint.h
Normal file
433
project/jni/application/sc2/src/libs/graphics/sdl/scaleint.h
Normal file
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alex Volkov (codepro@usa.net)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Scalers Internals
|
||||
|
||||
#ifndef SCALEINT_H_
|
||||
#define SCALEINT_H_
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
|
||||
|
||||
// Plain C names
|
||||
#define SCALE_(name) Scale ## _ ## name
|
||||
|
||||
// These are defaults
|
||||
#define SCALE_GETPIX(p) ( *(Uint32 *)(p) )
|
||||
#define SCALE_SETPIX(p, c) ( *(Uint32 *)(p) = (c) )
|
||||
|
||||
// Plain C defaults
|
||||
#define SCALE_CMPRGB(p1, p2) \
|
||||
SCALE_(GetRGBDelta) (fmt, p1, p2)
|
||||
|
||||
#define SCALE_TOYUV(p) \
|
||||
SCALE_(RGBtoYUV) (fmt, p)
|
||||
|
||||
#define SCALE_CMPYUV(p1, p2, toler) \
|
||||
SCALE_(CmpYUV) (fmt, p1, p2, toler)
|
||||
|
||||
#define SCALE_DIFFYUV(p1, p2) \
|
||||
SCALE_(DiffYUV) (p1, p2)
|
||||
#define SCALE_DIFFYUV_TY 0x40
|
||||
#define SCALE_DIFFYUV_TU 0x12
|
||||
#define SCALE_DIFFYUV_TV 0x0c
|
||||
|
||||
#define SCALE_GETY(p) \
|
||||
SCALE_(GetPixY) (fmt, p)
|
||||
|
||||
#define SCALE_BILINEAR_BLEND4(r0, r1, dst, dlen) \
|
||||
SCALE_(Blend_bilinear) (r0, r1, dst, dlen)
|
||||
|
||||
#define NO_PREFETCH 0
|
||||
#define INTEL_PREFETCH 1
|
||||
#define AMD_PREFETCH 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
YUV_XFORM_R = 0,
|
||||
YUV_XFORM_G = 1,
|
||||
YUV_XFORM_B = 2,
|
||||
YUV_XFORM_Y = 0,
|
||||
YUV_XFORM_U = 1,
|
||||
YUV_XFORM_V = 2
|
||||
} RGB_YUV_INDEX;
|
||||
|
||||
extern const int YUV_matrix[3][3];
|
||||
|
||||
// pre-computed transformations for 8 bits per channel
|
||||
extern int RGB_to_YUV[/*RGB*/ 3][/*YUV*/ 3][ /*mult-res*/ 256];
|
||||
extern sint16 dRGB_to_dYUV[/*RGB*/ 3][/*YUV*/ 3][ /*mult-res*/ 512];
|
||||
|
||||
typedef Uint32 YUV_VECTOR;
|
||||
// pre-computed transformations for RGB555
|
||||
extern YUV_VECTOR RGB15_to_YUV[0x8000];
|
||||
|
||||
|
||||
// Platform+Scaler function lookups
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
int flag;
|
||||
TFB_ScaleFunc func;
|
||||
} Scale_FuncDef_t;
|
||||
|
||||
|
||||
// expands the given rectangle in all directions by 'expansion'
|
||||
// guarded by 'limits'
|
||||
extern void Scale_ExpandRect (SDL_Rect* rect, int expansion,
|
||||
const SDL_Rect* limits);
|
||||
|
||||
|
||||
// Standard plain C versions of support functions
|
||||
|
||||
// Initialize various platform-specific features
|
||||
static inline void
|
||||
SCALE_(PlatInit) (void)
|
||||
{
|
||||
}
|
||||
|
||||
// Finish with various platform-specific features
|
||||
static inline void
|
||||
SCALE_(PlatDone) (void)
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline void
|
||||
SCALE_(Prefetch) (const void* p)
|
||||
{
|
||||
/* no-op in pure C */
|
||||
(void)p;
|
||||
}
|
||||
#else
|
||||
# define Scale_Prefetch(p)
|
||||
#endif
|
||||
|
||||
// compute the RGB distance squared between 2 pixels
|
||||
// Plain C version
|
||||
static inline int
|
||||
SCALE_(GetRGBDelta) (const SDL_PixelFormat* fmt, Uint32 pix1, Uint32 pix2)
|
||||
{
|
||||
int c;
|
||||
int delta;
|
||||
|
||||
c = ((pix1 >> fmt->Rshift) & 0xff) - ((pix2 >> fmt->Rshift) & 0xff);
|
||||
delta = c * c;
|
||||
|
||||
c = ((pix1 >> fmt->Gshift) & 0xff) - ((pix2 >> fmt->Gshift) & 0xff);
|
||||
delta += c * c;
|
||||
|
||||
c = ((pix1 >> fmt->Bshift) & 0xff) - ((pix2 >> fmt->Bshift) & 0xff);
|
||||
delta += c * c;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
// retrieve the Y (intensity) component of pixel's YUV
|
||||
// Plain C version
|
||||
static inline int
|
||||
SCALE_(GetPixY) (const SDL_PixelFormat* fmt, Uint32 pix)
|
||||
{
|
||||
Uint32 r, g, b;
|
||||
|
||||
r = (pix >> fmt->Rshift) & 0xff;
|
||||
g = (pix >> fmt->Gshift) & 0xff;
|
||||
b = (pix >> fmt->Bshift) & 0xff;
|
||||
|
||||
return RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_Y][r]
|
||||
+ RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_Y][g]
|
||||
+ RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_Y][b];
|
||||
}
|
||||
|
||||
static inline YUV_VECTOR
|
||||
SCALE_(RGBtoYUV) (const SDL_PixelFormat* fmt, Uint32 pix)
|
||||
{
|
||||
return RGB15_to_YUV[
|
||||
(((pix >> (fmt->Rshift + 3)) & 0x1f) << 10) |
|
||||
(((pix >> (fmt->Gshift + 3)) & 0x1f) << 5) |
|
||||
(((pix >> (fmt->Bshift + 3)) & 0x1f) )
|
||||
];
|
||||
}
|
||||
|
||||
// compare 2 pixels with respect to their YUV representations
|
||||
// tolerance set by toler arg
|
||||
// returns true: close; false: distant (-gt toler)
|
||||
// Plain C version
|
||||
static inline bool
|
||||
SCALE_(CmpYUV) (const SDL_PixelFormat* fmt, Uint32 pix1, Uint32 pix2, int toler)
|
||||
#if 1
|
||||
{
|
||||
int dr, dg, db;
|
||||
int delta;
|
||||
|
||||
dr = ((pix1 >> fmt->Rshift) & 0xff) - ((pix2 >> fmt->Rshift) & 0xff) + 255;
|
||||
dg = ((pix1 >> fmt->Gshift) & 0xff) - ((pix2 >> fmt->Gshift) & 0xff) + 255;
|
||||
db = ((pix1 >> fmt->Bshift) & 0xff) - ((pix2 >> fmt->Bshift) & 0xff) + 255;
|
||||
|
||||
// compute Y delta
|
||||
delta = abs (dRGB_to_dYUV [YUV_XFORM_R][YUV_XFORM_Y][dr]
|
||||
+ dRGB_to_dYUV [YUV_XFORM_G][YUV_XFORM_Y][dg]
|
||||
+ dRGB_to_dYUV [YUV_XFORM_B][YUV_XFORM_Y][db]);
|
||||
if (delta > toler)
|
||||
return false;
|
||||
|
||||
// compute U delta
|
||||
delta += abs (dRGB_to_dYUV [YUV_XFORM_R][YUV_XFORM_U][dr]
|
||||
+ dRGB_to_dYUV [YUV_XFORM_G][YUV_XFORM_U][dg]
|
||||
+ dRGB_to_dYUV [YUV_XFORM_B][YUV_XFORM_U][db]);
|
||||
if (delta > toler)
|
||||
return false;
|
||||
|
||||
// compute V delta
|
||||
delta += abs (dRGB_to_dYUV [YUV_XFORM_R][YUV_XFORM_V][dr]
|
||||
+ dRGB_to_dYUV [YUV_XFORM_G][YUV_XFORM_V][dg]
|
||||
+ dRGB_to_dYUV [YUV_XFORM_B][YUV_XFORM_V][db]);
|
||||
|
||||
return delta <= toler;
|
||||
}
|
||||
#else
|
||||
{
|
||||
int delta;
|
||||
Uint32 yuv1, yuv2;
|
||||
|
||||
yuv1 = RGB15_to_YUV[
|
||||
(((pix1 >> (fmt->Rshift + 3)) & 0x1f) << 10) |
|
||||
(((pix1 >> (fmt->Gshift + 3)) & 0x1f) << 5) |
|
||||
(((pix1 >> (fmt->Bshift + 3)) & 0x1f) )
|
||||
];
|
||||
|
||||
yuv2 = RGB15_to_YUV[
|
||||
(((pix2 >> (fmt->Rshift + 3)) & 0x1f) << 10) |
|
||||
(((pix2 >> (fmt->Gshift + 3)) & 0x1f) << 5) |
|
||||
(((pix2 >> (fmt->Bshift + 3)) & 0x1f) )
|
||||
];
|
||||
|
||||
// compute Y delta
|
||||
delta = abs ((yuv1 & 0xff0000) - (yuv2 & 0xff0000)) >> 16;
|
||||
if (delta > toler)
|
||||
return false;
|
||||
|
||||
// compute U delta
|
||||
delta += abs ((yuv1 & 0x00ff00) - (yuv2 & 0x00ff00)) >> 8;
|
||||
if (delta > toler)
|
||||
return false;
|
||||
|
||||
// compute V delta
|
||||
delta += abs ((yuv1 & 0x0000ff) - (yuv2 & 0x0000ff));
|
||||
|
||||
return delta <= toler;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if 2 pixels are different with respect to their
|
||||
// YUV representations
|
||||
// returns 0: close; ~0: distant
|
||||
static inline int
|
||||
SCALE_(DiffYUV) (Uint32 yuv1, Uint32 yuv2)
|
||||
{
|
||||
// non-branching version -- assumes 2's complement integers
|
||||
// delta math only needs 25 bits and we have 32 available;
|
||||
// only interested in the sign bits after subtraction
|
||||
sint32 delta, ret;
|
||||
|
||||
if (yuv1 == yuv2)
|
||||
return 0;
|
||||
|
||||
// compute Y delta
|
||||
delta = abs ((yuv1 & 0xff0000) - (yuv2 & 0xff0000));
|
||||
ret = (SCALE_DIFFYUV_TY << 16) - delta; // save sign bit
|
||||
|
||||
// compute U delta
|
||||
delta = abs ((yuv1 & 0x00ff00) - (yuv2 & 0x00ff00));
|
||||
ret |= (SCALE_DIFFYUV_TU << 8) - delta; // save sign bit
|
||||
|
||||
// compute V delta
|
||||
delta = abs ((yuv1 & 0x0000ff) - (yuv2 & 0x0000ff));
|
||||
ret |= SCALE_DIFFYUV_TV - delta; // save sign bit
|
||||
|
||||
return (ret >> 31);
|
||||
}
|
||||
|
||||
// blends two pixels with 1:1 ratio
|
||||
static inline Uint32
|
||||
SCALE_(Blend_11) (Uint32 pix1, Uint32 pix2)
|
||||
{
|
||||
/* (pix1 + pix2) >> 1 */
|
||||
return
|
||||
/* lower bits can be safely ignored - the error is minimal
|
||||
expression that calcs them is left for posterity
|
||||
(pix1 & pix2 & low_mask) +
|
||||
*/
|
||||
((pix1 & 0xfefefefe) >> 1) + ((pix2 & 0xfefefefe) >> 1);
|
||||
}
|
||||
|
||||
// blends four pixels with 1:1:1:1 ratio
|
||||
static inline Uint32
|
||||
SCALE_(Blend_1111) (Uint32 pix1, Uint32 pix2,
|
||||
Uint32 pix3, Uint32 pix4)
|
||||
{
|
||||
/* (pix1 + pix2 + pix3 + pix4) >> 2 */
|
||||
return
|
||||
/* lower bits can be safely ignored - the error is minimal
|
||||
expression that calcs them is left for posterity
|
||||
((((pix1 & low_mask) + (pix2 & low_mask) +
|
||||
(pix3 & low_mask) + (pix4 & low_mask)
|
||||
) >> 2) & low_mask) +
|
||||
*/
|
||||
((pix1 & 0xfcfcfcfc) >> 2) + ((pix2 & 0xfcfcfcfc) >> 2) +
|
||||
((pix3 & 0xfcfcfcfc) >> 2) + ((pix4 & 0xfcfcfcfc) >> 2);
|
||||
}
|
||||
|
||||
// blends pixels with 3:1 ratio
|
||||
static inline Uint32
|
||||
Scale_Blend_31 (Uint32 pix1, Uint32 pix2)
|
||||
{
|
||||
/* (pix1 * 3 + pix2) / 4 */
|
||||
/* lower bits can be safely ignored - the error is minimal */
|
||||
return ((pix1 & 0xfefefefe) >> 1) + ((pix1 & 0xfcfcfcfc) >> 2) +
|
||||
((pix2 & 0xfcfcfcfc) >> 2);
|
||||
}
|
||||
|
||||
// blends pixels with 2:1:1 ratio
|
||||
static inline Uint32
|
||||
Scale_Blend_211 (Uint32 pix1, Uint32 pix2, Uint32 pix3)
|
||||
{
|
||||
/* (pix1 * 2 + pix2 + pix3) / 4 */
|
||||
/* lower bits can be safely ignored - the error is minimal */
|
||||
return ((pix1 & 0xfefefefe) >> 1) +
|
||||
((pix2 & 0xfcfcfcfc) >> 2) +
|
||||
((pix3 & 0xfcfcfcfc) >> 2);
|
||||
}
|
||||
|
||||
// blends pixels with 5:2:1 ratio
|
||||
static inline Uint32
|
||||
Scale_Blend_521 (Uint32 pix1, Uint32 pix2, Uint32 pix3)
|
||||
{
|
||||
/* (pix1 * 5 + pix2 * 2 + pix3) / 8 */
|
||||
/* lower bits can be safely ignored - the error is minimal */
|
||||
return ((pix1 & 0xfefefefe) >> 1) + ((pix1 & 0xf8f8f8f8) >> 3) +
|
||||
((pix2 & 0xfcfcfcfc) >> 2) +
|
||||
((pix3 & 0xf8f8f8f8) >> 3) +
|
||||
0x02020202 /* half-error */;
|
||||
}
|
||||
|
||||
// blends pixels with 6:1:1 ratio
|
||||
static inline Uint32
|
||||
Scale_Blend_611 (Uint32 pix1, Uint32 pix2, Uint32 pix3)
|
||||
{
|
||||
/* (pix1 * 6 + pix2 + pix3) / 8 */
|
||||
/* lower bits can be safely ignored - the error is minimal */
|
||||
return ((pix1 & 0xfefefefe) >> 1) + ((pix1 & 0xfcfcfcfc) >> 2) +
|
||||
((pix2 & 0xf8f8f8f8) >> 3) +
|
||||
((pix3 & 0xf8f8f8f8) >> 3) +
|
||||
0x02020202 /* half-error */;
|
||||
}
|
||||
|
||||
// blends pixels with 2:3:3 ratio
|
||||
static inline Uint32
|
||||
Scale_Blend_233 (Uint32 pix1, Uint32 pix2, Uint32 pix3)
|
||||
{
|
||||
/* (pix1 * 2 + pix2 * 3 + pix3 * 3) / 8 */
|
||||
/* lower bits can be safely ignored - the error is minimal */
|
||||
return ((pix1 & 0xfcfcfcfc) >> 2) +
|
||||
((pix2 & 0xfcfcfcfc) >> 2) + ((pix2 & 0xf8f8f8f8) >> 3) +
|
||||
((pix3 & 0xfcfcfcfc) >> 2) + ((pix3 & 0xf8f8f8f8) >> 3) +
|
||||
0x02020202 /* half-error */;
|
||||
}
|
||||
|
||||
// blends pixels with 14:1:1 ratio
|
||||
static inline Uint32
|
||||
Scale_Blend_e11 (Uint32 pix1, Uint32 pix2, Uint32 pix3)
|
||||
{
|
||||
/* (pix1 * 14 + pix2 + pix3) >> 4 */
|
||||
/* lower bits can be safely ignored - the error is minimal */
|
||||
return ((pix1 & 0xfefefefe) >> 1) + ((pix1 & 0xfcfcfcfc) >> 2) +
|
||||
((pix1 & 0xf8f8f8f8) >> 3) +
|
||||
((pix2 & 0xf0f0f0f0) >> 4) +
|
||||
((pix3 & 0xf0f0f0f0) >> 4) +
|
||||
0x03030303 /* half-error */;
|
||||
}
|
||||
|
||||
// Halfs the pixel's intensity
|
||||
static inline Uint32
|
||||
SCALE_(HalfPixel) (Uint32 pix)
|
||||
{
|
||||
return ((pix & 0xfefefefe) >> 1);
|
||||
}
|
||||
|
||||
|
||||
// Bilinear weighted blend of four pixels
|
||||
// Function produces 4 blended pixels and writes them
|
||||
// out to the surface (in 2x2 matrix)
|
||||
// Pixels are computed using expanded weight matrix like so:
|
||||
// ('sp' - source pixel, 'dp' - destination pixel)
|
||||
// dp[0] = (9*sp[0] + 3*sp[1] + 3*sp[2] + 1*sp[3]) / 16
|
||||
// dp[1] = (3*sp[0] + 9*sp[1] + 1*sp[2] + 3*sp[3]) / 16
|
||||
// dp[2] = (3*sp[0] + 1*sp[1] + 9*sp[2] + 3*sp[3]) / 16
|
||||
// dp[3] = (1*sp[0] + 3*sp[1] + 3*sp[2] + 9*sp[3]) / 16
|
||||
static inline void
|
||||
SCALE_(Blend_bilinear) (const Uint32* row0, const Uint32* row1,
|
||||
Uint32* dst_p, Uint32 dlen)
|
||||
{
|
||||
// We loose some lower bits here and try to compensate for
|
||||
// that by adding half-error values.
|
||||
// In general, the error is minimal (+-7)
|
||||
// The >>4 reduction is achieved gradually
|
||||
# define BL_PACKED_HALF(p) \
|
||||
(((p) & 0xfefefefe) >> 1)
|
||||
# define BL_SUM(p1, p2) \
|
||||
(BL_PACKED_HALF(p1) + BL_PACKED_HALF(p2))
|
||||
# define BL_HALF_ERR 0x01010101
|
||||
# define BL_SUM_WERR(p1, p2) \
|
||||
(BL_PACKED_HALF(p1) + BL_PACKED_HALF(p2) + BL_HALF_ERR)
|
||||
|
||||
Uint32 sum1111, sum1331, sum3113;
|
||||
|
||||
// cache p[0] + 3*(p[1] + p[2]) + p[3] in sum1331
|
||||
// cache p[1] + 3*(p[0] + p[3]) + p[2] in sum3113
|
||||
sum1331 = BL_SUM (row0[1], row1[0]);
|
||||
sum3113 = BL_SUM (row0[0], row1[1]);
|
||||
|
||||
// cache p[0] + p[1] + p[2] + p[3] in sum1111
|
||||
sum1111 = BL_SUM_WERR (sum1331, sum3113);
|
||||
|
||||
sum1331 = BL_SUM_WERR (sum1331, sum1111);
|
||||
sum1331 = BL_PACKED_HALF (sum1331);
|
||||
sum3113 = BL_SUM_WERR (sum3113, sum1111);
|
||||
sum3113 = BL_PACKED_HALF (sum3113);
|
||||
|
||||
// pixel 0 math -- (9*p[0] + 3*(p[1] + p[2]) + p[3]) / 16
|
||||
dst_p[0] = BL_PACKED_HALF (row0[0]) + sum1331;
|
||||
|
||||
// pixel 1 math -- (9*p[1] + 3*(p[0] + p[3]) + p[2]) / 16
|
||||
dst_p[1] = BL_PACKED_HALF (row0[1]) + sum3113;
|
||||
|
||||
// pixel 2 math -- (9*p[2] + 3*(p[0] + p[3]) + p[1]) / 16
|
||||
dst_p[dlen] = BL_PACKED_HALF (row1[0]) + sum3113;
|
||||
|
||||
// pixel 3 math -- (9*p[3] + 3*(p[1] + p[2]) + p[0]) / 16
|
||||
dst_p[dlen + 1] = BL_PACKED_HALF (row1[1]) + sum1331;
|
||||
|
||||
# undef BL_PACKED_HALF
|
||||
# undef BL_SUM
|
||||
# undef BL_HALF_ERR
|
||||
# undef BL_SUM_WERR
|
||||
}
|
||||
|
||||
#endif /* SCALEINT_H_ */
|
||||
793
project/jni/application/sc2/src/libs/graphics/sdl/scalemmx.h
Normal file
793
project/jni/application/sc2/src/libs/graphics/sdl/scalemmx.h
Normal file
@@ -0,0 +1,793 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alex Volkov (codepro@usa.net)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SCALEMMX_H_
|
||||
#define SCALEMMX_H_
|
||||
|
||||
#if !defined(SCALE_)
|
||||
# error Please define SCALE_(name) before including scalemmx.h
|
||||
#endif
|
||||
|
||||
#if !defined(MSVC_ASM) && !defined(GCC_ASM)
|
||||
# error Please define target assembler (MSVC_ASM, GCC_ASM) before including scalemmx.h
|
||||
#endif
|
||||
|
||||
// MMX defaults (no Format param)
|
||||
#undef SCALE_CMPRGB
|
||||
#define SCALE_CMPRGB(p1, p2) \
|
||||
SCALE_(GetRGBDelta) (p1, p2)
|
||||
|
||||
#undef SCALE_TOYUV
|
||||
#define SCALE_TOYUV(p) \
|
||||
SCALE_(RGBtoYUV) (p)
|
||||
|
||||
#undef SCALE_CMPYUV
|
||||
#define SCALE_CMPYUV(p1, p2, toler) \
|
||||
SCALE_(CmpYUV) (p1, p2, toler)
|
||||
|
||||
#undef SCALE_GETY
|
||||
#define SCALE_GETY(p) \
|
||||
SCALE_(GetPixY) (p)
|
||||
|
||||
// MMX transformation multipliers
|
||||
extern Uint64 mmx_888to555_mult;
|
||||
extern Uint64 mmx_Y_mult;
|
||||
extern Uint64 mmx_U_mult;
|
||||
extern Uint64 mmx_V_mult;
|
||||
extern Uint64 mmx_YUV_threshold;
|
||||
|
||||
#define USE_YUV_LOOKUP
|
||||
|
||||
#if defined(MSVC_ASM)
|
||||
// MSVC inline assembly versions
|
||||
|
||||
#if defined(USE_MOVNTQ)
|
||||
# define MOVNTQ(addr, val) movntq [addr], val
|
||||
#else
|
||||
# define MOVNTQ(addr, val) movq [addr], val
|
||||
#endif
|
||||
|
||||
#if USE_PREFETCH == INTEL_PREFETCH
|
||||
// using Intel SSE non-temporal prefetch
|
||||
# define PREFETCH(addr) prefetchnta [addr]
|
||||
# define HAVE_PREFETCH
|
||||
#elif USE_PREFETCH == AMD_PREFETCH
|
||||
// using AMD 3DNOW! prefetch
|
||||
# define PREFETCH(addr) prefetch [addr]
|
||||
# define HAVE_PREFETCH
|
||||
#else
|
||||
// no prefetch -- too bad for poor MMX-only souls
|
||||
# define PREFETCH(addr)
|
||||
# undef HAVE_PREFETCH
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||||
# pragma warning( disable : 4799 )
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
SCALE_(PlatInit) (void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// mm0 will be kept == 0 throughout
|
||||
// 0 is needed for bytes->words unpack instructions
|
||||
pxor mm0, mm0
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
SCALE_(PlatDone) (void)
|
||||
{
|
||||
// finish with MMX registers and yield them to FPU
|
||||
__asm
|
||||
{
|
||||
emms
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_PREFETCH)
|
||||
static inline void
|
||||
SCALE_(Prefetch) (const void* p)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, p
|
||||
PREFETCH (eax)
|
||||
}
|
||||
}
|
||||
|
||||
#else /* Not HAVE_PREFETCH */
|
||||
|
||||
static inline void
|
||||
SCALE_(Prefetch) (const void* p)
|
||||
{
|
||||
(void)p; // silence compiler
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
#endif /* HAVE_PREFETCH */
|
||||
|
||||
// compute the RGB distance squared between 2 pixels
|
||||
static inline int
|
||||
SCALE_(GetRGBDelta) (Uint32 pix1, Uint32 pix2)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// load pixels
|
||||
movd mm1, pix1
|
||||
punpcklbw mm1, mm0
|
||||
movd mm2, pix2
|
||||
punpcklbw mm2, mm0
|
||||
// get the difference between RGBA components
|
||||
psubw mm1, mm2
|
||||
// squared and sumed
|
||||
pmaddwd mm1, mm1
|
||||
// finish suming the squares
|
||||
movq mm2, mm1
|
||||
punpckhdq mm2, mm0
|
||||
paddd mm1, mm2
|
||||
// store result
|
||||
movd eax, mm1
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve the Y (intensity) component of pixel's YUV
|
||||
static inline int
|
||||
SCALE_(GetPixY) (Uint32 pix)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// load pixel
|
||||
movd mm1, pix
|
||||
punpcklbw mm1, mm0
|
||||
// process
|
||||
pmaddwd mm1, mmx_Y_mult // RGB * Yvec
|
||||
movq mm2, mm1 // finish suming
|
||||
punpckhdq mm2, mm0 // ditto
|
||||
paddd mm1, mm2 // ditto
|
||||
// store result
|
||||
movd eax, mm1
|
||||
shr eax, 14
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_YUV_LOOKUP
|
||||
|
||||
// convert pixel RGB vector into YUV representation vector
|
||||
static inline YUV_VECTOR
|
||||
SCALE_(RGBtoYUV) (Uint32 pix)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// convert RGB888 to 555
|
||||
movd mm1, pix
|
||||
punpcklbw mm1, mm0
|
||||
psrlw mm1, 3 // 8->5 bit
|
||||
pmaddwd mm1, mmx_888to555_mult // shuffle into the right channel order
|
||||
movq mm2, mm1 // finish shuffling
|
||||
punpckhdq mm2, mm0 // ditto
|
||||
por mm1, mm2 // ditto
|
||||
|
||||
// lookup the YUV vector
|
||||
movd eax, mm1
|
||||
mov eax, [RGB15_to_YUV + eax * 4]
|
||||
}
|
||||
}
|
||||
|
||||
// compare 2 pixels with respect to their YUV representations
|
||||
// tolerance set by toler arg
|
||||
// returns true: close; false: distant (-gt toler)
|
||||
static inline bool
|
||||
SCALE_(CmpYUV) (Uint32 pix1, Uint32 pix2, int toler)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// convert RGB888 to 555
|
||||
movd mm1, pix1
|
||||
punpcklbw mm1, mm0
|
||||
psrlw mm1, 3 // 8->5 bit
|
||||
movd mm3, pix2
|
||||
punpcklbw mm3, mm0
|
||||
psrlw mm3, 3 // 8->5 bit
|
||||
pmaddwd mm1, mmx_888to555_mult // shuffle into the right channel order
|
||||
movq mm2, mm1 // finish shuffling
|
||||
pmaddwd mm3, mmx_888to555_mult // shuffle into the right channel order
|
||||
movq mm4, mm3 // finish shuffling
|
||||
punpckhdq mm2, mm0 // ditto
|
||||
por mm1, mm2 // ditto
|
||||
punpckhdq mm4, mm0 // ditto
|
||||
por mm3, mm4 // ditto
|
||||
|
||||
// lookup the YUV vector
|
||||
movd eax, mm1
|
||||
movd edx, mm3
|
||||
movd mm1, [RGB15_to_YUV + eax * 4]
|
||||
movq mm4, mm1
|
||||
movd mm2, [RGB15_to_YUV + edx * 4]
|
||||
|
||||
// get abs difference between YUV components
|
||||
#ifdef USE_PSADBW
|
||||
// we can use PSADBW and save us some grief
|
||||
psadbw mm1, mm2
|
||||
movd edx, mm1
|
||||
#else
|
||||
// no PSADBW -- have to do it the hard way
|
||||
psubusb mm1, mm2
|
||||
psubusb mm2, mm4
|
||||
por mm1, mm2
|
||||
|
||||
// sum the differences
|
||||
// XXX: technically, this produces a MAX diff of 510
|
||||
// but we do not need anything bigger, currently
|
||||
movq mm2, mm1
|
||||
psrlq mm2, 8
|
||||
paddusb mm1, mm2
|
||||
psrlq mm2, 8
|
||||
paddusb mm1, mm2
|
||||
movd edx, mm1
|
||||
and edx, 0xff
|
||||
#endif /* USE_PSADBW */
|
||||
xor eax, eax
|
||||
shl edx, 1
|
||||
cmp edx, toler
|
||||
// store result
|
||||
setle al
|
||||
}
|
||||
}
|
||||
|
||||
#else /* Not USE_YUV_LOOKUP */
|
||||
|
||||
// convert pixel RGB vector into YUV representation vector
|
||||
static inline YUV_VECTOR
|
||||
SCALE_(RGBtoYUV) (Uint32 pix)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
movd mm1, pix
|
||||
punpcklbw mm1, mm0
|
||||
|
||||
movq mm2, mm1
|
||||
|
||||
// Y vector multiply
|
||||
pmaddwd mm1, mmx_Y_mult
|
||||
movq mm4, mm1
|
||||
punpckhdq mm4, mm0
|
||||
punpckldq mm1, mm0 // clear out the high dword
|
||||
paddd mm1, mm4
|
||||
psrad mm1, 15
|
||||
|
||||
movq mm3, mm2
|
||||
|
||||
// U vector multiply
|
||||
pmaddwd mm2, mmx_U_mult
|
||||
psrad mm2, 10
|
||||
|
||||
// V vector multiply
|
||||
pmaddwd mm3, mmx_V_mult
|
||||
psrad mm3, 10
|
||||
|
||||
// load (1|1|1|1) into mm4
|
||||
pcmpeqw mm4, mm4
|
||||
psrlw mm4, 15
|
||||
|
||||
packssdw mm3, mm2
|
||||
pmaddwd mm3, mm4
|
||||
psrad mm3, 5
|
||||
|
||||
// load (64|64) into mm4
|
||||
punpcklwd mm4, mm0
|
||||
pslld mm4, 6
|
||||
paddd mm3, mm4
|
||||
|
||||
packssdw mm3, mm1
|
||||
packuswb mm3, mm0
|
||||
|
||||
movd eax, mm3
|
||||
}
|
||||
}
|
||||
|
||||
// compare 2 pixels with respect to their YUV representations
|
||||
// tolerance set by toler arg
|
||||
// returns true: close; false: distant (-gt toler)
|
||||
static inline bool
|
||||
SCALE_(CmpYUV) (Uint32 pix1, Uint32 pix2, int toler)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
movd mm1, pix1
|
||||
punpcklbw mm1, mm0
|
||||
movd mm2, pix2
|
||||
punpcklbw mm2, mm0
|
||||
|
||||
psubw mm1, mm2
|
||||
movq mm2, mm1
|
||||
|
||||
// Y vector multiply
|
||||
pmaddwd mm1, mmx_Y_mult
|
||||
movq mm4, mm1
|
||||
punpckhdq mm4, mm0
|
||||
paddd mm1, mm4
|
||||
// abs()
|
||||
movq mm4, mm1
|
||||
psrad mm4, 31
|
||||
pxor mm4, mm1
|
||||
psubd mm1, mm4
|
||||
|
||||
movq mm3, mm2
|
||||
|
||||
// U vector multiply
|
||||
pmaddwd mm2, mmx_U_mult
|
||||
movq mm4, mm2
|
||||
punpckhdq mm4, mm0
|
||||
paddd mm2, mm4
|
||||
// abs()
|
||||
movq mm4, mm2
|
||||
psrad mm4, 31
|
||||
pxor mm4, mm2
|
||||
psubd mm2, mm4
|
||||
|
||||
paddd mm1, mm2
|
||||
|
||||
// V vector multiply
|
||||
pmaddwd mm3, mmx_V_mult
|
||||
movq mm4, mm3
|
||||
punpckhdq mm3, mm0
|
||||
paddd mm3, mm4
|
||||
// abs()
|
||||
movq mm4, mm3
|
||||
psrad mm4, 31
|
||||
pxor mm4, mm3
|
||||
psubd mm3, mm4
|
||||
|
||||
paddd mm1, mm3
|
||||
|
||||
movd edx, mm1
|
||||
xor eax, eax
|
||||
shr edx, 14
|
||||
cmp edx, toler
|
||||
// store result
|
||||
setle al
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_YUV_LOOKUP */
|
||||
|
||||
// Check if 2 pixels are different with respect to their
|
||||
// YUV representations
|
||||
// returns 0: close; ~0: distant
|
||||
static inline int
|
||||
SCALE_(DiffYUV) (Uint32 yuv1, Uint32 yuv2)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// load YUV pixels
|
||||
movd mm1, yuv1
|
||||
movq mm4, mm1
|
||||
movd mm2, yuv2
|
||||
// abs difference between channels
|
||||
psubusb mm1, mm2
|
||||
psubusb mm2, mm4
|
||||
por mm1, mm2
|
||||
// compare to threshold
|
||||
psubusb mm1, mmx_YUV_threshold
|
||||
|
||||
movd edx, mm1
|
||||
// transform eax to 0 or ~0
|
||||
xor eax, eax
|
||||
or edx, edx
|
||||
setz al
|
||||
dec eax
|
||||
}
|
||||
}
|
||||
|
||||
// bilinear weighted blend of four pixels
|
||||
// MSVC asm version
|
||||
static inline void
|
||||
SCALE_(Blend_bilinear) (const Uint32* row0, const Uint32* row1,
|
||||
Uint32* dst_p, Uint32 dlen)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// EL0: setup vars
|
||||
mov ebx, row0 // EL0
|
||||
|
||||
// EL0: load pixels
|
||||
movq mm1, [ebx] // EL0
|
||||
movq mm2, mm1 // EL0: p[1] -> mm2
|
||||
PREFETCH (ebx + 0x80)
|
||||
punpckhbw mm2, mm0 // EL0: p[1] -> mm2
|
||||
mov ebx, row1
|
||||
punpcklbw mm1, mm0 // EL0: p[0] -> mm1
|
||||
movq mm3, [ebx]
|
||||
movq mm4, mm3 // EL0: p[3] -> mm4
|
||||
movq mm6, mm2 // EL1.1: p[1] -> mm6
|
||||
PREFETCH (ebx + 0x80)
|
||||
punpcklbw mm3, mm0 // EL0: p[2] -> mm3
|
||||
movq mm5, mm1 // EL1.1: p[0] -> mm5
|
||||
punpckhbw mm4, mm0 // EL0: p[3] -> mm4
|
||||
|
||||
mov edi, dst_p // EL0
|
||||
|
||||
// EL1: cache p[0] + 3*(p[1] + p[2]) + p[3] in mm6
|
||||
paddw mm6, mm3 // EL1.2: p[1] + p[2] -> mm6
|
||||
// EL1: cache p[0] + p[1] + p[2] + p[3] in mm7
|
||||
movq mm7, mm6 // EL1.3: p[1] + p[2] -> mm7
|
||||
// EL1: cache p[1] + 3*(p[0] + p[3]) + p[2] in mm5
|
||||
paddw mm5, mm4 // EL1.2: p[0] + p[3] -> mm5
|
||||
psllw mm6, 1 // EL1.4: 2*(p[1] + p[2]) -> mm6
|
||||
paddw mm7, mm5 // EL1.4: sum(p[]) -> mm7
|
||||
psllw mm5, 1 // EL1.5: 2*(p[0] + p[3]) -> mm5
|
||||
paddw mm6, mm7 // EL1.5: p[0] + 3*(p[1] + p[2]) + p[3] -> mm6
|
||||
paddw mm5, mm7 // EL1.6: p[1] + 3*(p[0] + p[3]) + p[2] -> mm5
|
||||
|
||||
// EL2: pixel 0 math -- (9*p[0] + 3*(p[1] + p[2]) + p[3]) / 16
|
||||
psllw mm1, 3 // EL2.1: 8*p[0] -> mm1
|
||||
paddw mm1, mm6 // EL2.2: 9*p[0] + 3*(p[1] + p[2]) + p[3] -> mm1
|
||||
psrlw mm1, 4 // EL2.3: sum[0]/16 -> mm1
|
||||
|
||||
mov edx, dlen // EL0
|
||||
|
||||
// EL3: pixel 1 math -- (9*p[1] + 3*(p[0] + p[3]) + p[2]) / 16
|
||||
psllw mm2, 3 // EL3.1: 8*p[1] -> mm2
|
||||
paddw mm2, mm5 // EL3.2: 9*p[1] + 3*(p[0] + p[3]) + p[2] -> mm2
|
||||
psrlw mm2, 4 // EL3.3: sum[1]/16 -> mm5
|
||||
|
||||
// EL2/3: store pixels 0 & 1
|
||||
packuswb mm1, mm2 // EL2/3: pack into bytes
|
||||
MOVNTQ (edi, mm1) // EL2/3: store 2 pixels
|
||||
|
||||
// EL4: pixel 2 math -- (9*p[2] + 3*(p[0] + p[3]) + p[1]) / 16
|
||||
psllw mm3, 3 // EL4.1: 8*p[2] -> mm3
|
||||
paddw mm3, mm5 // EL4.2: 9*p[2] + 3*(p[0] + p[3]) + p[1] -> mm3
|
||||
psrlw mm3, 4 // EL4.3: sum[2]/16 -> mm3
|
||||
|
||||
// EL5: pixel 3 math -- (9*p[3] + 3*(p[1] + p[2]) + p[0]) / 16
|
||||
psllw mm4, 3 // EL5.1: 8*p[3] -> mm4
|
||||
paddw mm4, mm6 // EL5.2: 9*p[3] + 3*(p[1] + p[2]) + p[0] -> mm4
|
||||
psrlw mm4, 4 // EL5.3: sum[3]/16 -> mm4
|
||||
|
||||
// EL4/5: store pixels 2 & 3
|
||||
packuswb mm3, mm4 // EL4/5: pack into bytes
|
||||
MOVNTQ (edi + edx*4, mm3) // EL4/5: store 2 pixels
|
||||
}
|
||||
}
|
||||
// End MSVC_ASM
|
||||
|
||||
#elif defined(GCC_ASM)
|
||||
// GCC inline assembly versions
|
||||
|
||||
#if defined(USE_MOVNTQ)
|
||||
# define MOVNTQ(val, addr) "movntq " #val "," #addr
|
||||
#else
|
||||
# define MOVNTQ(val, addr) "movq " #val "," #addr
|
||||
#endif
|
||||
|
||||
#if USE_PREFETCH == INTEL_PREFETCH
|
||||
// using Intel SSE non-temporal prefetch
|
||||
# define PREFETCH(addr) "prefetchnta " #addr
|
||||
#elif USE_PREFETCH == AMD_PREFETCH
|
||||
// using AMD 3DNOW! prefetch
|
||||
# define PREFETCH(addr) "prefetch " #addr
|
||||
#else
|
||||
// no prefetch -- too bad for poor MMX-only souls
|
||||
# define PREFETCH(addr)
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__)
|
||||
# define A_REG "rax"
|
||||
# define D_REG "rdx"
|
||||
# define CLR_UPPER32(r) "xor " "%%" r "," "%%" r
|
||||
#else
|
||||
# define A_REG "eax"
|
||||
# define D_REG "edx"
|
||||
# define CLR_UPPER32(r)
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
SCALE_(PlatInit) (void)
|
||||
{
|
||||
__asm__ (
|
||||
// mm0 will be kept == 0 throughout
|
||||
// 0 is needed for bytes->words unpack instructions
|
||||
"pxor %%mm0, %%mm0 \n\t"
|
||||
|
||||
: /* nothing */
|
||||
: /* nothing */
|
||||
);
|
||||
}
|
||||
|
||||
static inline void
|
||||
SCALE_(PlatDone) (void)
|
||||
{
|
||||
// finish with MMX registers and yield them to FPU
|
||||
__asm__ (
|
||||
"emms \n\t"
|
||||
: /* nothing */ : /* nothing */
|
||||
);
|
||||
}
|
||||
|
||||
static inline void
|
||||
SCALE_(Prefetch) (const void* p)
|
||||
{
|
||||
__asm__ __volatile__ ("" PREFETCH (%0) : /*nothing*/ : "m" (p) );
|
||||
}
|
||||
|
||||
// compute the RGB distance squared between 2 pixels
|
||||
static inline int
|
||||
SCALE_(GetRGBDelta) (Uint32 pix1, Uint32 pix2)
|
||||
{
|
||||
int res;
|
||||
|
||||
__asm__ (
|
||||
// load pixels
|
||||
"movd %1, %%mm1 \n\t"
|
||||
"punpcklbw %%mm0, %%mm1 \n\t"
|
||||
"movd %2, %%mm2 \n\t"
|
||||
"punpcklbw %%mm0, %%mm2 \n\t"
|
||||
// get the difference between RGBA components
|
||||
"psubw %%mm2, %%mm1 \n\t"
|
||||
// squared and sumed
|
||||
"pmaddwd %%mm1, %%mm1 \n\t"
|
||||
// finish suming the squares
|
||||
"movq %%mm1, %%mm2 \n\t"
|
||||
"punpckhdq %%mm0, %%mm2 \n\t"
|
||||
"paddd %%mm2, %%mm1 \n\t"
|
||||
// store result
|
||||
"movd %%mm1, %0 \n\t"
|
||||
|
||||
: /*0*/"=rm" (res)
|
||||
: /*1*/"rm" (pix1), /*2*/"rm" (pix2)
|
||||
);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// retrieve the Y (intensity) component of pixel's YUV
|
||||
static inline int
|
||||
SCALE_(GetPixY) (Uint32 pix)
|
||||
{
|
||||
int ret;
|
||||
|
||||
__asm__ (
|
||||
// load pixel
|
||||
"movd %1, %%mm1 \n\t"
|
||||
"punpcklbw %%mm0, %%mm1 \n\t"
|
||||
// process
|
||||
"pmaddwd %2, %%mm1 \n\t" // R,G,B * Yvec
|
||||
"movq %%mm1, %%mm2 \n\t" // finish suming
|
||||
"punpckhdq %%mm0, %%mm2 \n\t" // ditto
|
||||
"paddd %%mm2, %%mm1 \n\t" // ditto
|
||||
// store index
|
||||
"movd %%mm1, %0 \n\t"
|
||||
|
||||
: /*0*/"=r" (ret)
|
||||
: /*1*/"rm" (pix), /*2*/"m" (mmx_Y_mult)
|
||||
);
|
||||
return ret >> 14;
|
||||
}
|
||||
|
||||
#ifdef USE_YUV_LOOKUP
|
||||
|
||||
// convert pixel RGB vector into YUV representation vector
|
||||
static inline YUV_VECTOR
|
||||
SCALE_(RGBtoYUV) (Uint32 pix)
|
||||
{
|
||||
int i;
|
||||
|
||||
__asm__ (
|
||||
// convert RGB888 to 555
|
||||
"movd %1, %%mm1 \n\t"
|
||||
"punpcklbw %%mm0, %%mm1 \n\t"
|
||||
"psrlw $3, %%mm1 \n\t" // 8->5 bit
|
||||
"pmaddwd %2, %%mm1 \n\t" // shuffle into the right channel order
|
||||
"movq %%mm1, %%mm2 \n\t" // finish shuffling
|
||||
"punpckhdq %%mm0, %%mm2 \n\t" // ditto
|
||||
"por %%mm2, %%mm1 \n\t" // ditto
|
||||
"movd %%mm1, %0 \n\t"
|
||||
|
||||
: /*0*/"=rm" (i)
|
||||
: /*1*/"rm" (pix), /*2*/"m" (mmx_888to555_mult)
|
||||
);
|
||||
return RGB15_to_YUV[i];
|
||||
}
|
||||
|
||||
// compare 2 pixels with respect to their YUV representations
|
||||
// tolerance set by toler arg
|
||||
// returns true: close; false: distant (-gt toler)
|
||||
static inline bool
|
||||
SCALE_(CmpYUV) (Uint32 pix1, Uint32 pix2, int toler)
|
||||
{
|
||||
int delta;
|
||||
|
||||
__asm__ (
|
||||
"movd %1, %%mm1 \n\t"
|
||||
"movd %2, %%mm3 \n\t"
|
||||
|
||||
// convert RGB888 to 555
|
||||
// this is somewhat parallelized
|
||||
"punpcklbw %%mm0, %%mm1 \n\t"
|
||||
CLR_UPPER32 (A_REG) "\n\t"
|
||||
"psrlw $3, %%mm1 \n\t" // 8->5 bit
|
||||
"punpcklbw %%mm0, %%mm3 \n\t"
|
||||
"psrlw $3, %%mm3 \n\t" // 8->5 bit
|
||||
"pmaddwd %4, %%mm1 \n\t" // shuffle into the right channel order
|
||||
"movq %%mm1, %%mm2 \n\t" // finish shuffling
|
||||
"pmaddwd %4, %%mm3 \n\t" // shuffle into the right channel order
|
||||
CLR_UPPER32 (D_REG) "\n\t"
|
||||
"movq %%mm3, %%mm4 \n\t" // finish shuffling
|
||||
"punpckhdq %%mm0, %%mm2 \n\t" // ditto
|
||||
"por %%mm2, %%mm1 \n\t" // ditto
|
||||
"punpckhdq %%mm0, %%mm4 \n\t" // ditto
|
||||
"por %%mm4, %%mm3 \n\t" // ditto
|
||||
|
||||
// lookup the YUV vector
|
||||
"movd %%mm1, %%eax \n\t"
|
||||
"movd %%mm3, %%edx \n\t"
|
||||
"movd (%3, %%" A_REG ", 4), %%mm1 \n\t"
|
||||
"movq %%mm1, %%mm4 \n\t"
|
||||
"movd (%3, %%" D_REG ", 4), %%mm2 \n\t"
|
||||
|
||||
// get abs difference between YUV components
|
||||
#ifdef USE_PSADBW
|
||||
// we can use PSADBW and save us some grief
|
||||
"psadbw %%mm2, %%mm1 \n\t"
|
||||
"movd %%mm1, %0 \n\t"
|
||||
#else
|
||||
// no PSADBW -- have to do it the hard way
|
||||
"psubusb %%mm2, %%mm1 \n\t"
|
||||
"psubusb %%mm4, %%mm2 \n\t"
|
||||
"por %%mm2, %%mm1 \n\t"
|
||||
|
||||
// sum the differences
|
||||
// technically, this produces a MAX diff of 510
|
||||
// but we do not need anything bigger, currently
|
||||
"movq %%mm1, %%mm2 \n\t"
|
||||
"psrlq $8, %%mm2 \n\t"
|
||||
"paddusb %%mm2, %%mm1 \n\t"
|
||||
"psrlq $8, %%mm2 \n\t"
|
||||
"paddusb %%mm2, %%mm1 \n\t"
|
||||
// store intermediate delta
|
||||
"movd %%mm1, %0 \n\t"
|
||||
"andl $0xff, %0 \n\t"
|
||||
#endif /* USE_PSADBW */
|
||||
: /*0*/"=rm" (delta)
|
||||
: /*1*/"rm" (pix1), /*2*/"rm" (pix2),
|
||||
/*3*/ "r" (RGB15_to_YUV),
|
||||
/*4*/"m" (mmx_888to555_mult)
|
||||
: "%" A_REG, "%" D_REG, "cc"
|
||||
);
|
||||
|
||||
return (delta << 1) <= toler;
|
||||
}
|
||||
|
||||
#endif /* USE_YUV_LOOKUP */
|
||||
|
||||
// Check if 2 pixels are different with respect to their
|
||||
// YUV representations
|
||||
// returns 0: close; ~0: distant
|
||||
static inline int
|
||||
SCALE_(DiffYUV) (Uint32 yuv1, Uint32 yuv2)
|
||||
{
|
||||
sint32 ret;
|
||||
|
||||
__asm__ (
|
||||
// load YUV pixels
|
||||
"movd %1, %%mm1 \n\t"
|
||||
"movq %%mm1, %%mm4 \n\t"
|
||||
"movd %2, %%mm2 \n\t"
|
||||
// abs difference between channels
|
||||
"psubusb %%mm2, %%mm1 \n\t"
|
||||
"psubusb %%mm4, %%mm2 \n\t"
|
||||
CLR_UPPER32(D_REG) "\n\t"
|
||||
"por %%mm2, %%mm1 \n\t"
|
||||
// compare to threshold
|
||||
"psubusb %3, %%mm1 \n\t"
|
||||
|
||||
"movd %%mm1, %%edx \n\t"
|
||||
// transform eax to 0 or ~0
|
||||
"xor %%" A_REG ", %%" A_REG "\n\t"
|
||||
"or %%" D_REG ", %%" D_REG "\n\t"
|
||||
"setz %%al \n\t"
|
||||
"dec %%" A_REG " \n\t"
|
||||
|
||||
: /*0*/"=a" (ret)
|
||||
: /*1*/"rm" (yuv1), /*2*/"rm" (yuv2),
|
||||
/*3*/"m" (mmx_YUV_threshold)
|
||||
: "%" D_REG, "cc"
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Bilinear weighted blend of four pixels
|
||||
// Function produces 4 blended pixels (in 2x2 matrix) and writes them
|
||||
// out to the surface
|
||||
// Last version
|
||||
static inline void
|
||||
SCALE_(Blend_bilinear) (const Uint32* row0, const Uint32* row1,
|
||||
Uint32* dst_p, Uint32 dlen)
|
||||
{
|
||||
__asm__ (
|
||||
// EL0: load pixels
|
||||
"movq %0, %%mm1 \n\t" // EL0
|
||||
"movq %%mm1, %%mm2 \n\t" // EL0: p[1] -> mm2
|
||||
PREFETCH (0x80%0) "\n\t"
|
||||
"punpckhbw %%mm0, %%mm2 \n\t" // EL0: p[1] -> mm2
|
||||
"punpcklbw %%mm0, %%mm1 \n\t" // EL0: p[0] -> mm1
|
||||
"movq %1, %%mm3 \n\t"
|
||||
"movq %%mm3, %%mm4 \n\t" // EL0: p[3] -> mm4
|
||||
"movq %%mm2, %%mm6 \n\t" // EL1.1: p[1] -> mm6
|
||||
PREFETCH (0x80%1) "\n\t"
|
||||
"punpcklbw %%mm0, %%mm3 \n\t" // EL0: p[2] -> mm3
|
||||
"movq %%mm1, %%mm5 \n\t" // EL1.1: p[0] -> mm5
|
||||
"punpckhbw %%mm0, %%mm4 \n\t" // EL0: p[3] -> mm4
|
||||
|
||||
// EL1: cache p[0] + 3*(p[1] + p[2]) + p[3] in mm6
|
||||
"paddw %%mm3, %%mm6 \n\t" // EL1.2: p[1] + p[2] -> mm6
|
||||
// EL1: cache p[0] + p[1] + p[2] + p[3] in mm7
|
||||
"movq %%mm6, %%mm7 \n\t" // EL1.3: p[1] + p[2] -> mm7
|
||||
// EL1: cache p[1] + 3*(p[0] + p[3]) + p[2] in mm5
|
||||
"paddw %%mm4, %%mm5 \n\t" // EL1.2: p[0] + p[3] -> mm5
|
||||
"psllw $1, %%mm6 \n\t" // EL1.4: 2*(p[1] + p[2]) -> mm6
|
||||
"paddw %%mm5, %%mm7 \n\t" // EL1.4: sum(p[]) -> mm7
|
||||
"psllw $1, %%mm5 \n\t" // EL1.5: 2*(p[0] + p[3]) -> mm5
|
||||
"paddw %%mm7, %%mm6 \n\t" // EL1.5: p[0] + 3*(p[1] + p[2]) + p[3] -> mm6
|
||||
"paddw %%mm7, %%mm5 \n\t" // EL1.6: p[1] + 3*(p[0] + p[3]) + p[2] -> mm5
|
||||
|
||||
// EL2: pixel 0 math -- (9*p[0] + 3*(p[1] + p[2]) + p[3]) / 16
|
||||
"psllw $3, %%mm1 \n\t" // EL2.1: 8*p[0] -> mm1
|
||||
"paddw %%mm6, %%mm1 \n\t" // EL2.2: 9*p[0] + 3*(p[1] + p[2]) + p[3] -> mm1
|
||||
"psrlw $4, %%mm1 \n\t" // EL2.3: sum[0]/16 -> mm1
|
||||
|
||||
// EL3: pixel 1 math -- (9*p[1] + 3*(p[0] + p[3]) + p[2]) / 16
|
||||
"psllw $3, %%mm2 \n\t" // EL3.1: 8*p[1] -> mm2
|
||||
"paddw %%mm5, %%mm2 \n\t" // EL3.2: 9*p[1] + 3*(p[0] + p[3]) + p[2] -> mm5
|
||||
"psrlw $4, %%mm2 \n\t" // EL3.3: sum[1]/16 -> mm5
|
||||
|
||||
// EL2/4: store pixels 0 & 1
|
||||
"packuswb %%mm2, %%mm1 \n\t" // EL2/4: pack into bytes
|
||||
MOVNTQ (%%mm1, (%2)) "\n\t" // EL2/4: store 2 pixels
|
||||
|
||||
// EL4: pixel 2 math -- (9*p[2] + 3*(p[0] + p[3]) + p[1]) / 16
|
||||
"psllw $3, %%mm3 \n\t" // EL4.1: 8*p[2] -> mm3
|
||||
"paddw %%mm5, %%mm3 \n\t" // EL4.2: 9*p[2] + 3*(p[0] + p[3]) + p[1] -> mm3
|
||||
"psrlw $4, %%mm3 \n\t" // EL4.3: sum[2]/16 -> mm3
|
||||
|
||||
// EL5: pixel 3 math -- (9*p[3] + 3*(p[1] + p[2]) + p[0]) / 16
|
||||
"psllw $3, %%mm4 \n\t" // EL5.1: 8*p[3] -> mm4
|
||||
"paddw %%mm6, %%mm4 \n\t" // EL5.2: 9*p[3] + 3*(p[1] + p[2]) + p[0] -> mm4
|
||||
"psrlw $4, %%mm4 \n\t" // EL5.3: sum[3]/16 -> mm4
|
||||
|
||||
// EL4/5: store pixels 2 & 3
|
||||
"packuswb %%mm4, %%mm3 \n\t" // EL4/5: pack into bytes
|
||||
MOVNTQ (%%mm3, (%2,%3,4)) "\n\t" // EL4/5: store 2 pixels
|
||||
|
||||
: /* nothing */
|
||||
: /*0*/"m" (*row0), /*1*/"m" (*row1), /*2*/"r" (dst_p),
|
||||
/*3*/"r" ((unsigned long)dlen) /* 'long' is for proper reg alloc on amd64 */
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#undef A_REG
|
||||
#undef D_REG
|
||||
#undef CLR_UPPER32
|
||||
|
||||
#endif // GCC_ASM
|
||||
|
||||
#endif /* SCALEMMX_H_ */
|
||||
286
project/jni/application/sc2/src/libs/graphics/sdl/scalers.c
Normal file
286
project/jni/application/sc2/src/libs/graphics/sdl/scalers.c
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "libs/platform.h"
|
||||
#include "libs/log.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
#ifdef USE_PLATFORM_ACCEL
|
||||
# ifndef __APPLE__
|
||||
// MacOS X framework has no SDL_cpuinfo.h for some reason
|
||||
# include SDL_INCLUDE(SDL_cpuinfo.h)
|
||||
# endif
|
||||
# ifdef MMX_ASM
|
||||
# include "2xscalers_mmx.h"
|
||||
# endif /* MMX_ASM */
|
||||
#endif /* USE_PLATFORM_ACCEL */
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SCALEPLAT_NULL = PLATFORM_NULL,
|
||||
SCALEPLAT_C = PLATFORM_C,
|
||||
SCALEPLAT_MMX = PLATFORM_MMX,
|
||||
SCALEPLAT_SSE = PLATFORM_SSE,
|
||||
SCALEPLAT_3DNOW = PLATFORM_3DNOW,
|
||||
SCALEPLAT_ALTIVEC = PLATFORM_ALTIVEC,
|
||||
|
||||
SCALEPLAT_C_RGBA,
|
||||
SCALEPLAT_C_BGRA,
|
||||
SCALEPLAT_C_ARGB,
|
||||
SCALEPLAT_C_ABGR,
|
||||
|
||||
} Scale_PlatType_t;
|
||||
|
||||
|
||||
// RGB -> YUV transformation
|
||||
// the RGB vector is multiplied by the transformation matrix
|
||||
// to get the YUV vector
|
||||
#if 0
|
||||
// original table -- not used
|
||||
const int YUV_matrix[3][3] =
|
||||
{
|
||||
/* Y U V */
|
||||
/* R */ {0.2989, -0.1687, 0.5000},
|
||||
/* G */ {0.5867, -0.3312, -0.4183},
|
||||
/* B */ {0.1144, 0.5000, -0.0816}
|
||||
};
|
||||
#else
|
||||
// scaled up by a 2^14 factor, with Y doubled
|
||||
const int YUV_matrix[3][3] =
|
||||
{
|
||||
/* Y U V */
|
||||
/* R */ { 9794, -2764, 8192},
|
||||
/* G */ {19224, -5428, -6853},
|
||||
/* B */ { 3749, 8192, -1339}
|
||||
};
|
||||
#endif
|
||||
|
||||
// pre-computed transformations for 8 bits per channel
|
||||
int RGB_to_YUV[/*RGB*/ 3][/*YUV*/ 3][ /*mult-res*/ 256];
|
||||
sint16 dRGB_to_dYUV[/*RGB*/ 3][/*YUV*/ 3][ /*mult-res*/ 512];
|
||||
|
||||
// pre-computed transformations for RGB555
|
||||
YUV_VECTOR RGB15_to_YUV[0x8000];
|
||||
|
||||
PLATFORM_TYPE force_platform = PLATFORM_NULL;
|
||||
Scale_PlatType_t Scale_Platform = SCALEPLAT_NULL;
|
||||
|
||||
|
||||
// pre-compute the RGB->YUV transformations
|
||||
void
|
||||
Scale_Init (void)
|
||||
{
|
||||
int i1, i2, i3;
|
||||
|
||||
for (i1 = 0; i1 < 3; i1++) // enum R,G,B
|
||||
for (i2 = 0; i2 < 3; i2++) // enum Y,U,V
|
||||
for (i3 = 0; i3 < 256; i3++) // enum possible channel vals
|
||||
{
|
||||
RGB_to_YUV[i1][i2][i3] =
|
||||
(YUV_matrix[i1][i2] * i3) >> 14;
|
||||
}
|
||||
|
||||
for (i1 = 0; i1 < 3; i1++) // enum R,G,B
|
||||
for (i2 = 0; i2 < 3; i2++) // enum Y,U,V
|
||||
for (i3 = -255; i3 < 256; i3++) // enum possible channel delta vals
|
||||
{
|
||||
dRGB_to_dYUV[i1][i2][i3 + 255] =
|
||||
(YUV_matrix[i1][i2] * i3) >> 14;
|
||||
}
|
||||
|
||||
for (i1 = 0; i1 < 32; ++i1)
|
||||
for (i2 = 0; i2 < 32; ++i2)
|
||||
for (i3 = 0; i3 < 32; ++i3)
|
||||
{
|
||||
int y, u, v;
|
||||
// adding upper bits halved for error correction
|
||||
int r = (i1 << 3) | (i1 >> 3);
|
||||
int g = (i2 << 3) | (i2 >> 3);
|
||||
int b = (i3 << 3) | (i3 >> 3);
|
||||
|
||||
y = ( r * YUV_matrix[YUV_XFORM_R][YUV_XFORM_Y]
|
||||
+ g * YUV_matrix[YUV_XFORM_G][YUV_XFORM_Y]
|
||||
+ b * YUV_matrix[YUV_XFORM_B][YUV_XFORM_Y]
|
||||
) >> 15; // we dont need Y doubled, need Y to fit 8 bits
|
||||
|
||||
// U and V are half the importance of Y
|
||||
u = 64+(( r * YUV_matrix[YUV_XFORM_R][YUV_XFORM_U]
|
||||
+ g * YUV_matrix[YUV_XFORM_G][YUV_XFORM_U]
|
||||
+ b * YUV_matrix[YUV_XFORM_B][YUV_XFORM_U]
|
||||
) >> 15); // halved
|
||||
|
||||
v = 64+(( r * YUV_matrix[YUV_XFORM_R][YUV_XFORM_V]
|
||||
+ g * YUV_matrix[YUV_XFORM_G][YUV_XFORM_V]
|
||||
+ b * YUV_matrix[YUV_XFORM_B][YUV_XFORM_V]
|
||||
) >> 15); // halved
|
||||
|
||||
RGB15_to_YUV[(i1 << 10) | (i2 << 5) | i3] = (y << 16) | (u << 8) | v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// expands the given rectangle in all directions by 'expansion'
|
||||
// guarded by 'limits'
|
||||
void
|
||||
Scale_ExpandRect (SDL_Rect* rect, int expansion, const SDL_Rect* limits)
|
||||
{
|
||||
if (rect->x - expansion >= limits->x)
|
||||
{
|
||||
rect->w += expansion;
|
||||
rect->x -= expansion;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect->w += rect->x - limits->x;
|
||||
rect->x = limits->x;
|
||||
}
|
||||
|
||||
if (rect->y - expansion >= limits->y)
|
||||
{
|
||||
rect->h += expansion;
|
||||
rect->y -= expansion;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect->h += rect->y - limits->y;
|
||||
rect->y = limits->y;
|
||||
}
|
||||
|
||||
if (rect->x + rect->w + expansion <= limits->w)
|
||||
rect->w += expansion;
|
||||
else
|
||||
rect->w = limits->w - rect->x;
|
||||
|
||||
if (rect->y + rect->h + expansion <= limits->h)
|
||||
rect->h += expansion;
|
||||
else
|
||||
rect->h = limits->h - rect->y;
|
||||
}
|
||||
|
||||
|
||||
// Platform+Scaler function lookups
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Scale_PlatType_t platform;
|
||||
const Scale_FuncDef_t* funcdefs;
|
||||
} Scale_PlatDef_t;
|
||||
|
||||
|
||||
static const Scale_PlatDef_t
|
||||
Scale_PlatDefs[] =
|
||||
{
|
||||
#if defined(MMX_ASM)
|
||||
{SCALEPLAT_SSE, Scale_SSE_Functions},
|
||||
{SCALEPLAT_3DNOW, Scale_3DNow_Functions},
|
||||
{SCALEPLAT_MMX, Scale_MMX_Functions},
|
||||
#endif /* MMX_ASM */
|
||||
// Default
|
||||
{SCALEPLAT_NULL, Scale_C_Functions}
|
||||
};
|
||||
|
||||
|
||||
TFB_ScaleFunc
|
||||
Scale_PrepPlatform (int flags, const SDL_PixelFormat* fmt)
|
||||
{
|
||||
const Scale_PlatDef_t* pdef;
|
||||
const Scale_FuncDef_t* fdef;
|
||||
|
||||
(void)flags;
|
||||
|
||||
Scale_Platform = SCALEPLAT_NULL;
|
||||
|
||||
// first match wins
|
||||
// add better platform techs to the top
|
||||
#ifdef MMX_ASM
|
||||
if ( (!force_platform && (SDL_HasSSE () || SDL_HasMMXExt ()))
|
||||
|| force_platform == SCALEPLAT_SSE)
|
||||
{
|
||||
log_add (log_Info, "Screen scalers are using SSE/MMX-Ext/MMX code");
|
||||
Scale_Platform = SCALEPLAT_SSE;
|
||||
|
||||
Scale_SSE_PrepPlatform (fmt);
|
||||
}
|
||||
else
|
||||
if ( (!force_platform && SDL_HasAltiVec ())
|
||||
|| force_platform == SCALEPLAT_ALTIVEC)
|
||||
{
|
||||
log_add (log_Info, "Screen scalers would use AltiVec code "
|
||||
"if someone actually wrote it");
|
||||
//Scale_Platform = SCALEPLAT_ALTIVEC;
|
||||
}
|
||||
else
|
||||
if ( (!force_platform && SDL_Has3DNow ())
|
||||
|| force_platform == SCALEPLAT_3DNOW)
|
||||
{
|
||||
log_add (log_Info, "Screen scalers are using 3DNow/MMX code");
|
||||
Scale_Platform = SCALEPLAT_3DNOW;
|
||||
|
||||
Scale_3DNow_PrepPlatform (fmt);
|
||||
}
|
||||
else
|
||||
if ( (!force_platform && SDL_HasMMX ())
|
||||
|| force_platform == SCALEPLAT_MMX)
|
||||
{
|
||||
log_add (log_Info, "Screen scalers are using MMX code");
|
||||
Scale_Platform = SCALEPLAT_MMX;
|
||||
|
||||
Scale_MMX_PrepPlatform (fmt);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Scale_Platform == SCALEPLAT_NULL)
|
||||
{ // Plain C versions
|
||||
if (fmt->Rmask == 0xff000000 && fmt->Bmask == 0x0000ff00)
|
||||
Scale_Platform = SCALEPLAT_C_RGBA;
|
||||
else if (fmt->Rmask == 0x00ff0000 && fmt->Bmask == 0x000000ff)
|
||||
Scale_Platform = SCALEPLAT_C_ARGB;
|
||||
else if (fmt->Rmask == 0x0000ff00 && fmt->Bmask == 0xff000000)
|
||||
Scale_Platform = SCALEPLAT_C_BGRA;
|
||||
else if (fmt->Rmask == 0x000000ff && fmt->Bmask == 0x00ff0000)
|
||||
Scale_Platform = SCALEPLAT_C_ABGR;
|
||||
else
|
||||
{ // use slowest default
|
||||
log_add (log_Warning, "Scale_PrepPlatform(): unknown masks "
|
||||
"(Red %08x, Blue %08x)", fmt->Rmask, fmt->Bmask);
|
||||
Scale_Platform = SCALEPLAT_C;
|
||||
}
|
||||
|
||||
if (Scale_Platform == SCALEPLAT_C)
|
||||
log_add (log_Info, "Screen scalers are using slow generic C code");
|
||||
else
|
||||
log_add (log_Info, "Screen scalers are using optimized C code");
|
||||
}
|
||||
|
||||
// Lookup the scaling function
|
||||
// First find the right platform
|
||||
for (pdef = Scale_PlatDefs;
|
||||
pdef->platform != Scale_Platform && pdef->platform != SCALEPLAT_NULL;
|
||||
++pdef)
|
||||
;
|
||||
// Next find the right function
|
||||
for (fdef = pdef->funcdefs;
|
||||
(flags & fdef->flag) != fdef->flag;
|
||||
++fdef)
|
||||
;
|
||||
|
||||
return fdef->func;
|
||||
}
|
||||
|
||||
27
project/jni/application/sc2/src/libs/graphics/sdl/scalers.h
Normal file
27
project/jni/application/sc2/src/libs/graphics/sdl/scalers.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SCALERS_H_
|
||||
#define SCALERS_H_
|
||||
|
||||
void Scale_Init (void);
|
||||
|
||||
typedef void (* TFB_ScaleFunc) (SDL_Surface *src, SDL_Surface *dst,
|
||||
SDL_Rect *r);
|
||||
|
||||
TFB_ScaleFunc Scale_PrepPlatform (int flags, const SDL_PixelFormat* fmt);
|
||||
|
||||
#endif /* SCALERS_H_ */
|
||||
607
project/jni/application/sc2/src/libs/graphics/sdl/sdl_common.c
Normal file
607
project/jni/application/sc2/src/libs/graphics/sdl/sdl_common.c
Normal file
@@ -0,0 +1,607 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "sdl_common.h"
|
||||
#include "opengl.h"
|
||||
#include "pure.h"
|
||||
#include "primitives.h"
|
||||
#include "options.h"
|
||||
#include "uqmversion.h"
|
||||
#include "libs/graphics/drawcmd.h"
|
||||
#include "libs/graphics/dcqueue.h"
|
||||
#include "libs/graphics/cmap.h"
|
||||
#include "libs/input/sdl/input.h"
|
||||
// for ProcessInputEvent()
|
||||
#include "libs/graphics/bbox.h"
|
||||
#include "port.h"
|
||||
#include "libs/uio.h"
|
||||
#include "libs/log.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "libs/vidlib.h"
|
||||
#include SDL_INCLUDE(SDL_thread.h)
|
||||
|
||||
SDL_Surface *SDL_Video;
|
||||
SDL_Surface *SDL_Screen;
|
||||
SDL_Surface *TransitionScreen;
|
||||
|
||||
SDL_Surface *SDL_Screens[TFB_GFX_NUMSCREENS];
|
||||
|
||||
SDL_Surface *format_conv_surf = NULL;
|
||||
|
||||
static volatile BOOLEAN abortFlag = FALSE;
|
||||
|
||||
int GfxFlags = 0;
|
||||
|
||||
TFB_GRAPHICS_BACKEND *graphics_backend = NULL;
|
||||
|
||||
volatile int QuitPosted = 0;
|
||||
volatile int GameActive = 1; // Track the SDL_ACTIVEEVENT state SDL_APPACTIVE
|
||||
|
||||
void
|
||||
TFB_PreInit (void)
|
||||
{
|
||||
log_add (log_Info, "Initializing base SDL functionality.");
|
||||
log_add (log_Info, "Using SDL version %d.%d.%d (compiled with "
|
||||
"%d.%d.%d)", SDL_Linked_Version ()->major,
|
||||
SDL_Linked_Version ()->minor, SDL_Linked_Version ()->patch,
|
||||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL);
|
||||
#if 0
|
||||
if (SDL_Linked_Version ()->major != SDL_MAJOR_VERSION ||
|
||||
SDL_Linked_Version ()->minor != SDL_MINOR_VERSION ||
|
||||
SDL_Linked_Version ()->patch != SDL_PATCHLEVEL) {
|
||||
log_add (log_Warning, "The used SDL library is not the same version "
|
||||
"as the one used to compile The Ur-Quan Masters with! "
|
||||
"If you experience any crashes, this would be an excellent "
|
||||
"suspect.");
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((SDL_Init (SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) == -1))
|
||||
{
|
||||
log_add (log_Fatal, "Could not initialize SDL: %s.", SDL_GetError ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
TFB_ReInitGraphics (int driver, int flags, int width, int height)
|
||||
{
|
||||
int result;
|
||||
int togglefullscreen = 0;
|
||||
char caption[200];
|
||||
|
||||
if (GfxFlags == (flags ^ TFB_GFXFLAGS_FULLSCREEN) &&
|
||||
driver == GraphicsDriver &&
|
||||
width == ScreenWidthActual && height == ScreenHeightActual)
|
||||
{
|
||||
togglefullscreen = 1;
|
||||
}
|
||||
|
||||
GfxFlags = flags;
|
||||
|
||||
if (driver == TFB_GFXDRIVER_SDL_OPENGL)
|
||||
{
|
||||
#ifdef HAVE_OPENGL
|
||||
result = TFB_GL_ConfigureVideo (driver, flags, width, height,
|
||||
togglefullscreen);
|
||||
#else
|
||||
driver = TFB_GFXDRIVER_SDL_PURE;
|
||||
log_add (log_Warning, "OpenGL support not compiled in,"
|
||||
" so using pure SDL driver");
|
||||
result = TFB_Pure_ConfigureVideo (driver, flags, width, height,
|
||||
togglefullscreen);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
result = TFB_Pure_ConfigureVideo (driver, flags, width, height,
|
||||
togglefullscreen);
|
||||
}
|
||||
|
||||
sprintf (caption, "The Ur-Quan Masters v%d.%d.%d%s",
|
||||
UQM_MAJOR_VERSION, UQM_MINOR_VERSION,
|
||||
UQM_PATCH_VERSION, UQM_EXTRA_VERSION);
|
||||
SDL_WM_SetCaption (caption, NULL);
|
||||
|
||||
if (flags & TFB_GFXFLAGS_FULLSCREEN)
|
||||
SDL_ShowCursor (SDL_DISABLE);
|
||||
else
|
||||
SDL_ShowCursor (SDL_ENABLE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
TFB_InitGraphics (int driver, int flags, int width, int height)
|
||||
{
|
||||
int result, i;
|
||||
char caption[200];
|
||||
|
||||
/* Null out screen pointers the first time */
|
||||
for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
|
||||
{
|
||||
SDL_Screens[i] = NULL;
|
||||
}
|
||||
|
||||
GfxFlags = flags;
|
||||
|
||||
if (driver == TFB_GFXDRIVER_SDL_OPENGL)
|
||||
{
|
||||
#ifdef HAVE_OPENGL
|
||||
result = TFB_GL_InitGraphics (driver, flags, width, height);
|
||||
#else
|
||||
driver = TFB_GFXDRIVER_SDL_PURE;
|
||||
log_add (log_Warning, "OpenGL support not compiled in,"
|
||||
" so using pure SDL driver");
|
||||
result = TFB_Pure_InitGraphics (driver, flags, width, height);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
result = TFB_Pure_InitGraphics (driver, flags, width, height);
|
||||
}
|
||||
|
||||
sprintf (caption, "The Ur-Quan Masters v%d.%d.%d%s",
|
||||
UQM_MAJOR_VERSION, UQM_MINOR_VERSION,
|
||||
UQM_PATCH_VERSION, UQM_EXTRA_VERSION);
|
||||
SDL_WM_SetCaption (caption, NULL);
|
||||
|
||||
if (flags & TFB_GFXFLAGS_FULLSCREEN)
|
||||
SDL_ShowCursor (SDL_DISABLE);
|
||||
|
||||
Init_DrawCommandQueue ();
|
||||
|
||||
TFB_DrawCanvas_Initialize ();
|
||||
|
||||
atexit (TFB_UninitGraphics);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_UninitGraphics (void)
|
||||
{
|
||||
Uninit_DrawCommandQueue ();
|
||||
// TODO: Uninit whatever the drivers have set up for us
|
||||
SDL_Quit ();
|
||||
}
|
||||
|
||||
void
|
||||
TFB_ProcessEvents ()
|
||||
{
|
||||
SDL_Event Event;
|
||||
|
||||
while (SDL_PollEvent (&Event))
|
||||
{
|
||||
/* Run through the InputEvent filter. */
|
||||
ProcessInputEvent (&Event);
|
||||
/* Handle graphics and exposure events. */
|
||||
switch (Event.type) {
|
||||
case SDL_ACTIVEEVENT: /* Lose/gain visibility or focus */
|
||||
/* Up to three different state changes can occur in one event. */
|
||||
/* Here, disregard least significant change (mouse focus). */
|
||||
#if 0 /* Currently disabled in mainline */
|
||||
// This controls the automatic sleep/pause when minimized.
|
||||
// On small displays (e.g. mobile devices), APPINPUTFOCUS would
|
||||
// be an appropriate substitution for APPACTIVE:
|
||||
// if (Event.active.state & SDL_APPINPUTFOCUS)
|
||||
if (Event.active.state & SDL_APPACTIVE)
|
||||
GameActive = Event.active.gain;
|
||||
#endif
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
QuitPosted = 1;
|
||||
break;
|
||||
case SDL_VIDEORESIZE: /* User resized video mode */
|
||||
// TODO
|
||||
break;
|
||||
case SDL_VIDEOEXPOSE: /* Screen needs to be redrawn */
|
||||
TFB_SwapBuffers (TFB_REDRAW_EXPOSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOLEAN system_box_active = 0;
|
||||
static SDL_Rect system_box;
|
||||
|
||||
void
|
||||
SetSystemRect (const RECT *r)
|
||||
{
|
||||
system_box_active = TRUE;
|
||||
system_box.x = r->corner.x;
|
||||
system_box.y = r->corner.y;
|
||||
system_box.w = r->extent.width;
|
||||
system_box.h = r->extent.height;
|
||||
}
|
||||
|
||||
void
|
||||
ClearSystemRect (void)
|
||||
{
|
||||
system_box_active = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_SwapBuffers (int force_full_redraw)
|
||||
{
|
||||
static int last_fade_amount = 255, last_transition_amount = 255;
|
||||
static int fade_amount = 255, transition_amount = 255;
|
||||
|
||||
fade_amount = GetFadeAmount ();
|
||||
transition_amount = TransitionAmount;
|
||||
|
||||
if (force_full_redraw == TFB_REDRAW_NO && !TFB_BBox.valid &&
|
||||
fade_amount == 255 && transition_amount == 255 &&
|
||||
last_fade_amount == 255 && last_transition_amount == 255)
|
||||
return;
|
||||
|
||||
if (force_full_redraw == TFB_REDRAW_NO &&
|
||||
(fade_amount != 255 || transition_amount != 255 ||
|
||||
last_fade_amount != 255 || last_transition_amount != 255))
|
||||
force_full_redraw = TFB_REDRAW_FADING;
|
||||
|
||||
last_fade_amount = fade_amount;
|
||||
last_transition_amount = transition_amount;
|
||||
|
||||
graphics_backend->preprocess (force_full_redraw, transition_amount,
|
||||
fade_amount);
|
||||
graphics_backend->screen (TFB_SCREEN_MAIN, 255, NULL);
|
||||
|
||||
if (transition_amount != 255)
|
||||
{
|
||||
SDL_Rect r;
|
||||
r.x = TransitionClipRect.corner.x;
|
||||
r.y = TransitionClipRect.corner.y;
|
||||
r.w = TransitionClipRect.extent.width;
|
||||
r.h = TransitionClipRect.extent.height;
|
||||
graphics_backend->screen (TFB_SCREEN_TRANSITION,
|
||||
255 - transition_amount, &r);
|
||||
}
|
||||
|
||||
if (fade_amount != 255)
|
||||
{
|
||||
if (fade_amount < 255)
|
||||
{
|
||||
graphics_backend->color (0, 0, 0, 255 - fade_amount, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics_backend->color (255, 255, 255,
|
||||
fade_amount - 255, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (system_box_active)
|
||||
{
|
||||
graphics_backend->screen (TFB_SCREEN_MAIN, 255, &system_box);
|
||||
}
|
||||
|
||||
graphics_backend->postprocess ();
|
||||
}
|
||||
|
||||
/* Probably ought to clean this away at some point. */
|
||||
SDL_Surface *
|
||||
TFB_DisplayFormatAlpha (SDL_Surface *surface)
|
||||
{
|
||||
SDL_Surface* newsurf;
|
||||
SDL_PixelFormat* dstfmt;
|
||||
const SDL_PixelFormat* srcfmt = surface->format;
|
||||
|
||||
// figure out what format to use (alpha/no alpha)
|
||||
if (surface->format->Amask)
|
||||
dstfmt = format_conv_surf->format;
|
||||
else
|
||||
dstfmt = SDL_Screen->format;
|
||||
|
||||
if (srcfmt->BytesPerPixel == dstfmt->BytesPerPixel &&
|
||||
srcfmt->Rmask == dstfmt->Rmask &&
|
||||
srcfmt->Gmask == dstfmt->Gmask &&
|
||||
srcfmt->Bmask == dstfmt->Bmask &&
|
||||
srcfmt->Amask == dstfmt->Amask)
|
||||
return surface; // no conversion needed
|
||||
|
||||
newsurf = SDL_ConvertSurface (surface, dstfmt, surface->flags);
|
||||
// SDL_SRCCOLORKEY and SDL_SRCALPHA cannot work at the same time,
|
||||
// so we need to disable one of them
|
||||
if ((surface->flags & SDL_SRCCOLORKEY) && newsurf
|
||||
&& (newsurf->flags & SDL_SRCCOLORKEY)
|
||||
&& (newsurf->flags & SDL_SRCALPHA))
|
||||
SDL_SetAlpha (newsurf, 0, 255);
|
||||
|
||||
return newsurf;
|
||||
}
|
||||
|
||||
// This function should only be called from the graphics thread,
|
||||
// like from a TFB_DrawCommand_Callback command.
|
||||
TFB_Canvas
|
||||
TFB_GetScreenCanvas (SCREEN screen)
|
||||
{
|
||||
return SDL_Screens[screen];
|
||||
}
|
||||
|
||||
void
|
||||
TFB_BlitSurface (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst,
|
||||
SDL_Rect *dstrect, int blend_numer, int blend_denom)
|
||||
{
|
||||
BOOLEAN has_colorkey;
|
||||
int x, y, x1, y1, x2, y2, dst_x2, dst_y2, nr, ng, nb;
|
||||
int srcx, srcy, w, h;
|
||||
Uint8 sr, sg, sb, dr, dg, db;
|
||||
Uint32 src_pixval, dst_pixval, colorkey;
|
||||
GetPixelFn src_getpix, dst_getpix;
|
||||
PutPixelFn putpix;
|
||||
SDL_Rect fulldst;
|
||||
|
||||
if (blend_numer == blend_denom)
|
||||
{
|
||||
// normal blit: dst = src
|
||||
|
||||
// log_add (log_Debug, "normal blit\n");
|
||||
SDL_BlitSurface (src, srcrect, dst, dstrect);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: following clipping code is copied from SDL-1.2.4 sources
|
||||
|
||||
// If the destination rectangle is NULL, use the entire dest surface
|
||||
if (dstrect == NULL)
|
||||
{
|
||||
fulldst.x = fulldst.y = 0;
|
||||
dstrect = &fulldst;
|
||||
}
|
||||
|
||||
// clip the source rectangle to the source surface
|
||||
if (srcrect)
|
||||
{
|
||||
int maxw, maxh;
|
||||
|
||||
srcx = srcrect->x;
|
||||
w = srcrect->w;
|
||||
if (srcx < 0)
|
||||
{
|
||||
w += srcx;
|
||||
dstrect->x -= srcx;
|
||||
srcx = 0;
|
||||
}
|
||||
maxw = src->w - srcx;
|
||||
if (maxw < w)
|
||||
w = maxw;
|
||||
|
||||
srcy = srcrect->y;
|
||||
h = srcrect->h;
|
||||
if (srcy < 0)
|
||||
{
|
||||
h += srcy;
|
||||
dstrect->y -= srcy;
|
||||
srcy = 0;
|
||||
}
|
||||
maxh = src->h - srcy;
|
||||
if (maxh < h)
|
||||
h = maxh;
|
||||
}
|
||||
else
|
||||
{
|
||||
srcx = 0;
|
||||
srcy = 0;
|
||||
w = src->w;
|
||||
h = src->h;
|
||||
}
|
||||
|
||||
// clip the destination rectangle against the clip rectangle
|
||||
{
|
||||
SDL_Rect *clip = &dst->clip_rect;
|
||||
int dx, dy;
|
||||
|
||||
dx = clip->x - dstrect->x;
|
||||
if (dx > 0)
|
||||
{
|
||||
w -= dx;
|
||||
dstrect->x += dx;
|
||||
srcx += dx;
|
||||
}
|
||||
dx = dstrect->x + w - clip->x - clip->w;
|
||||
if (dx > 0)
|
||||
w -= dx;
|
||||
|
||||
dy = clip->y - dstrect->y;
|
||||
if (dy > 0)
|
||||
{
|
||||
h -= dy;
|
||||
dstrect->y += dy;
|
||||
srcy += dy;
|
||||
}
|
||||
dy = dstrect->y + h - clip->y - clip->h;
|
||||
if (dy > 0)
|
||||
h -= dy;
|
||||
}
|
||||
|
||||
dstrect->w = w;
|
||||
dstrect->h = h;
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
|
||||
x1 = srcx;
|
||||
y1 = srcy;
|
||||
x2 = srcx + w;
|
||||
y2 = srcy + h;
|
||||
|
||||
if (src->flags & SDL_SRCCOLORKEY)
|
||||
{
|
||||
has_colorkey = TRUE;
|
||||
colorkey = src->format->colorkey;
|
||||
}
|
||||
else
|
||||
{
|
||||
has_colorkey = FALSE;
|
||||
colorkey = 0; /* Satisfying compiler */
|
||||
}
|
||||
|
||||
src_getpix = getpixel_for (src);
|
||||
dst_getpix = getpixel_for (dst);
|
||||
putpix = putpixel_for (dst);
|
||||
|
||||
if (blend_denom < 0)
|
||||
{
|
||||
// additive blit: dst = src + dst
|
||||
#if 0
|
||||
log_add (log_Debug, "additive blit %d %d, src %d %d %d %d dst %d %d,"
|
||||
" srcbpp %d", blend_numer, blend_denom, x1, y1, x2, y2,
|
||||
dstrect->x, dstrect->y, src->format->BitsPerPixel);
|
||||
#endif
|
||||
for (y = y1; y < y2; ++y)
|
||||
{
|
||||
dst_y2 = dstrect->y + (y - y1);
|
||||
for (x = x1; x < x2; ++x)
|
||||
{
|
||||
dst_x2 = dstrect->x + (x - x1);
|
||||
src_pixval = src_getpix (src, x, y);
|
||||
|
||||
if (has_colorkey && src_pixval == colorkey)
|
||||
continue;
|
||||
|
||||
dst_pixval = dst_getpix (dst, dst_x2, dst_y2);
|
||||
|
||||
SDL_GetRGB (src_pixval, src->format, &sr, &sg, &sb);
|
||||
SDL_GetRGB (dst_pixval, dst->format, &dr, &dg, &db);
|
||||
|
||||
nr = sr + dr;
|
||||
ng = sg + dg;
|
||||
nb = sb + db;
|
||||
|
||||
if (nr > 255)
|
||||
nr = 255;
|
||||
if (ng > 255)
|
||||
ng = 255;
|
||||
if (nb > 255)
|
||||
nb = 255;
|
||||
|
||||
putpix (dst, dst_x2, dst_y2,
|
||||
SDL_MapRGB (dst->format, nr, ng, nb));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (blend_numer < 0)
|
||||
{
|
||||
// subtractive blit: dst = src - dst
|
||||
#if 0
|
||||
log_add (log_Debug, "subtractive blit %d %d, src %d %d %d %d"
|
||||
" dst %d %d, srcbpp %d", blend_numer, blend_denom,
|
||||
x1, y1, x2, y2, dstrect->x, dstrect->y,
|
||||
src->format->BitsPerPixel);
|
||||
#endif
|
||||
for (y = y1; y < y2; ++y)
|
||||
{
|
||||
dst_y2 = dstrect->y + (y - y1);
|
||||
for (x = x1; x < x2; ++x)
|
||||
{
|
||||
dst_x2 = dstrect->x + (x - x1);
|
||||
src_pixval = src_getpix (src, x, y);
|
||||
|
||||
if (has_colorkey && src_pixval == colorkey)
|
||||
continue;
|
||||
|
||||
dst_pixval = dst_getpix (dst, dst_x2, dst_y2);
|
||||
|
||||
SDL_GetRGB (src_pixval, src->format, &sr, &sg, &sb);
|
||||
SDL_GetRGB (dst_pixval, dst->format, &dr, &dg, &db);
|
||||
|
||||
nr = sr - dr;
|
||||
ng = sg - dg;
|
||||
nb = sb - db;
|
||||
|
||||
if (nr < 0)
|
||||
nr = 0;
|
||||
if (ng < 0)
|
||||
ng = 0;
|
||||
if (nb < 0)
|
||||
nb = 0;
|
||||
|
||||
putpix (dst, dst_x2, dst_y2,
|
||||
SDL_MapRGB (dst->format, nr, ng, nb));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// modulated blit: dst = src * (blend_numer / blend_denom)
|
||||
|
||||
float f = blend_numer / (float)blend_denom;
|
||||
#if 0
|
||||
log_add (log_Debug, "modulated blit %d %d, f %f, src %d %d %d %d"
|
||||
" dst %d %d, srcbpp %d\n", blend_numer, blend_denom, f,
|
||||
x1, y1, x2, y2, dstrect->x, dstrect->y,
|
||||
src->format->BitsPerPixel);
|
||||
#endif
|
||||
for (y = y1; y < y2; ++y)
|
||||
{
|
||||
dst_y2 = dstrect->y + (y - y1);
|
||||
for (x = x1; x < x2; ++x)
|
||||
{
|
||||
dst_x2 = dstrect->x + (x - x1);
|
||||
src_pixval = src_getpix (src, x, y);
|
||||
|
||||
if (has_colorkey && src_pixval == colorkey)
|
||||
continue;
|
||||
|
||||
SDL_GetRGB (src_pixval, src->format, &sr, &sg, &sb);
|
||||
|
||||
nr = (int)(sr * f);
|
||||
ng = (int)(sg * f);
|
||||
nb = (int)(sb * f);
|
||||
|
||||
if (nr > 255)
|
||||
nr = 255;
|
||||
if (ng > 255)
|
||||
ng = 255;
|
||||
if (nb > 255)
|
||||
nb = 255;
|
||||
|
||||
putpix (dst, dst_x2, dst_y2,
|
||||
SDL_MapRGB (dst->format, nr, ng, nb));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFB_UploadTransitionScreen (void)
|
||||
{
|
||||
#ifdef HAVE_OPENGL
|
||||
if (GraphicsDriver == TFB_GFXDRIVER_SDL_OPENGL)
|
||||
{
|
||||
TFB_GL_UploadTransitionScreen ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFB_SetGamma (float gamma)
|
||||
{
|
||||
if (SDL_SetGamma (gamma, gamma, gamma) == -1)
|
||||
{
|
||||
log_add (log_Warning, "Unable to set gamma correction.");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_add (log_Info, "Gamma correction set to %1.4f.", gamma);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SDL_COMMON_H
|
||||
#define SDL_COMMON_H
|
||||
|
||||
#include "port.h"
|
||||
#include SDL_INCLUDE(SDL.h)
|
||||
#include SDL_INCLUDE(SDL_byteorder.h)
|
||||
#include SDL_IMAGE_INCLUDE(SDL_image.h)
|
||||
|
||||
#include "../gfxintrn.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
|
||||
// The Graphics Backend vtable
|
||||
typedef struct _tfb_graphics_backend {
|
||||
void (*preprocess) (int force_redraw, int transition_amount, int fade_amount);
|
||||
void (*postprocess) (void);
|
||||
void (*screen) (SCREEN screen, Uint8 alpha, SDL_Rect *rect);
|
||||
void (*color) (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect);
|
||||
} TFB_GRAPHICS_BACKEND;
|
||||
|
||||
extern TFB_GRAPHICS_BACKEND *graphics_backend;
|
||||
|
||||
extern SDL_Surface *SDL_Video;
|
||||
extern SDL_Surface *SDL_Screen;
|
||||
extern SDL_Surface *TransitionScreen;
|
||||
|
||||
extern SDL_Surface *SDL_Screens[TFB_GFX_NUMSCREENS];
|
||||
|
||||
extern SDL_Surface *format_conv_surf;
|
||||
|
||||
SDL_Surface* TFB_DisplayFormatAlpha (SDL_Surface *surface);
|
||||
|
||||
#endif
|
||||
133
project/jni/application/sc2/src/libs/graphics/sdl/sdluio.c
Normal file
133
project/jni/application/sc2/src/libs/graphics/sdl/sdluio.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "sdluio.h"
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/uio.h"
|
||||
#include SDL_INCLUDE(SDL.h)
|
||||
#include SDL_INCLUDE(SDL_error.h)
|
||||
#include SDL_INCLUDE(SDL_rwops.h)
|
||||
#include SDL_IMAGE_INCLUDE(SDL_image.h)
|
||||
#include "libs/memlib.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static SDL_RWops *sdluio_makeRWops (uio_Stream *stream);
|
||||
|
||||
#if 0
|
||||
// For use for initialisation, using structure assignment.
|
||||
static SDL_RWops sdluio_templateRWops =
|
||||
{
|
||||
.seek = sdluio_seek,
|
||||
.read = sdluio_read,
|
||||
.write = sdluio_write,
|
||||
.close = sdluio_close,
|
||||
};
|
||||
#endif
|
||||
|
||||
SDL_Surface *
|
||||
sdluio_loadImage (uio_DirHandle *dir, const char *fileName) {
|
||||
uio_Stream *stream;
|
||||
SDL_RWops *rwops;
|
||||
SDL_Surface *result;
|
||||
|
||||
stream = uio_fopen (dir, fileName, "rb");
|
||||
if (stream == NULL)
|
||||
{
|
||||
SDL_SetError ("Couldn't open '%s': %s", fileName,
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
rwops = sdluio_makeRWops (stream);
|
||||
result = IMG_Load_RW (rwops, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sdluio_seek (SDL_RWops *context, int offset, int whence) {
|
||||
if (uio_fseek ((uio_Stream *) context->hidden.unknown.data1, offset,
|
||||
whence) == -1)
|
||||
{
|
||||
SDL_SetError ("Error seeking in uio_Stream: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return uio_ftell ((uio_Stream *) context->hidden.unknown.data1);
|
||||
}
|
||||
|
||||
int
|
||||
sdluio_read (SDL_RWops *context, void *ptr, int size, int maxnum) {
|
||||
size_t numRead;
|
||||
|
||||
numRead = uio_fread (ptr, (size_t) size, (size_t) maxnum,
|
||||
(uio_Stream *) context->hidden.unknown.data1);
|
||||
if (numRead == 0 && uio_ferror ((uio_Stream *)
|
||||
context->hidden.unknown.data1))
|
||||
{
|
||||
SDL_SetError ("Error reading from uio_Stream: %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
return (int) numRead;
|
||||
}
|
||||
|
||||
int
|
||||
sdluio_write (SDL_RWops *context, const void *ptr, int size, int num) {
|
||||
size_t numWritten;
|
||||
|
||||
numWritten = uio_fwrite (ptr, (size_t) size, (size_t) num,
|
||||
(uio_Stream *) context->hidden.unknown.data1);
|
||||
if (numWritten == 0 && uio_ferror ((uio_Stream *)
|
||||
context->hidden.unknown.data1))
|
||||
{
|
||||
SDL_SetError ("Error writing to uio_Stream: %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
return (size_t) numWritten;
|
||||
}
|
||||
|
||||
int
|
||||
sdluio_close (SDL_RWops *context) {
|
||||
int result;
|
||||
|
||||
result = uio_fclose ((uio_Stream *) context->hidden.unknown.data1);
|
||||
HFree (context);
|
||||
return result;
|
||||
}
|
||||
|
||||
static SDL_RWops *
|
||||
sdluio_makeRWops (uio_Stream *stream) {
|
||||
SDL_RWops *result;
|
||||
|
||||
result = HMalloc (sizeof (SDL_RWops));
|
||||
#if 0
|
||||
*(struct SDL_RWops *) result = sdluio_templateRWops;
|
||||
// structure assignment
|
||||
#endif
|
||||
result->seek = sdluio_seek;
|
||||
result->read = sdluio_read;
|
||||
result->write = sdluio_write;
|
||||
result->close = sdluio_close;
|
||||
result->hidden.unknown.data1 = stream;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
33
project/jni/application/sc2/src/libs/graphics/sdl/sdluio.h
Normal file
33
project/jni/application/sc2/src/libs/graphics/sdl/sdluio.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SDLUIO_H
|
||||
#define _SDLUIO_H
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/uio.h"
|
||||
#include SDL_INCLUDE(SDL.h)
|
||||
#include SDL_INCLUDE(SDL_rwops.h)
|
||||
|
||||
SDL_Surface *sdluio_loadImage (uio_DirHandle *dir, const char *fileName);
|
||||
int sdluio_seek (SDL_RWops *context, int offset, int whence);
|
||||
int sdluio_read (SDL_RWops *context, void *ptr, int size, int maxnum);
|
||||
int sdluio_write (SDL_RWops *context, const void *ptr, int size, int num);
|
||||
int sdluio_close (SDL_RWops *context);
|
||||
|
||||
|
||||
#endif /* _SDLUIO_H */
|
||||
|
||||
155
project/jni/application/sc2/src/libs/graphics/sdl/triscan2x.c
Normal file
155
project/jni/application/sc2/src/libs/graphics/sdl/triscan2x.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Core algorithm of the Triscan screen scaler (based on Scale2x)
|
||||
// (for scale2x please see http://scale2x.sf.net)
|
||||
// Template
|
||||
// When this file is built standalone is produces a plain C version
|
||||
// Also #included by 2xscalers_mmx.c for an MMX version
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "types.h"
|
||||
#include "scalers.h"
|
||||
#include "scaleint.h"
|
||||
#include "2xscalers.h"
|
||||
|
||||
|
||||
// Triscan scaling to 2x
|
||||
// derivative of scale2x -- scale2x.sf.net
|
||||
// The name expands to either
|
||||
// Scale_TriScanFilter (for plain C) or
|
||||
// Scale_MMX_TriScanFilter (for MMX)
|
||||
// [others when platforms are added]
|
||||
void
|
||||
SCALE_(TriScanFilter) (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r)
|
||||
{
|
||||
int x, y;
|
||||
const int w = src->w, h = src->h;
|
||||
int xend, yend;
|
||||
int dsrc, ddst;
|
||||
SDL_Rect *region = r;
|
||||
SDL_Rect limits;
|
||||
SDL_PixelFormat *fmt = dst->format;
|
||||
const int sp = src->pitch, dp = dst->pitch;
|
||||
const int bpp = fmt->BytesPerPixel;
|
||||
const int slen = sp / bpp, dlen = dp / bpp;
|
||||
// for clarity purposes, the 'pixels' array here is transposed
|
||||
Uint32 pixels[3][3];
|
||||
Uint32 *src_p = (Uint32 *)src->pixels;
|
||||
Uint32 *dst_p = (Uint32 *)dst->pixels;
|
||||
|
||||
int prevline, nextline;
|
||||
|
||||
// these macros are for clarity; they make the current pixel (0,0)
|
||||
// and allow to access pixels in all directions
|
||||
#define PIX(x, y) (pixels[1 + (x)][1 + (y)])
|
||||
|
||||
#define TRISCAN_YUV_MED 100
|
||||
// medium tolerance pixel comparison
|
||||
#define TRISCAN_CMPYUV(p1, p2) \
|
||||
(PIX p1 == PIX p2 || SCALE_CMPYUV (PIX p1, PIX p2, TRISCAN_YUV_MED))
|
||||
|
||||
|
||||
SCALE_(PlatInit) ();
|
||||
|
||||
// expand updated region if necessary
|
||||
// pixels neighbooring the updated region may
|
||||
// change as a result of updates
|
||||
limits.x = 0;
|
||||
limits.y = 0;
|
||||
limits.w = src->w;
|
||||
limits.h = src->h;
|
||||
Scale_ExpandRect (region, 1, &limits);
|
||||
|
||||
xend = region->x + region->w;
|
||||
yend = region->y + region->h;
|
||||
dsrc = slen - region->w;
|
||||
ddst = (dlen - region->w) * 2;
|
||||
|
||||
// move ptrs to the first updated pixel
|
||||
src_p += slen * region->y + region->x;
|
||||
dst_p += (dlen * region->y + region->x) * 2;
|
||||
|
||||
for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc)
|
||||
{
|
||||
if (y > 0)
|
||||
prevline = -slen;
|
||||
else
|
||||
prevline = 0;
|
||||
|
||||
if (y < h - 1)
|
||||
nextline = slen;
|
||||
else
|
||||
nextline = 0;
|
||||
|
||||
// prime the (tiny) sliding-window pixel arrays
|
||||
PIX( 1, 0) = src_p[0];
|
||||
|
||||
if (region->x > 0)
|
||||
PIX( 0, 0) = src_p[-1];
|
||||
else
|
||||
PIX( 0, 0) = PIX( 1, 0);
|
||||
|
||||
for (x = region->x; x < xend; ++x, ++src_p, dst_p += 2)
|
||||
{
|
||||
// slide the window
|
||||
PIX(-1, 0) = PIX( 0, 0);
|
||||
|
||||
PIX( 0, -1) = src_p[prevline];
|
||||
PIX( 0, 0) = PIX( 1, 0);
|
||||
PIX( 0, 1) = src_p[nextline];
|
||||
|
||||
if (x < w - 1)
|
||||
PIX( 1, 0) = src_p[1];
|
||||
else
|
||||
PIX( 1, 0) = PIX( 0, 0);
|
||||
|
||||
if (!TRISCAN_CMPYUV (( 0, -1), ( 0, 1)) &&
|
||||
!TRISCAN_CMPYUV ((-1, 0), ( 1, 0)))
|
||||
{
|
||||
if (TRISCAN_CMPYUV ((-1, 0), ( 0, -1)))
|
||||
dst_p[0] = Scale_Blend_11 (PIX(-1, 0), PIX(0, -1));
|
||||
else
|
||||
dst_p[0] = PIX(0, 0);
|
||||
|
||||
if (TRISCAN_CMPYUV (( 1, 0), ( 0, -1)))
|
||||
dst_p[1] = Scale_Blend_11 (PIX(1, 0), PIX(0, -1));
|
||||
else
|
||||
dst_p[1] = PIX(0, 0);
|
||||
|
||||
if (TRISCAN_CMPYUV ((-1, 0), ( 0, 1)))
|
||||
dst_p[dlen] = Scale_Blend_11 (PIX(-1, 0), PIX(0, 1));
|
||||
else
|
||||
dst_p[dlen] = PIX(0, 0);
|
||||
|
||||
if (TRISCAN_CMPYUV (( 1, 0), ( 0, 1)))
|
||||
dst_p[dlen+1] = Scale_Blend_11 (PIX(1, 0), PIX(0, 1));
|
||||
else
|
||||
dst_p[dlen+1] = PIX(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_p[0] = PIX(0, 0);
|
||||
dst_p[1] = PIX(0, 0);
|
||||
dst_p[dlen] = PIX(0, 0);
|
||||
dst_p[dlen+1] = PIX(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCALE_(PlatDone) ();
|
||||
}
|
||||
|
||||
484
project/jni/application/sc2/src/libs/graphics/tfb_draw.c
Normal file
484
project/jni/application/sc2/src/libs/graphics/tfb_draw.c
Normal file
@@ -0,0 +1,484 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "gfx_common.h"
|
||||
#include "tfb_draw.h"
|
||||
#include "drawcmd.h"
|
||||
#include "libs/log.h"
|
||||
#include "libs/memlib.h"
|
||||
|
||||
|
||||
static const HOT_SPOT NullHs = {0, 0};
|
||||
|
||||
void
|
||||
TFB_DrawScreen_Line (int x1, int y1, int x2, int y2, Color color,
|
||||
DrawMode mode, SCREEN dest)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_LINE;
|
||||
DC.data.line.x1 = x1;
|
||||
DC.data.line.y1 = y1;
|
||||
DC.data.line.x2 = x2;
|
||||
DC.data.line.y2 = y2;
|
||||
DC.data.line.color = color;
|
||||
DC.data.line.drawMode = mode;
|
||||
DC.data.line.destBuffer = dest;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_Rect (RECT *rect, Color color, DrawMode mode, SCREEN dest)
|
||||
{
|
||||
RECT locRect;
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
if (!rect)
|
||||
{
|
||||
locRect.corner.x = locRect.corner.y = 0;
|
||||
locRect.extent.width = ScreenWidth;
|
||||
locRect.extent.height = ScreenHeight;
|
||||
rect = &locRect;
|
||||
}
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_RECTANGLE;
|
||||
DC.data.rect.rect = *rect;
|
||||
DC.data.rect.color = color;
|
||||
DC.data.rect.drawMode = mode;
|
||||
DC.data.rect.destBuffer = dest;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, TFB_ColorMap *cmap, DrawMode mode, SCREEN dest)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_IMAGE;
|
||||
DC.data.image.image = img;
|
||||
DC.data.image.colormap = cmap;
|
||||
DC.data.image.x = x;
|
||||
DC.data.image.y = y;
|
||||
DC.data.image.scale = (scale == GSCALE_IDENTITY) ? 0 : scale;
|
||||
DC.data.image.scaleMode = scaleMode;
|
||||
DC.data.image.drawMode = mode;
|
||||
DC.data.image.destBuffer = dest;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, Color color, DrawMode mode, SCREEN dest)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_FILLEDIMAGE;
|
||||
DC.data.filledimage.image = img;
|
||||
DC.data.filledimage.x = x;
|
||||
DC.data.filledimage.y = y;
|
||||
DC.data.filledimage.scale = (scale == GSCALE_IDENTITY) ? 0 : scale;
|
||||
DC.data.filledimage.scaleMode = scaleMode;
|
||||
DC.data.filledimage.color = color;
|
||||
DC.data.filledimage.drawMode = mode;
|
||||
DC.data.filledimage.destBuffer = dest;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_FontChar (TFB_Char *fontChar, TFB_Image *backing,
|
||||
int x, int y, DrawMode mode, SCREEN dest)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_FONTCHAR;
|
||||
DC.data.fontchar.fontchar = fontChar;
|
||||
DC.data.fontchar.backing = backing;
|
||||
DC.data.fontchar.x = x;
|
||||
DC.data.fontchar.y = y;
|
||||
DC.data.fontchar.drawMode = mode;
|
||||
DC.data.fontchar.destBuffer = dest;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_CopyToImage (TFB_Image *img, const RECT *r, SCREEN src)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_COPYTOIMAGE;
|
||||
DC.data.copytoimage.rect = *r;
|
||||
DC.data.copytoimage.image = img;
|
||||
DC.data.copytoimage.srcBuffer = src;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_Copy (const RECT *r, SCREEN src, SCREEN dest)
|
||||
{
|
||||
RECT locRect;
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
if (!r)
|
||||
{
|
||||
locRect.corner.x = locRect.corner.y = 0;
|
||||
locRect.extent.width = ScreenWidth;
|
||||
locRect.extent.height = ScreenHeight;
|
||||
r = &locRect;
|
||||
}
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_COPY;
|
||||
DC.data.copy.rect = *r;
|
||||
DC.data.copy.srcBuffer = src;
|
||||
DC.data.copy.destBuffer = dest;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_SETMIPMAP;
|
||||
DC.data.setmipmap.image = img;
|
||||
DC.data.setmipmap.mipmap = mmimg;
|
||||
DC.data.setmipmap.hotx = hotx;
|
||||
DC.data.setmipmap.hoty = hoty;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_DeleteImage (TFB_Image *img)
|
||||
{
|
||||
if (img)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_DELETEIMAGE;
|
||||
DC.data.deleteimage.image = img;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_DeleteData (void *data)
|
||||
// data must be a result of HXalloc() call
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_DELETEDATA;
|
||||
DC.data.deletedata.data = data;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_WaitForSignal (void)
|
||||
{
|
||||
TFB_DrawCommand DrawCommand;
|
||||
Semaphore s;
|
||||
s = GetMyThreadLocal ()->flushSem;
|
||||
DrawCommand.Type = TFB_DRAWCOMMANDTYPE_SENDSIGNAL;
|
||||
DrawCommand.data.sendsignal.sem = s;
|
||||
Lock_DCQ (1);
|
||||
TFB_BatchReset ();
|
||||
TFB_EnqueueDrawCommand (&DrawCommand);
|
||||
Unlock_DCQ();
|
||||
SetSemaphore (s);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_ReinitVideo (int driver, int flags, int width, int height)
|
||||
{
|
||||
TFB_DrawCommand DrawCommand;
|
||||
DrawCommand.Type = TFB_DRAWCOMMANDTYPE_REINITVIDEO;
|
||||
DrawCommand.data.reinitvideo.driver = driver;
|
||||
DrawCommand.data.reinitvideo.flags = flags;
|
||||
DrawCommand.data.reinitvideo.width = width;
|
||||
DrawCommand.data.reinitvideo.height = height;
|
||||
TFB_EnqueueDrawCommand (&DrawCommand);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_Callback (void (*callback) (void *arg), void *arg)
|
||||
{
|
||||
TFB_DrawCommand DrawCommand;
|
||||
DrawCommand.Type = TFB_DRAWCOMMANDTYPE_CALLBACK;
|
||||
DrawCommand.data.callback.callback = callback;
|
||||
DrawCommand.data.callback.arg = arg;
|
||||
TFB_EnqueueDrawCommand(&DrawCommand);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_Line (int x1, int y1, int x2, int y2, Color color,
|
||||
DrawMode mode, TFB_Image *target)
|
||||
{
|
||||
LockMutex (target->mutex);
|
||||
TFB_DrawCanvas_Line (x1, y1, x2, y2, color, mode, target->NormalImg);
|
||||
target->dirty = TRUE;
|
||||
UnlockMutex (target->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_Rect (RECT *rect, Color color, DrawMode mode, TFB_Image *target)
|
||||
{
|
||||
LockMutex (target->mutex);
|
||||
TFB_DrawCanvas_Rect (rect, color, mode, target->NormalImg);
|
||||
target->dirty = TRUE;
|
||||
UnlockMutex (target->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_Image (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, TFB_ColorMap *cmap, DrawMode mode, TFB_Image *target)
|
||||
{
|
||||
LockMutex (target->mutex);
|
||||
TFB_DrawCanvas_Image (img, x, y, scale, scaleMode, cmap,
|
||||
mode, target->NormalImg);
|
||||
target->dirty = TRUE;
|
||||
UnlockMutex (target->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, Color color, DrawMode mode, TFB_Image *target)
|
||||
{
|
||||
LockMutex (target->mutex);
|
||||
TFB_DrawCanvas_FilledImage (img, x, y, scale, scaleMode, color,
|
||||
mode, target->NormalImg);
|
||||
target->dirty = TRUE;
|
||||
UnlockMutex (target->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_FontChar (TFB_Char *fontChar, TFB_Image *backing,
|
||||
int x, int y, DrawMode mode, TFB_Image *target)
|
||||
{
|
||||
LockMutex (target->mutex);
|
||||
TFB_DrawCanvas_FontChar (fontChar, backing, x, y, mode, target->NormalImg);
|
||||
target->dirty = TRUE;
|
||||
UnlockMutex (target->mutex);
|
||||
}
|
||||
|
||||
|
||||
TFB_Image *
|
||||
TFB_DrawImage_New (TFB_Canvas canvas)
|
||||
{
|
||||
TFB_Image *img = HMalloc (sizeof (TFB_Image));
|
||||
img->mutex = CreateMutex ("image lock", SYNC_CLASS_VIDEO);
|
||||
img->ScaledImg = NULL;
|
||||
img->MipmapImg = NULL;
|
||||
img->FilledImg = NULL;
|
||||
img->colormap_index = -1;
|
||||
img->colormap_version = 0;
|
||||
img->NormalHs = NullHs;
|
||||
img->MipmapHs = NullHs;
|
||||
img->last_scale_hs = NullHs;
|
||||
img->last_scale_type = -1;
|
||||
img->last_scale = 0;
|
||||
TFB_DrawCanvas_GetExtent (canvas, &img->extent);
|
||||
|
||||
if (TFB_DrawCanvas_IsPaletted (canvas))
|
||||
{
|
||||
img->NormalImg = canvas;
|
||||
}
|
||||
else
|
||||
{
|
||||
img->NormalImg = TFB_DrawCanvas_ToScreenFormat (canvas);
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
TFB_Image*
|
||||
TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha)
|
||||
{
|
||||
TFB_Image* img = HMalloc (sizeof (TFB_Image));
|
||||
img->mutex = CreateMutex ("image lock", SYNC_CLASS_VIDEO);
|
||||
img->ScaledImg = NULL;
|
||||
img->MipmapImg = NULL;
|
||||
img->FilledImg = NULL;
|
||||
img->colormap_index = -1;
|
||||
img->colormap_version = 0;
|
||||
img->NormalHs = NullHs;
|
||||
img->MipmapHs = NullHs;
|
||||
img->last_scale_hs = NullHs;
|
||||
img->last_scale_type = -1;
|
||||
img->last_scale = 0;
|
||||
img->extent.width = w;
|
||||
img->extent.height = h;
|
||||
|
||||
img->NormalImg = TFB_DrawCanvas_New_ForScreen (w, h, withalpha);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
TFB_Image *
|
||||
TFB_DrawImage_New_Rotated (TFB_Image *img, int angle)
|
||||
{
|
||||
TFB_Canvas dst;
|
||||
EXTENT size;
|
||||
TFB_Image* newimg;
|
||||
|
||||
/* sanity check */
|
||||
if (!img->NormalImg)
|
||||
{
|
||||
log_add (log_Warning, "TFB_DrawImage_New_Rotated: "
|
||||
"source canvas is NULL! Failing.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TFB_DrawCanvas_GetRotatedExtent (img->NormalImg, angle, &size);
|
||||
dst = TFB_DrawCanvas_New_RotationTarget (img->NormalImg, angle);
|
||||
if (!dst)
|
||||
{
|
||||
log_add (log_Warning, "TFB_DrawImage_New_Rotated: "
|
||||
"rotation target canvas not created! Failing.");
|
||||
return NULL;
|
||||
}
|
||||
TFB_DrawCanvas_Rotate (img->NormalImg, dst, angle, size);
|
||||
|
||||
newimg = TFB_DrawImage_New (dst);
|
||||
return newimg;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty)
|
||||
{
|
||||
bool imgpal;
|
||||
bool mmpal;
|
||||
|
||||
if (!img || !mmimg)
|
||||
return;
|
||||
|
||||
LockMutex (img->mutex);
|
||||
LockMutex (mmimg->mutex);
|
||||
|
||||
// Either both images must be using the same colormap, or mipmap image
|
||||
// must not be paletted. This restriction is due to the current
|
||||
// implementation of fill-stamp, which replaces the palette with
|
||||
// fill color.
|
||||
imgpal = TFB_DrawCanvas_IsPaletted (img->NormalImg);
|
||||
mmpal = TFB_DrawCanvas_IsPaletted (mmimg->NormalImg);
|
||||
if (!mmpal || (mmpal && imgpal &&
|
||||
img->colormap_index == mmimg->colormap_index))
|
||||
{
|
||||
img->MipmapImg = mmimg->NormalImg;
|
||||
img->MipmapHs.x = hotx;
|
||||
img->MipmapHs.y = hoty;
|
||||
}
|
||||
else
|
||||
{
|
||||
img->MipmapImg = NULL;
|
||||
}
|
||||
|
||||
UnlockMutex (mmimg->mutex);
|
||||
UnlockMutex (img->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_Delete (TFB_Image *image)
|
||||
{
|
||||
if (image == 0)
|
||||
{
|
||||
log_add (log_Warning, "INTERNAL ERROR: Tried to delete a null image!");
|
||||
/* Should we die here? */
|
||||
return;
|
||||
}
|
||||
LockMutex (image->mutex);
|
||||
|
||||
TFB_DrawCanvas_Delete (image->NormalImg);
|
||||
|
||||
if (image->ScaledImg) {
|
||||
TFB_DrawCanvas_Delete (image->ScaledImg);
|
||||
}
|
||||
|
||||
UnlockMutex (image->mutex);
|
||||
DestroyMutex (image->mutex);
|
||||
|
||||
HFree (image);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type)
|
||||
{
|
||||
if (image->dirty || !image->ScaledImg ||
|
||||
target != image->last_scale ||
|
||||
type != image->last_scale_type)
|
||||
{
|
||||
image->dirty = FALSE;
|
||||
image->ScaledImg = TFB_DrawCanvas_New_ScaleTarget (image->NormalImg,
|
||||
image->ScaledImg, type, image->last_scale_type);
|
||||
|
||||
if (type == TFB_SCALE_NEAREST)
|
||||
TFB_DrawCanvas_Rescale_Nearest (image->NormalImg,
|
||||
image->ScaledImg, target, &image->NormalHs,
|
||||
&image->extent, &image->last_scale_hs);
|
||||
else if (type == TFB_SCALE_BILINEAR)
|
||||
TFB_DrawCanvas_Rescale_Bilinear (image->NormalImg,
|
||||
image->ScaledImg, target, &image->NormalHs,
|
||||
&image->extent, &image->last_scale_hs);
|
||||
else
|
||||
TFB_DrawCanvas_Rescale_Trilinear (image->NormalImg,
|
||||
image->MipmapImg, image->ScaledImg, target,
|
||||
&image->NormalHs, &image->MipmapHs,
|
||||
&image->extent, &image->last_scale_hs);
|
||||
|
||||
image->last_scale_type = type;
|
||||
image->last_scale = target;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
TFB_DrawImage_Intersect (TFB_Image *img1, POINT img1org,
|
||||
TFB_Image *img2, POINT img2org, const RECT *interRect)
|
||||
{
|
||||
BOOLEAN ret;
|
||||
|
||||
LockMutex (img1->mutex);
|
||||
LockMutex (img2->mutex);
|
||||
ret = TFB_DrawCanvas_Intersect (img1->NormalImg, img1org,
|
||||
img2->NormalImg, img2org, interRect);
|
||||
UnlockMutex (img2->mutex);
|
||||
UnlockMutex (img1->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_CopyRect (TFB_Image *source, const RECT *srcRect,
|
||||
TFB_Image *target, POINT dstPt)
|
||||
{
|
||||
LockMutex (source->mutex);
|
||||
LockMutex (target->mutex);
|
||||
TFB_DrawCanvas_CopyRect (source->NormalImg, srcRect,
|
||||
target->NormalImg, dstPt);
|
||||
target->dirty = TRUE;
|
||||
UnlockMutex (target->mutex);
|
||||
UnlockMutex (source->mutex);
|
||||
}
|
||||
199
project/jni/application/sc2/src/libs/graphics/tfb_draw.h
Normal file
199
project/jni/application/sc2/src/libs/graphics/tfb_draw.h
Normal file
@@ -0,0 +1,199 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TFB_DRAW_H
|
||||
#define TFB_DRAW_H
|
||||
|
||||
#include "libs/threadlib.h"
|
||||
|
||||
|
||||
typedef void *TFB_Canvas;
|
||||
|
||||
typedef enum {
|
||||
TFB_SCREEN_MAIN,
|
||||
TFB_SCREEN_EXTRA,
|
||||
TFB_SCREEN_TRANSITION,
|
||||
|
||||
TFB_GFX_NUMSCREENS
|
||||
} SCREEN;
|
||||
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/graphics/cmap.h"
|
||||
|
||||
typedef struct tfb_image
|
||||
{
|
||||
TFB_Canvas NormalImg;
|
||||
TFB_Canvas ScaledImg;
|
||||
TFB_Canvas MipmapImg;
|
||||
TFB_Canvas FilledImg;
|
||||
int colormap_index;
|
||||
int colormap_version;
|
||||
HOT_SPOT NormalHs;
|
||||
HOT_SPOT MipmapHs;
|
||||
HOT_SPOT last_scale_hs;
|
||||
int last_scale;
|
||||
int last_scale_type;
|
||||
Color last_fill;
|
||||
EXTENT extent;
|
||||
Mutex mutex;
|
||||
BOOLEAN dirty;
|
||||
} TFB_Image;
|
||||
|
||||
typedef struct tfb_char
|
||||
{
|
||||
EXTENT extent;
|
||||
EXTENT disp;
|
||||
// Display extent
|
||||
HOT_SPOT HotSpot;
|
||||
BYTE* data;
|
||||
DWORD pitch;
|
||||
// Pitch is for storing all chars of a page
|
||||
// in one rectangular pixel matrix
|
||||
} TFB_Char;
|
||||
|
||||
// we do not support paletted format for now
|
||||
typedef struct tfb_pixelformat
|
||||
{
|
||||
int BitsPerPixel;
|
||||
int BytesPerPixel;
|
||||
DWORD Rmask, Gmask, Bmask, Amask;
|
||||
DWORD Rshift, Gshift, Bshift, Ashift;
|
||||
DWORD Rloss, Gloss, Bloss, Aloss;
|
||||
} TFB_PixelFormat;
|
||||
|
||||
// Drawing commands
|
||||
|
||||
void TFB_DrawScreen_Line (int x1, int y1, int x2, int y2, Color color,
|
||||
DrawMode, SCREEN dest);
|
||||
void TFB_DrawScreen_Rect (RECT *rect, Color, DrawMode, SCREEN dest);
|
||||
void TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, TFB_ColorMap *, DrawMode, SCREEN dest);
|
||||
void TFB_DrawScreen_Copy (const RECT *r, SCREEN src, SCREEN dest);
|
||||
void TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, Color, DrawMode, SCREEN dest);
|
||||
void TFB_DrawScreen_FontChar (TFB_Char *, TFB_Image *backing, int x, int y,
|
||||
DrawMode, SCREEN dest);
|
||||
|
||||
void TFB_DrawScreen_CopyToImage (TFB_Image *img, const RECT *r, SCREEN src);
|
||||
void TFB_DrawScreen_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx,
|
||||
int hoty);
|
||||
void TFB_DrawScreen_DeleteImage (TFB_Image *img);
|
||||
void TFB_DrawScreen_DeleteData (void *);
|
||||
void TFB_DrawScreen_WaitForSignal (void);
|
||||
void TFB_DrawScreen_ReinitVideo (int driver, int flags, int width, int height);
|
||||
void TFB_DrawScreen_Callback (void (*callback) (void *arg), void *arg);
|
||||
|
||||
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas);
|
||||
TFB_Image *TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha);
|
||||
TFB_Image *TFB_DrawImage_New_Rotated (TFB_Image *img, int angle);
|
||||
void TFB_DrawImage_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx,
|
||||
int hoty);
|
||||
void TFB_DrawImage_Delete (TFB_Image *image);
|
||||
void TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type);
|
||||
BOOLEAN TFB_DrawImage_Intersect (TFB_Image *img1, POINT img1org,
|
||||
TFB_Image *img2, POINT img2org, const RECT *interRect);
|
||||
void TFB_DrawImage_CopyRect (TFB_Image *source, const RECT *srcRect,
|
||||
TFB_Image *target, POINT dstPt);
|
||||
|
||||
void TFB_DrawImage_Line (int x1, int y1, int x2, int y2, Color color,
|
||||
DrawMode, TFB_Image *target);
|
||||
void TFB_DrawImage_Rect (RECT *rect, Color, DrawMode, TFB_Image *target);
|
||||
void TFB_DrawImage_Image (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, TFB_ColorMap *, DrawMode, TFB_Image *target);
|
||||
void TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, Color, DrawMode, TFB_Image *target);
|
||||
void TFB_DrawImage_FontChar (TFB_Char *, TFB_Image *backing, int x, int y,
|
||||
DrawMode, TFB_Image *target);
|
||||
|
||||
TFB_Canvas TFB_DrawCanvas_LoadFromFile (void *dir, const char *fileName);
|
||||
TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN hasalpha);
|
||||
TFB_Canvas TFB_DrawCanvas_New_ForScreen (int w, int h, BOOLEAN withalpha);
|
||||
TFB_Canvas TFB_DrawCanvas_New_Paletted (int w, int h, Color palette[256],
|
||||
int transparent_index);
|
||||
TFB_Canvas TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas,
|
||||
TFB_Canvas oldcanvas, int type, int last_type);
|
||||
TFB_Canvas TFB_DrawCanvas_New_RotationTarget (TFB_Canvas src, int angle);
|
||||
TFB_Canvas TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas);
|
||||
BOOLEAN TFB_DrawCanvas_IsPaletted (TFB_Canvas canvas);
|
||||
void TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src, TFB_Canvas dst,
|
||||
int scale, HOT_SPOT* src_hs, EXTENT* size, HOT_SPOT* dst_hs);
|
||||
void TFB_DrawCanvas_Rescale_Bilinear (TFB_Canvas src, TFB_Canvas dst,
|
||||
int scale, HOT_SPOT* src_hs, EXTENT* size, HOT_SPOT* dst_hs);
|
||||
void TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src, TFB_Canvas mipmap,
|
||||
TFB_Canvas dst, int scale, HOT_SPOT* src_hs, HOT_SPOT* mm_hs,
|
||||
EXTENT* size, HOT_SPOT* dst_hs);
|
||||
void TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, HOT_SPOT* src_hs,
|
||||
TFB_Canvas src_mipmap, HOT_SPOT* mm_hs,
|
||||
int scale, int type, EXTENT *size, HOT_SPOT *hs);
|
||||
void TFB_DrawCanvas_Rotate (TFB_Canvas src, TFB_Canvas dst, int angle,
|
||||
EXTENT size);
|
||||
void TFB_DrawCanvas_GetRotatedExtent (TFB_Canvas src, int angle, EXTENT *size);
|
||||
void TFB_DrawCanvas_GetExtent (TFB_Canvas canvas, EXTENT *size);
|
||||
void TFB_DrawCanvas_SetClipRect (TFB_Canvas canvas, const RECT *clipRect);
|
||||
|
||||
void TFB_DrawCanvas_Delete (TFB_Canvas canvas);
|
||||
|
||||
void TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2, Color color,
|
||||
DrawMode, TFB_Canvas target);
|
||||
void TFB_DrawCanvas_Rect (RECT *rect, Color, DrawMode, TFB_Canvas target);
|
||||
void TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, TFB_ColorMap *, DrawMode, TFB_Canvas target);
|
||||
void TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale,
|
||||
int scaleMode, Color, DrawMode, TFB_Canvas target);
|
||||
void TFB_DrawCanvas_FontChar (TFB_Char *, TFB_Image *backing, int x, int y,
|
||||
DrawMode, TFB_Canvas target);
|
||||
void TFB_DrawCanvas_CopyRect (TFB_Canvas source, const RECT *srcRect,
|
||||
TFB_Canvas target, POINT dstPt);
|
||||
|
||||
BOOLEAN TFB_DrawCanvas_GetFontCharData (TFB_Canvas canvas, BYTE *outData,
|
||||
unsigned dataPitch);
|
||||
Color *TFB_DrawCanvas_ExtractPalette (TFB_Canvas canvas);
|
||||
void TFB_DrawCanvas_SetPalette (TFB_Canvas target, Color palette[256]);
|
||||
int TFB_DrawCanvas_GetTransparentIndex (TFB_Canvas canvas);
|
||||
void TFB_DrawCanvas_SetTransparentIndex (TFB_Canvas canvas, int i,
|
||||
BOOLEAN rleaccel);
|
||||
BOOLEAN TFB_DrawCanvas_GetTransparentColor (TFB_Canvas canvas,
|
||||
Color *color);
|
||||
void TFB_DrawCanvas_SetTransparentColor (TFB_Canvas canvas,
|
||||
Color color, BOOLEAN rleaccel);
|
||||
void TFB_DrawCanvas_CopyTransparencyInfo (TFB_Canvas src, TFB_Canvas dst);
|
||||
void TFB_DrawCanvas_Initialize (void);
|
||||
void TFB_DrawCanvas_Lock (TFB_Canvas canvas);
|
||||
void TFB_DrawCanvas_Unlock (TFB_Canvas canvas);
|
||||
void TFB_DrawCanvas_GetScreenFormat (TFB_PixelFormat *fmt);
|
||||
int TFB_DrawCanvas_GetStride (TFB_Canvas canvas);
|
||||
void *TFB_DrawCanvas_GetLine (TFB_Canvas canvas, int line);
|
||||
Color TFB_DrawCanvas_GetPixel (TFB_Canvas canvas, int x, int y);
|
||||
BOOLEAN TFB_DrawCanvas_Intersect (TFB_Canvas canvas1, POINT c1org,
|
||||
TFB_Canvas canvas2, POINT c2org, const RECT *interRect);
|
||||
|
||||
BOOLEAN TFB_DrawCanvas_GetPixelColors (TFB_Canvas, Color *pixels,
|
||||
int width, int height);
|
||||
BOOLEAN TFB_DrawCanvas_SetPixelColors (TFB_Canvas, const Color *pixels,
|
||||
int width, int height);
|
||||
BOOLEAN TFB_DrawCanvas_GetPixelIndexes (TFB_Canvas, BYTE *data,
|
||||
int width, int height);
|
||||
BOOLEAN TFB_DrawCanvas_SetPixelIndexes (TFB_Canvas, const BYTE *data,
|
||||
int width, int height);
|
||||
|
||||
const char *TFB_DrawCanvas_GetError (void);
|
||||
|
||||
TFB_Canvas TFB_GetScreenCanvas (SCREEN screen);
|
||||
|
||||
#endif
|
||||
|
||||
237
project/jni/application/sc2/src/libs/graphics/tfb_prim.c
Normal file
237
project/jni/application/sc2/src/libs/graphics/tfb_prim.c
Normal file
@@ -0,0 +1,237 @@
|
||||
// Copyright Michael Martin, 2003
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* The original Primitive routines do various elaborate checks to
|
||||
* ensure we're within bounds for the clipping. Since clipping is
|
||||
* handled by the underlying TFB_Canvas implementation, we need not
|
||||
* worry about this. */
|
||||
|
||||
#include "gfxintrn.h"
|
||||
#include "gfx_common.h"
|
||||
#include "tfb_draw.h"
|
||||
#include "tfb_prim.h"
|
||||
#include "cmap.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
void
|
||||
TFB_Prim_Point (POINT *p, Color color, DrawMode mode, POINT ctxOrigin)
|
||||
{
|
||||
RECT r;
|
||||
|
||||
// The caller must scale the origin!
|
||||
r.corner.x = p->x + ctxOrigin.x;
|
||||
r.corner.y = p->y + ctxOrigin.y;
|
||||
r.extent.width = r.extent.height = 1;
|
||||
|
||||
if (_CurFramePtr->Type == SCREEN_DRAWABLE)
|
||||
TFB_DrawScreen_Rect (&r, color, mode, TFB_SCREEN_MAIN);
|
||||
else
|
||||
TFB_DrawImage_Rect (&r, color, mode, _CurFramePtr->image);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_Prim_Rect (RECT *r, Color color, DrawMode mode, POINT ctxOrigin)
|
||||
{
|
||||
RECT arm;
|
||||
int gscale;
|
||||
|
||||
// XXX: Rect prim scaling is currently unused
|
||||
// We scale the rect size just to be consistent with stamp prim,
|
||||
// which does same. The caller must scale the origin!
|
||||
gscale = GetGraphicScale ();
|
||||
arm = *r;
|
||||
arm.extent.width = r->extent.width;
|
||||
arm.extent.height = 1;
|
||||
TFB_Prim_FillRect (&arm, color, mode, ctxOrigin);
|
||||
arm.extent.height = r->extent.height;
|
||||
arm.extent.width = 1;
|
||||
TFB_Prim_FillRect (&arm, color, mode, ctxOrigin);
|
||||
// rounding error correction here
|
||||
arm.corner.x += ((r->extent.width * gscale + (GSCALE_IDENTITY >> 1))
|
||||
/ GSCALE_IDENTITY) - 1;
|
||||
TFB_Prim_FillRect (&arm, color, mode, ctxOrigin);
|
||||
arm.corner.x = r->corner.x;
|
||||
arm.corner.y += ((r->extent.height * gscale + (GSCALE_IDENTITY >> 1))
|
||||
/ GSCALE_IDENTITY) - 1;
|
||||
arm.extent.width = r->extent.width;
|
||||
arm.extent.height = 1;
|
||||
TFB_Prim_FillRect (&arm, color, mode, ctxOrigin);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_Prim_FillRect (RECT *r, Color color, DrawMode mode, POINT ctxOrigin)
|
||||
{
|
||||
RECT rect;
|
||||
int gscale;
|
||||
|
||||
rect.corner.x = r->corner.x + ctxOrigin.x;
|
||||
rect.corner.y = r->corner.y + ctxOrigin.y;
|
||||
rect.extent.width = r->extent.width;
|
||||
rect.extent.height = r->extent.height;
|
||||
|
||||
// XXX: Rect prim scaling is currently unused
|
||||
// We scale the rect size just to be consistent with stamp prim,
|
||||
// which does same. The caller must scale the origin!
|
||||
gscale = GetGraphicScale ();
|
||||
if (gscale != GSCALE_IDENTITY)
|
||||
{ // rounding error correction here
|
||||
rect.extent.width = (rect.extent.width * gscale
|
||||
+ (GSCALE_IDENTITY >> 1)) / GSCALE_IDENTITY;
|
||||
rect.extent.height = (rect.extent.height * gscale
|
||||
+ (GSCALE_IDENTITY >> 1)) / GSCALE_IDENTITY;
|
||||
}
|
||||
|
||||
if (_CurFramePtr->Type == SCREEN_DRAWABLE)
|
||||
TFB_DrawScreen_Rect (&rect, color, mode, TFB_SCREEN_MAIN);
|
||||
else
|
||||
TFB_DrawImage_Rect (&rect, color, mode, _CurFramePtr->image);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_Prim_Line (LINE *line, Color color, DrawMode mode, POINT ctxOrigin)
|
||||
{
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
// The caller must scale the origins!
|
||||
x1=line->first.x + ctxOrigin.x;
|
||||
y1=line->first.y + ctxOrigin.y;
|
||||
x2=line->second.x + ctxOrigin.x;
|
||||
y2=line->second.y + ctxOrigin.y;
|
||||
|
||||
if (_CurFramePtr->Type == SCREEN_DRAWABLE)
|
||||
TFB_DrawScreen_Line (x1, y1, x2, y2, color, mode, TFB_SCREEN_MAIN);
|
||||
else
|
||||
TFB_DrawImage_Line (x1, y1, x2, y2, color, mode, _CurFramePtr->image);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_Prim_Stamp (STAMP *stmp, DrawMode mode, POINT ctxOrigin)
|
||||
{
|
||||
int x, y;
|
||||
FRAME SrcFramePtr;
|
||||
TFB_Image *img;
|
||||
TFB_ColorMap *cmap = NULL;
|
||||
|
||||
SrcFramePtr = stmp->frame;
|
||||
if (!SrcFramePtr)
|
||||
{
|
||||
log_add (log_Warning, "TFB_Prim_Stamp: Tried to draw a NULL frame"
|
||||
" (Stamp address = %p)", stmp);
|
||||
return;
|
||||
}
|
||||
img = SrcFramePtr->image;
|
||||
|
||||
if (!img)
|
||||
{
|
||||
log_add (log_Warning, "Non-existent image to TFB_Prim_Stamp()");
|
||||
return;
|
||||
}
|
||||
|
||||
LockMutex (img->mutex);
|
||||
|
||||
img->NormalHs = SrcFramePtr->HotSpot;
|
||||
// We scale the image size here, but the caller must scale the origin!
|
||||
x = stmp->origin.x + ctxOrigin.x;
|
||||
y = stmp->origin.y + ctxOrigin.y;
|
||||
|
||||
if (TFB_DrawCanvas_IsPaletted(img->NormalImg) && img->colormap_index != -1)
|
||||
{
|
||||
// returned cmap is addrefed, must release later
|
||||
cmap = TFB_GetColorMap (img->colormap_index);
|
||||
}
|
||||
|
||||
UnlockMutex (img->mutex);
|
||||
|
||||
if (_CurFramePtr->Type == SCREEN_DRAWABLE)
|
||||
{
|
||||
TFB_DrawScreen_Image (img, x, y, GetGraphicScale (),
|
||||
GetGraphicScaleMode (), cmap, mode, TFB_SCREEN_MAIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
TFB_DrawImage_Image (img, x, y, GetGraphicScale (),
|
||||
GetGraphicScaleMode (), cmap, mode, _CurFramePtr->image);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFB_Prim_StampFill (STAMP *stmp, Color color, DrawMode mode, POINT ctxOrigin)
|
||||
{
|
||||
int x, y;
|
||||
FRAME SrcFramePtr;
|
||||
TFB_Image *img;
|
||||
|
||||
SrcFramePtr = stmp->frame;
|
||||
if (!SrcFramePtr)
|
||||
{
|
||||
log_add (log_Warning, "TFB_Prim_StampFill: Tried to draw a NULL frame"
|
||||
" (Stamp address = %p)", stmp);
|
||||
return;
|
||||
}
|
||||
img = SrcFramePtr->image;
|
||||
|
||||
if (!img)
|
||||
{
|
||||
log_add (log_Warning, "Non-existent image to TFB_Prim_StampFill()");
|
||||
return;
|
||||
}
|
||||
|
||||
LockMutex (img->mutex);
|
||||
|
||||
img->NormalHs = SrcFramePtr->HotSpot;
|
||||
// We scale the image size here, but the caller must scale the origin!
|
||||
x = stmp->origin.x + ctxOrigin.x;
|
||||
y = stmp->origin.y + ctxOrigin.y;
|
||||
|
||||
UnlockMutex (img->mutex);
|
||||
|
||||
if (_CurFramePtr->Type == SCREEN_DRAWABLE)
|
||||
{
|
||||
TFB_DrawScreen_FilledImage (img, x, y, GetGraphicScale (),
|
||||
GetGraphicScaleMode (), color, mode, TFB_SCREEN_MAIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
TFB_DrawImage_FilledImage (img, x, y, GetGraphicScale (),
|
||||
GetGraphicScaleMode (), color, mode, _CurFramePtr->image);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFB_Prim_FontChar (POINT charOrigin, TFB_Char *fontChar, TFB_Image *backing,
|
||||
DrawMode mode, POINT ctxOrigin)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
// Text prim does not scale
|
||||
x = charOrigin.x + ctxOrigin.x;
|
||||
y = charOrigin.y + ctxOrigin.y;
|
||||
|
||||
if (_CurFramePtr->Type == SCREEN_DRAWABLE)
|
||||
{
|
||||
TFB_DrawScreen_FontChar (fontChar, backing, x, y, mode,
|
||||
TFB_SCREEN_MAIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
TFB_DrawImage_FontChar (fontChar, backing, x, y, mode,
|
||||
_CurFramePtr->image);
|
||||
}
|
||||
}
|
||||
|
||||
// Text rendering is in font.c, under the name _text_blt
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user