Fixed mixer volume too high in REminiscence

This commit is contained in:
pelya
2010-11-11 20:44:02 +02:00
parent 004f298065
commit 11d676ddc0
39 changed files with 15271 additions and 15247 deletions

View File

@@ -1,340 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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.

View File

@@ -1,138 +1,138 @@
REminiscence README
Release version: 0.1.9 (Mar 16 2007)
-------------------------------------------------------------------------------
About:
------
REminiscence is a re-implementation of the engine used in the game Flashback
made by Delphine Software and released in 1992. More informations about the
game can be found at [1], [2] and [3].
Supported Versions:
-------------------
Only the PC DOS versions are supported. The engine has been reported to work
with english, french, german and spanish versions of the game.
Compiling:
----------
Tweak the Makefile if needed and type make (only gcc3 has been tested so far).
The SDL and zlib libraries are required.
Data Files:
-----------
You will need the original files, here is the required list :
FB_TXT.FNT
GLOBAL.ICN
GLOBAL.FIB
GLOBAL.SPC
*.OFF
*.SPR
*.MAP
*.PAL
*.ANI
*.CT
*.MBK
*.OBJ
*.PGE
*.RP
*.TBN
*.CMD
*.POL
*CINE.*
If you have a version distributed by SSI, you'll have to rename some files :
logosssi.cmd -> logos.cmd
logosssi.pol -> logos.pol
menu1ssi.map -> menu1.map
menu1ssi.pal -> menu1.pal
In order to hear music, you'll need the original music files (.mod) of the
amiga version. Copy them to the DATA directory and rename them like this :
mod.flashback-ascenseur
mod.flashback-ceinturea
mod.flashback-chute
mod.flashback-desintegr
mod.flashback-donneobjt
mod.flashback-fin
mod.flashback-fin2
mod.flashback-game_over
mod.flashback-holocube
mod.flashback-introb
mod.flashback-jungle
mod.flashback-logo
mod.flashback-memoire
mod.flashback-missionca
mod.flashback-options1
mod.flashback-options2
mod.flashback-reunion
mod.flashback-taxi
mod.flashback-teleport2
mod.flashback-teleporta
mod.flashback-voyage
Running:
--------
By default, the engine will try to load the game data files from the 'DATA'
directory (as the original game did). The savestates are saved in the current
directory. These paths can be changed using command line switches :
Usage: rs [OPTIONS]...
--datapath=PATH Path to data files (default 'DATA')
--savepath=PATH Path to save files (default '.')
In-game hotkeys :
Arrow Keys move Conrad
Enter use the current inventory object
Shift talk / use / run / shoot
Escape display the options
Backspace display the inventory
Alt Enter toggle windowed/fullscreen mode
Alt + and - change video scaler
Ctrl S save game state
Ctrl L load game state
Ctrl + and - change game state slot
Ctrl R toggle input keys record
Ctrl P toggle input keys replay
Debug hotkeys :
Ctrl F toggle fast mode
Ctrl I set Conrad life counter to 32767
Ctrl B toggle display of updated dirty blocks
Ctrl M mirror mode (just a hack, really)
Credits:
--------
Delphine Software, obviously, for making another great game.
Yaz0r, Pixel and gawd for sharing information they gathered on the game.
Contact:
--------
Gregory Montoir, cyx@users.sourceforge.net
URLs:
-----
[1] http://www.mobygames.com/game/flashback-the-quest-for-identity
[2] http://en.wikipedia.org/wiki/Flashback:_The_Quest_for_Identity
[3] http://ramal.free.fr/fb_en.htm
REminiscence README
Release version: 0.1.9 (Mar 16 2007)
-------------------------------------------------------------------------------
About:
------
REminiscence is a re-implementation of the engine used in the game Flashback
made by Delphine Software and released in 1992. More informations about the
game can be found at [1], [2] and [3].
Supported Versions:
-------------------
Only the PC DOS versions are supported. The engine has been reported to work
with english, french, german and spanish versions of the game.
Compiling:
----------
Tweak the Makefile if needed and type make (only gcc3 has been tested so far).
The SDL and zlib libraries are required.
Data Files:
-----------
You will need the original files, here is the required list :
FB_TXT.FNT
GLOBAL.ICN
GLOBAL.FIB
GLOBAL.SPC
*.OFF
*.SPR
*.MAP
*.PAL
*.ANI
*.CT
*.MBK
*.OBJ
*.PGE
*.RP
*.TBN
*.CMD
*.POL
*CINE.*
If you have a version distributed by SSI, you'll have to rename some files :
logosssi.cmd -> logos.cmd
logosssi.pol -> logos.pol
menu1ssi.map -> menu1.map
menu1ssi.pal -> menu1.pal
In order to hear music, you'll need the original music files (.mod) of the
amiga version. Copy them to the DATA directory and rename them like this :
mod.flashback-ascenseur
mod.flashback-ceinturea
mod.flashback-chute
mod.flashback-desintegr
mod.flashback-donneobjt
mod.flashback-fin
mod.flashback-fin2
mod.flashback-game_over
mod.flashback-holocube
mod.flashback-introb
mod.flashback-jungle
mod.flashback-logo
mod.flashback-memoire
mod.flashback-missionca
mod.flashback-options1
mod.flashback-options2
mod.flashback-reunion
mod.flashback-taxi
mod.flashback-teleport2
mod.flashback-teleporta
mod.flashback-voyage
Running:
--------
By default, the engine will try to load the game data files from the 'DATA'
directory (as the original game did). The savestates are saved in the current
directory. These paths can be changed using command line switches :
Usage: rs [OPTIONS]...
--datapath=PATH Path to data files (default 'DATA')
--savepath=PATH Path to save files (default '.')
In-game hotkeys :
Arrow Keys move Conrad
Enter use the current inventory object
Shift talk / use / run / shoot
Escape display the options
Backspace display the inventory
Alt Enter toggle windowed/fullscreen mode
Alt + and - change video scaler
Ctrl S save game state
Ctrl L load game state
Ctrl + and - change game state slot
Ctrl R toggle input keys record
Ctrl P toggle input keys replay
Debug hotkeys :
Ctrl F toggle fast mode
Ctrl I set Conrad life counter to 32767
Ctrl B toggle display of updated dirty blocks
Ctrl M mirror mode (just a hack, really)
Credits:
--------
Delphine Software, obviously, for making another great game.
Yaz0r, Pixel and gawd for sharing information they gathered on the game.
Contact:
--------
Gregory Montoir, cyx@users.sourceforge.net
URLs:
-----
[1] http://www.mobygames.com/game/flashback-the-quest-for-identity
[2] http://en.wikipedia.org/wiki/Flashback:_The_Quest_for_Identity
[3] http://ramal.free.fr/fb_en.htm

View File

@@ -1,138 +1,138 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __CUTSCENE_H__
#define __CUTSCENE_H__
#include "intern.h"
#include "graphics.h"
struct ModPlayer;
struct Resource;
struct SystemStub;
struct Video;
struct Cutscene {
typedef void (Cutscene::*OpcodeStub)();
enum {
NUM_OPCODES = 15,
TIMER_SLICE = 15
};
static const OpcodeStub _opcodeTable[];
static const char *_namesTable[];
static const uint16 _offsetsTable[];
static const uint16 _cosTable[];
static const uint16 _sinTable[];
static const uint8 _creditsData[];
static const uint16 _creditsCutSeq[];
static const uint8 _musicTable[];
static const uint8 _protectionShapeData[];
Graphics _gfx;
ModPlayer *_ply;
Resource *_res;
SystemStub *_stub;
Video *_vid;
Version _ver;
uint16 _id;
uint16 _deathCutsceneId;
bool _interrupted;
bool _stop;
uint8 *_polPtr;
uint8 *_cmdPtr;
uint8 *_cmdPtrBak;
uint32 _tstamp;
uint8 _frameDelay;
bool _newPal;
uint8 _palBuf[0x20 * 2];
uint16 _startOffset;
bool _creditsSequence;
uint32 _rotData[4];
uint8 _primitiveColor;
uint8 _clearScreen;
Point _vertices[0x80];
bool _hasAlphaColor;
uint8 _varText;
uint8 _varKey;
int16 _shape_ix;
int16 _shape_iy;
int16 _shape_ox;
int16 _shape_oy;
int16 _shape_cur_x;
int16 _shape_cur_y;
int16 _shape_prev_x;
int16 _shape_prev_y;
uint16 _shape_count;
uint32 _shape_cur_x16;
uint32 _shape_cur_y16;
uint32 _shape_prev_x16;
uint32 _shape_prev_y16;
uint8 _textSep[0x14];
uint8 _textBuf[500];
const uint8 *_textCurPtr;
uint8 *_textCurBuf;
uint8 _textUnk2;
uint8 _creditsTextPosX;
uint8 _creditsTextPosY;
int16 _creditsTextCounter;
uint8 *_page0, *_page1, *_pageC;
Cutscene(ModPlayer *player, Resource *res, SystemStub *stub, Video *vid, Version ver);
void sync();
void copyPalette(const uint8 *pal, uint16 num);
void updatePalette();
void setPalette();
void initRotationData(uint16 a, uint16 b, uint16 c);
uint16 findTextSeparators(const uint8 *p);
void drawText(int16 x, int16 y, const uint8 *p, uint16 color, uint8 *page, uint8 n);
void swapLayers();
void drawCreditsText();
void drawProtectionShape(uint8 shapeNum, int16 zoom);
void drawShape(const uint8 *data, int16 x, int16 y);
void drawShapeScale(const uint8 *data, int16 zoom, int16 b, int16 c, int16 d, int16 e, int16 f, int16 g);
void drawShapeScaleRotate(const uint8 *data, int16 zoom, int16 b, int16 c, int16 d, int16 e, int16 f, int16 g);
void op_markCurPos();
void op_refreshScreen();
void op_waitForSync();
void op_drawShape();
void op_setPalette();
void op_drawStringAtBottom();
void op_nop();
void op_skip3();
void op_refreshAll();
void op_drawShapeScale();
void op_drawShapeScaleRotate();
void op_drawCreditsText();
void op_drawStringAtPos();
void op_handleKeys();
uint8 fetchNextCmdByte();
uint16 fetchNextCmdWord();
void mainLoop(uint16 offset);
void load(uint16 cutName);
void prepare();
void startCredits();
void play();
};
#endif // __CUTSCENE_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __CUTSCENE_H__
#define __CUTSCENE_H__
#include "intern.h"
#include "graphics.h"
struct ModPlayer;
struct Resource;
struct SystemStub;
struct Video;
struct Cutscene {
typedef void (Cutscene::*OpcodeStub)();
enum {
NUM_OPCODES = 15,
TIMER_SLICE = 15
};
static const OpcodeStub _opcodeTable[];
static const char *_namesTable[];
static const uint16 _offsetsTable[];
static const uint16 _cosTable[];
static const uint16 _sinTable[];
static const uint8 _creditsData[];
static const uint16 _creditsCutSeq[];
static const uint8 _musicTable[];
static const uint8 _protectionShapeData[];
Graphics _gfx;
ModPlayer *_ply;
Resource *_res;
SystemStub *_stub;
Video *_vid;
Version _ver;
uint16 _id;
uint16 _deathCutsceneId;
bool _interrupted;
bool _stop;
uint8 *_polPtr;
uint8 *_cmdPtr;
uint8 *_cmdPtrBak;
uint32 _tstamp;
uint8 _frameDelay;
bool _newPal;
uint8 _palBuf[0x20 * 2];
uint16 _startOffset;
bool _creditsSequence;
uint32 _rotData[4];
uint8 _primitiveColor;
uint8 _clearScreen;
Point _vertices[0x80];
bool _hasAlphaColor;
uint8 _varText;
uint8 _varKey;
int16 _shape_ix;
int16 _shape_iy;
int16 _shape_ox;
int16 _shape_oy;
int16 _shape_cur_x;
int16 _shape_cur_y;
int16 _shape_prev_x;
int16 _shape_prev_y;
uint16 _shape_count;
uint32 _shape_cur_x16;
uint32 _shape_cur_y16;
uint32 _shape_prev_x16;
uint32 _shape_prev_y16;
uint8 _textSep[0x14];
uint8 _textBuf[500];
const uint8 *_textCurPtr;
uint8 *_textCurBuf;
uint8 _textUnk2;
uint8 _creditsTextPosX;
uint8 _creditsTextPosY;
int16 _creditsTextCounter;
uint8 *_page0, *_page1, *_pageC;
Cutscene(ModPlayer *player, Resource *res, SystemStub *stub, Video *vid, Version ver);
void sync();
void copyPalette(const uint8 *pal, uint16 num);
void updatePalette();
void setPalette();
void initRotationData(uint16 a, uint16 b, uint16 c);
uint16 findTextSeparators(const uint8 *p);
void drawText(int16 x, int16 y, const uint8 *p, uint16 color, uint8 *page, uint8 n);
void swapLayers();
void drawCreditsText();
void drawProtectionShape(uint8 shapeNum, int16 zoom);
void drawShape(const uint8 *data, int16 x, int16 y);
void drawShapeScale(const uint8 *data, int16 zoom, int16 b, int16 c, int16 d, int16 e, int16 f, int16 g);
void drawShapeScaleRotate(const uint8 *data, int16 zoom, int16 b, int16 c, int16 d, int16 e, int16 f, int16 g);
void op_markCurPos();
void op_refreshScreen();
void op_waitForSync();
void op_drawShape();
void op_setPalette();
void op_drawStringAtBottom();
void op_nop();
void op_skip3();
void op_refreshAll();
void op_drawShapeScale();
void op_drawShapeScaleRotate();
void op_drawCreditsText();
void op_drawStringAtPos();
void op_handleKeys();
uint8 fetchNextCmdByte();
uint16 fetchNextCmdWord();
void mainLoop(uint16 offset);
void load(uint16 cutName);
void prepare();
void startCredits();
void play();
};
#endif // __CUTSCENE_H__

View File

@@ -1,222 +1,222 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "zlib.h"
#include "file.h"
struct File_impl {
bool _ioErr;
File_impl() : _ioErr(false) {}
virtual bool open(const char *path, const char *mode) = 0;
virtual void close() = 0;
virtual uint32 size() = 0;
virtual void seek(int32 off) = 0;
virtual void read(void *ptr, uint32 len) = 0;
virtual void write(void *ptr, uint32 len) = 0;
};
struct stdFile : File_impl {
FILE *_fp;
stdFile() : _fp(0) {}
bool open(const char *path, const char *mode) {
_ioErr = false;
_fp = fopen(path, mode);
return (_fp != 0);
}
void close() {
if (_fp) {
fclose(_fp);
_fp = 0;
}
}
uint32 size() {
uint32 sz = 0;
if (_fp) {
int pos = ftell(_fp);
fseek(_fp, 0, SEEK_END);
sz = ftell(_fp);
fseek(_fp, pos, SEEK_SET);
}
return sz;
}
void seek(int32 off) {
if (_fp) {
fseek(_fp, off, SEEK_SET);
}
}
void read(void *ptr, uint32 len) {
if (_fp) {
uint32 r = fread(ptr, 1, len, _fp);
if (r != len) {
_ioErr = true;
}
}
}
void write(void *ptr, uint32 len) {
if (_fp) {
uint32 r = fwrite(ptr, 1, len, _fp);
if (r != len) {
_ioErr = true;
}
}
}
};
struct zlibFile : File_impl {
gzFile _fp;
zlibFile() : _fp(0) {}
bool open(const char *path, const char *mode) {
_ioErr = false;
_fp = gzopen(path, mode);
return (_fp != 0);
}
void close() {
if (_fp) {
gzclose(_fp);
_fp = 0;
}
}
uint32 size() {
uint32 sz = 0;
if (_fp) {
int pos = gztell(_fp);
gzseek(_fp, 0, SEEK_END);
sz = gztell(_fp);
gzseek(_fp, pos, SEEK_SET);
}
return sz;
}
void seek(int32 off) {
if (_fp) {
gzseek(_fp, off, SEEK_SET);
}
}
void read(void *ptr, uint32 len) {
if (_fp) {
uint32 r = gzread(_fp, ptr, len);
if (r != len) {
_ioErr = true;
}
}
}
void write(void *ptr, uint32 len) {
if (_fp) {
uint32 r = gzwrite(_fp, ptr, len);
if (r != len) {
_ioErr = true;
}
}
}
};
File::File(bool gzipped) {
if (gzipped) {
_impl = new zlibFile;
} else {
_impl = new stdFile;
}
}
File::~File() {
_impl->close();
delete _impl;
}
bool File::open(const char *filename, const char *directory, const char *mode) {
_impl->close();
char buf[512];
sprintf(buf, "%s/%s", directory, filename);
char *p = buf + strlen(directory) + 1;
string_lower(p);
bool opened = _impl->open(buf, mode);
if (!opened) { // let's try uppercase
string_upper(p);
opened = _impl->open(buf, mode);
}
return opened;
}
void File::close() {
_impl->close();
}
bool File::ioErr() const {
return _impl->_ioErr;
}
uint32 File::size() {
return _impl->size();
}
void File::seek(int32 off) {
_impl->seek(off);
}
void File::read(void *ptr, uint32 len) {
_impl->read(ptr, len);
}
uint8 File::readByte() {
uint8 b;
read(&b, 1);
return b;
}
uint16 File::readUint16LE() {
uint8 lo = readByte();
uint8 hi = readByte();
return (hi << 8) | lo;
}
uint32 File::readUint32LE() {
uint16 lo = readUint16LE();
uint16 hi = readUint16LE();
return (hi << 16) | lo;
}
uint16 File::readUint16BE() {
uint8 hi = readByte();
uint8 lo = readByte();
return (hi << 8) | lo;
}
uint32 File::readUint32BE() {
uint16 hi = readUint16BE();
uint16 lo = readUint16BE();
return (hi << 16) | lo;
}
void File::write(void *ptr, uint32 len) {
_impl->write(ptr, len);
}
void File::writeByte(uint8 b) {
write(&b, 1);
}
void File::writeUint16BE(uint16 n) {
writeByte(n >> 8);
writeByte(n & 0xFF);
}
void File::writeUint32BE(uint32 n) {
writeUint16BE(n >> 16);
writeUint16BE(n & 0xFFFF);
}
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "zlib.h"
#include "file.h"
struct File_impl {
bool _ioErr;
File_impl() : _ioErr(false) {}
virtual bool open(const char *path, const char *mode) = 0;
virtual void close() = 0;
virtual uint32 size() = 0;
virtual void seek(int32 off) = 0;
virtual void read(void *ptr, uint32 len) = 0;
virtual void write(void *ptr, uint32 len) = 0;
};
struct stdFile : File_impl {
FILE *_fp;
stdFile() : _fp(0) {}
bool open(const char *path, const char *mode) {
_ioErr = false;
_fp = fopen(path, mode);
return (_fp != 0);
}
void close() {
if (_fp) {
fclose(_fp);
_fp = 0;
}
}
uint32 size() {
uint32 sz = 0;
if (_fp) {
int pos = ftell(_fp);
fseek(_fp, 0, SEEK_END);
sz = ftell(_fp);
fseek(_fp, pos, SEEK_SET);
}
return sz;
}
void seek(int32 off) {
if (_fp) {
fseek(_fp, off, SEEK_SET);
}
}
void read(void *ptr, uint32 len) {
if (_fp) {
uint32 r = fread(ptr, 1, len, _fp);
if (r != len) {
_ioErr = true;
}
}
}
void write(void *ptr, uint32 len) {
if (_fp) {
uint32 r = fwrite(ptr, 1, len, _fp);
if (r != len) {
_ioErr = true;
}
}
}
};
struct zlibFile : File_impl {
gzFile _fp;
zlibFile() : _fp(0) {}
bool open(const char *path, const char *mode) {
_ioErr = false;
_fp = gzopen(path, mode);
return (_fp != 0);
}
void close() {
if (_fp) {
gzclose(_fp);
_fp = 0;
}
}
uint32 size() {
uint32 sz = 0;
if (_fp) {
int pos = gztell(_fp);
gzseek(_fp, 0, SEEK_END);
sz = gztell(_fp);
gzseek(_fp, pos, SEEK_SET);
}
return sz;
}
void seek(int32 off) {
if (_fp) {
gzseek(_fp, off, SEEK_SET);
}
}
void read(void *ptr, uint32 len) {
if (_fp) {
uint32 r = gzread(_fp, ptr, len);
if (r != len) {
_ioErr = true;
}
}
}
void write(void *ptr, uint32 len) {
if (_fp) {
uint32 r = gzwrite(_fp, ptr, len);
if (r != len) {
_ioErr = true;
}
}
}
};
File::File(bool gzipped) {
if (gzipped) {
_impl = new zlibFile;
} else {
_impl = new stdFile;
}
}
File::~File() {
_impl->close();
delete _impl;
}
bool File::open(const char *filename, const char *directory, const char *mode) {
_impl->close();
char buf[512];
sprintf(buf, "%s/%s", directory, filename);
char *p = buf + strlen(directory) + 1;
string_lower(p);
bool opened = _impl->open(buf, mode);
if (!opened) { // let's try uppercase
string_upper(p);
opened = _impl->open(buf, mode);
}
return opened;
}
void File::close() {
_impl->close();
}
bool File::ioErr() const {
return _impl->_ioErr;
}
uint32 File::size() {
return _impl->size();
}
void File::seek(int32 off) {
_impl->seek(off);
}
void File::read(void *ptr, uint32 len) {
_impl->read(ptr, len);
}
uint8 File::readByte() {
uint8 b;
read(&b, 1);
return b;
}
uint16 File::readUint16LE() {
uint8 lo = readByte();
uint8 hi = readByte();
return (hi << 8) | lo;
}
uint32 File::readUint32LE() {
uint16 lo = readUint16LE();
uint16 hi = readUint16LE();
return (hi << 16) | lo;
}
uint16 File::readUint16BE() {
uint8 hi = readByte();
uint8 lo = readByte();
return (hi << 8) | lo;
}
uint32 File::readUint32BE() {
uint16 hi = readUint16BE();
uint16 lo = readUint16BE();
return (hi << 16) | lo;
}
void File::write(void *ptr, uint32 len) {
_impl->write(ptr, len);
}
void File::writeByte(uint8 b) {
write(&b, 1);
}
void File::writeUint16BE(uint16 n) {
writeByte(n >> 8);
writeByte(n & 0xFF);
}
void File::writeUint32BE(uint32 n) {
writeUint16BE(n >> 16);
writeUint16BE(n & 0xFFFF);
}

View File

@@ -1,49 +1,49 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __FILE_H__
#define __FILE_H__
#include "intern.h"
struct File_impl;
struct File {
File(bool gzipped = false);
~File();
File_impl *_impl;
bool open(const char *filename, const char *directory, const char *mode);
void close();
bool ioErr() const;
uint32 size();
void seek(int32 off);
void read(void *ptr, uint32 len);
uint8 readByte();
uint16 readUint16LE();
uint32 readUint32LE();
uint16 readUint16BE();
uint32 readUint32BE();
void write(void *ptr, uint32 size);
void writeByte(uint8 b);
void writeUint16BE(uint16 n);
void writeUint32BE(uint32 n);
};
#endif // __FILE_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __FILE_H__
#define __FILE_H__
#include "intern.h"
struct File_impl;
struct File {
File(bool gzipped = false);
~File();
File_impl *_impl;
bool open(const char *filename, const char *directory, const char *mode);
void close();
bool ioErr() const;
uint32 size();
void seek(int32 off);
void read(void *ptr, uint32 len);
uint8 readByte();
uint16 readUint16LE();
uint32 readUint32LE();
uint16 readUint16BE();
uint32 readUint32BE();
void write(void *ptr, uint32 size);
void writeByte(uint8 b);
void writeUint16BE(uint16 n);
void writeUint32BE(uint32 n);
};
#endif // __FILE_H__

View File

@@ -1,391 +1,391 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __GAME_H__
#define __GAME_H__
#include "intern.h"
#include "cutscene.h"
#include "menu.h"
#include "mixer.h"
#include "mod_player.h"
#include "resource.h"
#include "sfx_player.h"
#include "video.h"
struct File;
struct SystemStub;
struct Game {
typedef int (Game::*pge_OpcodeProc)(ObjectOpcodeArgs *args);
typedef int (Game::*pge_ZOrderCallback)(LivePGE *, LivePGE *, uint8, uint8);
typedef int (Game::*col_Callback1)(LivePGE *, LivePGE *, int16, int16);
typedef int (Game::*col_Callback2)(LivePGE *, int16, int16, int16);
enum {
CT_UP_ROOM = 0x00,
CT_DOWN_ROOM = 0x40,
CT_RIGHT_ROOM = 0x80,
CT_LEFT_ROOM = 0xC0
};
static const Level _gameLevels[];
static const uint16 _scoreTable[];
static const uint8 _monsterListLevel1[];
static const uint8 _monsterListLevel2[];
static const uint8 _monsterListLevel3[];
static const uint8 _monsterListLevel4_1[];
static const uint8 _monsterListLevel4_2[];
static const uint8 _monsterListLevel5_1[];
static const uint8 _monsterListLevel5_2[];
static const uint8 *_monsterListLevels[];
static const uint8 _monsterPals[4][32];
static const char *_monsterNames[];
static const pge_OpcodeProc _pge_opcodeTable[];
static const uint8 _pge_modKeysTable[];
static const uint8 _protectionCodeData[];
static const uint8 _protectionPal[];
Cutscene _cut;
Menu _menu;
Mixer _mix;
ModPlayer _modPly;
Resource _res;
SfxPlayer _sfxPly;
Video _vid;
SystemStub *_stub;
const char *_savePath;
const uint8 *_stringsTable;
const char **_textsTable;
uint8 _currentLevel;
uint8 _skillLevel;
uint32 _score;
uint8 _currentRoom;
uint8 _currentIcon;
bool _loadMap;
uint8 _printLevelCodeCounter;
uint32 _randSeed;
uint16 _currentInventoryIconNum;
uint16 _curMonsterFrame;
uint16 _curMonsterNum;
uint8 _blinkingConradCounter;
uint16 _textToDisplay;
bool _eraseBackground;
AnimBufferState _animBuffer0State[41];
AnimBufferState _animBuffer1State[6]; // Conrad
AnimBufferState _animBuffer2State[42];
AnimBufferState _animBuffer3State[12];
AnimBuffers _animBuffers;
uint8 _bankData[0x7000];
uint8 *_firstBankData;
uint8 *_lastBankData;
BankSlot _bankSlots[49];
BankSlot *_curBankSlot;
const uint8 *_bankDataPtrs;
uint16 _deathCutsceneCounter;
bool _saveStateCompleted;
Game(SystemStub *, const char *dataPath, const char *savePath, Version ver);
void run();
void resetGameState();
void mainLoop();
void updateTiming();
void playCutscene(int id = -1);
void loadLevelMap();
void loadLevelData();
void start();
void drawIcon(uint8 iconNum, int16 x, int16 y, uint8 colMask);
void drawCurrentInventoryItem();
void printLevelCode();
void showFinalScore();
bool handleConfigPanel();
bool handleContinueAbort();
bool handleProtectionScreen();
void printSaveStateCompleted();
void drawLevelTexts();
void drawStoryTexts();
void prepareAnims();
void prepareAnimsHelper(LivePGE *pge, int16 dx, int16 dy);
void drawAnims();
void drawAnimBuffer(uint8 stateNum, AnimBufferState *state);
void drawObject(const uint8 *dataPtr, int16 x, int16 y, uint8 flags);
void drawObjectFrame(const uint8 *dataPtr, int16 x, int16 y, uint8 flags);
void decodeCharacterFrame(const uint8 *dataPtr, uint8 *dstPtr);
void drawCharacter(const uint8 *dataPtr, int16 x, int16 y, uint8 a, uint8 b, uint8 flags);
uint8 *loadBankData(uint16 MbkEntryNum);
int loadMonsterSprites(LivePGE *pge);
void playSound(uint8 sfxId, uint8 softVol);
uint16 getRandomNumber();
void changeLevel();
uint16 getLineLength(const uint8 *str) const;
void handleInventory();
uint8 *findBankData(uint16 entryNum);
// pieges
bool _pge_playAnimSound;
GroupPGE _pge_groups[256];
GroupPGE *_pge_groupsTable[256];
GroupPGE *_pge_nextFreeGroup;
LivePGE *_pge_liveTable2[256]; // active pieges list (index = pge number)
LivePGE *_pge_liveTable1[256]; // pieges list by room (index = room)
LivePGE _pgeLive[256];
uint8 _pge_currentPiegeRoom;
bool _pge_currentPiegeFacingDir; // (false == left)
bool _pge_processOBJ;
uint8 _pge_inpKeysMask;
uint16 _pge_opTempVar1;
uint16 _pge_opTempVar2;
uint16 _pge_compareVar1;
uint16 _pge_compareVar2;
void pge_resetGroups();
void pge_removeFromGroup(uint8 idx);
int pge_isInGroup(LivePGE *pge_dst, uint16 group_id, uint16 counter);
void pge_loadForCurrentLevel(uint16 idx);
void pge_process(LivePGE *pge);
void pge_setupNextAnimFrame(LivePGE *pge, GroupPGE *le);
void pge_playAnimSound(LivePGE *pge, uint16 arg2);
void pge_setupAnim(LivePGE *pge);
int pge_execute(LivePGE *live_pge, InitPGE *init_pge, const Object *obj);
void pge_prepare();
void pge_setupDefaultAnim(LivePGE *pge);
uint16 pge_processOBJ(LivePGE *pge);
void pge_setupOtherPieges(LivePGE *pge, InitPGE *init_pge);
void pge_addToCurrentRoomList(LivePGE *pge, uint8 room);
void pge_getInput();
int pge_op_isInpUp(ObjectOpcodeArgs *args);
int pge_op_isInpBackward(ObjectOpcodeArgs *args);
int pge_op_isInpDown(ObjectOpcodeArgs *args);
int pge_op_isInpForward(ObjectOpcodeArgs *args);
int pge_op_isInpUpMod(ObjectOpcodeArgs *args);
int pge_op_isInpBackwardMod(ObjectOpcodeArgs *args);
int pge_op_isInpDownMod(ObjectOpcodeArgs *args);
int pge_op_isInpForwardMod(ObjectOpcodeArgs *args);
int pge_op_isInpIdle(ObjectOpcodeArgs *args);
int pge_op_isInpNoMod(ObjectOpcodeArgs *args);
int pge_op_getCollision0u(ObjectOpcodeArgs *args);
int pge_op_getCollision00(ObjectOpcodeArgs *args);
int pge_op_getCollision0d(ObjectOpcodeArgs *args);
int pge_op_getCollision1u(ObjectOpcodeArgs *args);
int pge_op_getCollision10(ObjectOpcodeArgs *args);
int pge_op_getCollision1d(ObjectOpcodeArgs *args);
int pge_op_getCollision2u(ObjectOpcodeArgs *args);
int pge_op_getCollision20(ObjectOpcodeArgs *args);
int pge_op_getCollision2d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide0u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide00(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide0d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide1u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide10(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide1d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide2u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide20(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide2d(ObjectOpcodeArgs *args);
int pge_op_collides0o0d(ObjectOpcodeArgs *args);
int pge_op_collides2o2d(ObjectOpcodeArgs *args);
int pge_op_collides0o0u(ObjectOpcodeArgs *args);
int pge_op_collides2o2u(ObjectOpcodeArgs *args);
int pge_op_collides2u2o(ObjectOpcodeArgs *args);
int pge_op_isInGroup(ObjectOpcodeArgs *args);
int pge_op_updateGroup0(ObjectOpcodeArgs *args);
int pge_op_updateGroup1(ObjectOpcodeArgs *args);
int pge_op_updateGroup2(ObjectOpcodeArgs *args);
int pge_op_updateGroup3(ObjectOpcodeArgs *args);
int pge_op_isPiegeDead(ObjectOpcodeArgs *args);
int pge_op_collides1u2o(ObjectOpcodeArgs *args);
int pge_op_collides1u1o(ObjectOpcodeArgs *args);
int pge_op_collides1o1u(ObjectOpcodeArgs *args);
int pge_o_unk0x2B(ObjectOpcodeArgs *args);
int pge_o_unk0x2C(ObjectOpcodeArgs *args);
int pge_o_unk0x2D(ObjectOpcodeArgs *args);
int pge_op_nop(ObjectOpcodeArgs *args);
int pge_op_pickupObject(ObjectOpcodeArgs *args);
int pge_op_addItemToInventory(ObjectOpcodeArgs *args);
int pge_op_copyPiege(ObjectOpcodeArgs *args);
int pge_op_canUseCurrentInventoryItem(ObjectOpcodeArgs *args);
int pge_op_removeItemFromInventory(ObjectOpcodeArgs *args);
int pge_o_unk0x34(ObjectOpcodeArgs *args);
int pge_op_isInpMod(ObjectOpcodeArgs *args);
int pge_op_setCollisionState1(ObjectOpcodeArgs *args);
int pge_op_setCollisionState0(ObjectOpcodeArgs *args);
int pge_op_isInGroup1(ObjectOpcodeArgs *args);
int pge_op_isInGroup2(ObjectOpcodeArgs *args);
int pge_op_isInGroup3(ObjectOpcodeArgs *args);
int pge_op_isInGroup4(ObjectOpcodeArgs *args);
int pge_o_unk0x3C(ObjectOpcodeArgs *args);
int pge_o_unk0x3D(ObjectOpcodeArgs *args);
int pge_op_setPiegeCounter(ObjectOpcodeArgs *args);
int pge_op_decPiegeCounter(ObjectOpcodeArgs *args);
int pge_o_unk0x40(ObjectOpcodeArgs *args);
int pge_op_wakeUpPiege(ObjectOpcodeArgs *args);
int pge_op_removePiege(ObjectOpcodeArgs *args);
int pge_op_removePiegeIfNotNear(ObjectOpcodeArgs *args);
int pge_op_loadPiegeCounter(ObjectOpcodeArgs *args);
int pge_o_unk0x45(ObjectOpcodeArgs *args);
int pge_o_unk0x46(ObjectOpcodeArgs *args);
int pge_o_unk0x47(ObjectOpcodeArgs *args);
int pge_o_unk0x48(ObjectOpcodeArgs *args);
int pge_o_unk0x49(ObjectOpcodeArgs *args);
int pge_o_unk0x4A(ObjectOpcodeArgs *args);
int pge_op_killPiege(ObjectOpcodeArgs *args);
int pge_op_isInCurrentRoom(ObjectOpcodeArgs *args);
int pge_op_isNotInCurrentRoom(ObjectOpcodeArgs *args);
int pge_op_scrollPosY(ObjectOpcodeArgs *args);
int pge_op_playDefaultDeathCutscene(ObjectOpcodeArgs *args);
int pge_o_unk0x50(ObjectOpcodeArgs *args);
int pge_o_unk0x52(ObjectOpcodeArgs *args);
int pge_o_unk0x53(ObjectOpcodeArgs *args);
int pge_op_isPiegeNear(ObjectOpcodeArgs *args);
int pge_op_setLife(ObjectOpcodeArgs *args);
int pge_op_incLife(ObjectOpcodeArgs *args);
int pge_op_setPiegeDefaultAnim(ObjectOpcodeArgs *args);
int pge_op_setLifeCounter(ObjectOpcodeArgs *args);
int pge_op_decLifeCounter(ObjectOpcodeArgs *args);
int pge_op_playCutscene(ObjectOpcodeArgs *args);
int pge_op_isTempVar2Set(ObjectOpcodeArgs *args);
int pge_op_playDeathCutscene(ObjectOpcodeArgs *args);
int pge_o_unk0x5D(ObjectOpcodeArgs *args);
int pge_o_unk0x5E(ObjectOpcodeArgs *args);
int pge_o_unk0x5F(ObjectOpcodeArgs *args);
int pge_op_findAndCopyPiege(ObjectOpcodeArgs *args);
int pge_op_isInRandomRange(ObjectOpcodeArgs *args);
int pge_o_unk0x62(ObjectOpcodeArgs *args);
int pge_o_unk0x63(ObjectOpcodeArgs *args);
int pge_o_unk0x64(ObjectOpcodeArgs *args);
int pge_op_addToCredits(ObjectOpcodeArgs *args);
int pge_op_subFromCredits(ObjectOpcodeArgs *args);
int pge_o_unk0x67(ObjectOpcodeArgs *args);
int pge_op_setCollisionState2(ObjectOpcodeArgs *args);
int pge_op_saveState(ObjectOpcodeArgs *args);
int pge_o_unk0x6A(ObjectOpcodeArgs *args);
int pge_op_isInGroupSlice(ObjectOpcodeArgs *args);
int pge_o_unk0x6C(ObjectOpcodeArgs *args);
int pge_op_isCollidingObject(ObjectOpcodeArgs *args);
int pge_o_unk0x6E(ObjectOpcodeArgs *args);
int pge_o_unk0x6F(ObjectOpcodeArgs *args);
int pge_o_unk0x70(ObjectOpcodeArgs *args);
int pge_o_unk0x71(ObjectOpcodeArgs *args);
int pge_o_unk0x72(ObjectOpcodeArgs *args);
int pge_o_unk0x73(ObjectOpcodeArgs *args);
int pge_op_collides4u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide4u(ObjectOpcodeArgs *args);
int pge_op_isBelowConrad(ObjectOpcodeArgs *args);
int pge_op_isAboveConrad(ObjectOpcodeArgs *args);
int pge_op_isNotFacingConrad(ObjectOpcodeArgs *args);
int pge_op_isFacingConrad(ObjectOpcodeArgs *args);
int pge_op_collides2u1u(ObjectOpcodeArgs *args);
int pge_op_displayText(ObjectOpcodeArgs *args);
int pge_o_unk0x7C(ObjectOpcodeArgs *args);
int pge_op_playSound(ObjectOpcodeArgs *args);
int pge_o_unk0x7E(ObjectOpcodeArgs *args);
int pge_o_unk0x7F(ObjectOpcodeArgs *args);
int pge_op_setPiegePosX(ObjectOpcodeArgs *args);
int pge_op_setPiegePosModX(ObjectOpcodeArgs *args);
int pge_op_changeRoom(ObjectOpcodeArgs *args);
int pge_op_hasInventoryItem(ObjectOpcodeArgs *args);
int pge_op_changeLevel(ObjectOpcodeArgs *args);
int pge_op_shakeScreen(ObjectOpcodeArgs *args);
int pge_o_unk0x86(ObjectOpcodeArgs *args);
int pge_op_playSoundGroup(ObjectOpcodeArgs *args);
int pge_op_adjustPos(ObjectOpcodeArgs *args);
int pge_op_setTempVar1(ObjectOpcodeArgs *args);
int pge_op_isTempVar1Set(ObjectOpcodeArgs *args);
int pge_setCurrentInventoryObject(LivePGE *pge);
void pge_updateInventory(LivePGE *pge1, LivePGE *pge2);
void pge_reorderInventory(LivePGE *pge);
LivePGE *pge_getInventoryItemBefore(LivePGE *pge, LivePGE *last_pge);
void pge_addToInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
int pge_updateCollisionState(LivePGE *pge, int16 pge_dy, uint8 var8);
int pge_ZOrder(LivePGE *pge, int16 num, pge_ZOrderCallback compare, uint16 unk);
void pge_updateGroup(uint8 idx, uint8 unk1, int16 unk2);
void pge_removeFromInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
int pge_ZOrderByAnimY(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderByAnimYIfType(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfIndex(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderByIndex(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderByObj(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfSameDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfTypeAndSameDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfTypeAndDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderByNumber(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
// collision
CollisionSlot _col_slots[256];
uint8 _col_curPos;
CollisionSlot *_col_slotsTable[256];
CollisionSlot *_col_curSlot;
CollisionSlot2 _col_slots2[256];
CollisionSlot2 *_col_slots2Cur;
CollisionSlot2 *_col_slots2Next;
uint8 _col_activeCollisionSlots[0x30 * 3]; // left, current, right
uint8 _col_currentLeftRoom;
uint8 _col_currentRightRoom;
int16 _col_currentPiegeGridPosX;
int16 _col_currentPiegeGridPosY;
void col_prepareRoomState();
void col_clearState();
LivePGE *col_findPiege(LivePGE *pge, uint16 arg2);
int16 col_findSlot(int16 pos);
void col_preparePiegeState(LivePGE *dst_pge);
uint16 col_getGridPos(LivePGE *pge, int16 dx);
int16 col_getGridData(LivePGE *pge, int16 dy, int16 dx);
uint8 col_findCurrentCollidingObject(LivePGE *pge, uint8 n1, uint8 n2, uint8 n3, LivePGE **pge_out);
int16 col_detectHit(LivePGE *pge, int16 arg2, int16 arg4, col_Callback1 callback1, col_Callback2 callback2, int16 argA, int16 argC);
int col_detectHitCallback2(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
int col_detectHitCallback3(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
int col_detectHitCallback4(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
int col_detectHitCallback5(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
int col_detectHitCallback1(LivePGE *pge, int16 dy, int16 unk1, int16 unk2);
int col_detectHitCallback6(LivePGE *pge, int16 dy, int16 unk1, int16 unk2);
int col_detectHitCallbackHelper(LivePGE *pge, int16 unk1);
int col_detectGunHitCallback1(LivePGE *pge, int16 arg2, int16 arg4, int16 arg6);
int col_detectGunHitCallback2(LivePGE *pge1, LivePGE *pge2, int16 arg4, int16);
int col_detectGunHitCallback3(LivePGE *pge1, LivePGE *pge2, int16 arg4, int16);
int col_detectGunHit(LivePGE *pge, int16 arg2, int16 arg4, col_Callback1 callback1, col_Callback2 callback2, int16 argA, int16 argC);
// input
uint8 _inp_lastKeysHit;
uint8 _inp_lastKeysHitLeftRight;
bool _inp_replay;
bool _inp_record;
File *_inp_demo;
void inp_handleSpecialKeys();
void inp_update();
// save/load state
uint8 _stateSlot;
bool _validSaveState;
void makeGameDemoName(char *buf);
void makeGameStateName(uint8 slot, char *buf);
bool saveGameState(uint8 slot);
bool loadGameState(uint8 slot);
void saveState(File *f);
void loadState(File *f);
};
#endif // __GAME_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __GAME_H__
#define __GAME_H__
#include "intern.h"
#include "cutscene.h"
#include "menu.h"
#include "mixer.h"
#include "mod_player.h"
#include "resource.h"
#include "sfx_player.h"
#include "video.h"
struct File;
struct SystemStub;
struct Game {
typedef int (Game::*pge_OpcodeProc)(ObjectOpcodeArgs *args);
typedef int (Game::*pge_ZOrderCallback)(LivePGE *, LivePGE *, uint8, uint8);
typedef int (Game::*col_Callback1)(LivePGE *, LivePGE *, int16, int16);
typedef int (Game::*col_Callback2)(LivePGE *, int16, int16, int16);
enum {
CT_UP_ROOM = 0x00,
CT_DOWN_ROOM = 0x40,
CT_RIGHT_ROOM = 0x80,
CT_LEFT_ROOM = 0xC0
};
static const Level _gameLevels[];
static const uint16 _scoreTable[];
static const uint8 _monsterListLevel1[];
static const uint8 _monsterListLevel2[];
static const uint8 _monsterListLevel3[];
static const uint8 _monsterListLevel4_1[];
static const uint8 _monsterListLevel4_2[];
static const uint8 _monsterListLevel5_1[];
static const uint8 _monsterListLevel5_2[];
static const uint8 *_monsterListLevels[];
static const uint8 _monsterPals[4][32];
static const char *_monsterNames[];
static const pge_OpcodeProc _pge_opcodeTable[];
static const uint8 _pge_modKeysTable[];
static const uint8 _protectionCodeData[];
static const uint8 _protectionPal[];
Cutscene _cut;
Menu _menu;
Mixer _mix;
ModPlayer _modPly;
Resource _res;
SfxPlayer _sfxPly;
Video _vid;
SystemStub *_stub;
const char *_savePath;
const uint8 *_stringsTable;
const char **_textsTable;
uint8 _currentLevel;
uint8 _skillLevel;
uint32 _score;
uint8 _currentRoom;
uint8 _currentIcon;
bool _loadMap;
uint8 _printLevelCodeCounter;
uint32 _randSeed;
uint16 _currentInventoryIconNum;
uint16 _curMonsterFrame;
uint16 _curMonsterNum;
uint8 _blinkingConradCounter;
uint16 _textToDisplay;
bool _eraseBackground;
AnimBufferState _animBuffer0State[41];
AnimBufferState _animBuffer1State[6]; // Conrad
AnimBufferState _animBuffer2State[42];
AnimBufferState _animBuffer3State[12];
AnimBuffers _animBuffers;
uint8 _bankData[0x7000];
uint8 *_firstBankData;
uint8 *_lastBankData;
BankSlot _bankSlots[49];
BankSlot *_curBankSlot;
const uint8 *_bankDataPtrs;
uint16 _deathCutsceneCounter;
bool _saveStateCompleted;
Game(SystemStub *, const char *dataPath, const char *savePath, Version ver);
void run();
void resetGameState();
void mainLoop();
void updateTiming();
void playCutscene(int id = -1);
void loadLevelMap();
void loadLevelData();
void start();
void drawIcon(uint8 iconNum, int16 x, int16 y, uint8 colMask);
void drawCurrentInventoryItem();
void printLevelCode();
void showFinalScore();
bool handleConfigPanel();
bool handleContinueAbort();
bool handleProtectionScreen();
void printSaveStateCompleted();
void drawLevelTexts();
void drawStoryTexts();
void prepareAnims();
void prepareAnimsHelper(LivePGE *pge, int16 dx, int16 dy);
void drawAnims();
void drawAnimBuffer(uint8 stateNum, AnimBufferState *state);
void drawObject(const uint8 *dataPtr, int16 x, int16 y, uint8 flags);
void drawObjectFrame(const uint8 *dataPtr, int16 x, int16 y, uint8 flags);
void decodeCharacterFrame(const uint8 *dataPtr, uint8 *dstPtr);
void drawCharacter(const uint8 *dataPtr, int16 x, int16 y, uint8 a, uint8 b, uint8 flags);
uint8 *loadBankData(uint16 MbkEntryNum);
int loadMonsterSprites(LivePGE *pge);
void playSound(uint8 sfxId, uint8 softVol);
uint16 getRandomNumber();
void changeLevel();
uint16 getLineLength(const uint8 *str) const;
void handleInventory();
uint8 *findBankData(uint16 entryNum);
// pieges
bool _pge_playAnimSound;
GroupPGE _pge_groups[256];
GroupPGE *_pge_groupsTable[256];
GroupPGE *_pge_nextFreeGroup;
LivePGE *_pge_liveTable2[256]; // active pieges list (index = pge number)
LivePGE *_pge_liveTable1[256]; // pieges list by room (index = room)
LivePGE _pgeLive[256];
uint8 _pge_currentPiegeRoom;
bool _pge_currentPiegeFacingDir; // (false == left)
bool _pge_processOBJ;
uint8 _pge_inpKeysMask;
uint16 _pge_opTempVar1;
uint16 _pge_opTempVar2;
uint16 _pge_compareVar1;
uint16 _pge_compareVar2;
void pge_resetGroups();
void pge_removeFromGroup(uint8 idx);
int pge_isInGroup(LivePGE *pge_dst, uint16 group_id, uint16 counter);
void pge_loadForCurrentLevel(uint16 idx);
void pge_process(LivePGE *pge);
void pge_setupNextAnimFrame(LivePGE *pge, GroupPGE *le);
void pge_playAnimSound(LivePGE *pge, uint16 arg2);
void pge_setupAnim(LivePGE *pge);
int pge_execute(LivePGE *live_pge, InitPGE *init_pge, const Object *obj);
void pge_prepare();
void pge_setupDefaultAnim(LivePGE *pge);
uint16 pge_processOBJ(LivePGE *pge);
void pge_setupOtherPieges(LivePGE *pge, InitPGE *init_pge);
void pge_addToCurrentRoomList(LivePGE *pge, uint8 room);
void pge_getInput();
int pge_op_isInpUp(ObjectOpcodeArgs *args);
int pge_op_isInpBackward(ObjectOpcodeArgs *args);
int pge_op_isInpDown(ObjectOpcodeArgs *args);
int pge_op_isInpForward(ObjectOpcodeArgs *args);
int pge_op_isInpUpMod(ObjectOpcodeArgs *args);
int pge_op_isInpBackwardMod(ObjectOpcodeArgs *args);
int pge_op_isInpDownMod(ObjectOpcodeArgs *args);
int pge_op_isInpForwardMod(ObjectOpcodeArgs *args);
int pge_op_isInpIdle(ObjectOpcodeArgs *args);
int pge_op_isInpNoMod(ObjectOpcodeArgs *args);
int pge_op_getCollision0u(ObjectOpcodeArgs *args);
int pge_op_getCollision00(ObjectOpcodeArgs *args);
int pge_op_getCollision0d(ObjectOpcodeArgs *args);
int pge_op_getCollision1u(ObjectOpcodeArgs *args);
int pge_op_getCollision10(ObjectOpcodeArgs *args);
int pge_op_getCollision1d(ObjectOpcodeArgs *args);
int pge_op_getCollision2u(ObjectOpcodeArgs *args);
int pge_op_getCollision20(ObjectOpcodeArgs *args);
int pge_op_getCollision2d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide0u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide00(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide0d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide1u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide10(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide1d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide2u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide20(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide2d(ObjectOpcodeArgs *args);
int pge_op_collides0o0d(ObjectOpcodeArgs *args);
int pge_op_collides2o2d(ObjectOpcodeArgs *args);
int pge_op_collides0o0u(ObjectOpcodeArgs *args);
int pge_op_collides2o2u(ObjectOpcodeArgs *args);
int pge_op_collides2u2o(ObjectOpcodeArgs *args);
int pge_op_isInGroup(ObjectOpcodeArgs *args);
int pge_op_updateGroup0(ObjectOpcodeArgs *args);
int pge_op_updateGroup1(ObjectOpcodeArgs *args);
int pge_op_updateGroup2(ObjectOpcodeArgs *args);
int pge_op_updateGroup3(ObjectOpcodeArgs *args);
int pge_op_isPiegeDead(ObjectOpcodeArgs *args);
int pge_op_collides1u2o(ObjectOpcodeArgs *args);
int pge_op_collides1u1o(ObjectOpcodeArgs *args);
int pge_op_collides1o1u(ObjectOpcodeArgs *args);
int pge_o_unk0x2B(ObjectOpcodeArgs *args);
int pge_o_unk0x2C(ObjectOpcodeArgs *args);
int pge_o_unk0x2D(ObjectOpcodeArgs *args);
int pge_op_nop(ObjectOpcodeArgs *args);
int pge_op_pickupObject(ObjectOpcodeArgs *args);
int pge_op_addItemToInventory(ObjectOpcodeArgs *args);
int pge_op_copyPiege(ObjectOpcodeArgs *args);
int pge_op_canUseCurrentInventoryItem(ObjectOpcodeArgs *args);
int pge_op_removeItemFromInventory(ObjectOpcodeArgs *args);
int pge_o_unk0x34(ObjectOpcodeArgs *args);
int pge_op_isInpMod(ObjectOpcodeArgs *args);
int pge_op_setCollisionState1(ObjectOpcodeArgs *args);
int pge_op_setCollisionState0(ObjectOpcodeArgs *args);
int pge_op_isInGroup1(ObjectOpcodeArgs *args);
int pge_op_isInGroup2(ObjectOpcodeArgs *args);
int pge_op_isInGroup3(ObjectOpcodeArgs *args);
int pge_op_isInGroup4(ObjectOpcodeArgs *args);
int pge_o_unk0x3C(ObjectOpcodeArgs *args);
int pge_o_unk0x3D(ObjectOpcodeArgs *args);
int pge_op_setPiegeCounter(ObjectOpcodeArgs *args);
int pge_op_decPiegeCounter(ObjectOpcodeArgs *args);
int pge_o_unk0x40(ObjectOpcodeArgs *args);
int pge_op_wakeUpPiege(ObjectOpcodeArgs *args);
int pge_op_removePiege(ObjectOpcodeArgs *args);
int pge_op_removePiegeIfNotNear(ObjectOpcodeArgs *args);
int pge_op_loadPiegeCounter(ObjectOpcodeArgs *args);
int pge_o_unk0x45(ObjectOpcodeArgs *args);
int pge_o_unk0x46(ObjectOpcodeArgs *args);
int pge_o_unk0x47(ObjectOpcodeArgs *args);
int pge_o_unk0x48(ObjectOpcodeArgs *args);
int pge_o_unk0x49(ObjectOpcodeArgs *args);
int pge_o_unk0x4A(ObjectOpcodeArgs *args);
int pge_op_killPiege(ObjectOpcodeArgs *args);
int pge_op_isInCurrentRoom(ObjectOpcodeArgs *args);
int pge_op_isNotInCurrentRoom(ObjectOpcodeArgs *args);
int pge_op_scrollPosY(ObjectOpcodeArgs *args);
int pge_op_playDefaultDeathCutscene(ObjectOpcodeArgs *args);
int pge_o_unk0x50(ObjectOpcodeArgs *args);
int pge_o_unk0x52(ObjectOpcodeArgs *args);
int pge_o_unk0x53(ObjectOpcodeArgs *args);
int pge_op_isPiegeNear(ObjectOpcodeArgs *args);
int pge_op_setLife(ObjectOpcodeArgs *args);
int pge_op_incLife(ObjectOpcodeArgs *args);
int pge_op_setPiegeDefaultAnim(ObjectOpcodeArgs *args);
int pge_op_setLifeCounter(ObjectOpcodeArgs *args);
int pge_op_decLifeCounter(ObjectOpcodeArgs *args);
int pge_op_playCutscene(ObjectOpcodeArgs *args);
int pge_op_isTempVar2Set(ObjectOpcodeArgs *args);
int pge_op_playDeathCutscene(ObjectOpcodeArgs *args);
int pge_o_unk0x5D(ObjectOpcodeArgs *args);
int pge_o_unk0x5E(ObjectOpcodeArgs *args);
int pge_o_unk0x5F(ObjectOpcodeArgs *args);
int pge_op_findAndCopyPiege(ObjectOpcodeArgs *args);
int pge_op_isInRandomRange(ObjectOpcodeArgs *args);
int pge_o_unk0x62(ObjectOpcodeArgs *args);
int pge_o_unk0x63(ObjectOpcodeArgs *args);
int pge_o_unk0x64(ObjectOpcodeArgs *args);
int pge_op_addToCredits(ObjectOpcodeArgs *args);
int pge_op_subFromCredits(ObjectOpcodeArgs *args);
int pge_o_unk0x67(ObjectOpcodeArgs *args);
int pge_op_setCollisionState2(ObjectOpcodeArgs *args);
int pge_op_saveState(ObjectOpcodeArgs *args);
int pge_o_unk0x6A(ObjectOpcodeArgs *args);
int pge_op_isInGroupSlice(ObjectOpcodeArgs *args);
int pge_o_unk0x6C(ObjectOpcodeArgs *args);
int pge_op_isCollidingObject(ObjectOpcodeArgs *args);
int pge_o_unk0x6E(ObjectOpcodeArgs *args);
int pge_o_unk0x6F(ObjectOpcodeArgs *args);
int pge_o_unk0x70(ObjectOpcodeArgs *args);
int pge_o_unk0x71(ObjectOpcodeArgs *args);
int pge_o_unk0x72(ObjectOpcodeArgs *args);
int pge_o_unk0x73(ObjectOpcodeArgs *args);
int pge_op_collides4u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide4u(ObjectOpcodeArgs *args);
int pge_op_isBelowConrad(ObjectOpcodeArgs *args);
int pge_op_isAboveConrad(ObjectOpcodeArgs *args);
int pge_op_isNotFacingConrad(ObjectOpcodeArgs *args);
int pge_op_isFacingConrad(ObjectOpcodeArgs *args);
int pge_op_collides2u1u(ObjectOpcodeArgs *args);
int pge_op_displayText(ObjectOpcodeArgs *args);
int pge_o_unk0x7C(ObjectOpcodeArgs *args);
int pge_op_playSound(ObjectOpcodeArgs *args);
int pge_o_unk0x7E(ObjectOpcodeArgs *args);
int pge_o_unk0x7F(ObjectOpcodeArgs *args);
int pge_op_setPiegePosX(ObjectOpcodeArgs *args);
int pge_op_setPiegePosModX(ObjectOpcodeArgs *args);
int pge_op_changeRoom(ObjectOpcodeArgs *args);
int pge_op_hasInventoryItem(ObjectOpcodeArgs *args);
int pge_op_changeLevel(ObjectOpcodeArgs *args);
int pge_op_shakeScreen(ObjectOpcodeArgs *args);
int pge_o_unk0x86(ObjectOpcodeArgs *args);
int pge_op_playSoundGroup(ObjectOpcodeArgs *args);
int pge_op_adjustPos(ObjectOpcodeArgs *args);
int pge_op_setTempVar1(ObjectOpcodeArgs *args);
int pge_op_isTempVar1Set(ObjectOpcodeArgs *args);
int pge_setCurrentInventoryObject(LivePGE *pge);
void pge_updateInventory(LivePGE *pge1, LivePGE *pge2);
void pge_reorderInventory(LivePGE *pge);
LivePGE *pge_getInventoryItemBefore(LivePGE *pge, LivePGE *last_pge);
void pge_addToInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
int pge_updateCollisionState(LivePGE *pge, int16 pge_dy, uint8 var8);
int pge_ZOrder(LivePGE *pge, int16 num, pge_ZOrderCallback compare, uint16 unk);
void pge_updateGroup(uint8 idx, uint8 unk1, int16 unk2);
void pge_removeFromInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
int pge_ZOrderByAnimY(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderByAnimYIfType(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfIndex(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderByIndex(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderByObj(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfSameDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfTypeAndSameDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderIfTypeAndDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
int pge_ZOrderByNumber(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
// collision
CollisionSlot _col_slots[256];
uint8 _col_curPos;
CollisionSlot *_col_slotsTable[256];
CollisionSlot *_col_curSlot;
CollisionSlot2 _col_slots2[256];
CollisionSlot2 *_col_slots2Cur;
CollisionSlot2 *_col_slots2Next;
uint8 _col_activeCollisionSlots[0x30 * 3]; // left, current, right
uint8 _col_currentLeftRoom;
uint8 _col_currentRightRoom;
int16 _col_currentPiegeGridPosX;
int16 _col_currentPiegeGridPosY;
void col_prepareRoomState();
void col_clearState();
LivePGE *col_findPiege(LivePGE *pge, uint16 arg2);
int16 col_findSlot(int16 pos);
void col_preparePiegeState(LivePGE *dst_pge);
uint16 col_getGridPos(LivePGE *pge, int16 dx);
int16 col_getGridData(LivePGE *pge, int16 dy, int16 dx);
uint8 col_findCurrentCollidingObject(LivePGE *pge, uint8 n1, uint8 n2, uint8 n3, LivePGE **pge_out);
int16 col_detectHit(LivePGE *pge, int16 arg2, int16 arg4, col_Callback1 callback1, col_Callback2 callback2, int16 argA, int16 argC);
int col_detectHitCallback2(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
int col_detectHitCallback3(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
int col_detectHitCallback4(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
int col_detectHitCallback5(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
int col_detectHitCallback1(LivePGE *pge, int16 dy, int16 unk1, int16 unk2);
int col_detectHitCallback6(LivePGE *pge, int16 dy, int16 unk1, int16 unk2);
int col_detectHitCallbackHelper(LivePGE *pge, int16 unk1);
int col_detectGunHitCallback1(LivePGE *pge, int16 arg2, int16 arg4, int16 arg6);
int col_detectGunHitCallback2(LivePGE *pge1, LivePGE *pge2, int16 arg4, int16);
int col_detectGunHitCallback3(LivePGE *pge1, LivePGE *pge2, int16 arg4, int16);
int col_detectGunHit(LivePGE *pge, int16 arg2, int16 arg4, col_Callback1 callback1, col_Callback2 callback2, int16 argA, int16 argC);
// input
uint8 _inp_lastKeysHit;
uint8 _inp_lastKeysHitLeftRight;
bool _inp_replay;
bool _inp_record;
File *_inp_demo;
void inp_handleSpecialKeys();
void inp_update();
// save/load state
uint8 _stateSlot;
bool _validSaveState;
void makeGameDemoName(char *buf);
void makeGameStateName(uint8 slot, char *buf);
bool saveGameState(uint8 slot);
bool loadGameState(uint8 slot);
void saveState(File *f);
void loadState(File *f);
};
#endif // __GAME_H__

View File

@@ -1,40 +1,40 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __GRAPHICS_H__
#define __GRAPHICS_H__
#include "intern.h"
struct Graphics {
uint8 *_layer;
int16 _areaPoints[0x200];
int16 _crx, _cry, _crw, _crh;
void setClippingRect(int16 vx, int16 vy, int16 vw, int16 vh);
void drawPoint(uint8 color, const Point *pt);
void drawLine(uint8 color, const Point *pt1, const Point *pt2);
void addEllipseRadius(int16 y, int16 x1, int16 x2);
void drawEllipse(uint8 color, bool hasAlpha, const Point *pt, int16 rx, int16 ry);
void fillArea(uint8 color, bool hasAlpha);
void drawSegment(uint8 color, bool hasAlpha, int16 ys, const Point *pts, uint8 numPts);
void drawPolygonOutline(uint8 color, const Point *pts, uint8 numPts);
void drawPolygon(uint8 color, bool hasAlpha, const Point *pts, uint8 numPts);
};
#endif // __GRAPHICS_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __GRAPHICS_H__
#define __GRAPHICS_H__
#include "intern.h"
struct Graphics {
uint8 *_layer;
int16 _areaPoints[0x200];
int16 _crx, _cry, _crw, _crh;
void setClippingRect(int16 vx, int16 vy, int16 vw, int16 vh);
void drawPoint(uint8 color, const Point *pt);
void drawLine(uint8 color, const Point *pt1, const Point *pt2);
void addEllipseRadius(int16 y, int16 x1, int16 x2);
void drawEllipse(uint8 color, bool hasAlpha, const Point *pt, int16 rx, int16 ry);
void fillArea(uint8 color, bool hasAlpha);
void drawSegment(uint8 color, bool hasAlpha, int16 ys, const Point *pts, uint8 numPts);
void drawPolygonOutline(uint8 color, const Point *pts, uint8 numPts);
void drawPolygon(uint8 color, bool hasAlpha, const Point *pts, uint8 numPts);
};
#endif // __GRAPHICS_H__

View File

@@ -1,193 +1,193 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __INTERN_H__
#define __INTERN_H__
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include "sys.h"
#include "util.h"
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
template<typename T>
inline void SWAP(T &a, T &b) {
T tmp = a;
a = b;
b = tmp;
}
enum Version {
VER_FR,
VER_EN,
VER_DE,
VER_SP
};
struct Color {
uint8 r;
uint8 g;
uint8 b;
};
struct Point {
int16 x;
int16 y;
};
struct Level {
const char *name;
const char *name2;
uint16 cutscene_id;
};
struct InitPGE {
uint16 type;
int16 pos_x;
int16 pos_y;
uint16 obj_node_number;
uint16 life;
int16 counter_values[4];
uint8 object_type;
uint8 init_room;
uint8 room_location;
uint8 init_flags;
uint8 colliding_icon_num;
uint8 icon_num;
uint8 object_id;
uint8 skill;
uint8 mirror_x;
uint8 flags;
uint8 unk1C; // collidable, collision_data_len
uint8 text_num;
};
struct LivePGE {
uint16 obj_type;
int16 pos_x;
int16 pos_y;
uint8 anim_seq;
uint8 room_location;
int16 life;
int16 counter_value;
uint8 collision_slot;
uint8 next_inventory_PGE;
uint8 current_inventory_PGE;
uint8 unkF; // unk_inventory_PGE
uint16 anim_number;
uint8 flags;
uint8 index;
uint16 first_obj_number;
LivePGE *next_PGE_in_room;
InitPGE *init_PGE;
};
struct GroupPGE {
GroupPGE *next_entry;
uint16 index;
uint16 group_id;
};
struct Object {
uint16 type;
int8 dx;
int8 dy;
uint16 init_obj_type;
uint8 opcode2;
uint8 opcode1;
uint8 flags;
uint8 opcode3;
uint16 init_obj_number;
int16 opcode_arg1;
int16 opcode_arg2;
int16 opcode_arg3;
};
struct ObjectNode {
uint16 last_obj_number;
Object *objects;
uint16 num_objects;
};
struct ObjectOpcodeArgs {
LivePGE *pge; // arg0
int16 a; // arg2
int16 b; // arg4
};
struct AnimBufferState {
int16 x;
int16 y;
const uint8 *dataPtr;
LivePGE *pge;
};
struct AnimBuffers {
AnimBufferState *_states[4];
uint8 _curPos[4];
void addState(uint8 stateNum, int16 x, int16 y, const uint8 *dataPtr, LivePGE *pge);
};
struct CollisionSlot {
int16 ct_pos;
CollisionSlot *prev_slot;
LivePGE *live_pge;
uint16 index;
};
struct MbkEntry {
uint16 offset;
uint16 len;
};
struct BankSlot {
uint16 entryNum;
uint8 *ptr;
};
struct CollisionSlot2 {
CollisionSlot2 *next_slot;
int8 *unk2;
uint8 data_size;
uint8 data_buf[0x10]; // XXX check size
};
struct InventoryItem {
uint8 icon_num;
InitPGE *init_pge;
LivePGE *live_pge;
};
struct SoundFx {
uint32 offset;
uint16 len;
uint8 *data;
};
#endif // __INTERN_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __INTERN_H__
#define __INTERN_H__
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include "sys.h"
#include "util.h"
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
template<typename T>
inline void SWAP(T &a, T &b) {
T tmp = a;
a = b;
b = tmp;
}
enum Version {
VER_FR,
VER_EN,
VER_DE,
VER_SP
};
struct Color {
uint8 r;
uint8 g;
uint8 b;
};
struct Point {
int16 x;
int16 y;
};
struct Level {
const char *name;
const char *name2;
uint16 cutscene_id;
};
struct InitPGE {
uint16 type;
int16 pos_x;
int16 pos_y;
uint16 obj_node_number;
uint16 life;
int16 counter_values[4];
uint8 object_type;
uint8 init_room;
uint8 room_location;
uint8 init_flags;
uint8 colliding_icon_num;
uint8 icon_num;
uint8 object_id;
uint8 skill;
uint8 mirror_x;
uint8 flags;
uint8 unk1C; // collidable, collision_data_len
uint8 text_num;
};
struct LivePGE {
uint16 obj_type;
int16 pos_x;
int16 pos_y;
uint8 anim_seq;
uint8 room_location;
int16 life;
int16 counter_value;
uint8 collision_slot;
uint8 next_inventory_PGE;
uint8 current_inventory_PGE;
uint8 unkF; // unk_inventory_PGE
uint16 anim_number;
uint8 flags;
uint8 index;
uint16 first_obj_number;
LivePGE *next_PGE_in_room;
InitPGE *init_PGE;
};
struct GroupPGE {
GroupPGE *next_entry;
uint16 index;
uint16 group_id;
};
struct Object {
uint16 type;
int8 dx;
int8 dy;
uint16 init_obj_type;
uint8 opcode2;
uint8 opcode1;
uint8 flags;
uint8 opcode3;
uint16 init_obj_number;
int16 opcode_arg1;
int16 opcode_arg2;
int16 opcode_arg3;
};
struct ObjectNode {
uint16 last_obj_number;
Object *objects;
uint16 num_objects;
};
struct ObjectOpcodeArgs {
LivePGE *pge; // arg0
int16 a; // arg2
int16 b; // arg4
};
struct AnimBufferState {
int16 x;
int16 y;
const uint8 *dataPtr;
LivePGE *pge;
};
struct AnimBuffers {
AnimBufferState *_states[4];
uint8 _curPos[4];
void addState(uint8 stateNum, int16 x, int16 y, const uint8 *dataPtr, LivePGE *pge);
};
struct CollisionSlot {
int16 ct_pos;
CollisionSlot *prev_slot;
LivePGE *live_pge;
uint16 index;
};
struct MbkEntry {
uint16 offset;
uint16 len;
};
struct BankSlot {
uint16 entryNum;
uint8 *ptr;
};
struct CollisionSlot2 {
CollisionSlot2 *next_slot;
int8 *unk2;
uint8 data_size;
uint8 data_buf[0x10]; // XXX check size
};
struct InventoryItem {
uint8 icon_num;
InitPGE *init_pge;
LivePGE *live_pge;
};
struct SoundFx {
uint32 offset;
uint16 len;
uint8 *data;
};
#endif // __INTERN_H__

View File

@@ -1,50 +1,50 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2006 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "locale.h"
Locale::Locale(Version ver)
: _ver(ver) {
switch (_ver) {
case VER_FR:
_stringsTable = _stringsTableFR;
_textsTable = _textsTableFR;
break;
case VER_EN:
_stringsTable = _stringsTableEN;
_textsTable = _textsTableEN;
break;
case VER_DE:
_stringsTable = _stringsTableDE;
_textsTable = _textsTableDE;
break;
case VER_SP:
_stringsTable = _stringsTableSP;
_textsTable = _textsTableSP;
break;
}
}
const char *Locale::get(int id) const {
const char *text = 0;
if (id >= 0 && id < LI_NUM) {
text = _textsTable[id];
}
return text;
}
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2006 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "locale.h"
Locale::Locale(Version ver)
: _ver(ver) {
switch (_ver) {
case VER_FR:
_stringsTable = _stringsTableFR;
_textsTable = _textsTableFR;
break;
case VER_EN:
_stringsTable = _stringsTableEN;
_textsTable = _textsTableEN;
break;
case VER_DE:
_stringsTable = _stringsTableDE;
_textsTable = _textsTableDE;
break;
case VER_SP:
_stringsTable = _stringsTableSP;
_textsTable = _textsTableSP;
break;
}
}
const char *Locale::get(int id) const {
const char *text = 0;
if (id >= 0 && id < LI_NUM) {
text = _textsTable[id];
}
return text;
}

View File

@@ -1,69 +1,69 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2006 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __LOCALE_H__
#define __LOCALE_H__
#include "intern.h"
struct Locale {
enum Id {
LI_01_CONTINUE_OR_ABORT = 0,
LI_02_TIME,
LI_03_CONTINUE,
LI_04_ABORT,
LI_05_COMPLETED,
LI_06_LEVEL,
LI_07_START,
LI_08_SKILL,
LI_09_PASSWORD,
LI_10_INFO,
LI_11_QUIT,
LI_12_SKILL_LEVEL,
LI_13_EASY,
LI_14_NORMAL,
LI_15_EXPERT,
LI_16_ENTER_PASSWORD1,
LI_17_ENTER_PASSWORD2,
LI_18_RESUME_GAME,
LI_19_ABORT_GAME,
LI_20_LOAD_GAME,
LI_21_SAVE_GAME,
LI_22_SAVE_SLOT,
LI_NUM
};
static const char *_textsTableFR[];
static const char *_textsTableEN[];
static const char *_textsTableDE[];
static const char *_textsTableSP[];
static const uint8 _stringsTableFR[];
static const uint8 _stringsTableEN[];
static const uint8 _stringsTableDE[];
static const uint8 _stringsTableSP[];
Version _ver;
const char **_textsTable;
const uint8 *_stringsTable;
Locale(Version ver);
const char *get(int id) const;
};
#endif // __LOCALE_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2006 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __LOCALE_H__
#define __LOCALE_H__
#include "intern.h"
struct Locale {
enum Id {
LI_01_CONTINUE_OR_ABORT = 0,
LI_02_TIME,
LI_03_CONTINUE,
LI_04_ABORT,
LI_05_COMPLETED,
LI_06_LEVEL,
LI_07_START,
LI_08_SKILL,
LI_09_PASSWORD,
LI_10_INFO,
LI_11_QUIT,
LI_12_SKILL_LEVEL,
LI_13_EASY,
LI_14_NORMAL,
LI_15_EXPERT,
LI_16_ENTER_PASSWORD1,
LI_17_ENTER_PASSWORD2,
LI_18_RESUME_GAME,
LI_19_ABORT_GAME,
LI_20_LOAD_GAME,
LI_21_SAVE_GAME,
LI_22_SAVE_SLOT,
LI_NUM
};
static const char *_textsTableFR[];
static const char *_textsTableEN[];
static const char *_textsTableDE[];
static const char *_textsTableSP[];
static const uint8 _stringsTableFR[];
static const uint8 _stringsTableEN[];
static const uint8 _stringsTableDE[];
static const uint8 _stringsTableSP[];
Version _ver;
const char **_textsTable;
const uint8 *_stringsTable;
Locale(Version ver);
const char *get(int id) const;
};
#endif // __LOCALE_H__

View File

@@ -1,316 +1,316 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "game.h"
#include "mod_player.h"
#include "resource.h"
#include "systemstub.h"
#include "video.h"
#include "menu.h"
Menu::Menu(ModPlayer *ply, Resource *res, SystemStub *stub, Video *vid)
: _ply(ply), _res(res), _stub(stub), _vid(vid) {
}
void Menu::drawString(const char *str, int16 y, int16 x, uint8 color) {
debug(DBG_MENU, "Menu::drawString()");
uint8 v1b = _vid->_charFrontColor;
uint8 v2b = _vid->_charTransparentColor;
uint8 v3b = _vid->_charShadowColor;
switch (color) {
case 0:
_vid->_charFrontColor = _charVar1;
_vid->_charTransparentColor = _charVar2;
_vid->_charShadowColor = _charVar2;
break;
case 1:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = _charVar1;
_vid->_charShadowColor = _charVar1;
break;
case 2:
_vid->_charFrontColor = _charVar3;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 3:
_vid->_charFrontColor = _charVar4;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 4:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 5:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar5;
break;
}
drawString2(str, y, x);
_vid->_charFrontColor = v1b;
_vid->_charTransparentColor = v2b;
_vid->_charShadowColor = v3b;
}
void Menu::drawString2(const char *str, int16 y, int16 x) {
debug(DBG_MENU, "Menu::drawString2()");
int len = 0;
while (*str) {
_vid->drawChar((uint8)*str, y, x + len);
++str;
++len;
}
_vid->markBlockAsDirty(x * 8, y * 8, len * 8, 8);
}
void Menu::loadPicture(const char *prefix) {
debug(DBG_MENU, "Menu::loadPicture('%s')", prefix);
_res->load_MAP_menu(prefix, _res->_memBuf);
for (int i = 0; i < 4; ++i) {
for (int y = 0; y < 224; ++y) {
for (int x = 0; x < 64; ++x) {
_vid->_frontLayer[i + x * 4 + 256 * y] = _res->_memBuf[0x3800 * i + x + 64 * y];
}
}
}
_res->load_PAL_menu(prefix, _res->_memBuf);
_stub->setPalette(_res->_memBuf, 256);
}
void Menu::handleInfoScreen() {
debug(DBG_MENU, "Menu::handleInfoScreen()");
_vid->fadeOut();
switch (_res->_ver) {
case VER_FR:
loadPicture("instru_f");
break;
case VER_EN:
case VER_DE:
case VER_SP:
loadPicture("instru_e");
break;
}
_vid->fullRefresh();
_vid->updateScreen();
do {
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
break;
}
} while (!_stub->_pi.quit);
}
void Menu::handleSkillScreen(uint8 &new_skill) {
debug(DBG_MENU, "Menu::handleSkillScreen()");
static const uint8 option_colors[3][3] = { { 2, 3, 3 }, { 3, 2, 3}, { 3, 3, 2 } };
_vid->fadeOut();
loadPicture("menu3");
_vid->fullRefresh();
drawString(_res->getMenuString(LocaleData::LI_12_SKILL_LEVEL), 12, 4, 3);
int skill_level = new_skill;
do {
drawString(_res->getMenuString(LocaleData::LI_13_EASY), 15, 14, option_colors[skill_level][0]);
drawString(_res->getMenuString(LocaleData::LI_14_NORMAL), 17, 14, option_colors[skill_level][1]);
drawString(_res->getMenuString(LocaleData::LI_15_EXPERT), 19, 14, option_colors[skill_level][2]);
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
if (skill_level != 0) {
--skill_level;
} else {
skill_level = 2;
}
}
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
if (skill_level != 2) {
++skill_level;
} else {
skill_level = 0;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
new_skill = skill_level;
return;
}
} while (!_stub->_pi.quit);
new_skill = 1;
}
bool Menu::handlePasswordScreen(uint8 &new_skill, uint8 &new_level) {
debug(DBG_MENU, "Menu::handlePasswordScreen()");
_vid->fadeOut();
_vid->_charShadowColor = _charVar1;
_vid->_charTransparentColor = 0xFF;
_vid->_charFrontColor = _charVar4;
_vid->fullRefresh();
char password[7];
int len = 0;
do {
loadPicture("menu2");
drawString2(_res->getMenuString(LocaleData::LI_16_ENTER_PASSWORD1), 15, 3);
drawString2(_res->getMenuString(LocaleData::LI_17_ENTER_PASSWORD2), 17, 3);
for (int i = 0; i < len; ++i) {
_vid->drawChar((uint8)password[i], 21, i + 15);
}
_vid->drawChar(0x20, 21, len + 15);
_vid->markBlockAsDirty(15 * 8, 21 * 8, (len + 1) * 8, 8);
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
char c = _stub->_pi.lastChar;
if (c != 0) {
_stub->_pi.lastChar = 0;
if (len < 6) {
if (c >= 'a' && c <= 'z') {
c &= ~0x20;
}
if ((c >= 'A' && c <= 'Z') || (c == 0x20)) {
password[len] = c;
++len;
}
}
}
if (_stub->_pi.backspace) {
_stub->_pi.backspace = false;
if (len > 0) {
--len;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
password[len] = '\0';
for (int level = 0; level < 8; ++level) {
for (int skill = 0; skill < 3; ++skill) {
if (strcmp(_passwords[level][skill], password) == 0) {
new_level = level;
new_skill = skill;
return true;
}
}
}
return false;
}
} while (!_stub->_pi.quit);
return false;
}
bool Menu::handleTitleScreen(uint8 &new_skill, uint8 &new_level) {
debug(DBG_MENU, "Menu::handleTitleScreen()");
bool quit_loop = false;
int menu_entry = 0;
bool reinit_screen = true;
bool continue_game = true;
_charVar1 = 0;
_charVar2 = 0;
_charVar3 = 0;
_charVar4 = 0;
_charVar5 = 0;
_ply->play(1);
while (!quit_loop) {
if (reinit_screen) {
_vid->fadeOut();
loadPicture("menu1");
_vid->fullRefresh();
_charVar3 = 1;
_charVar4 = 2;
menu_entry = 0;
reinit_screen = false;
}
int selected_menu_entry = -1;
for (int i = 0; i < 5; ++i) {
int color = (i == menu_entry) ? 2 : 3;
drawString(_res->getMenuString(LocaleData::LI_07_START + i), 16 + i * 2, 20, color);
}
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
if (menu_entry != 0) {
--menu_entry;
} else {
menu_entry = 4;
}
}
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
if (menu_entry != 4) {
++menu_entry;
} else {
menu_entry = 0;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
selected_menu_entry = menu_entry;
}
if (selected_menu_entry != -1) {
switch (selected_menu_entry) {
case MENU_OPTION_ITEM_START:
new_level = 0;
quit_loop = true;
break;
case MENU_OPTION_ITEM_SKILL:
handleSkillScreen(new_skill);
reinit_screen = true;
break;
case MENU_OPTION_ITEM_PASSWORD:
if (handlePasswordScreen(new_skill, new_level)) {
quit_loop = true;
} else {
reinit_screen = true;
}
break;
case MENU_OPTION_ITEM_INFO:
handleInfoScreen();
reinit_screen = true;
break;
case MENU_OPTION_ITEM_QUIT:
continue_game = false;
quit_loop = true;
break;
}
}
if (_stub->_pi.quit) {
continue_game = false;
quit_loop = true;
break;
}
}
_ply->stop();
return continue_game;
}
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "game.h"
#include "mod_player.h"
#include "resource.h"
#include "systemstub.h"
#include "video.h"
#include "menu.h"
Menu::Menu(ModPlayer *ply, Resource *res, SystemStub *stub, Video *vid)
: _ply(ply), _res(res), _stub(stub), _vid(vid) {
}
void Menu::drawString(const char *str, int16 y, int16 x, uint8 color) {
debug(DBG_MENU, "Menu::drawString()");
uint8 v1b = _vid->_charFrontColor;
uint8 v2b = _vid->_charTransparentColor;
uint8 v3b = _vid->_charShadowColor;
switch (color) {
case 0:
_vid->_charFrontColor = _charVar1;
_vid->_charTransparentColor = _charVar2;
_vid->_charShadowColor = _charVar2;
break;
case 1:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = _charVar1;
_vid->_charShadowColor = _charVar1;
break;
case 2:
_vid->_charFrontColor = _charVar3;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 3:
_vid->_charFrontColor = _charVar4;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 4:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 5:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar5;
break;
}
drawString2(str, y, x);
_vid->_charFrontColor = v1b;
_vid->_charTransparentColor = v2b;
_vid->_charShadowColor = v3b;
}
void Menu::drawString2(const char *str, int16 y, int16 x) {
debug(DBG_MENU, "Menu::drawString2()");
int len = 0;
while (*str) {
_vid->drawChar((uint8)*str, y, x + len);
++str;
++len;
}
_vid->markBlockAsDirty(x * 8, y * 8, len * 8, 8);
}
void Menu::loadPicture(const char *prefix) {
debug(DBG_MENU, "Menu::loadPicture('%s')", prefix);
_res->load_MAP_menu(prefix, _res->_memBuf);
for (int i = 0; i < 4; ++i) {
for (int y = 0; y < 224; ++y) {
for (int x = 0; x < 64; ++x) {
_vid->_frontLayer[i + x * 4 + 256 * y] = _res->_memBuf[0x3800 * i + x + 64 * y];
}
}
}
_res->load_PAL_menu(prefix, _res->_memBuf);
_stub->setPalette(_res->_memBuf, 256);
}
void Menu::handleInfoScreen() {
debug(DBG_MENU, "Menu::handleInfoScreen()");
_vid->fadeOut();
switch (_res->_ver) {
case VER_FR:
loadPicture("instru_f");
break;
case VER_EN:
case VER_DE:
case VER_SP:
loadPicture("instru_e");
break;
}
_vid->fullRefresh();
_vid->updateScreen();
do {
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
break;
}
} while (!_stub->_pi.quit);
}
void Menu::handleSkillScreen(uint8 &new_skill) {
debug(DBG_MENU, "Menu::handleSkillScreen()");
static const uint8 option_colors[3][3] = { { 2, 3, 3 }, { 3, 2, 3}, { 3, 3, 2 } };
_vid->fadeOut();
loadPicture("menu3");
_vid->fullRefresh();
drawString(_res->getMenuString(LocaleData::LI_12_SKILL_LEVEL), 12, 4, 3);
int skill_level = new_skill;
do {
drawString(_res->getMenuString(LocaleData::LI_13_EASY), 15, 14, option_colors[skill_level][0]);
drawString(_res->getMenuString(LocaleData::LI_14_NORMAL), 17, 14, option_colors[skill_level][1]);
drawString(_res->getMenuString(LocaleData::LI_15_EXPERT), 19, 14, option_colors[skill_level][2]);
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
if (skill_level != 0) {
--skill_level;
} else {
skill_level = 2;
}
}
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
if (skill_level != 2) {
++skill_level;
} else {
skill_level = 0;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
new_skill = skill_level;
return;
}
} while (!_stub->_pi.quit);
new_skill = 1;
}
bool Menu::handlePasswordScreen(uint8 &new_skill, uint8 &new_level) {
debug(DBG_MENU, "Menu::handlePasswordScreen()");
_vid->fadeOut();
_vid->_charShadowColor = _charVar1;
_vid->_charTransparentColor = 0xFF;
_vid->_charFrontColor = _charVar4;
_vid->fullRefresh();
char password[7];
int len = 0;
do {
loadPicture("menu2");
drawString2(_res->getMenuString(LocaleData::LI_16_ENTER_PASSWORD1), 15, 3);
drawString2(_res->getMenuString(LocaleData::LI_17_ENTER_PASSWORD2), 17, 3);
for (int i = 0; i < len; ++i) {
_vid->drawChar((uint8)password[i], 21, i + 15);
}
_vid->drawChar(0x20, 21, len + 15);
_vid->markBlockAsDirty(15 * 8, 21 * 8, (len + 1) * 8, 8);
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
char c = _stub->_pi.lastChar;
if (c != 0) {
_stub->_pi.lastChar = 0;
if (len < 6) {
if (c >= 'a' && c <= 'z') {
c &= ~0x20;
}
if ((c >= 'A' && c <= 'Z') || (c == 0x20)) {
password[len] = c;
++len;
}
}
}
if (_stub->_pi.backspace) {
_stub->_pi.backspace = false;
if (len > 0) {
--len;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
password[len] = '\0';
for (int level = 0; level < 8; ++level) {
for (int skill = 0; skill < 3; ++skill) {
if (strcmp(_passwords[level][skill], password) == 0) {
new_level = level;
new_skill = skill;
return true;
}
}
}
return false;
}
} while (!_stub->_pi.quit);
return false;
}
bool Menu::handleTitleScreen(uint8 &new_skill, uint8 &new_level) {
debug(DBG_MENU, "Menu::handleTitleScreen()");
bool quit_loop = false;
int menu_entry = 0;
bool reinit_screen = true;
bool continue_game = true;
_charVar1 = 0;
_charVar2 = 0;
_charVar3 = 0;
_charVar4 = 0;
_charVar5 = 0;
_ply->play(1);
while (!quit_loop) {
if (reinit_screen) {
_vid->fadeOut();
loadPicture("menu1");
_vid->fullRefresh();
_charVar3 = 1;
_charVar4 = 2;
menu_entry = 0;
reinit_screen = false;
}
int selected_menu_entry = -1;
for (int i = 0; i < 5; ++i) {
int color = (i == menu_entry) ? 2 : 3;
drawString(_res->getMenuString(LocaleData::LI_07_START + i), 16 + i * 2, 20, color);
}
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
if (menu_entry != 0) {
--menu_entry;
} else {
menu_entry = 4;
}
}
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
if (menu_entry != 4) {
++menu_entry;
} else {
menu_entry = 0;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
selected_menu_entry = menu_entry;
}
if (selected_menu_entry != -1) {
switch (selected_menu_entry) {
case MENU_OPTION_ITEM_START:
new_level = 0;
quit_loop = true;
break;
case MENU_OPTION_ITEM_SKILL:
handleSkillScreen(new_skill);
reinit_screen = true;
break;
case MENU_OPTION_ITEM_PASSWORD:
if (handlePasswordScreen(new_skill, new_level)) {
quit_loop = true;
} else {
reinit_screen = true;
}
break;
case MENU_OPTION_ITEM_INFO:
handleInfoScreen();
reinit_screen = true;
break;
case MENU_OPTION_ITEM_QUIT:
continue_game = false;
quit_loop = true;
break;
}
}
if (_stub->_pi.quit) {
continue_game = false;
quit_loop = true;
break;
}
}
_ply->stop();
return continue_game;
}

View File

@@ -1,67 +1,67 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MENU_H__
#define __MENU_H__
#include "intern.h"
struct ModPlayer;
struct Resource;
struct SystemStub;
struct Video;
struct Menu {
enum {
MENU_OPTION_ITEM_START = 0,
MENU_OPTION_ITEM_SKILL,
MENU_OPTION_ITEM_PASSWORD,
MENU_OPTION_ITEM_INFO,
MENU_OPTION_ITEM_QUIT
};
enum {
EVENTS_DELAY = 80
};
static const char *_passwords[8][3];
ModPlayer *_ply;
Resource *_res;
SystemStub *_stub;
Video *_vid;
const char **_textOptions;
uint8 _charVar1;
uint8 _charVar2;
uint8 _charVar3;
uint8 _charVar4;
uint8 _charVar5;
Menu(ModPlayer *ply, Resource *res, SystemStub *stub, Video *vid);
void drawString(const char *str, int16 y, int16 x, uint8 color);
void drawString2(const char *str, int16 y, int16 x);
void loadPicture(const char *prefix);
void handleInfoScreen();
void handleSkillScreen(uint8 &new_skill);
bool handlePasswordScreen(uint8 &new_skill, uint8 &new_level);
bool handleTitleScreen(uint8 &new_skill, uint8 &new_level);
};
#endif // __MENU_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MENU_H__
#define __MENU_H__
#include "intern.h"
struct ModPlayer;
struct Resource;
struct SystemStub;
struct Video;
struct Menu {
enum {
MENU_OPTION_ITEM_START = 0,
MENU_OPTION_ITEM_SKILL,
MENU_OPTION_ITEM_PASSWORD,
MENU_OPTION_ITEM_INFO,
MENU_OPTION_ITEM_QUIT
};
enum {
EVENTS_DELAY = 80
};
static const char *_passwords[8][3];
ModPlayer *_ply;
Resource *_res;
SystemStub *_stub;
Video *_vid;
const char **_textOptions;
uint8 _charVar1;
uint8 _charVar2;
uint8 _charVar3;
uint8 _charVar4;
uint8 _charVar5;
Menu(ModPlayer *ply, Resource *res, SystemStub *stub, Video *vid);
void drawString(const char *str, int16 y, int16 x, uint8 color);
void drawString2(const char *str, int16 y, int16 x);
void loadPicture(const char *prefix);
void handleInfoScreen();
void handleSkillScreen(uint8 &new_skill);
bool handlePasswordScreen(uint8 &new_skill, uint8 &new_level);
bool handleTitleScreen(uint8 &new_skill, uint8 &new_level);
};
#endif // __MENU_H__

View File

@@ -1,121 +1,124 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mixer.h"
#include "systemstub.h"
Mixer::Mixer(SystemStub *stub)
: _stub(stub) {
}
void Mixer::init() {
memset(_channels, 0, sizeof(_channels));
_premixHook = 0;
_mutex = _stub->createMutex();
_stub->startAudio(Mixer::mixCallback, this);
}
void Mixer::free() {
stopAll();
_stub->stopAudio();
_stub->destroyMutex(_mutex);
}
void Mixer::setPremixHook(PremixHook premixHook, void *userData) {
debug(DBG_SND, "Mixer::setPremixHook()");
MutexStack(_stub, _mutex);
_premixHook = premixHook;
_premixHookData = userData;
}
void Mixer::play(const MixerChunk *mc, uint16 freq, uint8 volume) {
debug(DBG_SND, "Mixer::play(%d, %d)", freq, volume);
MutexStack(_stub, _mutex);
MixerChannel *ch = 0;
for (int i = 0; i < NUM_CHANNELS; ++i) {
MixerChannel *cur = &_channels[i];
if (cur->active) {
if (cur->chunk.data == mc->data) {
cur->chunkPos = 0;
return;
}
} else {
ch = cur;
break;
}
}
if (ch) {
ch->active = true;
ch->volume = volume;
ch->chunk = *mc;
ch->chunkPos = 0;
ch->chunkInc = (freq << FRAC_BITS) / _stub->getOutputSampleRate();
}
}
uint32 Mixer::getSampleRate() const {
return _stub->getOutputSampleRate();
}
void Mixer::stopAll() {
debug(DBG_SND, "Mixer::stopAll()");
MutexStack(_stub, _mutex);
for (uint8 i = 0; i < NUM_CHANNELS; ++i) {
_channels[i].active = false;
}
}
void Mixer::mix(int8 *buf, int len) {
MutexStack(_stub, _mutex);
memset(buf, 0, len);
if (_premixHook) {
if (!_premixHook(_premixHookData, buf, len)) {
_premixHook = 0;
_premixHookData = 0;
}
}
for (uint8 i = 0; i < NUM_CHANNELS; ++i) {
MixerChannel *ch = &_channels[i];
if (ch->active) {
for (int pos = 0; pos < len; ++pos) {
if ((ch->chunkPos >> FRAC_BITS) >= (ch->chunk.len - 1)) {
ch->active = false;
break;
}
int out = resampleLinear(&ch->chunk, ch->chunkPos, ch->chunkInc, FRAC_BITS);
addclamp(buf[pos], out * ch->volume / Mixer::MAX_VOLUME);
ch->chunkPos += ch->chunkInc;
}
}
}
}
void Mixer::addclamp(int8& a, int b) {
int add = a + b;
if (add < -128) {
add = -128;
} else if (add > 127) {
add = 127;
}
a = add;
}
void Mixer::mixCallback(void *param, uint8 *buf, int len) {
((Mixer *)param)->mix((int8 *)buf, len);
}
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mixer.h"
#include "systemstub.h"
Mixer::Mixer(SystemStub *stub)
: _stub(stub) {
}
void Mixer::init() {
memset(_channels, 0, sizeof(_channels));
_premixHook = 0;
_mutex = _stub->createMutex();
_stub->startAudio(Mixer::mixCallback, this);
}
void Mixer::free() {
stopAll();
_stub->stopAudio();
_stub->destroyMutex(_mutex);
}
void Mixer::setPremixHook(PremixHook premixHook, void *userData) {
debug(DBG_SND, "Mixer::setPremixHook()");
MutexStack(_stub, _mutex);
_premixHook = premixHook;
_premixHookData = userData;
}
void Mixer::play(const MixerChunk *mc, uint16 freq, uint8 volume) {
debug(DBG_SND, "Mixer::play(%d, %d)", freq, volume);
MutexStack(_stub, _mutex);
MixerChannel *ch = 0;
for (int i = 0; i < NUM_CHANNELS; ++i) {
MixerChannel *cur = &_channels[i];
if (cur->active) {
if (cur->chunk.data == mc->data) {
cur->chunkPos = 0;
return;
}
} else {
ch = cur;
break;
}
}
if (ch) {
ch->active = true;
ch->volume = volume;
ch->chunk = *mc;
ch->chunkPos = 0;
ch->chunkInc = (freq << FRAC_BITS) / _stub->getOutputSampleRate();
}
}
uint32 Mixer::getSampleRate() const {
return _stub->getOutputSampleRate();
}
void Mixer::stopAll() {
debug(DBG_SND, "Mixer::stopAll()");
MutexStack(_stub, _mutex);
for (uint8 i = 0; i < NUM_CHANNELS; ++i) {
_channels[i].active = false;
}
}
inline void addclamp(int16& a, int b) {
int add = a + b;
if (add < -32767) {
add = -32767;
} else if (add > 32767) {
add = 32767;
}
a = add;
}
void Mixer::mix(int8 *buf1, int len) {
int16 *buf = (int16 *)buf1;
MutexStack(_stub, _mutex);
memset(buf, 0, len);
len /= 2;
if (_premixHook) {
if (!_premixHook(_premixHookData, buf, len)) {
_premixHook = 0;
_premixHookData = 0;
}
}
for (uint8 i = 0; i < NUM_CHANNELS; ++i) {
MixerChannel *ch = &_channels[i];
if (ch->active) {
for (int pos = 0; pos < len; ++pos) {
if ((ch->chunkPos >> FRAC_BITS) >= (ch->chunk.len - 1)) {
ch->active = false;
break;
}
int out = resampleLinear(&ch->chunk, ch->chunkPos, ch->chunkInc, FRAC_BITS);
addclamp(buf[pos], out * Mixer::MIX_AMPLIFICATIION * ch->volume / Mixer::MAX_VOLUME );
ch->chunkPos += ch->chunkInc;
}
}
}
}
void Mixer::mixCallback(void *param, uint8 *buf, int len) {
((Mixer *)param)->mix((int8 *)buf, len);
}

View File

@@ -1,95 +1,96 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MIXER_H__
#define __MIXER_H__
#include "intern.h"
struct MixerChunk {
uint8 *data;
uint32 len;
int8 getPCM(int offset) const {
if (offset < 0) {
offset = 0;
} else if (offset >= (int)len) {
offset = len - 1;
}
return (int8)data[offset];
}
};
struct MixerChannel {
uint8 active;
uint8 volume;
MixerChunk chunk;
uint32 chunkPos;
uint32 chunkInc;
};
struct SystemStub;
struct Mixer {
typedef bool (*PremixHook)(void *userData, int8 *buf, int len);
enum {
NUM_CHANNELS = 4,
FRAC_BITS = 12,
MAX_VOLUME = 64
};
void *_mutex;
SystemStub *_stub;
MixerChannel _channels[NUM_CHANNELS];
PremixHook _premixHook;
void *_premixHookData;
Mixer(SystemStub *stub);
void init();
void free();
void setPremixHook(PremixHook premixHook, void *userData);
void play(const MixerChunk *mc, uint16 freq, uint8 volume);
void stopAll();
uint32 getSampleRate() const;
void mix(int8 *buf, int len);
static void addclamp(int8 &a, int b);
static void mixCallback(void *param, uint8 *buf, int len);
};
template <class T>
int resampleLinear(T *sample, int pos, int step, int fracBits) {
const int inputPos = pos >> fracBits;
const int inputFrac = (1 << fracBits) - 1;
int out = sample->getPCM(inputPos);
out += (sample->getPCM(inputPos + 1) - out) * inputFrac >> fracBits;
return out;
}
template <class T>
int resample3Pt(T *sample, int pos, int step, int fracBits) {
const int inputPos = pos >> fracBits;
const int inputFrac = (1 << fracBits) - 1;
int out = sample->getPCM(inputPos) >> 1;
out += sample->getPCM(inputPos + ((inputFrac - (step >> 1)) >> fracBits)) >> 2;
out += sample->getPCM(inputPos + ((inputFrac + (step >> 1)) >> fracBits)) >> 2;
return out;
}
#endif // __MIXER_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MIXER_H__
#define __MIXER_H__
#include "intern.h"
struct MixerChunk {
uint8 *data;
uint32 len;
int8 getPCM(int offset) const {
if (offset < 0) {
offset = 0;
} else if (offset >= (int)len) {
offset = len - 1;
}
return (int8)data[offset];
}
};
struct MixerChannel {
uint8 active;
uint8 volume;
MixerChunk chunk;
uint32 chunkPos;
uint32 chunkInc;
};
struct SystemStub;
struct Mixer {
typedef bool (*PremixHook)(void *userData, int16 *buf, int len);
enum {
NUM_CHANNELS = 4,
FRAC_BITS = 12,
MAX_VOLUME = 64,
MIX_AMPLIFICATIION = 64 // TODO: edit here to tweak sound
};
void *_mutex;
SystemStub *_stub;
MixerChannel _channels[NUM_CHANNELS];
PremixHook _premixHook;
void *_premixHookData;
Mixer(SystemStub *stub);
void init();
void free();
void setPremixHook(PremixHook premixHook, void *userData);
void play(const MixerChunk *mc, uint16 freq, uint8 volume);
void stopAll();
uint32 getSampleRate() const;
void mix(int8 *buf, int len);
//static void addclamp(int16 &a, int b);
static void mixCallback(void *param, uint8 *buf, int len);
};
template <class T>
int resampleLinear(T *sample, int pos, int step, int fracBits) {
const int inputPos = pos >> fracBits;
const int inputFrac = (1 << fracBits) - 1;
int out = sample->getPCM(inputPos);
out += (sample->getPCM(inputPos + 1) - out) * inputFrac >> fracBits;
return out;
}
template <class T>
int resample3Pt(T *sample, int pos, int step, int fracBits) {
const int inputPos = pos >> fracBits;
const int inputFrac = (1 << fracBits) - 1;
int out = sample->getPCM(inputPos) >> 1;
out += sample->getPCM(inputPos + ((inputFrac - (step >> 1)) >> fracBits)) >> 2;
out += sample->getPCM(inputPos + ((inputFrac + (step >> 1)) >> fracBits)) >> 2;
return out;
}
#endif // __MIXER_H__

View File

@@ -1,122 +1,122 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MOD_PLAYER_H__
#define __MOD_PLAYER_H__
#include "intern.h"
struct File;
struct Mixer;
struct ModPlayer {
enum {
NUM_SAMPLES = 31,
NUM_TRACKS = 4,
NUM_PATTERNS = 128,
FRAC_BITS = 12,
PAULA_FREQ = 3546897
};
struct SampleInfo {
char name[23];
uint16 len;
uint8 fineTune;
uint8 volume;
uint16 repeatPos;
uint16 repeatLen;
int8 *data;
int8 getPCM(int offset) const {
if (offset < 0) {
offset = 0;
} else if (offset >= (int)len) {
offset = len - 1;
}
return data[offset];
}
};
struct ModuleInfo {
char songName[21];
SampleInfo samples[NUM_SAMPLES];
uint8 numPatterns;
uint8 patternOrderTable[NUM_PATTERNS];
uint8 *patternsTable;
};
struct Track {
SampleInfo *sample;
uint8 volume;
int pos;
int freq;
uint16 period;
uint16 periodIndex;
uint16 effectData;
int vibratoSpeed;
int vibratoAmp;
int vibratoPos;
int portamento;
int portamentoSpeed;
int retriggerCounter;
int delayCounter;
int cutCounter;
};
static const int8 _sineWaveTable[];
static const uint16 _periodTable[];
static const char *_modulesFiles[][2];
static const int _modulesFilesCount;
ModuleInfo _modInfo;
uint8 _currentPatternOrder;
uint8 _currentPatternPos;
uint8 _currentTick;
uint8 _songSpeed;
uint8 _songTempo;
int _patternDelay;
int _patternLoopPos;
int _patternLoopCount;
int _samplesLeft;
uint8 _songNum;
bool _introSongHack;
bool _playing;
Track _tracks[NUM_TRACKS];
Mixer *_mix;
const char *_dataPath;
ModPlayer(Mixer *mixer, const char *dataPath);
uint16 findPeriod(uint16 period, uint8 fineTune) const;
void load(File *f);
void unload();
void play(uint8 num);
void stop();
void handleNote(int trackNum, uint32 noteData);
void handleTick();
void applyVolumeSlide(int trackNum, int amount);
void applyVibrato(int trackNum);
void applyPortamento(int trackNum);
void handleEffect(int trackNum, bool tick);
void mixSamples(int8 *buf, int len);
bool mix(int8 *buf, int len);
static bool mixCallback(void *param, int8 *buf, int len);
};
#endif // __MOD_PLAYER_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MOD_PLAYER_H__
#define __MOD_PLAYER_H__
#include "intern.h"
struct File;
struct Mixer;
struct ModPlayer {
enum {
NUM_SAMPLES = 31,
NUM_TRACKS = 4,
NUM_PATTERNS = 128,
FRAC_BITS = 12,
PAULA_FREQ = 3546897
};
struct SampleInfo {
char name[23];
uint16 len;
uint8 fineTune;
uint8 volume;
uint16 repeatPos;
uint16 repeatLen;
int8 *data;
int8 getPCM(int offset) const {
if (offset < 0) {
offset = 0;
} else if (offset >= (int)len) {
offset = len - 1;
}
return data[offset];
}
};
struct ModuleInfo {
char songName[21];
SampleInfo samples[NUM_SAMPLES];
uint8 numPatterns;
uint8 patternOrderTable[NUM_PATTERNS];
uint8 *patternsTable;
};
struct Track {
SampleInfo *sample;
uint8 volume;
int pos;
int freq;
uint16 period;
uint16 periodIndex;
uint16 effectData;
int vibratoSpeed;
int vibratoAmp;
int vibratoPos;
int portamento;
int portamentoSpeed;
int retriggerCounter;
int delayCounter;
int cutCounter;
};
static const int8 _sineWaveTable[];
static const uint16 _periodTable[];
static const char *_modulesFiles[][2];
static const int _modulesFilesCount;
ModuleInfo _modInfo;
uint8 _currentPatternOrder;
uint8 _currentPatternPos;
uint8 _currentTick;
uint8 _songSpeed;
uint8 _songTempo;
int _patternDelay;
int _patternLoopPos;
int _patternLoopCount;
int _samplesLeft;
uint8 _songNum;
bool _introSongHack;
bool _playing;
Track _tracks[NUM_TRACKS];
Mixer *_mix;
const char *_dataPath;
ModPlayer(Mixer *mixer, const char *dataPath);
uint16 findPeriod(uint16 period, uint8 fineTune) const;
void load(File *f);
void unload();
void play(uint8 num);
void stop();
void handleNote(int trackNum, uint32 noteData);
void handleTick();
void applyVolumeSlide(int trackNum, int amount);
void applyVibrato(int trackNum);
void applyPortamento(int trackNum);
void handleEffect(int trackNum, bool tick);
void mixSamples(int16 *buf, int len);
bool mix(int16 *buf, int len);
static bool mixCallback(void *param, int16 *buf, int len);
};
#endif // __MOD_PLAYER_H__

View File

@@ -1,169 +1,169 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __RESOURCE_H__
#define __RESOURCE_H__
#include "intern.h"
struct File;
struct LocaleData {
enum Id {
LI_01_CONTINUE_OR_ABORT = 0,
LI_02_TIME,
LI_03_CONTINUE,
LI_04_ABORT,
LI_05_COMPLETED,
LI_06_LEVEL,
LI_07_START,
LI_08_SKILL,
LI_09_PASSWORD,
LI_10_INFO,
LI_11_QUIT,
LI_12_SKILL_LEVEL,
LI_13_EASY,
LI_14_NORMAL,
LI_15_EXPERT,
LI_16_ENTER_PASSWORD1,
LI_17_ENTER_PASSWORD2,
LI_18_RESUME_GAME,
LI_19_ABORT_GAME,
LI_20_LOAD_GAME,
LI_21_SAVE_GAME,
LI_22_SAVE_SLOT,
LI_NUM
};
static const char *_textsTableFR[];
static const char *_textsTableEN[];
static const char *_textsTableDE[];
static const char *_textsTableSP[];
static const uint8 _stringsTableFR[];
static const uint8 _stringsTableEN[];
static const uint8 _stringsTableDE[];
static const uint8 _stringsTableSP[];
};
struct Resource {
typedef void (Resource::*LoadStub)(File *);
enum ObjectType {
OT_MBK = 0x00,
OT_PGE = 0x01,
OT_PAL = 0x02,
OT_CT = 0x03,
OT_MAP = 0x04,
OT_SGD = 0x05,
OT_SPC = 0x06,
OT_RP = 0x07,
OT_DEMO = 0x08,
OT_ANI = 0x09,
OT_OBJ = 0x0A,
OT_TBN = 0x0B,
OT_SPR = 0x0C,
OT_TAB = 0x0D,
OT_ICN = 0x0E,
OT_FNT = 0x0F,
OT_TXTBIN = 0x10,
OT_CMD = 0x11,
OT_POL = 0x12,
OT_SPRM = 0x13,
OT_OFF = 0x14,
OT_NUM = 0x15
};
static const uint16 _voicesOffsetsTable[];
const char *_dataPath;
Version _ver;
char _entryName[30];
uint8 *_fnt;
MbkEntry *_mbk;
uint8 *_mbkData;
uint8 *_icn;
uint8 *_tab;
uint8 *_spc; // BE
uint16 _numSpc;
uint8 _rp[0x4A];
uint8 *_pal; // BE
uint8 *_ani;
uint8 *_tbn;
int8 _ctData[0x1D00];
uint8 *_spr1;
uint8 *_spr_off[1287]; // 0-0x22F + 0x28E-0x2E9 ... conrad, 0x22F-0x28D : junkie
uint8 _sprm[0x8411]; // MERCENAI.SPR size
uint16 _pgeNum;
InitPGE _pgeInit[256];
uint8 *_map;
uint16 _numObjectNodes;
ObjectNode *_objectNodesMap[255];
uint8 *_memBuf;
SoundFx *_sfxList;
uint8 _numSfx;
uint8 *_cmd;
uint8 *_pol;
uint8 *_cine_off;
uint8 *_cine_txt;
uint8 *_voiceBuf;
char **_extTextsTable;
const char **_textsTable;
uint8 *_extStringsTable;
const uint8 *_stringsTable;
Resource(const char *dataPath, Version ver);
~Resource();
void clearLevelRes();
void load_FIB(const char *fileName);
void load_MAP_menu(const char *fileName, uint8 *dstPtr);
void load_PAL_menu(const char *fileName, uint8 *dstPtr);
void load_SPR_OFF(const char *fileName, uint8 *sprData);
void load_CINE();
void load_TEXT();
void free_TEXT();
void load(const char *objName, int objType);
void load_CT(File *pf);
void load_FNT(File *pf);
void load_MBK(File *pf);
void load_ICN(File *pf);
void load_SPR(File *pf);
void load_SPRM(File *pf);
void load_RP(File *pf);
void load_SPC(File *pf);
void load_PAL(File *pf);
void load_MAP(File *pf);
void load_OBJ(File *pf);
void free_OBJ();
void load_PGE(File *pf);
void load_ANI(File *pf);
void load_TBN(File *pf);
void load_CMD(File *pf);
void load_POL(File *pf);
void load_VCE(int num, int segment, uint8 **buf, uint32 *bufSize);
const uint8 *getGameString(int num) {
return _stringsTable + READ_LE_UINT16(_stringsTable + num * 2);
}
const char *getMenuString(int num) {
return (num >= 0 && num < LocaleData::LI_NUM) ? _textsTable[num] : "";
}
};
#endif // __RESOURCE_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __RESOURCE_H__
#define __RESOURCE_H__
#include "intern.h"
struct File;
struct LocaleData {
enum Id {
LI_01_CONTINUE_OR_ABORT = 0,
LI_02_TIME,
LI_03_CONTINUE,
LI_04_ABORT,
LI_05_COMPLETED,
LI_06_LEVEL,
LI_07_START,
LI_08_SKILL,
LI_09_PASSWORD,
LI_10_INFO,
LI_11_QUIT,
LI_12_SKILL_LEVEL,
LI_13_EASY,
LI_14_NORMAL,
LI_15_EXPERT,
LI_16_ENTER_PASSWORD1,
LI_17_ENTER_PASSWORD2,
LI_18_RESUME_GAME,
LI_19_ABORT_GAME,
LI_20_LOAD_GAME,
LI_21_SAVE_GAME,
LI_22_SAVE_SLOT,
LI_NUM
};
static const char *_textsTableFR[];
static const char *_textsTableEN[];
static const char *_textsTableDE[];
static const char *_textsTableSP[];
static const uint8 _stringsTableFR[];
static const uint8 _stringsTableEN[];
static const uint8 _stringsTableDE[];
static const uint8 _stringsTableSP[];
};
struct Resource {
typedef void (Resource::*LoadStub)(File *);
enum ObjectType {
OT_MBK = 0x00,
OT_PGE = 0x01,
OT_PAL = 0x02,
OT_CT = 0x03,
OT_MAP = 0x04,
OT_SGD = 0x05,
OT_SPC = 0x06,
OT_RP = 0x07,
OT_DEMO = 0x08,
OT_ANI = 0x09,
OT_OBJ = 0x0A,
OT_TBN = 0x0B,
OT_SPR = 0x0C,
OT_TAB = 0x0D,
OT_ICN = 0x0E,
OT_FNT = 0x0F,
OT_TXTBIN = 0x10,
OT_CMD = 0x11,
OT_POL = 0x12,
OT_SPRM = 0x13,
OT_OFF = 0x14,
OT_NUM = 0x15
};
static const uint16 _voicesOffsetsTable[];
const char *_dataPath;
Version _ver;
char _entryName[30];
uint8 *_fnt;
MbkEntry *_mbk;
uint8 *_mbkData;
uint8 *_icn;
uint8 *_tab;
uint8 *_spc; // BE
uint16 _numSpc;
uint8 _rp[0x4A];
uint8 *_pal; // BE
uint8 *_ani;
uint8 *_tbn;
int8 _ctData[0x1D00];
uint8 *_spr1;
uint8 *_spr_off[1287]; // 0-0x22F + 0x28E-0x2E9 ... conrad, 0x22F-0x28D : junkie
uint8 _sprm[0x8411]; // MERCENAI.SPR size
uint16 _pgeNum;
InitPGE _pgeInit[256];
uint8 *_map;
uint16 _numObjectNodes;
ObjectNode *_objectNodesMap[255];
uint8 *_memBuf;
SoundFx *_sfxList;
uint8 _numSfx;
uint8 *_cmd;
uint8 *_pol;
uint8 *_cine_off;
uint8 *_cine_txt;
uint8 *_voiceBuf;
char **_extTextsTable;
const char **_textsTable;
uint8 *_extStringsTable;
const uint8 *_stringsTable;
Resource(const char *dataPath, Version ver);
~Resource();
void clearLevelRes();
void load_FIB(const char *fileName);
void load_MAP_menu(const char *fileName, uint8 *dstPtr);
void load_PAL_menu(const char *fileName, uint8 *dstPtr);
void load_SPR_OFF(const char *fileName, uint8 *sprData);
void load_CINE();
void load_TEXT();
void free_TEXT();
void load(const char *objName, int objType);
void load_CT(File *pf);
void load_FNT(File *pf);
void load_MBK(File *pf);
void load_ICN(File *pf);
void load_SPR(File *pf);
void load_SPRM(File *pf);
void load_RP(File *pf);
void load_SPC(File *pf);
void load_PAL(File *pf);
void load_MAP(File *pf);
void load_OBJ(File *pf);
void free_OBJ();
void load_PGE(File *pf);
void load_ANI(File *pf);
void load_TBN(File *pf);
void load_CMD(File *pf);
void load_POL(File *pf);
void load_VCE(int num, int segment, uint8 **buf, uint32 *bufSize);
const uint8 *getGameString(int num) {
return _stringsTable + READ_LE_UINT16(_stringsTable + num * 2);
}
const char *getMenuString(int num) {
return (num >= 0 && num < LocaleData::LI_NUM) ? _textsTable[num] : "";
}
};
#endif // __RESOURCE_H__

View File

@@ -1,142 +1,142 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "scaler.h"
const Scaler _scalers[] = {
{ "point1x", &point1x, 1 },
{ "point2x", &point2x, 2 },
{ "scale2x", &scale2x, 2 },
{ "point3x", &point3x, 3 },
{ "scale3x", &scale3x, 3 }
};
void point1x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
memcpy(dst, src, w * 2);
dst += dstPitch;
src += srcPitch;
}
}
void point2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
uint16 *p = dst;
for (int i = 0; i < w; ++i, p += 2) {
uint16 c = *(src + i);
*(p) = c;
*(p + 1) = c;
*(p + dstPitch) = c;
*(p + dstPitch + 1) = c;
}
dst += dstPitch * 2;
src += srcPitch;
}
}
void point3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
uint16 *p = dst;
for (int i = 0; i < w; ++i, p += 3) {
uint16 c = *(src + i);
*(p) = c;
*(p + 1) = c;
*(p + 2) = c;
*(p + dstPitch) = c;
*(p + dstPitch + 1) = c;
*(p + dstPitch + 2) = c;
*(p + 2 * dstPitch) = c;
*(p + 2 * dstPitch + 1) = c;
*(p + 2 * dstPitch + 2) = c;
}
dst += dstPitch * 3;
src += srcPitch;
}
}
void scale2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
uint16 *p = dst;
for (int i = 0; i < w; ++i, p += 2) {
uint16 B = *(src + i - srcPitch);
uint16 D = *(src + i - 1);
uint16 E = *(src + i);
uint16 F = *(src + i + 1);
uint16 H = *(src + i + srcPitch);
if (B != H && D != F) {
*(p) = D == B ? D : E;
*(p + 1) = B == F ? F : E;
*(p + dstPitch) = D == H ? D : E;
*(p + dstPitch + 1) = H == F ? F : E;
} else {
*(p) = E;
*(p + 1) = E;
*(p + dstPitch) = E;
*(p + dstPitch + 1) = E;
}
}
dst += dstPitch * 2;
src += srcPitch;
}
}
void scale3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
uint16 *p = dst;
for (int i = 0; i < w; ++i, p += 3) {
uint16 A = *(src + i - srcPitch - 1);
uint16 B = *(src + i - srcPitch);
uint16 C = *(src + i - srcPitch + 1);
uint16 D = *(src + i - 1);
uint16 E = *(src + i);
uint16 F = *(src + i + 1);
uint16 G = *(src + i + srcPitch - 1);
uint16 H = *(src + i + srcPitch);
uint16 I = *(src + i + srcPitch + 1);
if (B != H && D != F) {
*(p) = D == B ? D : E;
*(p + 1) = (D == B && E != C) || (B == F && E != A) ? B : E;
*(p + 2) = B == F ? F : E;
*(p + dstPitch) = (D == B && E != G) || (D == B && E != A) ? D : E;
*(p + dstPitch + 1) = E;
*(p + dstPitch + 2) = (B == F && E != I) || (H == F && E != C) ? F : E;
*(p + 2 * dstPitch) = D == H ? D : E;
*(p + 2 * dstPitch + 1) = (D == H && E != I) || (H == F && E != G) ? H : E;
*(p + 2 * dstPitch + 2) = H == F ? F : E;
} else {
*(p) = E;
*(p + 1) = E;
*(p + 2) = E;
*(p + dstPitch) = E;
*(p + dstPitch + 1) = E;
*(p + dstPitch + 2) = E;
*(p + 2 * dstPitch) = E;
*(p + 2 * dstPitch + 1) = E;
*(p + 2 * dstPitch + 2) = E;
}
}
dst += dstPitch * 3;
src += srcPitch;
}
}
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "scaler.h"
const Scaler _scalers[] = {
{ "point1x", &point1x, 1 },
{ "point2x", &point2x, 2 },
{ "scale2x", &scale2x, 2 },
{ "point3x", &point3x, 3 },
{ "scale3x", &scale3x, 3 }
};
void point1x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
memcpy(dst, src, w * 2);
dst += dstPitch;
src += srcPitch;
}
}
void point2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
uint16 *p = dst;
for (int i = 0; i < w; ++i, p += 2) {
uint16 c = *(src + i);
*(p) = c;
*(p + 1) = c;
*(p + dstPitch) = c;
*(p + dstPitch + 1) = c;
}
dst += dstPitch * 2;
src += srcPitch;
}
}
void point3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
uint16 *p = dst;
for (int i = 0; i < w; ++i, p += 3) {
uint16 c = *(src + i);
*(p) = c;
*(p + 1) = c;
*(p + 2) = c;
*(p + dstPitch) = c;
*(p + dstPitch + 1) = c;
*(p + dstPitch + 2) = c;
*(p + 2 * dstPitch) = c;
*(p + 2 * dstPitch + 1) = c;
*(p + 2 * dstPitch + 2) = c;
}
dst += dstPitch * 3;
src += srcPitch;
}
}
void scale2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
uint16 *p = dst;
for (int i = 0; i < w; ++i, p += 2) {
uint16 B = *(src + i - srcPitch);
uint16 D = *(src + i - 1);
uint16 E = *(src + i);
uint16 F = *(src + i + 1);
uint16 H = *(src + i + srcPitch);
if (B != H && D != F) {
*(p) = D == B ? D : E;
*(p + 1) = B == F ? F : E;
*(p + dstPitch) = D == H ? D : E;
*(p + dstPitch + 1) = H == F ? F : E;
} else {
*(p) = E;
*(p + 1) = E;
*(p + dstPitch) = E;
*(p + dstPitch + 1) = E;
}
}
dst += dstPitch * 2;
src += srcPitch;
}
}
void scale3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
dstPitch >>= 1;
while (h--) {
uint16 *p = dst;
for (int i = 0; i < w; ++i, p += 3) {
uint16 A = *(src + i - srcPitch - 1);
uint16 B = *(src + i - srcPitch);
uint16 C = *(src + i - srcPitch + 1);
uint16 D = *(src + i - 1);
uint16 E = *(src + i);
uint16 F = *(src + i + 1);
uint16 G = *(src + i + srcPitch - 1);
uint16 H = *(src + i + srcPitch);
uint16 I = *(src + i + srcPitch + 1);
if (B != H && D != F) {
*(p) = D == B ? D : E;
*(p + 1) = (D == B && E != C) || (B == F && E != A) ? B : E;
*(p + 2) = B == F ? F : E;
*(p + dstPitch) = (D == B && E != G) || (D == B && E != A) ? D : E;
*(p + dstPitch + 1) = E;
*(p + dstPitch + 2) = (B == F && E != I) || (H == F && E != C) ? F : E;
*(p + 2 * dstPitch) = D == H ? D : E;
*(p + 2 * dstPitch + 1) = (D == H && E != I) || (H == F && E != G) ? H : E;
*(p + 2 * dstPitch + 2) = H == F ? F : E;
} else {
*(p) = E;
*(p + 1) = E;
*(p + 2) = E;
*(p + dstPitch) = E;
*(p + dstPitch + 1) = E;
*(p + dstPitch + 2) = E;
*(p + 2 * dstPitch) = E;
*(p + 2 * dstPitch + 1) = E;
*(p + 2 * dstPitch + 2) = E;
}
}
dst += dstPitch * 3;
src += srcPitch;
}
}

View File

@@ -1,44 +1,44 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SCALER_H__
#define __SCALER_H__
#include "intern.h"
typedef void (*ScaleProc)(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
enum {
NUM_SCALERS = 5
};
struct Scaler {
const char *name;
ScaleProc proc;
uint8 factor;
};
extern const Scaler _scalers[];
void point1x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
void point2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
void point3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
void scale2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
void scale3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
#endif // __SCALER_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SCALER_H__
#define __SCALER_H__
#include "intern.h"
typedef void (*ScaleProc)(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
enum {
NUM_SCALERS = 5
};
struct Scaler {
const char *name;
ScaleProc proc;
uint8 factor;
};
extern const Scaler _scalers[];
void point1x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
void point2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
void point3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
void scale2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
void scale3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
#endif // __SCALER_H__

View File

@@ -1,175 +1,185 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mixer.h"
#include "sfx_player.h"
SfxPlayer::SfxPlayer(Mixer *mixer)
: _mod(0), _playing(false), _mix(mixer) {
}
void SfxPlayer::play(uint8 num) {
debug(DBG_SFX, "SfxPlayer::play(%d)", num);
if (!_playing) {
if (num >= 68 && num <= 75) {
static const Module *modTable[] = {
&_module68, &_module68, &_module70, &_module70,
&_module72, &_module73, &_module74, &_module75
};
_mod = modTable[num - 68];
_curOrder = 0;
_numOrders = READ_BE_UINT16(_mod->moduleData);
_orderDelay = 0;
_modData = _mod->moduleData + 0x22;
memset(_samples, 0, sizeof(_samples));
_samplesLeft = 0;
_mix->setPremixHook(mixCallback, this);
_playing = true;
}
}
}
void SfxPlayer::stop() {
if (_playing) {
_mix->setPremixHook(0, 0);
_playing = false;
}
}
void SfxPlayer::playSample(int channel, const uint8 *sampleData, uint16 period) {
assert(channel < NUM_CHANNELS);
SampleInfo *si = &_samples[channel];
si->len = READ_BE_UINT16(sampleData); sampleData += 2;
si->vol = READ_BE_UINT16(sampleData); sampleData += 2;
si->loopPos = READ_BE_UINT16(sampleData); sampleData += 2;
si->loopLen = READ_BE_UINT16(sampleData); sampleData += 2;
si->freq = PAULA_FREQ / period;
si->pos = 0;
si->data = sampleData;
}
void SfxPlayer::handleTick() {
if (!_playing) {
return;
}
if (_orderDelay != 0) {
--_orderDelay;
// check for end of song
if (_orderDelay == 0 && _modData == 0) {
_playing = false;
}
} else {
_orderDelay = READ_BE_UINT16(_mod->moduleData + 2);
debug(DBG_SFX, "curOrder=%d/%d _orderDelay=%d\n", _curOrder, _numOrders, _orderDelay);
int16 period = 0;
for (int ch = 0; ch < 3; ++ch) {
const uint8 *sampleData = 0;
uint8 b = *_modData++;
if (b != 0) {
--b;
assert(b < 5);
period = READ_BE_UINT16(_mod->moduleData + 4 + b * 2);
sampleData = _mod->sampleData[b];
}
b = *_modData++;
if (b != 0) {
int16 per = period + (b - 1);
if (per >= 0 && per < 40) {
per = _periodTable[per];
} else if (per == -3) {
per = 0xA0;
} else {
per = 0x71;
}
playSample(ch, sampleData, per);
}
}
++_curOrder;
if (_curOrder >= _numOrders) {
debug(DBG_SFX, "End of song");
_orderDelay += 20;
_modData = 0;
}
}
}
void SfxPlayer::mixSamples(int8 *buf, int samplesLen) {
for (int i = 0; i < NUM_CHANNELS; ++i) {
SampleInfo *si = &_samples[i];
if (si->data) {
int8 *mixbuf = buf;
int len = si->len << FRAC_BITS;
int loopLen = si->loopLen << FRAC_BITS;
int loopPos = si->loopPos << FRAC_BITS;
int deltaPos = (si->freq << FRAC_BITS) / _mix->getSampleRate();
int curLen = samplesLen;
int pos = si->pos;
while (curLen != 0) {
int count;
if (loopLen > (2 << FRAC_BITS)) {
assert(si->loopPos + si->loopLen <= si->len);
if (pos >= loopPos + loopLen) {
pos -= loopLen;
}
count = MIN(curLen, (loopPos + loopLen - pos - 1) / deltaPos + 1);
curLen -= count;
} else {
if (pos >= len) {
count = 0;
} else {
count = MIN(curLen, (len - pos - 1) / deltaPos + 1);
}
curLen = 0;
}
while (count--) {
int out = resample3Pt(si, pos, deltaPos, FRAC_BITS);
Mixer::addclamp(*mixbuf++, out * si->vol / 64);
pos += deltaPos;
}
}
si->pos = pos;
}
}
}
bool SfxPlayer::mix(int8 *buf, int len) {
if (_playing) {
memset(buf, 0, len);
const int samplesPerTick = _mix->getSampleRate() / 50;
while (len != 0) {
if (_samplesLeft == 0) {
handleTick();
_samplesLeft = samplesPerTick;
}
int count = _samplesLeft;
if (count > len) {
count = len;
}
_samplesLeft -= count;
len -= count;
mixSamples(buf, count);
buf += count;
}
}
return _playing;
}
bool SfxPlayer::mixCallback(void *param, int8 *buf, int len) {
return ((SfxPlayer *)param)->mix(buf, len);
}
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mixer.h"
#include "sfx_player.h"
SfxPlayer::SfxPlayer(Mixer *mixer)
: _mod(0), _playing(false), _mix(mixer) {
}
void SfxPlayer::play(uint8 num) {
debug(DBG_SFX, "SfxPlayer::play(%d)", num);
if (!_playing) {
if (num >= 68 && num <= 75) {
static const Module *modTable[] = {
&_module68, &_module68, &_module70, &_module70,
&_module72, &_module73, &_module74, &_module75
};
_mod = modTable[num - 68];
_curOrder = 0;
_numOrders = READ_BE_UINT16(_mod->moduleData);
_orderDelay = 0;
_modData = _mod->moduleData + 0x22;
memset(_samples, 0, sizeof(_samples));
_samplesLeft = 0;
_mix->setPremixHook(mixCallback, this);
_playing = true;
}
}
}
void SfxPlayer::stop() {
if (_playing) {
_mix->setPremixHook(0, 0);
_playing = false;
}
}
void SfxPlayer::playSample(int channel, const uint8 *sampleData, uint16 period) {
assert(channel < NUM_CHANNELS);
SampleInfo *si = &_samples[channel];
si->len = READ_BE_UINT16(sampleData); sampleData += 2;
si->vol = READ_BE_UINT16(sampleData); sampleData += 2;
si->loopPos = READ_BE_UINT16(sampleData); sampleData += 2;
si->loopLen = READ_BE_UINT16(sampleData); sampleData += 2;
si->freq = PAULA_FREQ / period;
si->pos = 0;
si->data = sampleData;
}
void SfxPlayer::handleTick() {
if (!_playing) {
return;
}
if (_orderDelay != 0) {
--_orderDelay;
// check for end of song
if (_orderDelay == 0 && _modData == 0) {
_playing = false;
}
} else {
_orderDelay = READ_BE_UINT16(_mod->moduleData + 2);
debug(DBG_SFX, "curOrder=%d/%d _orderDelay=%d\n", _curOrder, _numOrders, _orderDelay);
int16 period = 0;
for (int ch = 0; ch < 3; ++ch) {
const uint8 *sampleData = 0;
uint8 b = *_modData++;
if (b != 0) {
--b;
assert(b < 5);
period = READ_BE_UINT16(_mod->moduleData + 4 + b * 2);
sampleData = _mod->sampleData[b];
}
b = *_modData++;
if (b != 0) {
int16 per = period + (b - 1);
if (per >= 0 && per < 40) {
per = _periodTable[per];
} else if (per == -3) {
per = 0xA0;
} else {
per = 0x71;
}
playSample(ch, sampleData, per);
}
}
++_curOrder;
if (_curOrder >= _numOrders) {
debug(DBG_SFX, "End of song");
_orderDelay += 20;
_modData = 0;
}
}
}
inline void addclamp(int16& a, int b) {
int add = a + b;
if (add < -32767) {
add = -32767;
} else if (add > 32767) {
add = 32767;
}
a = add;
}
void SfxPlayer::mixSamples(int16 *buf, int samplesLen) {
for (int i = 0; i < NUM_CHANNELS; ++i) {
SampleInfo *si = &_samples[i];
if (si->data) {
int16 *mixbuf = buf;
int len = si->len << FRAC_BITS;
int loopLen = si->loopLen << FRAC_BITS;
int loopPos = si->loopPos << FRAC_BITS;
int deltaPos = (si->freq << FRAC_BITS) / _mix->getSampleRate();
int curLen = samplesLen;
int pos = si->pos;
while (curLen != 0) {
int count;
if (loopLen > (2 << FRAC_BITS)) {
assert(si->loopPos + si->loopLen <= si->len);
if (pos >= loopPos + loopLen) {
pos -= loopLen;
}
count = MIN(curLen, (loopPos + loopLen - pos - 1) / deltaPos + 1);
curLen -= count;
} else {
if (pos >= len) {
count = 0;
} else {
count = MIN(curLen, (len - pos - 1) / deltaPos + 1);
}
curLen = 0;
}
while (count--) {
int out = resample3Pt(si, pos, deltaPos, FRAC_BITS);
addclamp(*mixbuf++, out * Mixer::MIX_AMPLIFICATIION * si->vol / 64);
pos += deltaPos;
}
}
si->pos = pos;
}
}
}
bool SfxPlayer::mix(int16 *buf, int len) {
if (_playing) {
memset(buf, 0, len*2);
const int samplesPerTick = _mix->getSampleRate() / 50;
while (len != 0) {
if (_samplesLeft == 0) {
handleTick();
_samplesLeft = samplesPerTick;
}
int count = _samplesLeft;
if (count > len) {
count = len;
}
_samplesLeft -= count;
len -= count;
mixSamples(buf, count);
buf += count;
}
}
return _playing;
}
bool SfxPlayer::mixCallback(void *param, int16 *buf, int len) {
return ((SfxPlayer *)param)->mix(buf, len);
}

View File

@@ -1,102 +1,102 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SFX_PLAYER_H__
#define __SFX_PLAYER_H__
#include "intern.h"
struct Mixer;
struct SfxPlayer {
enum {
NUM_SAMPLES = 5,
NUM_CHANNELS = 3,
FRAC_BITS = 12,
PAULA_FREQ = 3546897
};
struct Module {
const uint8 *sampleData[NUM_SAMPLES];
const uint8 *moduleData;
};
struct SampleInfo {
uint16 len;
uint16 vol;
uint16 loopPos;
uint16 loopLen;
int freq;
int pos;
const uint8 *data;
int8 getPCM(int offset) const {
if (offset < 0) {
offset = 0;
} else if (offset >= (int)len) {
offset = len - 1;
}
return (int8)data[offset];
}
};
static const uint8 _musicData68[];
static const uint8 _musicData70[];
static const uint8 _musicData72[];
static const uint8 _musicData73[];
static const uint8 _musicData74[];
static const uint8 _musicData75[];
static const uint8 _musicDataSample1[];
static const uint8 _musicDataSample2[]; // tick
static const uint8 _musicDataSample3[]; // bell
static const uint8 _musicDataSample4[];
static const uint8 _musicDataSample5[];
static const uint8 _musicDataSample6[];
static const uint8 _musicDataSample7[];
static const uint8 _musicDataSample8[];
static const Module _module68;
static const Module _module70;
static const Module _module72;
static const Module _module73;
static const Module _module74;
static const Module _module75;
static const uint16 _periodTable[];
const Module *_mod;
bool _playing;
int _samplesLeft;
uint16 _curOrder;
uint16 _numOrders;
uint16 _orderDelay;
const uint8 *_modData;
SampleInfo _samples[NUM_CHANNELS];
Mixer *_mix;
SfxPlayer(Mixer *mixer);
void play(uint8 num);
void stop();
void playSample(int channel, const uint8 *sampleData, uint16 period);
void handleTick();
bool mix(int8 *buf, int len);
void mixSamples(int8 *buf, int samplesLen);
static bool mixCallback(void *param, int8 *buf, int len);
};
#endif // __SFX_PLAYER_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SFX_PLAYER_H__
#define __SFX_PLAYER_H__
#include "intern.h"
struct Mixer;
struct SfxPlayer {
enum {
NUM_SAMPLES = 5,
NUM_CHANNELS = 3,
FRAC_BITS = 12,
PAULA_FREQ = 3546897
};
struct Module {
const uint8 *sampleData[NUM_SAMPLES];
const uint8 *moduleData;
};
struct SampleInfo {
uint16 len;
uint16 vol;
uint16 loopPos;
uint16 loopLen;
int freq;
int pos;
const uint8 *data;
int8 getPCM(int offset) const {
if (offset < 0) {
offset = 0;
} else if (offset >= (int)len) {
offset = len - 1;
}
return (int8)data[offset];
}
};
static const uint8 _musicData68[];
static const uint8 _musicData70[];
static const uint8 _musicData72[];
static const uint8 _musicData73[];
static const uint8 _musicData74[];
static const uint8 _musicData75[];
static const uint8 _musicDataSample1[];
static const uint8 _musicDataSample2[]; // tick
static const uint8 _musicDataSample3[]; // bell
static const uint8 _musicDataSample4[];
static const uint8 _musicDataSample5[];
static const uint8 _musicDataSample6[];
static const uint8 _musicDataSample7[];
static const uint8 _musicDataSample8[];
static const Module _module68;
static const Module _module70;
static const Module _module72;
static const Module _module73;
static const Module _module74;
static const Module _module75;
static const uint16 _periodTable[];
const Module *_mod;
bool _playing;
int _samplesLeft;
uint16 _curOrder;
uint16 _numOrders;
uint16 _orderDelay;
const uint8 *_modData;
SampleInfo _samples[NUM_CHANNELS];
Mixer *_mix;
SfxPlayer(Mixer *mixer);
void play(uint8 num);
void stop();
void playSample(int channel, const uint8 *sampleData, uint16 period);
void handleTick();
bool mix(int16 *buf, int len);
void mixSamples(int16 *buf, int samplesLen);
static bool mixCallback(void *param, int16 *buf, int len);
};
#endif // __SFX_PLAYER_H__

View File

@@ -1,49 +1,49 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SYS_H__
#define __SYS_H__
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned long uint32;
typedef signed long int32;
inline uint16 READ_BE_UINT16(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 8) | b[1];
}
inline uint32 READ_BE_UINT32(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
}
inline uint16 READ_LE_UINT16(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[1] << 8) | b[0];
}
inline uint32 READ_LE_UINT32(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
}
#endif // __SYS_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SYS_H__
#define __SYS_H__
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned long uint32;
typedef signed long int32;
inline uint16 READ_BE_UINT16(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 8) | b[1];
}
inline uint32 READ_BE_UINT32(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
}
inline uint16 READ_LE_UINT16(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[1] << 8) | b[0];
}
inline uint32 READ_LE_UINT32(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
}
#endif // __SYS_H__

View File

@@ -1,106 +1,106 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SYSTEMSTUB_H__
#define __SYSTEMSTUB_H__
#include "intern.h"
struct PlayerInput {
enum {
DIR_UP = 1 << 0,
DIR_DOWN = 1 << 1,
DIR_LEFT = 1 << 2,
DIR_RIGHT = 1 << 3
};
enum {
DF_FASTMODE = 1 << 0,
DF_DBLOCKS = 1 << 1,
DF_SETLIFE = 1 << 2
};
uint8 dirMask;
bool enter;
bool space;
bool shift;
bool backspace;
bool escape;
char lastChar;
bool save;
bool load;
int stateSlot;
bool inpRecord;
bool inpReplay;
bool mirrorMode;
uint8 dbgMask;
bool quit;
};
struct SystemStub {
typedef void (*AudioCallback)(void *param, uint8 *stream, int len);
PlayerInput _pi;
virtual ~SystemStub() {}
virtual void init(const char *title, uint16 w, uint16 h) = 0;
virtual void destroy() = 0;
virtual void setPalette(const uint8 *pal, uint16 n) = 0;
virtual void setPaletteEntry(uint8 i, const Color *c) = 0;
virtual void getPaletteEntry(uint8 i, Color *c) = 0;
virtual void setOverscanColor(uint8 i) = 0;
virtual void copyRect(int16 x, int16 y, uint16 w, uint16 h, const uint8 *buf, uint32 pitch) = 0;
virtual void updateScreen(uint8 shakeOffset) = 0;
virtual void processEvents() = 0;
virtual void sleep(uint32 duration) = 0;
virtual uint32 getTimeStamp() = 0;
virtual void startAudio(AudioCallback callback, void *param) = 0;
virtual void stopAudio() = 0;
virtual uint32 getOutputSampleRate() = 0;
virtual void *createMutex() = 0;
virtual void destroyMutex(void *mutex) = 0;
virtual void lockMutex(void *mutex) = 0;
virtual void unlockMutex(void *mutex) = 0;
};
struct MutexStack {
SystemStub *_stub;
void *_mutex;
MutexStack(SystemStub *stub, void *mutex)
: _stub(stub), _mutex(mutex) {
_stub->lockMutex(_mutex);
}
~MutexStack() {
_stub->unlockMutex(_mutex);
}
};
extern SystemStub *SystemStub_SDL_create();
extern SystemStub *SystemStub_Win32_create();
#endif // __SYSTEMSTUB_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SYSTEMSTUB_H__
#define __SYSTEMSTUB_H__
#include "intern.h"
struct PlayerInput {
enum {
DIR_UP = 1 << 0,
DIR_DOWN = 1 << 1,
DIR_LEFT = 1 << 2,
DIR_RIGHT = 1 << 3
};
enum {
DF_FASTMODE = 1 << 0,
DF_DBLOCKS = 1 << 1,
DF_SETLIFE = 1 << 2
};
uint8 dirMask;
bool enter;
bool space;
bool shift;
bool backspace;
bool escape;
char lastChar;
bool save;
bool load;
int stateSlot;
bool inpRecord;
bool inpReplay;
bool mirrorMode;
uint8 dbgMask;
bool quit;
};
struct SystemStub {
typedef void (*AudioCallback)(void *param, uint8 *stream, int len);
PlayerInput _pi;
virtual ~SystemStub() {}
virtual void init(const char *title, uint16 w, uint16 h) = 0;
virtual void destroy() = 0;
virtual void setPalette(const uint8 *pal, uint16 n) = 0;
virtual void setPaletteEntry(uint8 i, const Color *c) = 0;
virtual void getPaletteEntry(uint8 i, Color *c) = 0;
virtual void setOverscanColor(uint8 i) = 0;
virtual void copyRect(int16 x, int16 y, uint16 w, uint16 h, const uint8 *buf, uint32 pitch) = 0;
virtual void updateScreen(uint8 shakeOffset) = 0;
virtual void processEvents() = 0;
virtual void sleep(uint32 duration) = 0;
virtual uint32 getTimeStamp() = 0;
virtual void startAudio(AudioCallback callback, void *param) = 0;
virtual void stopAudio() = 0;
virtual uint32 getOutputSampleRate() = 0;
virtual void *createMutex() = 0;
virtual void destroyMutex(void *mutex) = 0;
virtual void lockMutex(void *mutex) = 0;
virtual void unlockMutex(void *mutex) = 0;
};
struct MutexStack {
SystemStub *_stub;
void *_mutex;
MutexStack(SystemStub *stub, void *mutex)
: _stub(stub), _mutex(mutex) {
_stub->lockMutex(_mutex);
}
~MutexStack() {
_stub->unlockMutex(_mutex);
}
};
extern SystemStub *SystemStub_SDL_create();
extern SystemStub *SystemStub_Win32_create();
#endif // __SYSTEMSTUB_H__

View File

@@ -1,103 +1,103 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "unpack.h"
static int rcr(UnpackCtx *uc, int CF) {
int rCF = (uc->chk & 1);
uc->chk >>= 1;
if (CF) {
uc->chk |= 0x80000000;
}
return rCF;
}
static int next_chunk(UnpackCtx *uc) {
int CF = rcr(uc, 0);
if (uc->chk == 0) {
uc->chk = READ_BE_UINT32(uc->src); uc->src -= 4;
uc->crc ^= uc->chk;
CF = rcr(uc, 1);
}
return CF;
}
static uint16 get_code(UnpackCtx *uc, uint8 num_chunks) {
uint16 c = 0;
while (num_chunks--) {
c <<= 1;
if (next_chunk(uc)) {
c |= 1;
}
}
return c;
}
static void dec_unk1(UnpackCtx *uc, uint8 num_chunks, uint8 add_count) {
uint16 count = get_code(uc, num_chunks) + add_count + 1;
uc->datasize -= count;
while (count--) {
*uc->dst = (uint8)get_code(uc, 8);
--uc->dst;
}
}
static void dec_unk2(UnpackCtx *uc, uint8 num_chunks) {
uint16 i = get_code(uc, num_chunks);
uint16 count = uc->size + 1;
uc->datasize -= count;
while (count--) {
*uc->dst = *(uc->dst + i);
--uc->dst;
}
}
bool delphine_unpack(uint8 *dst, const uint8 *src, int len) {
UnpackCtx uc;
uc.src = src + len - 4;
uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4;
uc.dst = dst + uc.datasize - 1;
uc.size = 0;
uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4;
uc.chk = READ_BE_UINT32(uc.src); uc.src -= 4;
debug(DBG_UNPACK, "delphine_unpack() crc=0x%X datasize=0x%X", uc.crc, uc.datasize);
uc.crc ^= uc.chk;
do {
if (!next_chunk(&uc)) {
uc.size = 1;
if (!next_chunk(&uc)) {
dec_unk1(&uc, 3, 0);
} else {
dec_unk2(&uc, 8);
}
} else {
uint16 c = get_code(&uc, 2);
if (c == 3) {
dec_unk1(&uc, 8, 8);
} else if (c < 2) {
uc.size = c + 2;
dec_unk2(&uc, c + 9);
} else {
uc.size = get_code(&uc, 8);
dec_unk2(&uc, 12);
}
}
} while (uc.datasize > 0);
return uc.crc == 0;
}
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "unpack.h"
static int rcr(UnpackCtx *uc, int CF) {
int rCF = (uc->chk & 1);
uc->chk >>= 1;
if (CF) {
uc->chk |= 0x80000000;
}
return rCF;
}
static int next_chunk(UnpackCtx *uc) {
int CF = rcr(uc, 0);
if (uc->chk == 0) {
uc->chk = READ_BE_UINT32(uc->src); uc->src -= 4;
uc->crc ^= uc->chk;
CF = rcr(uc, 1);
}
return CF;
}
static uint16 get_code(UnpackCtx *uc, uint8 num_chunks) {
uint16 c = 0;
while (num_chunks--) {
c <<= 1;
if (next_chunk(uc)) {
c |= 1;
}
}
return c;
}
static void dec_unk1(UnpackCtx *uc, uint8 num_chunks, uint8 add_count) {
uint16 count = get_code(uc, num_chunks) + add_count + 1;
uc->datasize -= count;
while (count--) {
*uc->dst = (uint8)get_code(uc, 8);
--uc->dst;
}
}
static void dec_unk2(UnpackCtx *uc, uint8 num_chunks) {
uint16 i = get_code(uc, num_chunks);
uint16 count = uc->size + 1;
uc->datasize -= count;
while (count--) {
*uc->dst = *(uc->dst + i);
--uc->dst;
}
}
bool delphine_unpack(uint8 *dst, const uint8 *src, int len) {
UnpackCtx uc;
uc.src = src + len - 4;
uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4;
uc.dst = dst + uc.datasize - 1;
uc.size = 0;
uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4;
uc.chk = READ_BE_UINT32(uc.src); uc.src -= 4;
debug(DBG_UNPACK, "delphine_unpack() crc=0x%X datasize=0x%X", uc.crc, uc.datasize);
uc.crc ^= uc.chk;
do {
if (!next_chunk(&uc)) {
uc.size = 1;
if (!next_chunk(&uc)) {
dec_unk1(&uc, 3, 0);
} else {
dec_unk2(&uc, 8);
}
} else {
uint16 c = get_code(&uc, 2);
if (c == 3) {
dec_unk1(&uc, 8, 8);
} else if (c < 2) {
uc.size = c + 2;
dec_unk2(&uc, c + 9);
} else {
uc.size = get_code(&uc, 8);
dec_unk2(&uc, 12);
}
}
} while (uc.datasize > 0);
return uc.crc == 0;
}

View File

@@ -1,36 +1,36 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __UNPACK_H__
#define __UNPACK_H__
#include "intern.h"
struct UnpackCtx {
int size, datasize;
uint32 crc;
uint32 chk;
uint8 *dst;
const uint8 *src;
};
extern bool delphine_unpack(uint8 *dst, const uint8 *src, int len);
#endif // __UNPACK_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __UNPACK_H__
#define __UNPACK_H__
#include "intern.h"
struct UnpackCtx {
int size, datasize;
uint32 crc;
uint32 chk;
uint8 *dst;
const uint8 *src;
};
extern bool delphine_unpack(uint8 *dst, const uint8 *src, int len);
#endif // __UNPACK_H__

View File

@@ -1,74 +1,74 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <cstdarg>
#include "util.h"
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <cstdarg>
#include "util.h"
#include <android/log.h>
uint16 g_debugMask;
void debug(uint16 cm, const char *msg, ...) {
char buf[1024];
if (cm & g_debugMask) {
va_list va;
va_start(va, msg);
vsprintf(buf, msg, va);
va_end(va);
printf("%s\n", buf);
fflush(stdout);
uint16 g_debugMask;
void debug(uint16 cm, const char *msg, ...) {
char buf[1024];
if (cm & g_debugMask) {
va_list va;
va_start(va, msg);
vsprintf(buf, msg, va);
va_end(va);
printf("%s\n", buf);
fflush(stdout);
__android_log_print(ANDROID_LOG_INFO, "REminiscence", "%s", buf);
}
}
void error(const char *msg, ...) {
char buf[1024];
va_list va;
va_start(va, msg);
vsprintf(buf, msg, va);
va_end(va);
fprintf(stderr, "ERROR: %s!\n", buf);
}
}
void error(const char *msg, ...) {
char buf[1024];
va_list va;
va_start(va, msg);
vsprintf(buf, msg, va);
va_end(va);
fprintf(stderr, "ERROR: %s!\n", buf);
__android_log_print(ANDROID_LOG_INFO, "REminiscence", "ERROR: %s", buf);
exit(-1);
}
void warning(const char *msg, ...) {
char buf[1024];
va_list va;
va_start(va, msg);
vsprintf(buf, msg, va);
va_end(va);
fprintf(stderr, "WARNING: %s!\n", buf);
exit(-1);
}
void warning(const char *msg, ...) {
char buf[1024];
va_list va;
va_start(va, msg);
vsprintf(buf, msg, va);
va_end(va);
fprintf(stderr, "WARNING: %s!\n", buf);
__android_log_print(ANDROID_LOG_INFO, "REminiscence", "WARNING: %s", buf);
}
void string_lower(char *p) {
for (; *p; ++p) {
if (*p >= 'A' && *p <= 'Z') {
*p += 'a' - 'A';
}
}
}
void string_upper(char *p) {
for (; *p; ++p) {
if (*p >= 'a' && *p <= 'z') {
*p += 'A' - 'a';
}
}
}
}
void string_lower(char *p) {
for (; *p; ++p) {
if (*p >= 'A' && *p <= 'Z') {
*p += 'a' - 'A';
}
}
}
void string_upper(char *p) {
for (; *p; ++p) {
if (*p >= 'a' && *p <= 'z') {
*p += 'A' - 'a';
}
}
}

View File

@@ -1,48 +1,48 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __UTIL_H__
#define __UTIL_H__
#include "intern.h"
enum {
DBG_INFO = 1 << 0,
DBG_RES = 1 << 1,
DBG_MENU = 1 << 2,
DBG_UNPACK = 1 << 3,
DBG_PGE = 1 << 4,
DBG_VIDEO = 1 << 5,
DBG_GAME = 1 << 6,
DBG_COL = 1 << 7,
DBG_SND = 1 << 8,
DBG_CUT = 1 << 9,
DBG_MOD = 1 << 10,
DBG_SFX = 1 << 11
};
extern uint16 g_debugMask;
extern void debug(uint16 cm, const char *msg, ...);
extern void error(const char *msg, ...);
extern void warning(const char *msg, ...);
extern void string_lower(char *p);
extern void string_upper(char *p);
#endif // __UTIL_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __UTIL_H__
#define __UTIL_H__
#include "intern.h"
enum {
DBG_INFO = 1 << 0,
DBG_RES = 1 << 1,
DBG_MENU = 1 << 2,
DBG_UNPACK = 1 << 3,
DBG_PGE = 1 << 4,
DBG_VIDEO = 1 << 5,
DBG_GAME = 1 << 6,
DBG_COL = 1 << 7,
DBG_SND = 1 << 8,
DBG_CUT = 1 << 9,
DBG_MOD = 1 << 10,
DBG_SFX = 1 << 11
};
extern uint16 g_debugMask;
extern void debug(uint16 cm, const char *msg, ...);
extern void error(const char *msg, ...);
extern void warning(const char *msg, ...);
extern void string_lower(char *p);
extern void string_upper(char *p);
#endif // __UTIL_H__

View File

@@ -1,411 +1,411 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "resource.h"
#include "systemstub.h"
#include "video.h"
Video::Video(Resource *res, SystemStub *stub)
: _res(res), _stub(stub) {
_frontLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
memset(_frontLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
_backLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
memset(_backLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
_tempLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
memset(_tempLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
_tempLayer2 = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
memset(_tempLayer2, 0, GAMESCREEN_W * GAMESCREEN_H);
_screenBlocks = (uint8 *)malloc((GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
memset(_screenBlocks, 0, (GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
_fullRefresh = true;
_shakeOffset = 0;
_charFrontColor = 0;
_charTransparentColor = 0;
_charShadowColor = 0;
}
Video::~Video() {
free(_frontLayer);
free(_backLayer);
free(_tempLayer);
free(_tempLayer2);
free(_screenBlocks);
}
void Video::markBlockAsDirty(int16 x, int16 y, uint16 w, uint16 h) {
debug(DBG_VIDEO, "Video::markBlockAsDirty(%d, %d, %d, %d)", x, y, w, h);
assert(x >= 0 && x + w <= GAMESCREEN_W && y >= 0 && y + h <= GAMESCREEN_H);
int bx1 = x / SCREENBLOCK_W;
int by1 = y / SCREENBLOCK_H;
int bx2 = (x + w - 1) / SCREENBLOCK_W;
int by2 = (y + h - 1) / SCREENBLOCK_H;
assert(bx2 < GAMESCREEN_W / SCREENBLOCK_W && by2 < GAMESCREEN_H / SCREENBLOCK_H);
for (; by1 <= by2; ++by1) {
for (int i = bx1; i <= bx2; ++i) {
_screenBlocks[by1 * (GAMESCREEN_W / SCREENBLOCK_W) + i] = 2;
}
}
}
void Video::updateScreen() {
debug(DBG_VIDEO, "Video::updateScreen()");
// _fullRefresh = true;
if (_fullRefresh) {
_stub->copyRect(0, 0, Video::GAMESCREEN_W, Video::GAMESCREEN_H, _frontLayer, 256);
_stub->updateScreen(_shakeOffset);
_fullRefresh = false;
} else {
int i, j;
int count = 0;
uint8 *p = _screenBlocks;
for (j = 0; j < GAMESCREEN_H / SCREENBLOCK_H; ++j) {
uint16 nh = 0;
for (i = 0; i < GAMESCREEN_W / SCREENBLOCK_W; ++i) {
if (p[i] != 0) {
--p[i];
++nh;
} else if (nh != 0) {
int16 x = (i - nh) * SCREENBLOCK_W;
_stub->copyRect(x, j * SCREENBLOCK_H, nh * SCREENBLOCK_W, SCREENBLOCK_H, _frontLayer, 256);
nh = 0;
++count;
}
}
if (nh != 0) {
int16 x = (i - nh) * SCREENBLOCK_W;
_stub->copyRect(x, j * SCREENBLOCK_H, nh * SCREENBLOCK_W, SCREENBLOCK_H, _frontLayer, 256);
++count;
}
p += GAMESCREEN_W / SCREENBLOCK_W;
}
if (count != 0) {
_stub->updateScreen(_shakeOffset);
}
}
if (_shakeOffset != 0) {
_shakeOffset = 0;
_fullRefresh = true;
}
}
void Video::fullRefresh() {
debug(DBG_VIDEO, "Video::fullRefresh()");
_fullRefresh = true;
memset(_screenBlocks, 0, (GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
}
void Video::fadeOut() {
debug(DBG_VIDEO, "Video::fadeOut()");
for (int step = 16; step >= 0; --step) {
for (int c = 0; c < 256; ++c) {
Color col;
_stub->getPaletteEntry(c, &col);
col.r = col.r * step >> 4;
col.g = col.g * step >> 4;
col.b = col.b * step >> 4;
_stub->setPaletteEntry(c, &col);
}
fullRefresh();
updateScreen();
_stub->sleep(50);
}
}
void Video::setPaletteSlotBE(int palSlot, int palNum) {
debug(DBG_VIDEO, "Video::setPaletteSlotBE()");
const uint8 *p = _res->_pal + palNum * 0x20;
for (int i = 0; i < 16; ++i) {
uint16 color = READ_BE_UINT16(p); p += 2;
uint8 t = (color == 0) ? 0 : 3;
Color c;
c.r = ((color & 0x00F) << 2) | t;
c.g = ((color & 0x0F0) >> 2) | t;
c.b = ((color & 0xF00) >> 6) | t;
_stub->setPaletteEntry(palSlot * 0x10 + i, &c);
}
}
void Video::setPaletteSlotLE(int palSlot, const uint8 *palData) {
debug(DBG_VIDEO, "Video::setPaletteSlotLE()");
for (int i = 0; i < 16; ++i) {
uint16 color = READ_LE_UINT16(palData); palData += 2;
Color c;
c.b = (color & 0x00F) << 2;
c.g = (color & 0x0F0) >> 2;
c.r = (color & 0xF00) >> 6;
_stub->setPaletteEntry(palSlot * 0x10 + i, &c);
}
}
void Video::setTextPalette() {
debug(DBG_VIDEO, "Video::setTextPalette()");
const uint8 *p = _textPal;
for (int i = 0; i < 16; ++i) {
uint16 color = READ_LE_UINT16(p); p += 2;
Color c;
c.b = (color & 0x00F) << 2;
c.g = (color & 0x0F0) >> 2;
c.r = (color & 0xF00) >> 6;
_stub->setPaletteEntry(0xE0 + i, &c);
}
}
void Video::setPalette0xF() {
debug(DBG_VIDEO, "Video::setPalette0xF()");
const uint8 *p = _palSlot0xF;
for (int i = 0; i < 16; ++i) {
Color c;
c.r = *p++ >> 2;
c.g = *p++ >> 2;
c.b = *p++ >> 2;
_stub->setPaletteEntry(0xF0 + i, &c);
}
}
void Video::copyLevelMap(uint16 room) {
debug(DBG_VIDEO, "Video::copyLevelMap(%d)", room);
assert(room < 0x40);
int32 off = READ_LE_UINT32(_res->_map + room * 6);
if (off == 0) {
error("Invalid room %d", room);
}
bool packed = true;
if (off < 0) {
off = -off;
packed = false;
}
const uint8 *p = _res->_map + off;
_mapPalSlot1 = *p++;
_mapPalSlot2 = *p++;
_mapPalSlot3 = *p++;
_mapPalSlot4 = *p++;
if (packed) {
uint8 *vid = _frontLayer;
for (int i = 0; i < 4; ++i) {
uint16 sz = READ_LE_UINT16(p); p += 2;
decodeLevelMap(sz, p, _res->_memBuf); p += sz;
memcpy(vid, _res->_memBuf, 256 * 56);
vid += 256 * 56;
}
} else {
for (int i = 0; i < 4; ++i) {
for (int y = 0; y < 224; ++y) {
for (int x = 0; x < 64; ++x) {
_frontLayer[i + x * 4 + 256 * y] = p[256 * 56 * i + x + 64 * y];
}
}
}
}
memcpy(_backLayer, _frontLayer, Video::GAMESCREEN_W * Video::GAMESCREEN_H);
}
void Video::decodeLevelMap(uint16 sz, const uint8 *src, uint8 *dst) {
debug(DBG_VIDEO, "Video::decodeLevelMap() sz = 0x%X", sz);
const uint8 *end = src + sz;
while (src < end) {
int16 code = (int8)*src++;
if (code < 0) {
int len = 1 - code;
memset(dst, *src++, len);
dst += len;
} else {
++code;
memcpy(dst, src, code);
src += code;
dst += code;
}
}
}
void Video::setLevelPalettes() {
debug(DBG_VIDEO, "Video::setLevelPalettes()");
if (_unkPalSlot2 == 0) {
_unkPalSlot2 = _mapPalSlot3;
}
if (_unkPalSlot1 == 0) {
_unkPalSlot1 = _mapPalSlot3;
}
setPaletteSlotBE(0x0, _mapPalSlot1);
setPaletteSlotBE(0x1, _mapPalSlot2);
setPaletteSlotBE(0x2, _mapPalSlot3);
setPaletteSlotBE(0x3, _mapPalSlot4);
if (_unkPalSlot1 == _mapPalSlot3) {
setPaletteSlotLE(4, _conradPal1);
} else {
setPaletteSlotLE(4, _conradPal2);
}
// slot 5 is monster palette
setPaletteSlotBE(0x8, _mapPalSlot1);
setPaletteSlotBE(0x9, _mapPalSlot2);
setPaletteSlotBE(0xA, _unkPalSlot2);
setPaletteSlotBE(0xB, _mapPalSlot4);
// slots 0xC and 0xD are cutscene palettes
setTextPalette();
}
void Video::drawSpriteSub1(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub1(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[i] != 0) {
dst[i] = src[i] | colMask;
}
}
src += pitch;
dst += 256;
}
}
void Video::drawSpriteSub2(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub2(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[-i] != 0) {
dst[i] = src[-i] | colMask;
}
}
src += pitch;
dst += 256;
}
}
void Video::drawSpriteSub3(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub3(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[i] != 0 && !(dst[i] & 0x80)) {
dst[i] = src[i] | colMask;
}
}
src += pitch;
dst += 256;
}
}
void Video::drawSpriteSub4(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub4(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[-i] != 0 && !(dst[i] & 0x80)) {
dst[i] = src[-i] | colMask;
}
}
src += pitch;
dst += 256;
}
}
void Video::drawSpriteSub5(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub5(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[i * pitch] != 0 && !(dst[i] & 0x80)) {
dst[i] = src[i * pitch] | colMask;
}
}
++src;
dst += 256;
}
}
void Video::drawSpriteSub6(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub6(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[-i * pitch] != 0 && !(dst[i] & 0x80)) {
dst[i] = src[-i * pitch] | colMask;
}
}
++src;
dst += 256;
}
}
void Video::drawChar(uint8 c, int16 y, int16 x) {
debug(DBG_VIDEO, "Video::drawChar(0x%X, %d, %d)", c, y, x);
y *= 8;
x *= 8;
const uint8 *src = _res->_fnt + (c - 32) * 32;
uint8 *dst = _frontLayer + x + 256 * y;
for (int h = 0; h < 8; ++h) {
for (int i = 0; i < 4; ++i) {
uint8 c1 = (*src & 0xF0) >> 4;
uint8 c2 = (*src & 0x0F) >> 0;
++src;
if (c1 != 0) {
if (c1 != 2) {
*dst = _charFrontColor;
} else {
*dst = _charShadowColor;
}
} else if (_charTransparentColor != 0xFF) {
*dst = _charTransparentColor;
}
++dst;
if (c2 != 0) {
if (c2 != 2) {
*dst = _charFrontColor;
} else {
*dst = _charShadowColor;
}
} else if (_charTransparentColor != 0xFF) {
*dst = _charTransparentColor;
}
++dst;
}
dst += 256 - 8;
}
}
const char *Video::drawString(const char *str, int16 x, int16 y, uint8 col) {
debug(DBG_VIDEO, "Video::drawString('%s', %d, %d, 0x%X)", str, x, y, col);
int len = 0;
int offset = y * 256 + x;
uint8 *dst = _frontLayer + offset;
while (1) {
uint8 c = *str++;
if (c == 0 || c == 0xB || c == 0xA) {
break;
}
uint8 *dst_char = dst;
const uint8 *src = _res->_fnt + (c - 32) * 32;
for (int h = 0; h < 8; ++h) {
for (int w = 0; w < 4; ++w) {
uint8 c1 = (*src & 0xF0) >> 4;
uint8 c2 = (*src & 0x0F) >> 0;
++src;
if (c1 != 0) {
*dst_char = (c1 == 0xF) ? col : (0xE0 + c1);
}
++dst_char;
if (c2 != 0) {
*dst_char = (c2 == 0xF) ? col : (0xE0 + c2);
}
++dst_char;
}
dst_char += 256 - 8;
}
dst += 8; // character width
++len;
}
markBlockAsDirty(x, y, len * 8, 8);
return str - 1;
}
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "resource.h"
#include "systemstub.h"
#include "video.h"
Video::Video(Resource *res, SystemStub *stub)
: _res(res), _stub(stub) {
_frontLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
memset(_frontLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
_backLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
memset(_backLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
_tempLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
memset(_tempLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
_tempLayer2 = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
memset(_tempLayer2, 0, GAMESCREEN_W * GAMESCREEN_H);
_screenBlocks = (uint8 *)malloc((GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
memset(_screenBlocks, 0, (GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
_fullRefresh = true;
_shakeOffset = 0;
_charFrontColor = 0;
_charTransparentColor = 0;
_charShadowColor = 0;
}
Video::~Video() {
free(_frontLayer);
free(_backLayer);
free(_tempLayer);
free(_tempLayer2);
free(_screenBlocks);
}
void Video::markBlockAsDirty(int16 x, int16 y, uint16 w, uint16 h) {
debug(DBG_VIDEO, "Video::markBlockAsDirty(%d, %d, %d, %d)", x, y, w, h);
assert(x >= 0 && x + w <= GAMESCREEN_W && y >= 0 && y + h <= GAMESCREEN_H);
int bx1 = x / SCREENBLOCK_W;
int by1 = y / SCREENBLOCK_H;
int bx2 = (x + w - 1) / SCREENBLOCK_W;
int by2 = (y + h - 1) / SCREENBLOCK_H;
assert(bx2 < GAMESCREEN_W / SCREENBLOCK_W && by2 < GAMESCREEN_H / SCREENBLOCK_H);
for (; by1 <= by2; ++by1) {
for (int i = bx1; i <= bx2; ++i) {
_screenBlocks[by1 * (GAMESCREEN_W / SCREENBLOCK_W) + i] = 2;
}
}
}
void Video::updateScreen() {
debug(DBG_VIDEO, "Video::updateScreen()");
// _fullRefresh = true;
if (_fullRefresh) {
_stub->copyRect(0, 0, Video::GAMESCREEN_W, Video::GAMESCREEN_H, _frontLayer, 256);
_stub->updateScreen(_shakeOffset);
_fullRefresh = false;
} else {
int i, j;
int count = 0;
uint8 *p = _screenBlocks;
for (j = 0; j < GAMESCREEN_H / SCREENBLOCK_H; ++j) {
uint16 nh = 0;
for (i = 0; i < GAMESCREEN_W / SCREENBLOCK_W; ++i) {
if (p[i] != 0) {
--p[i];
++nh;
} else if (nh != 0) {
int16 x = (i - nh) * SCREENBLOCK_W;
_stub->copyRect(x, j * SCREENBLOCK_H, nh * SCREENBLOCK_W, SCREENBLOCK_H, _frontLayer, 256);
nh = 0;
++count;
}
}
if (nh != 0) {
int16 x = (i - nh) * SCREENBLOCK_W;
_stub->copyRect(x, j * SCREENBLOCK_H, nh * SCREENBLOCK_W, SCREENBLOCK_H, _frontLayer, 256);
++count;
}
p += GAMESCREEN_W / SCREENBLOCK_W;
}
if (count != 0) {
_stub->updateScreen(_shakeOffset);
}
}
if (_shakeOffset != 0) {
_shakeOffset = 0;
_fullRefresh = true;
}
}
void Video::fullRefresh() {
debug(DBG_VIDEO, "Video::fullRefresh()");
_fullRefresh = true;
memset(_screenBlocks, 0, (GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
}
void Video::fadeOut() {
debug(DBG_VIDEO, "Video::fadeOut()");
for (int step = 16; step >= 0; --step) {
for (int c = 0; c < 256; ++c) {
Color col;
_stub->getPaletteEntry(c, &col);
col.r = col.r * step >> 4;
col.g = col.g * step >> 4;
col.b = col.b * step >> 4;
_stub->setPaletteEntry(c, &col);
}
fullRefresh();
updateScreen();
_stub->sleep(50);
}
}
void Video::setPaletteSlotBE(int palSlot, int palNum) {
debug(DBG_VIDEO, "Video::setPaletteSlotBE()");
const uint8 *p = _res->_pal + palNum * 0x20;
for (int i = 0; i < 16; ++i) {
uint16 color = READ_BE_UINT16(p); p += 2;
uint8 t = (color == 0) ? 0 : 3;
Color c;
c.r = ((color & 0x00F) << 2) | t;
c.g = ((color & 0x0F0) >> 2) | t;
c.b = ((color & 0xF00) >> 6) | t;
_stub->setPaletteEntry(palSlot * 0x10 + i, &c);
}
}
void Video::setPaletteSlotLE(int palSlot, const uint8 *palData) {
debug(DBG_VIDEO, "Video::setPaletteSlotLE()");
for (int i = 0; i < 16; ++i) {
uint16 color = READ_LE_UINT16(palData); palData += 2;
Color c;
c.b = (color & 0x00F) << 2;
c.g = (color & 0x0F0) >> 2;
c.r = (color & 0xF00) >> 6;
_stub->setPaletteEntry(palSlot * 0x10 + i, &c);
}
}
void Video::setTextPalette() {
debug(DBG_VIDEO, "Video::setTextPalette()");
const uint8 *p = _textPal;
for (int i = 0; i < 16; ++i) {
uint16 color = READ_LE_UINT16(p); p += 2;
Color c;
c.b = (color & 0x00F) << 2;
c.g = (color & 0x0F0) >> 2;
c.r = (color & 0xF00) >> 6;
_stub->setPaletteEntry(0xE0 + i, &c);
}
}
void Video::setPalette0xF() {
debug(DBG_VIDEO, "Video::setPalette0xF()");
const uint8 *p = _palSlot0xF;
for (int i = 0; i < 16; ++i) {
Color c;
c.r = *p++ >> 2;
c.g = *p++ >> 2;
c.b = *p++ >> 2;
_stub->setPaletteEntry(0xF0 + i, &c);
}
}
void Video::copyLevelMap(uint16 room) {
debug(DBG_VIDEO, "Video::copyLevelMap(%d)", room);
assert(room < 0x40);
int32 off = READ_LE_UINT32(_res->_map + room * 6);
if (off == 0) {
error("Invalid room %d", room);
}
bool packed = true;
if (off < 0) {
off = -off;
packed = false;
}
const uint8 *p = _res->_map + off;
_mapPalSlot1 = *p++;
_mapPalSlot2 = *p++;
_mapPalSlot3 = *p++;
_mapPalSlot4 = *p++;
if (packed) {
uint8 *vid = _frontLayer;
for (int i = 0; i < 4; ++i) {
uint16 sz = READ_LE_UINT16(p); p += 2;
decodeLevelMap(sz, p, _res->_memBuf); p += sz;
memcpy(vid, _res->_memBuf, 256 * 56);
vid += 256 * 56;
}
} else {
for (int i = 0; i < 4; ++i) {
for (int y = 0; y < 224; ++y) {
for (int x = 0; x < 64; ++x) {
_frontLayer[i + x * 4 + 256 * y] = p[256 * 56 * i + x + 64 * y];
}
}
}
}
memcpy(_backLayer, _frontLayer, Video::GAMESCREEN_W * Video::GAMESCREEN_H);
}
void Video::decodeLevelMap(uint16 sz, const uint8 *src, uint8 *dst) {
debug(DBG_VIDEO, "Video::decodeLevelMap() sz = 0x%X", sz);
const uint8 *end = src + sz;
while (src < end) {
int16 code = (int8)*src++;
if (code < 0) {
int len = 1 - code;
memset(dst, *src++, len);
dst += len;
} else {
++code;
memcpy(dst, src, code);
src += code;
dst += code;
}
}
}
void Video::setLevelPalettes() {
debug(DBG_VIDEO, "Video::setLevelPalettes()");
if (_unkPalSlot2 == 0) {
_unkPalSlot2 = _mapPalSlot3;
}
if (_unkPalSlot1 == 0) {
_unkPalSlot1 = _mapPalSlot3;
}
setPaletteSlotBE(0x0, _mapPalSlot1);
setPaletteSlotBE(0x1, _mapPalSlot2);
setPaletteSlotBE(0x2, _mapPalSlot3);
setPaletteSlotBE(0x3, _mapPalSlot4);
if (_unkPalSlot1 == _mapPalSlot3) {
setPaletteSlotLE(4, _conradPal1);
} else {
setPaletteSlotLE(4, _conradPal2);
}
// slot 5 is monster palette
setPaletteSlotBE(0x8, _mapPalSlot1);
setPaletteSlotBE(0x9, _mapPalSlot2);
setPaletteSlotBE(0xA, _unkPalSlot2);
setPaletteSlotBE(0xB, _mapPalSlot4);
// slots 0xC and 0xD are cutscene palettes
setTextPalette();
}
void Video::drawSpriteSub1(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub1(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[i] != 0) {
dst[i] = src[i] | colMask;
}
}
src += pitch;
dst += 256;
}
}
void Video::drawSpriteSub2(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub2(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[-i] != 0) {
dst[i] = src[-i] | colMask;
}
}
src += pitch;
dst += 256;
}
}
void Video::drawSpriteSub3(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub3(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[i] != 0 && !(dst[i] & 0x80)) {
dst[i] = src[i] | colMask;
}
}
src += pitch;
dst += 256;
}
}
void Video::drawSpriteSub4(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub4(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[-i] != 0 && !(dst[i] & 0x80)) {
dst[i] = src[-i] | colMask;
}
}
src += pitch;
dst += 256;
}
}
void Video::drawSpriteSub5(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub5(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[i * pitch] != 0 && !(dst[i] & 0x80)) {
dst[i] = src[i * pitch] | colMask;
}
}
++src;
dst += 256;
}
}
void Video::drawSpriteSub6(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
debug(DBG_VIDEO, "Video::drawSpriteSub6(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
while (h--) {
for (int i = 0; i < w; ++i) {
if (src[-i * pitch] != 0 && !(dst[i] & 0x80)) {
dst[i] = src[-i * pitch] | colMask;
}
}
++src;
dst += 256;
}
}
void Video::drawChar(uint8 c, int16 y, int16 x) {
debug(DBG_VIDEO, "Video::drawChar(0x%X, %d, %d)", c, y, x);
y *= 8;
x *= 8;
const uint8 *src = _res->_fnt + (c - 32) * 32;
uint8 *dst = _frontLayer + x + 256 * y;
for (int h = 0; h < 8; ++h) {
for (int i = 0; i < 4; ++i) {
uint8 c1 = (*src & 0xF0) >> 4;
uint8 c2 = (*src & 0x0F) >> 0;
++src;
if (c1 != 0) {
if (c1 != 2) {
*dst = _charFrontColor;
} else {
*dst = _charShadowColor;
}
} else if (_charTransparentColor != 0xFF) {
*dst = _charTransparentColor;
}
++dst;
if (c2 != 0) {
if (c2 != 2) {
*dst = _charFrontColor;
} else {
*dst = _charShadowColor;
}
} else if (_charTransparentColor != 0xFF) {
*dst = _charTransparentColor;
}
++dst;
}
dst += 256 - 8;
}
}
const char *Video::drawString(const char *str, int16 x, int16 y, uint8 col) {
debug(DBG_VIDEO, "Video::drawString('%s', %d, %d, 0x%X)", str, x, y, col);
int len = 0;
int offset = y * 256 + x;
uint8 *dst = _frontLayer + offset;
while (1) {
uint8 c = *str++;
if (c == 0 || c == 0xB || c == 0xA) {
break;
}
uint8 *dst_char = dst;
const uint8 *src = _res->_fnt + (c - 32) * 32;
for (int h = 0; h < 8; ++h) {
for (int w = 0; w < 4; ++w) {
uint8 c1 = (*src & 0xF0) >> 4;
uint8 c2 = (*src & 0x0F) >> 0;
++src;
if (c1 != 0) {
*dst_char = (c1 == 0xF) ? col : (0xE0 + c1);
}
++dst_char;
if (c2 != 0) {
*dst_char = (c2 == 0xF) ? col : (0xE0 + c2);
}
++dst_char;
}
dst_char += 256 - 8;
}
dst += 8; // character width
++len;
}
markBlockAsDirty(x, y, len * 8, 8);
return str - 1;
}

View File

@@ -1,82 +1,82 @@
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __VIDEO_H__
#define __VIDEO_H__
#include "intern.h"
struct Resource;
struct SystemStub;
struct Video {
enum {
GAMESCREEN_W = 256,
GAMESCREEN_H = 224,
SCREENBLOCK_W = 8,
SCREENBLOCK_H = 8,
CHAR_W = 8,
CHAR_H = 8
};
static const uint8 _conradPal1[];
static const uint8 _conradPal2[];
static const uint8 _textPal[];
static const uint8 _palSlot0xF[];
Resource *_res;
SystemStub *_stub;
uint8 *_frontLayer;
uint8 *_backLayer;
uint8 *_tempLayer;
uint8 *_tempLayer2;
uint8 _unkPalSlot1, _unkPalSlot2;
uint8 _mapPalSlot1, _mapPalSlot2, _mapPalSlot3, _mapPalSlot4;
uint8 _charFrontColor;
uint8 _charTransparentColor;
uint8 _charShadowColor;
uint8 *_screenBlocks;
bool _fullRefresh;
uint8 _shakeOffset;
Video(Resource *res, SystemStub *stub);
~Video();
void markBlockAsDirty(int16 x, int16 y, uint16 w, uint16 h);
void updateScreen();
void fullRefresh();
void fadeOut();
void setPaletteSlotBE(int palSlot, int palNum);
void setPaletteSlotLE(int palSlot, const uint8 *palData);
void setTextPalette();
void setPalette0xF();
void copyLevelMap(uint16 room);
void decodeLevelMap(uint16 sz, const uint8 *src, uint8 *dst);
void setLevelPalettes();
void drawSpriteSub1(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub2(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub3(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub4(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub5(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub6(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawChar(uint8 c, int16 y, int16 x);
const char *drawString(const char *str, int16 x, int16 y, uint8 col);
};
#endif // __VIDEO_H__
/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __VIDEO_H__
#define __VIDEO_H__
#include "intern.h"
struct Resource;
struct SystemStub;
struct Video {
enum {
GAMESCREEN_W = 256,
GAMESCREEN_H = 224,
SCREENBLOCK_W = 8,
SCREENBLOCK_H = 8,
CHAR_W = 8,
CHAR_H = 8
};
static const uint8 _conradPal1[];
static const uint8 _conradPal2[];
static const uint8 _textPal[];
static const uint8 _palSlot0xF[];
Resource *_res;
SystemStub *_stub;
uint8 *_frontLayer;
uint8 *_backLayer;
uint8 *_tempLayer;
uint8 *_tempLayer2;
uint8 _unkPalSlot1, _unkPalSlot2;
uint8 _mapPalSlot1, _mapPalSlot2, _mapPalSlot3, _mapPalSlot4;
uint8 _charFrontColor;
uint8 _charTransparentColor;
uint8 _charShadowColor;
uint8 *_screenBlocks;
bool _fullRefresh;
uint8 _shakeOffset;
Video(Resource *res, SystemStub *stub);
~Video();
void markBlockAsDirty(int16 x, int16 y, uint16 w, uint16 h);
void updateScreen();
void fullRefresh();
void fadeOut();
void setPaletteSlotBE(int palSlot, int palNum);
void setPaletteSlotLE(int palSlot, const uint8 *palData);
void setTextPalette();
void setPalette0xF();
void copyLevelMap(uint16 room);
void decodeLevelMap(uint16 sz, const uint8 *src, uint8 *dst);
void setLevelPalettes();
void drawSpriteSub1(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub2(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub3(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub4(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub5(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawSpriteSub6(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
void drawChar(uint8 c, int16 y, int16 x);
const char *drawString(const char *str, int16 x, int16 y, uint8 col);
};
#endif // __VIDEO_H__

View File

@@ -14,16 +14,16 @@
#define CONTENTDIR ""
/* Directory where game data will be stored */
#define USERDIR "config/"
#define USERDIR "/data/data/com.sourceforge.sc2/files/config/"
/* Directory where config files will be stored */
#define CONFIGDIR USERDIR
/* Directory where supermelee teams will be stored */
#define MELEEDIR "teams/"
#define MELEEDIR "${UQM_CONFIG_DIR}/teams/"
/* Directory where save games will be stored */
#define SAVEDIR "save/"
#define SAVEDIR "${UQM_CONFIG_DIR}/save/"
/* Defined if words are stored with the most significant byte first */
#ifdef __ARMEL__

View File

@@ -817,10 +817,10 @@ VControl_ProcessJoyAxis (int port, int axis, int value)
int t;
if (!joysticks[port].stick)
return;
joysticks[port].axes[axis].value = value;
#ifdef ANDROID
value = -value; // Axes are swapped, too lazy to fix that on SDL side
#endif
joysticks[port].axes[axis].value = value;
t = joysticks[port].threshold;
if (value > t)
{