first commit
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
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 Lesser 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 Lesser General
|
||||
Public License instead of this License.
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
; Hovertank 3-D Source Code
|
||||
; Copyright (C) 1993-2014 Flat Rock Software
|
||||
;
|
||||
; 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.
|
||||
|
||||
;=====================================
|
||||
;
|
||||
; Graphics DEFINE file for .HOV
|
||||
; IGRAB-ed on Thu Dec 02 11:07:47 1993
|
||||
;
|
||||
;=====================================
|
||||
|
||||
MAN1PIC = 0
|
||||
MAN2PIC = 1
|
||||
MANDIE1PIC = 2
|
||||
MANDIE2PIC = 3
|
||||
MANDIE3PIC = 4
|
||||
MANDIE4PIC = 5
|
||||
MANDIE5PIC = 6
|
||||
WOMAN1PIC = 7
|
||||
WOMAN2PIC = 8
|
||||
WOMANDIE1PIC = 9
|
||||
WOMANDIE2PIC = 10
|
||||
WOMANDIE3PIC = 11
|
||||
WOMANDIE4PIC = 12
|
||||
WOMANDIE5PIC = 13
|
||||
BIGSHOTPIC = 14
|
||||
PSHOTPIC = 15
|
||||
MSHOTPIC = 16
|
||||
SHOTDIE1PIC = 17
|
||||
SHOTDIE2PIC = 18
|
||||
SHOTDIE3PIC = 19
|
||||
SHOTDIE4PIC = 20
|
||||
SHOTDIE5PIC = 21
|
||||
TANK1PIC = 22
|
||||
TANKDIE1PIC = 23
|
||||
TANKDIE2PIC = 24
|
||||
TANKDIE3PIC = 25
|
||||
TANKDIE4PIC = 26
|
||||
TANKDIE5PIC = 27
|
||||
MUTANT1PIC = 28
|
||||
MUTANT2PIC = 29
|
||||
MUTANT3PIC = 30
|
||||
MUTANT4PIC = 31
|
||||
MUTANTDIE1PIC = 32
|
||||
MUTANTDIE2PIC = 33
|
||||
MUTANTDIE3PIC = 34
|
||||
MUTANTDIE4PIC = 35
|
||||
MUTANTDIE5PIC = 36
|
||||
MUTANTSWINGPIC = 37
|
||||
MUTANTHITPIC = 38
|
||||
SHIELD1PIC = 39
|
||||
SHIELD2PIC = 40
|
||||
DRONE1PIC = 41
|
||||
DRONE2PIC = 42
|
||||
DRONE3PIC = 43
|
||||
DRONE4PIC = 44
|
||||
DRONEDIE1PIC = 45
|
||||
DRONEDIE2PIC = 46
|
||||
DRONEDIE3PIC = 47
|
||||
DRONEDIE4PIC = 48
|
||||
DRONEDIE5PIC = 49
|
||||
WARP1PIC = 50
|
||||
WARP2PIC = 51
|
||||
WARP3PIC = 52
|
||||
WARP4PIC = 53
|
||||
DASHPIC = 54
|
||||
DIGIT0PIC = 55
|
||||
DIGIT1PIC = 56
|
||||
DIGIT2PIC = 57
|
||||
DIGIT3PIC = 58
|
||||
DIGIT4PIC = 59
|
||||
DIGIT5PIC = 60
|
||||
DIGIT6PIC = 61
|
||||
DIGIT7PIC = 62
|
||||
DIGIT8PIC = 63
|
||||
DIGIT9PIC = 64
|
||||
SHIELDFULLPIC = 65
|
||||
SHIELDHALFPIC = 66
|
||||
SHIELDLOWPIC = 67
|
||||
EMPTYGUYPIC = 68
|
||||
SAVEDGUYPIC = 69
|
||||
DEADGUYPIC = 70
|
||||
REARMINGPIC = 71
|
||||
READYPIC = 72
|
||||
CHARGINGPIC = 73
|
||||
MAXPOWERPIC = 74
|
||||
ENDPIC = 75
|
||||
LOGOPIC = 76
|
||||
STARSPIC = 77
|
||||
TITLEPIC = 78
|
||||
DEATHPIC = 79
|
||||
MISSIONPIC = 80
|
||||
UFAPIC = 81
|
||||
MADUFAPIC = 82
|
||||
|
||||
|
||||
|
||||
;
|
||||
; Amount of each data item
|
||||
;
|
||||
NUMCHUNKS = 86
|
||||
NUMFONT = 0
|
||||
NUMFONTM = 1
|
||||
NUMPICS = 83
|
||||
NUMPICM = 0
|
||||
NUMSPRITES = 0
|
||||
NUMTILE8 = 72
|
||||
NUMTILE8M = 0
|
||||
NUMTILE16 = 0
|
||||
NUMTILE16M = 0
|
||||
NUMTILE32 = 0
|
||||
NUMTILE32M = 0
|
||||
;
|
||||
; File offsets for data items
|
||||
;
|
||||
STRUCTPIC = 0
|
||||
|
||||
STARTFONT = 1
|
||||
STARTFONTM = 1
|
||||
STARTPICS = 2
|
||||
STARTPICM = 85
|
||||
STARTSPRITES = 85
|
||||
STARTTILE8 = 85
|
||||
STARTTILE8M = 86
|
||||
STARTTILE16 = 86
|
||||
STARTTILE16M = 86
|
||||
STARTTILE32 = 86
|
||||
STARTTILE32M = 86
|
||||
|
||||
;
|
||||
; Thank you for using IGRAB!
|
||||
;
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//////////////////////////////////////
|
||||
//
|
||||
// Graphics DEFINE file for .HOV
|
||||
// IGRAB-ed on Thu Dec 02 11:07:46 1993
|
||||
//
|
||||
//////////////////////////////////////
|
||||
|
||||
#define MAN1PIC 0
|
||||
#define MAN2PIC 1
|
||||
#define MANDIE1PIC 2
|
||||
#define MANDIE2PIC 3
|
||||
#define MANDIE3PIC 4
|
||||
#define MANDIE4PIC 5
|
||||
#define MANDIE5PIC 6
|
||||
#define WOMAN1PIC 7
|
||||
#define WOMAN2PIC 8
|
||||
#define WOMANDIE1PIC 9
|
||||
#define WOMANDIE2PIC 10
|
||||
#define WOMANDIE3PIC 11
|
||||
#define WOMANDIE4PIC 12
|
||||
#define WOMANDIE5PIC 13
|
||||
#define BIGSHOTPIC 14
|
||||
#define PSHOTPIC 15
|
||||
#define MSHOTPIC 16
|
||||
#define SHOTDIE1PIC 17
|
||||
#define SHOTDIE2PIC 18
|
||||
#define SHOTDIE3PIC 19
|
||||
#define SHOTDIE4PIC 20
|
||||
#define SHOTDIE5PIC 21
|
||||
#define TANK1PIC 22
|
||||
#define TANKDIE1PIC 23
|
||||
#define TANKDIE2PIC 24
|
||||
#define TANKDIE3PIC 25
|
||||
#define TANKDIE4PIC 26
|
||||
#define TANKDIE5PIC 27
|
||||
#define MUTANT1PIC 28
|
||||
#define MUTANT2PIC 29
|
||||
#define MUTANT3PIC 30
|
||||
#define MUTANT4PIC 31
|
||||
#define MUTANTDIE1PIC 32
|
||||
#define MUTANTDIE2PIC 33
|
||||
#define MUTANTDIE3PIC 34
|
||||
#define MUTANTDIE4PIC 35
|
||||
#define MUTANTDIE5PIC 36
|
||||
#define MUTANTSWINGPIC 37
|
||||
#define MUTANTHITPIC 38
|
||||
#define SHIELD1PIC 39
|
||||
#define SHIELD2PIC 40
|
||||
#define DRONE1PIC 41
|
||||
#define DRONE2PIC 42
|
||||
#define DRONE3PIC 43
|
||||
#define DRONE4PIC 44
|
||||
#define DRONEDIE1PIC 45
|
||||
#define DRONEDIE2PIC 46
|
||||
#define DRONEDIE3PIC 47
|
||||
#define DRONEDIE4PIC 48
|
||||
#define DRONEDIE5PIC 49
|
||||
#define WARP1PIC 50
|
||||
#define WARP2PIC 51
|
||||
#define WARP3PIC 52
|
||||
#define WARP4PIC 53
|
||||
#define DASHPIC 54
|
||||
#define DIGIT0PIC 55
|
||||
#define DIGIT1PIC 56
|
||||
#define DIGIT2PIC 57
|
||||
#define DIGIT3PIC 58
|
||||
#define DIGIT4PIC 59
|
||||
#define DIGIT5PIC 60
|
||||
#define DIGIT6PIC 61
|
||||
#define DIGIT7PIC 62
|
||||
#define DIGIT8PIC 63
|
||||
#define DIGIT9PIC 64
|
||||
#define SHIELDFULLPIC 65
|
||||
#define SHIELDHALFPIC 66
|
||||
#define SHIELDLOWPIC 67
|
||||
#define EMPTYGUYPIC 68
|
||||
#define SAVEDGUYPIC 69
|
||||
#define DEADGUYPIC 70
|
||||
#define REARMINGPIC 71
|
||||
#define READYPIC 72
|
||||
#define CHARGINGPIC 73
|
||||
#define MAXPOWERPIC 74
|
||||
#define ENDPIC 75
|
||||
#define LOGOPIC 76
|
||||
#define STARSPIC 77
|
||||
#define TITLEPIC 78
|
||||
#define DEATHPIC 79
|
||||
#define MISSIONPIC 80
|
||||
#define UFAPIC 81
|
||||
#define MADUFAPIC 82
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Amount of each data item
|
||||
//
|
||||
#define NUMCHUNKS 86
|
||||
#define NUMFONT 0
|
||||
#define NUMFONTM 1
|
||||
#define NUMPICS 83
|
||||
#define NUMPICM 0
|
||||
#define NUMSPRITES 0
|
||||
#define NUMTILE8 72
|
||||
#define NUMTILE8M 0
|
||||
#define NUMTILE16 0
|
||||
#define NUMTILE16M 0
|
||||
#define NUMTILE32 0
|
||||
#define NUMTILE32M 0
|
||||
//
|
||||
// File offsets for data items
|
||||
//
|
||||
#define STRUCTPIC 0
|
||||
|
||||
#define STARTFONT 1
|
||||
#define STARTFONTM 1
|
||||
#define STARTPICS 2
|
||||
#define STARTPICM 85
|
||||
#define STARTSPRITES 85
|
||||
#define STARTTILE8 85
|
||||
#define STARTTILE8M 86
|
||||
#define STARTTILE16 86
|
||||
#define STARTTILE16M 86
|
||||
#define STARTTILE32 86
|
||||
#define STARTTILE32M 86
|
||||
|
||||
//
|
||||
// Thank you for using IGRAB!
|
||||
//
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
HOVERTANK MAIN
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
#include "JM_SB.H"
|
||||
#include "IDLIB.H"
|
||||
#include <MATH.H>
|
||||
|
||||
//#define PROFILE
|
||||
|
||||
#ifndef PROFILE
|
||||
#define ADAPTIVE
|
||||
#endif
|
||||
|
||||
|
||||
//#define TESTCASE
|
||||
|
||||
#define MAXTICS 8
|
||||
|
||||
#define NUMLEVELS 20
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
REFRESH
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
#define VIEWX 0 // corner of view window
|
||||
#define VIEWY 0
|
||||
#define VIEWWIDTH (40*8) // size of view window
|
||||
#define VIEWHEIGHT (18*8)
|
||||
#define VIEWXH (VIEWX+VIEWWIDTH-1)
|
||||
#define VIEWYH (VIEWY+VIEWHEIGHT-1)
|
||||
|
||||
#define CENTERX (VIEWX+VIEWWIDTH/2) // middle of view window
|
||||
#define CENTERY (VIEWY+VIEWHEIGHT/2)
|
||||
|
||||
#define STATUSLINES (9*8) // dash board
|
||||
|
||||
#define GLOBAL1 (1l<<16)
|
||||
#define TILEGLOBAL GLOBAL1
|
||||
#define TILESHIFT 16
|
||||
|
||||
#define MINDIST (2*GLOBAL1/5)
|
||||
#define FOCALLENGTH (TILEGLOBAL) // in global coordinates
|
||||
|
||||
#define ANGLES 360 // must be divisable by 4
|
||||
|
||||
#define MAPSIZE 64 // maps are 64*64 max
|
||||
#define MAXOBJECTS 100 // max number of tanks, etc / map
|
||||
|
||||
//
|
||||
// 1 sign bit
|
||||
// 15 bits units
|
||||
// 16 bits fractional
|
||||
//
|
||||
#define SIGNBIT 0x80000000l
|
||||
|
||||
typedef long fixed;
|
||||
|
||||
#define NORTH 0
|
||||
#define EAST 1
|
||||
#define SOUTH 2
|
||||
#define WEST 3
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
DASH INSTRUMENTS
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
#define TIMESECX 3
|
||||
#define TIMESECY 54
|
||||
#define TIMEMINX 1
|
||||
#define TIMEMINY 54
|
||||
|
||||
#define RADARX 284 // center of radar
|
||||
#define RADARY 36
|
||||
#define RADARSIZE 26 // each way
|
||||
#define RADARRANGE (TILEGLOBAL*18) // each way
|
||||
#define RADARSCALE (RADARRANGE/RADARSIZE)
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
HOVMAIN
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
extern int tedlevel;
|
||||
extern memptr scalesegs[NUMPICS];
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
HOVDRAW
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {int x,y;} tilept;
|
||||
typedef struct {fixed x,y;} globpt;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x1,x2,leftclip,rightclip;// first pixel of wall (may not be visable)
|
||||
unsigned height1,height2,color;
|
||||
} walltype;
|
||||
|
||||
#define MAXWALLS 100
|
||||
#define DANGERHIGH 90
|
||||
#define DANGERLOW 10
|
||||
|
||||
#define MIDWALL (MAXWALLS/2)
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
||||
extern tilept tile,lasttile,focal,left,mid,right;
|
||||
|
||||
extern globpt edge,view;
|
||||
|
||||
extern unsigned screenloc[3];
|
||||
|
||||
extern int screenpage,tics;
|
||||
|
||||
extern long lasttimecount;
|
||||
#define SHIFTFRAMES 256
|
||||
extern int yshift[SHIFTFRAMES]; // screen sliding variables
|
||||
|
||||
extern int firstangle,lastangle;
|
||||
|
||||
extern fixed prestep;
|
||||
|
||||
extern int traceclip,tracetop;
|
||||
|
||||
extern fixed sintable[ANGLES+ANGLES/4],*costable;
|
||||
|
||||
extern fixed viewx,viewy,viewsin,viewcos; // the focal point
|
||||
extern int viewangle;
|
||||
|
||||
extern fixed scale,scaleglobal;
|
||||
extern unsigned slideofs;
|
||||
|
||||
extern int zbuffer[VIEWXH+1];
|
||||
|
||||
extern walltype walls[MAXWALLS],*leftwall,*rightwall;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
||||
void DrawLine (int xl, int xh, int y,int color);
|
||||
void DrawWall (walltype *wallptr);
|
||||
void TraceRay (unsigned angle);
|
||||
fixed FixedByFrac (fixed a, fixed b);
|
||||
fixed FixedAdd (fixed a, fixed b);
|
||||
void TransformPoint (fixed gx, fixed gy, int *screenx, unsigned *screenheight);
|
||||
fixed TransformX (fixed gx, fixed gy);
|
||||
int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max);
|
||||
void ForwardTrace (void);
|
||||
int FinishWall (void);
|
||||
int TurnClockwise (void);
|
||||
int TurnCounterClockwise (void);
|
||||
void FollowWall (void);
|
||||
|
||||
void NewScene (void);
|
||||
void BuildTables (void);
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
HOVLOOP
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
//
|
||||
// temp stuff
|
||||
//
|
||||
extern int statx,staty;
|
||||
|
||||
|
||||
extern unsigned tilemap[MAPSIZE][MAPSIZE];
|
||||
|
||||
typedef enum
|
||||
{nothing,playerobj,refugeeobj,droneobj,tankobj,mutantobj,warpobj,
|
||||
pshotobj,pbigshotobj,mshotobj,inertobj,shieldobj} classtype;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int active;
|
||||
classtype class;
|
||||
fixed x,y;
|
||||
fixed viewx,viewy; // x,y in view coordinate space (NOT pixels!)
|
||||
int angle;
|
||||
int hitpoints;
|
||||
int radarx,radary,radarcolor;
|
||||
long speed;
|
||||
unsigned size; // global radius for hit rect calculation
|
||||
fixed xl,xh,yl,yh; // hit rectangle
|
||||
int ticcount;
|
||||
int shapenum,stage;
|
||||
int temp1,temp2;
|
||||
dirtype dir;
|
||||
void (*think)();
|
||||
} objtype;
|
||||
|
||||
typedef struct {int min,sec;} timetype;
|
||||
extern timetype timestruct;
|
||||
|
||||
extern ControlStruct c;
|
||||
|
||||
extern int guncount,bordertime;
|
||||
|
||||
extern fixed warpx,warpy; // where to spawn warp gate
|
||||
extern fixed xmove,ymove;
|
||||
|
||||
|
||||
extern int godmode,singlestep,leveldone,resetgame;
|
||||
extern int numrefugees,totalrefugees,savedcount,killedcount;
|
||||
|
||||
extern objtype objlist[MAXOBJECTS],obon,*new,*obj,*lastobj,*check;
|
||||
|
||||
void PlayerThink (void);
|
||||
|
||||
void PlayLoop (void);
|
||||
void PlayGame (void);
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
HOVSCALE
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
extern unsigned scaleblockwidth,
|
||||
scaleblockheight,
|
||||
scaleblockdest;
|
||||
|
||||
int SC_ScaleShape (int x,int y,unsigned scale, memptr shape);
|
||||
+530
@@ -0,0 +1,530 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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 "HOVERDEF.H"
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
Id Software EGA scaling routines
|
||||
|
||||
by John Carmack, 4-16-91
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
These routines implement SPARSE SCALING, a very fast way to draw a given
|
||||
shape at various sizes.
|
||||
|
||||
SC_Setup
|
||||
--------
|
||||
Builds tables used by the drawing routines to select which pixels to draw
|
||||
at different scales. A scale of 256 is regular size, 128 half size, 512
|
||||
double size, etc. Usually you won't need exact precision in scaling, so
|
||||
some tables are used for a few scales. Basetables convert from a given
|
||||
pixel offset on the original shape to pixels on the scaled shape, screentables
|
||||
convert from a scaled offset to the original offset.
|
||||
|
||||
SC_MakeShape
|
||||
------------
|
||||
Converts a standard four plane pic or sprite of the given width/height to
|
||||
sparse scaling format. The pixels are converted from four individual bits
|
||||
to segments of byte values (0-15). Pixels of BACKGROUND color are considered
|
||||
masks, and will not apear in the scaled shape. By considering the shape
|
||||
as a list of vertical line segments no masking is needed, as only visable
|
||||
pixels are scaled.
|
||||
|
||||
SC_ScaleShape
|
||||
-------------
|
||||
Draws the shape CENTERED at the given x,y at the given scale, clipped to
|
||||
scalexl,scalexh,scaleyl,scaleyh (inclusive). The drawing is done vertically
|
||||
so the bit mask register need only be set once for each line.
|
||||
|
||||
SC_ScaleLine (ASM)
|
||||
------------
|
||||
Low level scaling routine to scale a given source of byte values (0-15) to
|
||||
a given point on the screen. No bounds checking. This is self modifying
|
||||
unwound code (coding purists go hide), with a string of 200 scaling
|
||||
operations that get a RET stuck in the code after the number of pixels
|
||||
that need to be scaled have been.
|
||||
|
||||
|
||||
DEPENDENCIES
|
||||
------------
|
||||
|
||||
|
||||
LIMITATIONS
|
||||
-----------
|
||||
Shapes must never scale over MAXHEIGHT pixels high, or the scale tables are
|
||||
invalid. Greater than 256 character height is impossible without major
|
||||
changes in any case.
|
||||
|
||||
The clipping bounds must be between 0 and 320 horizontally or the byte/mask
|
||||
tables are invalid.
|
||||
|
||||
The segmented scaling isn't perfect
|
||||
|
||||
|
||||
POSSIBLE IMPROVEMENTS
|
||||
---------------------
|
||||
256 color VGA scaling can be done over twice as fast as 16 color EGA
|
||||
because the pixels can be written out without having to load the latches!
|
||||
Sparsing the shape with horizontal scans would also make an improvement.
|
||||
|
||||
SCALESTEP probably shouldn't be linear, as size change perception varies
|
||||
with the original size
|
||||
|
||||
Seperate horizontal/vertical scaling for stretching effects
|
||||
|
||||
vertical clipping
|
||||
|
||||
Bitmap holography... (coming soon!)
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
#define MAXPICHEIGHT 256 // tallest pic to be scaled
|
||||
#define BACKGROUND 5 // background pixel for make shape
|
||||
|
||||
#define BASESCALE 64 // normal size
|
||||
#define MAXSCALE 256 // largest scale possible
|
||||
#define SCALESTEP 3
|
||||
#define DISCREETSCALES (MAXSCALE/SCALESTEP)
|
||||
|
||||
|
||||
|
||||
typedef struct scseg
|
||||
{
|
||||
int start; // relative to top of shape
|
||||
int length; // pixels in this segment
|
||||
unsigned next; // offset from segment, NULL if last segment
|
||||
char data[]; // pixel values
|
||||
} scaleseg;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width; // number of vertical lines
|
||||
int height; // only used for centering
|
||||
unsigned first[]; // offsets from segment to topmost segment on
|
||||
// each line, NULL if no pixels on line
|
||||
} scaleshape;
|
||||
|
||||
|
||||
#define SCREENPIXELS 320
|
||||
|
||||
unsigned char bytetable[SCREENPIXELS],masktable[SCREENPIXELS];
|
||||
|
||||
memptr basetableseg,screentableseg; // segment of basetables and screentables
|
||||
unsigned basetables[DISCREETSCALES], // offsets in basetableseg
|
||||
screentables[DISCREETSCALES]; // offsets in screentableseg
|
||||
|
||||
int scalexl = 0,
|
||||
scalexh = 319,
|
||||
scaleyl = 0,
|
||||
scaleyh = 144;
|
||||
|
||||
unsigned scaleblockwidth,
|
||||
scaleblockheight,
|
||||
scaleblockdest;
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
===========================
|
||||
=
|
||||
= SC_Setup
|
||||
=
|
||||
===========================
|
||||
*/
|
||||
|
||||
void SC_Setup (void)
|
||||
{
|
||||
unsigned mask,i,step,scale,space;
|
||||
unsigned char far *baseptr, far *screenptr;
|
||||
unsigned offset1,offset2,size;
|
||||
|
||||
//
|
||||
// fast ploting tables
|
||||
//
|
||||
mask = 128;
|
||||
for (i=0;i<320;i++)
|
||||
{
|
||||
bytetable[i]=i/8;
|
||||
masktable[i]=mask;
|
||||
if (!(mask>>=1))
|
||||
mask = 128;
|
||||
}
|
||||
|
||||
//
|
||||
// fast scaling tables
|
||||
//
|
||||
|
||||
offset1 = offset2 = 0;
|
||||
|
||||
for (step=0;step<DISCREETSCALES;step++)
|
||||
{
|
||||
screentables [step] = offset1;
|
||||
scale = (step+1)*SCALESTEP;
|
||||
size = scale*MAXPICHEIGHT/BASESCALE;
|
||||
offset1 += size+1;
|
||||
basetables [step] = offset2;
|
||||
offset2 += MAXPICHEIGHT;
|
||||
}
|
||||
|
||||
MMGetPtr(&basetableseg,offset2);
|
||||
MMGetPtr(&screentableseg,offset1);
|
||||
|
||||
for (step=0;step<DISCREETSCALES;step++)
|
||||
{
|
||||
baseptr = (unsigned char _seg *)basetableseg + basetables[step];
|
||||
screenptr = (unsigned char _seg *)screentableseg + screentables[step];
|
||||
|
||||
scale = (step+1)*SCALESTEP;
|
||||
size = scale*MAXPICHEIGHT/BASESCALE;
|
||||
|
||||
for (i=0;i<MAXPICHEIGHT;i++)
|
||||
*baseptr++ = scale*i/BASESCALE; // basetable
|
||||
|
||||
for (i=0;i<=size;i++)
|
||||
*screenptr++ = i*BASESCALE/scale; // screentable
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
===========================
|
||||
=
|
||||
= MakeShape
|
||||
=
|
||||
= Takes a raw bit map of width bytes by height and creates a scaleable shape
|
||||
=
|
||||
= Returns the length of the shape in bytes
|
||||
=
|
||||
===========================
|
||||
*/
|
||||
|
||||
|
||||
void SC_MakeShape (memptr src,int width,int height, memptr *shapeseg)
|
||||
{
|
||||
int pixwidth,x,y;
|
||||
|
||||
//
|
||||
// bit plane to byte vars
|
||||
//
|
||||
unsigned char far *plane0,far *plane1,far *plane2,far *plane3;
|
||||
unsigned char by0,by1,by2,by3;
|
||||
unsigned b,offset,color,shift;
|
||||
|
||||
//
|
||||
// sparse convert vars
|
||||
//
|
||||
int hitpixel,start,length;
|
||||
unsigned far *segptr;
|
||||
char far *saveptr;
|
||||
char far *byteptr, far *dataptr;
|
||||
memptr byteseg;
|
||||
scaleshape _seg *tempseg;
|
||||
|
||||
|
||||
pixwidth = width*8;
|
||||
|
||||
MMGetPtr(&(memptr)tempseg,pixwidth*(height+20)); // larger than needed buffer
|
||||
|
||||
tempseg->width = pixwidth; // pixel dimensions
|
||||
tempseg->height = height;
|
||||
|
||||
//
|
||||
// convert ega pixels to byte color values in a temp buffer
|
||||
//
|
||||
// Stored in a collumn format, not rows!
|
||||
//
|
||||
MMGetPtr(&byteseg,pixwidth*height);
|
||||
|
||||
byteptr = (char far *)byteseg;
|
||||
|
||||
plane0 = src;
|
||||
plane1 = plane0 + width*height;
|
||||
plane2 = plane1 + width*height;
|
||||
plane3 = plane2 + width*height;
|
||||
|
||||
for (x=0;x<width;x++)
|
||||
for (b=0;b<8;b++)
|
||||
{
|
||||
shift=8-b;
|
||||
offset = x;
|
||||
|
||||
for (y=0;y<height;y++)
|
||||
{
|
||||
by0 = *(plane0+offset);
|
||||
by1 = *(plane1+offset);
|
||||
by2 = *(plane2+offset);
|
||||
by3 = *(plane3+offset);
|
||||
offset+=width;
|
||||
|
||||
color = 0;
|
||||
asm mov cl,[BYTE PTR shift]
|
||||
asm mov al,[BYTE PTR by3]
|
||||
asm rcr al,cl;
|
||||
asm rcl [BYTE PTR color],1;
|
||||
|
||||
asm mov cl,[BYTE PTR shift]
|
||||
asm mov al,[BYTE PTR by2]
|
||||
asm rcr al,cl;
|
||||
asm rcl [BYTE PTR color],1;
|
||||
|
||||
asm mov cl,[BYTE PTR shift]
|
||||
asm mov al,[BYTE PTR by1]
|
||||
asm rcr al,cl;
|
||||
asm rcl [BYTE PTR color],1;
|
||||
|
||||
asm mov cl,[BYTE PTR shift]
|
||||
asm mov al,[BYTE PTR by0]
|
||||
asm rcr al,cl;
|
||||
asm rcl [BYTE PTR color],1;
|
||||
|
||||
*byteptr++ = color;
|
||||
} // Y
|
||||
|
||||
} // B / X
|
||||
|
||||
//
|
||||
// convert byte map to sparse scaling format
|
||||
//
|
||||
saveptr = (char far *)&tempseg->first[pixwidth];
|
||||
// start filling in data after all pointers to line segments
|
||||
|
||||
byteptr = byteseg; // first pixel in byte array
|
||||
|
||||
for (x=0;x<pixwidth;x++)
|
||||
{
|
||||
//
|
||||
// each vertical line can have 0 or more segments of pixels in it
|
||||
//
|
||||
y= 0;
|
||||
segptr = (unsigned far *)&tempseg->first[x];
|
||||
*segptr = 0; // in case there are no segments on line
|
||||
do
|
||||
{
|
||||
// scan for first pixel to be scaled
|
||||
while (*byteptr == BACKGROUND && y<height)
|
||||
{
|
||||
byteptr++;
|
||||
y++;
|
||||
}
|
||||
if (y==height) // if not, the line is finished
|
||||
continue;
|
||||
|
||||
//
|
||||
// start a segment by pointing the last link (either shape.first[x] if it
|
||||
// is the first segment, or a seg.next if not) to the current spot in
|
||||
// the tempseg, setting segptr to this segments next link, and copying
|
||||
// all the pixels in the segment
|
||||
//
|
||||
*segptr = FP_OFF(saveptr); // pointer to start of this segment
|
||||
|
||||
start = y;
|
||||
length = 0;
|
||||
|
||||
dataptr = &((scaleseg far *)saveptr)->data[0];
|
||||
|
||||
//
|
||||
// copy bytes in the segment to the shape
|
||||
//
|
||||
while (*byteptr != BACKGROUND && y<height)
|
||||
{
|
||||
length++;
|
||||
*dataptr++ = *byteptr++;
|
||||
y++;
|
||||
}
|
||||
((scaleseg far *)saveptr)->start = start;
|
||||
((scaleseg far *)saveptr)->length = length;
|
||||
((scaleseg far *)saveptr)->next = 0;
|
||||
// get ready for next segment
|
||||
segptr = (unsigned far *)&((scaleseg far *)saveptr)->next;
|
||||
saveptr = dataptr; // next free byte to be used
|
||||
|
||||
} while (y<height);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// allocate exact space needed and copy shape to it, then free buffers
|
||||
//
|
||||
|
||||
MMGetPtr (shapeseg,FP_OFF(saveptr));
|
||||
_fmemcpy (*shapeseg,tempseg,FP_OFF(saveptr));
|
||||
MMFreePtr (&byteseg);
|
||||
MMFreePtr (&(memptr)tempseg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= SC_ScaleShape
|
||||
=
|
||||
= Scales the shape centered on x,y to size scale (256=1:1, 512=2:1, etc)
|
||||
=
|
||||
= Clips to scalexl/scalexh, scaleyl/scaleyh
|
||||
= Returns true if something was drawn
|
||||
=
|
||||
= Must be called in write mode 2!
|
||||
=
|
||||
====================
|
||||
*/
|
||||
int SC_ScaleShape (int x,int y,unsigned scale, memptr shape)
|
||||
{
|
||||
int scalechop;
|
||||
unsigned fullwidth,fullheight,scalewidth,scaleheight;
|
||||
int xl,xh,yl,yh,sx,sy,sxl,sxh,syl,syh;
|
||||
unsigned screencorner,screen,yoffset,shapeofs,xbyte,mask;
|
||||
int shapex,i,blockx,blocky;
|
||||
scaleseg far *shapeptr;
|
||||
unsigned char far *basetoscreenptr, far *screentobaseptr;
|
||||
unsigned char far *masterptr;
|
||||
|
||||
scalechop = scale/SCALESTEP - 1;
|
||||
|
||||
if (scalechop<0)
|
||||
return 0; // can't scale this size
|
||||
|
||||
if (scalechop>=DISCREETSCALES)
|
||||
scalechop = DISCREETSCALES-1;
|
||||
|
||||
basetoscreenptr = (unsigned char _seg *)basetableseg + basetables[scalechop];
|
||||
screentobaseptr = (unsigned char _seg *)screentableseg + screentables[scalechop];
|
||||
|
||||
|
||||
//
|
||||
// figure bounding rectangle for scaled image
|
||||
//
|
||||
fullwidth = ((scaleshape _seg *)shape)->width;
|
||||
fullheight = ((scaleshape _seg *)shape)->height;
|
||||
|
||||
scalewidth = fullwidth*((scalechop+1)*SCALESTEP)/BASESCALE; //basetoscreenptr[fullwidth-1];
|
||||
scaleheight = basetoscreenptr[fullheight-1];
|
||||
|
||||
xl=x-scalewidth/2;
|
||||
xh=xl+scalewidth-1;
|
||||
yl=y-scaleheight/2;
|
||||
yh=yl+scaleheight-1;
|
||||
|
||||
|
||||
// off screen?
|
||||
|
||||
if (xl>scalexh || xh<scalexl || yl>scaleyh || yh<scaleyl)
|
||||
return 0;
|
||||
|
||||
//
|
||||
// clip to sides of screen
|
||||
//
|
||||
if (xl<scalexl)
|
||||
sxl=scalexl;
|
||||
else
|
||||
sxl=xl;
|
||||
if (xh>scalexh)
|
||||
sxh=scalexh;
|
||||
else
|
||||
sxh=xh;
|
||||
|
||||
//
|
||||
// clip both sides to zbuffer
|
||||
//
|
||||
sx=sxl;
|
||||
while (zbuffer[sx]>scale && sx<=sxh)
|
||||
sx++;
|
||||
sxl=sx;
|
||||
|
||||
sx=sxh;
|
||||
while (zbuffer[sx]>scale && sx>sxl)
|
||||
sx--;
|
||||
sxh=sx;
|
||||
|
||||
if (sxl>sxh)
|
||||
return 0; // behind a wall
|
||||
|
||||
//
|
||||
// save block info for background erasing
|
||||
//
|
||||
screencorner = screenofs+yl*linewidth;
|
||||
|
||||
scaleblockdest = screencorner + sxl/8;
|
||||
scaleblockwidth = sxh/8-sxl/8+1;
|
||||
scaleblockheight = yh-yl+1;
|
||||
|
||||
|
||||
//
|
||||
// start drawing
|
||||
//
|
||||
|
||||
|
||||
for (sx=sxl;sx<=sxh;sx++)
|
||||
{
|
||||
shapex=screentobaseptr[sx-xl];
|
||||
|
||||
if ( (shapeofs = ((scaleshape _seg *)shape)->first[shapex]) != 0)
|
||||
{
|
||||
xbyte = bytetable[sx];
|
||||
mask = masktable[sx];
|
||||
if (scale>BASESCALE)
|
||||
{
|
||||
//
|
||||
// make a multiple pixel scale pass if possible
|
||||
//
|
||||
while ( ( (sx&7) != 7) && (screentobaseptr[sx+1-xl] == shapex) )
|
||||
{
|
||||
sx++;
|
||||
mask |= masktable[sx];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// set bit mask
|
||||
//
|
||||
asm mov ah,[BYTE PTR mask]
|
||||
asm mov al,GC_BITMASK
|
||||
asm mov dx,GC_INDEX
|
||||
asm out dx,ax
|
||||
|
||||
do
|
||||
{
|
||||
shapeptr=MK_FP(FP_SEG(shape),shapeofs);
|
||||
yoffset=basetoscreenptr[shapeptr->start];// pixels on screen to be skipped
|
||||
screen=screencorner+ylookup[yoffset]+xbyte;
|
||||
|
||||
ScaleLine
|
||||
(basetoscreenptr[shapeptr->length],
|
||||
screentobaseptr,
|
||||
&shapeptr->data[0],
|
||||
screen);
|
||||
|
||||
shapeofs = shapeptr->next;
|
||||
} while (shapeofs);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
char *levnames[20] =
|
||||
{/*......................................*/
|
||||
"Zone 1: Langston Research Facility",
|
||||
"Zone 2: Gardens of Marvin M. Mitchell",
|
||||
"Zone 3: Caves, Brazos de la Madre",
|
||||
"Zone 4: Fort Smith",
|
||||
"Zone 5: Coyote Canyon",
|
||||
"Zone 6: Santa Maria Cathedral",
|
||||
"Zone 7: Pax Humana Commune",
|
||||
"Zone 8: Sewers below New Trenton",
|
||||
"Zone 9: Old UFA Headquarters",
|
||||
"Zone 10: Braker's Mountain",
|
||||
"Zone 11: Wounded Village",
|
||||
"Zone 12: Murder Hill",
|
||||
"Zone 13: TerraChem Corp.",
|
||||
"Zone 14: Gulf Tech University",
|
||||
"Zone 15: Agromatic Inc. Farm",
|
||||
"Zone 16: National Agency for Defense",
|
||||
"Zone 17: Jackson International Airport",
|
||||
"Zone 18: Museum of Modern Art",
|
||||
"Zone 19: AUF Headquarters",
|
||||
"Zone 20: UFA Headquarters",
|
||||
};
|
||||
|
||||
|
||||
char *levtext[20] =
|
||||
{/*......................................*/
|
||||
"Your first assignment is to rescue a\n"
|
||||
"bunch of scientists who have\n"
|
||||
"barracaded themselves inside the\n"
|
||||
"Langston Research Facility. They were\n"
|
||||
"working on a new, clean fuel until\n"
|
||||
"some big oil corporations decided to\n"
|
||||
"buy Langston out. Now insiders say\n"
|
||||
"the corporation is going to nuke them.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"The Mitchell estate is home to many of\n"
|
||||
"the world's most famous activists,\n"
|
||||
"philanthropists, and do-gooders.\n"
|
||||
"We've just found out that a group of\n"
|
||||
"extremely rich industrialists have\n"
|
||||
"funded a tactical strike on the estate\n"
|
||||
"after some of the activists irritated\n"
|
||||
"some of their interests.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"A group of terrorists known as The Dark\n"
|
||||
"Legion are holding a bunch of children\n"
|
||||
"hostage until their demands are met.\n"
|
||||
"The goverment has decided, with their\n"
|
||||
"usual compassion, to nuke the Legion\n"
|
||||
"along with their hostages. Get the\n"
|
||||
"hostages out of there.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"The last renegades of the local\n"
|
||||
"resistance are imprisoned for holding\n"
|
||||
"rallies and publishing their anti-\n"
|
||||
"government pamphlets. A superpower is\n"
|
||||
"is planning to nuke Fort Smith for its\n"
|
||||
"strategic importance. We want those\n"
|
||||
"renegades.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"A brilliant scientist and his daughter\n"
|
||||
"are living on a missile site in the\n"
|
||||
"canyon. The site is a military target,\n"
|
||||
"and we want you to get Professor\n"
|
||||
"Phillips back safely to Headquarters.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"A group of priests have been tending\n"
|
||||
"the dying at the cathedral, even\n"
|
||||
"though their area is likely to be\n"
|
||||
"bombed again. The mutants swarming\n"
|
||||
"the area are insane. Be careful!\n"
|
||||
|
||||
,/*......................................*/
|
||||
"This commune of peace demonstrators is\n"
|
||||
"about to be toasted by the NMC -- the\n"
|
||||
"National Munitions Corporation. Pax\n"
|
||||
"Humana has been a thorn in their side\n"
|
||||
"for many years. The thorn is about to\n"
|
||||
"be removed...by nuclear means.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"This city's sewers hold the survivors\n"
|
||||
"of the last nuclear attack. Unlucky\n"
|
||||
"for them, the last one wasn't the\n"
|
||||
"last one....\n"
|
||||
|
||||
,/*......................................*/
|
||||
"Some operatives remain at the old\n"
|
||||
"headquarters after the move, and\n"
|
||||
"those looking for us have finally\n"
|
||||
"located the old base. You'll have\n"
|
||||
"to work fast.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"A dangerous horde of mutants are\n"
|
||||
"holding humans prisoner inside the\n"
|
||||
"mountain. Rescue them before the\n"
|
||||
"area is 'sanitized.'\n"
|
||||
|
||||
,/*......................................*/
|
||||
"Drones have gone rampant and are\n"
|
||||
"killing the population of this\n"
|
||||
"village. Before the situation is\n"
|
||||
"'gotten under control,' you need to\n"
|
||||
"get those people out of there.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"A tank brigade is hunting down AWOL\n"
|
||||
"soldiers. Little do they know that\n"
|
||||
"the whole area is about be baked by\n"
|
||||
"enemy missiles. Those soldiers have\n"
|
||||
"some interesting information that we\n"
|
||||
"would like to acquire.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"There are engineers trapped in the\n"
|
||||
"TerraChem building. Get them back so\n"
|
||||
"they can testify against TerraChem.\n"
|
||||
"But hurry, the whole building's gonna\n"
|
||||
"blow!\n"
|
||||
|
||||
,/*......................................*/
|
||||
"Terrorists are about to bomb Gulf Tech\n"
|
||||
"University off the face of the earth.\n"
|
||||
"We haven't been able to reach the\n"
|
||||
"scientists there. Get them out of there!\n"
|
||||
|
||||
,/*......................................*/
|
||||
"The Agromatic Inc. Corporate farm is\n"
|
||||
"being nuked by their competitors at\n"
|
||||
"at TerraTronic Inc. Get the innocent\n"
|
||||
"farmers to safety.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"Some of our UFA spies are trapped in\n"
|
||||
"NAD headquarters. Rescue them before\n"
|
||||
"the enemy missiles get there.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"The airport is under siege by\n"
|
||||
"terrorist forces. Get the civilians \n"
|
||||
"out before the Company takes care of\n"
|
||||
"the situation.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"The Museum is going to be bombed by\n"
|
||||
"by Dadaists. The bombing is their\n"
|
||||
"form of anti-expression. They've\n"
|
||||
"barred the exits and the missiles are\n"
|
||||
"coming. Good luck.\n"
|
||||
|
||||
,/*......................................*/
|
||||
"Our competitors, the Alliance for a\n"
|
||||
"Utopian Future, are getting a little\n"
|
||||
"too good to ignore. We're nuking them.\n"
|
||||
"However, we really don't want to kill\n"
|
||||
"anyone, so get them out of there\n"
|
||||
"before our missiles get there.\n"
|
||||
"It's just a matter of business, you\n"
|
||||
"understand..."
|
||||
|
||||
,/*......................................*/
|
||||
"The AUF apparently had a backup strike\n"
|
||||
"force that we didn't know about. All\n"
|
||||
"our people are alerted, but there are\n"
|
||||
"a number of people on the lower levels\n"
|
||||
"that won't be able to get out in time.\n"
|
||||
"Get them quick! Meet you at Basepoint\n"
|
||||
"Delta!\n"
|
||||
|
||||
};
|
||||
|
||||
+822
@@ -0,0 +1,822 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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 "HOVERDEF.H"
|
||||
|
||||
//==========================================================================
|
||||
|
||||
int FinishWall (void);
|
||||
|
||||
//==========================================================================
|
||||
|
||||
fixed edgex,edgey;
|
||||
|
||||
int wallon;
|
||||
int basecolor;
|
||||
|
||||
walltype *oldwall;
|
||||
|
||||
//
|
||||
// offsets from upper left corner of a tile to the left and right edges of
|
||||
// a given wall (NORTH-WEST)
|
||||
//
|
||||
fixed point1x[4] = {GLOBAL1,GLOBAL1,0 ,0 };
|
||||
fixed point1y[4] = {0 ,GLOBAL1,GLOBAL1,0 };
|
||||
|
||||
fixed point2x[4] = {0 ,GLOBAL1,GLOBAL1,0 };
|
||||
fixed point2y[4] = {0 ,0 ,GLOBAL1 ,GLOBAL1};
|
||||
|
||||
|
||||
//
|
||||
// offset from tile.x,tile.y of the tile that shares wallon side
|
||||
// (side is not visable if it is shared)
|
||||
//
|
||||
int sharex[4] = { 0, 1, 0,-1};
|
||||
int sharey[4] = {-1, 0, 1, 0};
|
||||
|
||||
//
|
||||
// amount to move tile.x,tile.y to follow wallon to another tile
|
||||
//
|
||||
int followx[4] = {-1, 0, 1, 0};
|
||||
int followy[4] = { 0,-1, 0, 1};
|
||||
|
||||
//
|
||||
// cornerwall gives the wall on the same tile to start following when the
|
||||
// wall ends at an empty tile (go around an edge on same tile)
|
||||
// turnwall gives the wall on tile.x+sharex,tile.y+sharey to start following
|
||||
// when the wall hits another tile (right angle corner)
|
||||
//
|
||||
int cornerwall[4] = {WEST,NORTH,EAST,SOUTH};
|
||||
int turnwall[4] = {EAST,SOUTH,WEST,NORTH};
|
||||
|
||||
//
|
||||
// wall visabilities in reletive locations
|
||||
// -,- 0,- +,-
|
||||
// -,0 0,0 +,0
|
||||
// -,+ 0,+ +,+
|
||||
//
|
||||
int visable[9][4] =
|
||||
{
|
||||
{0,1,1,0}, {0,0,1,0}, {0,0,1,1},
|
||||
{0,1,0,0}, {0,0,0,0}, {0,0,0,1},
|
||||
{1,1,0,0}, {1,0,0,0}, {1,0,0,1}
|
||||
};
|
||||
|
||||
int startwall[9] = {2,2,3, 1,0,3, 1,0,0};
|
||||
int backupwall[9] = {3,3,0, 2,0,0, 2,1,1};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= FollowTrace
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max)
|
||||
{
|
||||
int tx,ty,otx,oty;
|
||||
long absdx,absdy,xstep,ystep;
|
||||
|
||||
tx = tracex>>TILESHIFT;
|
||||
ty = tracey>>TILESHIFT;
|
||||
|
||||
absdx=LABS(deltax);
|
||||
absdy=LABS(deltay);
|
||||
|
||||
if (absdx>absdy)
|
||||
{
|
||||
ystep = (deltay<<8)/(absdx>>8);
|
||||
|
||||
if (!ystep)
|
||||
ystep = deltay>0 ? 1 : -1;
|
||||
|
||||
oty = (tracey+ystep)>>TILESHIFT;
|
||||
if (deltax>0)
|
||||
{
|
||||
//###############
|
||||
//
|
||||
// step x by +1
|
||||
//
|
||||
//###############
|
||||
do
|
||||
{
|
||||
tx++;
|
||||
tracey+=ystep;
|
||||
ty = tracey>>TILESHIFT;
|
||||
|
||||
if (ty!=oty)
|
||||
{
|
||||
if (tilemap[tx-1][ty])
|
||||
{
|
||||
tile.x = tx-1;
|
||||
tile.y = ty;
|
||||
return 1;
|
||||
}
|
||||
oty = ty;
|
||||
}
|
||||
if (tilemap[tx][ty])
|
||||
{
|
||||
tile.x = tx;
|
||||
tile.y = ty;
|
||||
return 1;
|
||||
}
|
||||
} while (--max);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//###############
|
||||
//
|
||||
// step x by -1
|
||||
//
|
||||
//###############
|
||||
do
|
||||
{
|
||||
tx--;
|
||||
tracey+=ystep;
|
||||
ty = tracey>>TILESHIFT;
|
||||
|
||||
if (ty!=oty)
|
||||
{
|
||||
if (tilemap[tx][oty])
|
||||
{
|
||||
tile.x = tx;
|
||||
tile.y = oty;
|
||||
return 1;
|
||||
}
|
||||
oty = ty;
|
||||
}
|
||||
if (tilemap[tx][ty])
|
||||
{
|
||||
tile.x = tx;
|
||||
tile.y = ty;
|
||||
return 1;
|
||||
}
|
||||
} while (--max);
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xstep = (deltax<<8)/(absdy>>8);
|
||||
if (!xstep)
|
||||
xstep = deltax>0 ? 1 : -1;
|
||||
|
||||
|
||||
otx = (tracex+xstep)>>TILESHIFT;
|
||||
if (deltay>0)
|
||||
{
|
||||
//###############
|
||||
//
|
||||
// step y by +1
|
||||
//
|
||||
//###############
|
||||
do
|
||||
{
|
||||
ty++;
|
||||
tracex+=xstep;
|
||||
tx = tracex>>TILESHIFT;
|
||||
|
||||
if (tx!=otx)
|
||||
{
|
||||
if (tilemap[tx][ty-1])
|
||||
{
|
||||
tile.x = tx;
|
||||
tile.y = ty-1;
|
||||
return 1;
|
||||
}
|
||||
otx = tx;
|
||||
}
|
||||
if (tilemap[tx][ty])
|
||||
{
|
||||
tile.x = tx;
|
||||
tile.y = ty;
|
||||
return 1;
|
||||
}
|
||||
} while (--max);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//###############
|
||||
//
|
||||
// step y by -1
|
||||
//
|
||||
//###############
|
||||
do
|
||||
{
|
||||
ty--;
|
||||
tracex+=xstep;
|
||||
tx = tracex>>TILESHIFT;
|
||||
|
||||
if (tx!=otx)
|
||||
{
|
||||
if (tilemap[otx][ty])
|
||||
{
|
||||
tile.x = otx;
|
||||
tile.y = ty;
|
||||
return 1;
|
||||
}
|
||||
otx = tx;
|
||||
}
|
||||
if (tilemap[tx][ty])
|
||||
{
|
||||
tile.x = tx;
|
||||
tile.y = ty;
|
||||
return 1;
|
||||
}
|
||||
} while (--max);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= BackTrace
|
||||
=
|
||||
= Traces backwards from edgex,edgey to viewx,viewy to see if a closer
|
||||
= tile obscures the given point. If it does, it finishes the wall and
|
||||
= starts a new one.
|
||||
= Returns true if a tile is hit.
|
||||
= Call with a 1 to have it automatically finish the current wall
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
int BackTrace (int finish)
|
||||
{
|
||||
fixed tracex,tracey;
|
||||
long deltax,deltay,absdx,absdy;
|
||||
int steps,otx,oty,testx,testheight,offset,wall;
|
||||
|
||||
deltax = viewx-edgex;
|
||||
deltay = viewy-edgey;
|
||||
|
||||
absdx = LABS(deltax);
|
||||
absdy = LABS(deltay);
|
||||
|
||||
if (absdx>absdy)
|
||||
steps = ABS(focal.x-(edgex>>TILESHIFT))-1;
|
||||
else
|
||||
steps = ABS(focal.y-(edgey>>TILESHIFT))-1;
|
||||
|
||||
if (steps<=0)
|
||||
return 0;
|
||||
|
||||
otx = tile.x;
|
||||
oty = tile.y;
|
||||
if (!FollowTrace(edgex,edgey,deltax,deltay,steps))
|
||||
return 0;
|
||||
|
||||
//
|
||||
// if the start wall is behind the focal point, the trace went too far back
|
||||
//
|
||||
if (ABS(tile.x-focal.x)<2 && ABS(tile.y-focal.y)<2) // too close
|
||||
{
|
||||
if (tile.x == focal.x && tile.y == focal.y)
|
||||
{
|
||||
tile.x = otx;
|
||||
tile.y = oty;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tile.x<focal.x)
|
||||
{
|
||||
if (tile.y<focal.y)
|
||||
wall = SOUTH;
|
||||
else
|
||||
wall = EAST;
|
||||
}
|
||||
else if (tile.x==focal.x)
|
||||
{
|
||||
if (tile.y<focal.y)
|
||||
wall = SOUTH;
|
||||
else
|
||||
wall = NORTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tile.y<=focal.y)
|
||||
wall = WEST;
|
||||
else
|
||||
wall = NORTH;
|
||||
}
|
||||
|
||||
//
|
||||
// rotate the X value to see if it is behind the view plane
|
||||
//
|
||||
if (TransformX (((long)tile.x<<16)+point1x[wall],
|
||||
((long)tile.y<<16)+point1y[wall]) < FOCALLENGTH)
|
||||
{
|
||||
tile.x = otx;
|
||||
tile.y = oty;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// if the old wall is still behind a closer wall, ignore the back trace
|
||||
// and continue on (dealing with limited precision...)
|
||||
//
|
||||
if (finish && !FinishWall ()) // the wall is still behind a forward wall
|
||||
{
|
||||
tile.x = otx;
|
||||
tile.y = oty;
|
||||
rightwall->x1 = oldwall->x2; // common edge with last wall
|
||||
rightwall->height1 = oldwall->height2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// back up along the intersecting face to find the rightmost wall
|
||||
//
|
||||
|
||||
if (tile.y<focal.y)
|
||||
offset = 0;
|
||||
else if (tile.y==focal.y)
|
||||
offset = 3;
|
||||
else
|
||||
offset = 6;
|
||||
if (tile.x==focal.x)
|
||||
offset ++;
|
||||
else if (tile.x>focal.x)
|
||||
offset += 2;
|
||||
|
||||
wallon = backupwall[offset];
|
||||
|
||||
while (tilemap[tile.x][tile.y])
|
||||
{
|
||||
tile.x += followx[wallon];
|
||||
tile.y += followy[wallon];
|
||||
};
|
||||
|
||||
tile.x -= followx[wallon];
|
||||
tile.y -= followy[wallon];
|
||||
|
||||
wallon = cornerwall[wallon]; // turn to first visable face
|
||||
|
||||
edgex = ((long)tile.x<<16);
|
||||
edgey = ((long)tile.y<<16);
|
||||
|
||||
TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],
|
||||
&rightwall->x1,&rightwall->height1);
|
||||
|
||||
basecolor = tilemap[tile.x][tile.y];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= ForwardTrace
|
||||
=
|
||||
= Traces forwards from edgex,edgey along the line from viewx,viewy until
|
||||
= a solid tile is hit. Sets tile.x,tile.y
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void ForwardTrace (void)
|
||||
{
|
||||
int offset;
|
||||
fixed tracex,tracey;
|
||||
long deltax,deltay;
|
||||
|
||||
deltax = edgex-viewx;
|
||||
deltay = edgey-viewy;
|
||||
|
||||
FollowTrace(edgex,edgey,deltax,deltay,0);
|
||||
|
||||
if (tile.y<focal.y)
|
||||
offset = 0;
|
||||
else if (tile.y==focal.y)
|
||||
offset = 3;
|
||||
else
|
||||
offset = 6;
|
||||
if (tile.x==focal.x)
|
||||
offset ++;
|
||||
else if (tile.x>focal.x)
|
||||
offset += 2;
|
||||
|
||||
wallon = startwall[offset];
|
||||
|
||||
//
|
||||
// start the new wall
|
||||
//
|
||||
edgex = ((long)tile.x<<16);
|
||||
edgey = ((long)tile.y<<16);
|
||||
|
||||
//
|
||||
// if entire first wall is invisable, corner
|
||||
//
|
||||
TransformPoint (edgex+point2x[wallon],edgey+point2y[wallon],
|
||||
&rightwall->x2,&rightwall->height2);
|
||||
|
||||
if (tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]]
|
||||
|| rightwall->x2 < (rightwall-1)->x2 )
|
||||
wallon = cornerwall [wallon];
|
||||
|
||||
//
|
||||
// transform first point
|
||||
//
|
||||
|
||||
TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],
|
||||
&rightwall->x1,&rightwall->height1);
|
||||
|
||||
basecolor = tilemap[tile.x][tile.y];
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= FinishWall
|
||||
=
|
||||
= Transforms edgex,edgey as the next point of the current wall
|
||||
= and sticks it in the wall list
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
int FinishWall (void)
|
||||
{
|
||||
char num[20];
|
||||
|
||||
oldwall = rightwall;
|
||||
|
||||
if (wallon&1)
|
||||
rightwall->color = basecolor+8; // high intensity walls
|
||||
else
|
||||
rightwall->color = basecolor;
|
||||
|
||||
TransformPoint (edgex,edgey,&rightwall->x2,&rightwall->height2);
|
||||
|
||||
if (rightwall->x2 <= (rightwall-1)->x2+2
|
||||
&& rightwall->height2 < (rightwall-1)->height2 )
|
||||
return 0;
|
||||
|
||||
rightwall++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= InsideCorner
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void InsideCorner (void)
|
||||
{
|
||||
int offset;
|
||||
|
||||
//
|
||||
// the wall turned -90 degrees, so draw what we have, move to the new tile,
|
||||
// change wallon, change color, and continue following.
|
||||
//
|
||||
FinishWall ();
|
||||
|
||||
tile.x += sharex[wallon];
|
||||
tile.y += sharey[wallon];
|
||||
|
||||
wallon = turnwall[wallon];
|
||||
|
||||
//
|
||||
// if the new wall is visable, continue following it. Otherwise
|
||||
// follow it backwards until it turns
|
||||
//
|
||||
if (tile.y<focal.y)
|
||||
offset = 0;
|
||||
else if (tile.y==focal.y)
|
||||
offset = 3;
|
||||
else
|
||||
offset = 6;
|
||||
if (tile.x==focal.x)
|
||||
offset ++;
|
||||
else if (tile.x>focal.x)
|
||||
offset += 2;
|
||||
|
||||
if (visable[offset][wallon])
|
||||
{
|
||||
//
|
||||
// just turn to the next wall and continue
|
||||
//
|
||||
rightwall->x1 = oldwall->x2; // common edge with last wall
|
||||
rightwall->height1 = oldwall->height2;
|
||||
basecolor = tilemap[tile.x][tile.y];
|
||||
return; // continue from here
|
||||
}
|
||||
|
||||
//
|
||||
// back follow the invisable wall until it turns, then follow that
|
||||
//
|
||||
do
|
||||
{
|
||||
tile.x += followx[wallon];
|
||||
tile.y += followy[wallon];
|
||||
} while (tilemap[tile.x][tile.y]);
|
||||
|
||||
tile.x -= followx[wallon];
|
||||
tile.y -= followy[wallon];
|
||||
|
||||
wallon = cornerwall[wallon]; // turn to first visable face
|
||||
|
||||
edgex = ((long)tile.x<<16)+point1x[wallon];
|
||||
edgey = ((long)tile.y<<16)+point1y[wallon];
|
||||
|
||||
if (!BackTrace(0)) // backtrace without finishing a wall
|
||||
{
|
||||
TransformPoint (edgex,edgey,&rightwall->x1,&rightwall->height1);
|
||||
basecolor = tilemap[tile.x][tile.y];
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= OutsideCorner
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void OutsideCorner (void)
|
||||
{
|
||||
int offset;
|
||||
|
||||
//
|
||||
// edge is the outside edge of a corner, so draw the current wall and
|
||||
// turn the corner (+90 degrees)
|
||||
//
|
||||
FinishWall ();
|
||||
|
||||
tile.x -= followx[wallon]; // backup to the real tile
|
||||
tile.y -= followy[wallon];
|
||||
wallon = cornerwall[wallon];
|
||||
|
||||
//
|
||||
// if the new wall is visable, continue following it. Otherwise
|
||||
// trace a ray from the corner to find a wall in the distance to
|
||||
// follow
|
||||
//
|
||||
if (tile.y<focal.y)
|
||||
offset = 0;
|
||||
else if (tile.y==focal.y)
|
||||
offset = 3;
|
||||
else
|
||||
offset = 6;
|
||||
if (tile.x==focal.x)
|
||||
offset ++;
|
||||
else if (tile.x>focal.x)
|
||||
offset += 2;
|
||||
|
||||
if (visable[offset][wallon])
|
||||
{
|
||||
//
|
||||
// the new wall is visable, so just continue on
|
||||
//
|
||||
rightwall->x1 = oldwall->x2; // common edge with last wall
|
||||
rightwall->height1 = oldwall->height2;
|
||||
return; // still on same tile, so color is ok
|
||||
}
|
||||
|
||||
//
|
||||
// start from a new tile further away
|
||||
//
|
||||
ForwardTrace(); // find the next wall further back
|
||||
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= FollowWalls
|
||||
=
|
||||
= Starts a wall edge at the leftmost edge of tile.x,tile.y and follows it
|
||||
= until something else is seen or the entire view area is covered
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void FollowWalls (void)
|
||||
{
|
||||
int height,newcolor,offset,wall;
|
||||
|
||||
//####################
|
||||
//
|
||||
// figure leftmost wall of new tile
|
||||
//
|
||||
//####################
|
||||
|
||||
restart:
|
||||
|
||||
if (tile.y<focal.y)
|
||||
offset = 0;
|
||||
else if (tile.y==focal.y)
|
||||
offset = 3;
|
||||
else
|
||||
offset = 6;
|
||||
if (tile.x==focal.x)
|
||||
offset ++;
|
||||
else if (tile.x>focal.x)
|
||||
offset += 2;
|
||||
|
||||
wallon = startwall[offset];
|
||||
|
||||
//
|
||||
// if the start wall is inside a block, skip it by cornering to the second wall
|
||||
//
|
||||
if ( tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]])
|
||||
wallon = cornerwall [wallon];
|
||||
|
||||
//
|
||||
// transform first edge to screen coordinates
|
||||
//
|
||||
edgex = ((long)tile.x<<16);
|
||||
edgey = ((long)tile.y<<16);
|
||||
|
||||
TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],
|
||||
&rightwall->x1,&rightwall->height1);
|
||||
|
||||
basecolor = tilemap[tile.x][tile.y];
|
||||
|
||||
//##################
|
||||
//
|
||||
// follow the wall as long as possible
|
||||
//
|
||||
//##################
|
||||
|
||||
advance:
|
||||
|
||||
do // while ( tile.x != right.x || tile.y != right.y)
|
||||
{
|
||||
//
|
||||
// check for conditions that shouldn't happed...
|
||||
//
|
||||
if (rightwall->x1 > VIEWXH) // somehow missed right tile...
|
||||
return;
|
||||
|
||||
if (rightwall == &walls[DANGERHIGH])
|
||||
{
|
||||
//
|
||||
// somethiing got messed up! Correct by thrusting ahead...
|
||||
//
|
||||
ColorBorder(15);
|
||||
bordertime = 60;
|
||||
Thrust();
|
||||
if (++obon.angle==ANGLES)
|
||||
obon.angle = 0;
|
||||
objlist[0] = obon;
|
||||
StartView ();
|
||||
goto restart;
|
||||
|
||||
#if 0
|
||||
strcpy (str,"Wall list overflow at LE:");
|
||||
itoa(level,num,10);
|
||||
strcat (str,num);
|
||||
strcat (str," X:");
|
||||
ltoa(objlist[0].x,num,10);
|
||||
strcat (str,num);
|
||||
strcat (str," Y:");
|
||||
ltoa(objlist[0].y,num,10);
|
||||
strcat (str,num);
|
||||
strcat (str," AN:");
|
||||
itoa(objlist[0].angle,num,10);
|
||||
strcat (str,num);
|
||||
|
||||
Quit (str);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// proceed along wall
|
||||
//
|
||||
|
||||
edgex = ((long)tile.x<<16)+point2x[wallon];
|
||||
edgey = ((long)tile.y<<16)+point2y[wallon];
|
||||
|
||||
if (BackTrace(1)) // went behind a closer wall
|
||||
continue;
|
||||
|
||||
//
|
||||
// advance to next tile along wall
|
||||
//
|
||||
tile.x += followx[wallon];
|
||||
tile.y += followy[wallon];
|
||||
|
||||
if (tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]])
|
||||
{
|
||||
InsideCorner (); // turn at a corner
|
||||
continue;
|
||||
}
|
||||
|
||||
newcolor = tilemap[tile.x][tile.y];
|
||||
|
||||
if (!newcolor) // turn around an edge
|
||||
{
|
||||
OutsideCorner ();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newcolor != basecolor)
|
||||
{
|
||||
//
|
||||
// wall changed color, so draw what we have and continue following
|
||||
//
|
||||
FinishWall ();
|
||||
rightwall->x1 = oldwall->x2; // new wall shares this edge
|
||||
rightwall->height1 = oldwall->height2;
|
||||
basecolor = newcolor;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
} while (tile.x != right.x || tile.y != right.y);
|
||||
|
||||
|
||||
|
||||
//######################
|
||||
//
|
||||
// draw the last tile
|
||||
//
|
||||
//######################
|
||||
|
||||
edgex = ((long)tile.x<<16)+point2x[wallon];
|
||||
edgey = ((long)tile.y<<16)+point2y[wallon];
|
||||
FinishWall();
|
||||
|
||||
wallon = cornerwall[wallon];
|
||||
|
||||
//
|
||||
// if the corner wall is visable, draw it
|
||||
//
|
||||
if (tile.y<focal.y)
|
||||
offset = 0;
|
||||
else if (tile.y==focal.y)
|
||||
offset = 3;
|
||||
else
|
||||
offset = 6;
|
||||
if (tile.x==focal.x)
|
||||
offset ++;
|
||||
else if (tile.x>focal.x)
|
||||
offset += 2;
|
||||
|
||||
if (visable[offset][wallon])
|
||||
{
|
||||
rightwall->x1 = oldwall->x2; // common edge with last wall
|
||||
rightwall->height1 = oldwall->height2;
|
||||
edgex = ((long)tile.x<<16)+point2x[wallon];
|
||||
edgey = ((long)tile.y<<16)+point2y[wallon];
|
||||
FinishWall();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
+1653
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,494 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#define EXTENSION "HOV"
|
||||
|
||||
#include "GRAPHHOV.H"
|
||||
#include "SNDSHOV.H"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <dos.h>
|
||||
#include <mem.h>
|
||||
#include <sys\stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
|
||||
#ifndef __jm__
|
||||
typedef enum {false,true} boolean;
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
char extern ch,str[80]; // scratch variables
|
||||
|
||||
#define SIGN(x) ((x)>0?1:-1)
|
||||
#define ABS(x) ((int)(x)>0?(x):-(x))
|
||||
#define LABS(x) ((long)(x)>0?(x):-(x))
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
MEMORY MANAGER
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
typedef void _seg * memptr;
|
||||
|
||||
#define MEMPTR(x) ((memptr)((unsigned)x))
|
||||
|
||||
extern unsigned totalmem; // total paragraphs available
|
||||
extern int EMSpresent,XMSpresent;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
||||
//
|
||||
// public prototypes
|
||||
//
|
||||
|
||||
void MMStartup (void);
|
||||
void MMShutdown (void);
|
||||
void MMMapEMS (void);
|
||||
void MMGetPtr (memptr *baseptr,long size);
|
||||
void MMFreePtr (memptr *baseptr);
|
||||
void MMSetPurge (memptr *baseptr, int purge);
|
||||
void MMSortMem (void);
|
||||
void MMBlockDump (void);
|
||||
unsigned MMUnusedMemory (void);
|
||||
unsigned MMTotalFree (void);
|
||||
|
||||
void PatchPointers (void); // must be present in the main program
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
** Sound routines
|
||||
** Ties into INT 8, with a timer tic at 8 * normal rate (144/sec)
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
typedef enum {off,spkr,adlib} soundtype;
|
||||
|
||||
typedef struct {unsigned start;
|
||||
byte priority;
|
||||
byte samplerate;
|
||||
char name[12];} spksndtype;
|
||||
|
||||
typedef struct {char id[4];
|
||||
unsigned filelength;
|
||||
unsigned filler[5];
|
||||
spksndtype sounds[63];
|
||||
unsigned freqdata[];} SPKRtable;
|
||||
|
||||
|
||||
soundtype extern soundmode;
|
||||
|
||||
extern unsigned timerspeed;
|
||||
extern int dontplay;
|
||||
extern unsigned inttime;
|
||||
extern long timecount;
|
||||
|
||||
extern unsigned int8hook; // address of function to call every tic
|
||||
|
||||
extern memptr soundseg;
|
||||
extern unsigned sndptr;
|
||||
|
||||
void StartupSound (void);
|
||||
void CallTimer (void);
|
||||
void ShutdownSound (void);
|
||||
void PlaySound (int sound);
|
||||
void PauseSound (void);
|
||||
void ContinueSound (void);
|
||||
void StopSound (void);
|
||||
void WaitEndSound (void);
|
||||
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
** Control routines
|
||||
** Ties into INT 9 to intercept all key presses, but passes on to BIOS
|
||||
** The control panel handles all this stuff!
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
typedef enum {north,northeast,east,southeast,south,southwest,west,
|
||||
northwest,nodir} dirtype;
|
||||
|
||||
typedef struct {dirtype dir;
|
||||
boolean button1,button2;} ControlStruct;
|
||||
|
||||
typedef enum {keyboard,mouse,joystick1,joystick2,demo} inputtype;
|
||||
|
||||
enum demoenum {notdemo,demoplay,recording};
|
||||
enum demoenum extern indemo;
|
||||
|
||||
inputtype extern playermode[3];
|
||||
char extern keydown[128];
|
||||
int extern JoyXlow[3],
|
||||
JoyXhigh[3],
|
||||
JoyYlow [3],
|
||||
JoyYhigh [3]; // 1&2 are used, 0 is just space
|
||||
|
||||
int extern MouseSensitivity;
|
||||
char extern key[8], keyB1, keyB2; // scan codes for key control
|
||||
|
||||
|
||||
void StartupKbd (void); /* ASM */
|
||||
void ShutdownKbd (void); /* ASM */
|
||||
|
||||
void ReadJoystick (int joynum,int *xcount,int *ycount);
|
||||
|
||||
int JoyButton (void);
|
||||
void CalibrateJoy (int joynum);
|
||||
void Printscan (int sc);
|
||||
void calibratekeys (void);
|
||||
|
||||
ControlStruct ControlKBD (void);
|
||||
ControlStruct ControlMouse (void);
|
||||
ControlStruct ControlJoystick (int joynum);
|
||||
ControlStruct ControlPlayer (int player);
|
||||
|
||||
int NoBiosKey(int parm);
|
||||
extern int NBKscan,NBKascii,lastkey;
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
** Miscellaneous library routines
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned bit0,bit1; // 0-255 is a character, > is a pointer to a node
|
||||
} huffnode;
|
||||
|
||||
extern int useegamem;
|
||||
|
||||
long unsigned int LoadFile(char *filename,char huge *buffer);
|
||||
void SaveFile(char *filename,char huge *buffer, long size);
|
||||
long Verify(char *filename);
|
||||
void StopDrive (void);
|
||||
|
||||
void BloadinMM (char *filename,memptr *spot);
|
||||
void BloadinRLEMM (char *filename,memptr *spot);
|
||||
void BloadinHUFFMM (char *filename,memptr *spot);
|
||||
|
||||
void HuffExpandFile (unsigned char huge *infile,
|
||||
unsigned char huge *outfile);
|
||||
|
||||
void HuffExpand (unsigned char huge *source, unsigned char huge *dest,
|
||||
long length,huffnode *hufftable);
|
||||
|
||||
void RLEBExpand (unsigned char far *source, unsigned char far *dest);
|
||||
|
||||
void RLEExpand (char far *surce,char far *dest,long length);
|
||||
unsigned RLECompress (char far *source, unsigned Length, char far *dest);
|
||||
|
||||
void InitRnd (boolean randomize); /* ASM */
|
||||
int Rnd (int max); /* ASM */
|
||||
void InitRndT (boolean randomize); /* ASM */
|
||||
int RndT (void); /* ASM */
|
||||
|
||||
void ClearKeys (void);
|
||||
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
** Graphic routines
|
||||
** Edge graphic file not needed
|
||||
**
|
||||
** Many of these #defines are duplicates as EQUs in EDGEASM, and must be ==
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#define SC_INDEX 0x3C4
|
||||
#define SC_RESET 0
|
||||
#define SC_CLOCK 1
|
||||
#define SC_MAPMASK 2
|
||||
#define SC_CHARMAP 3
|
||||
#define SC_MEMMODE 4
|
||||
|
||||
#define CRTC_INDEX 0x3D4
|
||||
#define CRTC_H_TOTAL 0
|
||||
#define CRTC_H_DISPEND 1
|
||||
#define CRTC_H_BLANK 2
|
||||
#define CRTC_H_ENDBLANK 3
|
||||
#define CRTC_H_RETRACE 4
|
||||
#define CRTC_H_ENDRETRACE 5
|
||||
#define CRTC_V_TOTAL 6
|
||||
#define CRTC_OVERFLOW 7
|
||||
#define CRTC_ROWSCAN 8
|
||||
#define CRTC_MAXSCANLINE 9
|
||||
#define CRTC_CURSORSTART 10
|
||||
#define CRTC_CURSOREND 11
|
||||
#define CRTC_STARTHIGH 12
|
||||
#define CRTC_STARTLOW 13
|
||||
#define CRTC_CURSORHIGH 14
|
||||
#define CRTC_CURSORLOW 15
|
||||
#define CRTC_V_RETRACE 16
|
||||
#define CRTC_V_ENDRETRACE 17
|
||||
#define CRTC_V_DISPEND 18
|
||||
#define CRTC_OFFSET 19
|
||||
#define CRTC_UNDERLINE 20
|
||||
#define CRTC_V_BLANK 21
|
||||
#define CRTC_V_ENDBLANK 22
|
||||
#define CRTC_MODE 23
|
||||
#define CRTC_LINECOMPARE 24
|
||||
|
||||
|
||||
#define GC_INDEX 0x3CE
|
||||
#define GC_SETRESET 0
|
||||
#define GC_ENABLESETRESET 1
|
||||
#define GC_COLORCOMPARE 2
|
||||
#define GC_DATAROTATE 3
|
||||
#define GC_READMAP 4
|
||||
#define GC_MODE 5
|
||||
#define GC_MISCELLANEOUS 6
|
||||
#define GC_COLORDONTCARE 7
|
||||
#define GC_BITMASK 8
|
||||
|
||||
#define ATR_INDEX 0x3c0
|
||||
#define ATR_MODE 16
|
||||
#define ATR_OVERSCAN 17
|
||||
#define ATR_COLORPLANEENABLE 18
|
||||
#define ATR_PELPAN 19
|
||||
#define ATR_COLORSELECT 20
|
||||
|
||||
#define SCREENWIDTH 40
|
||||
|
||||
#define EGAWRITEMODE(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_MODE+256*x;out dx,ax;sti;}
|
||||
#define EGABITMASK(x) asm{mov dx,GC_INDEX;mov ax,GC_BITMASK+256*x;out dx,ax;sti;}
|
||||
#define EGAMAPMASK(x) asm{cli;mov dx,SC_INDEX;mov ax,SC_MAPMASK+x*256;out dx,ax;sti;}
|
||||
|
||||
typedef enum {text,CGAgr,EGAgr,VGAgr} grtype;
|
||||
typedef enum {NOcard,MDAcard,CGAcard,EGAcard,MCGAcard,VGAcard,
|
||||
HGCcard=0x80,HGCPcard,HICcard} cardtype;
|
||||
|
||||
grtype extern grmode;
|
||||
cardtype extern videocard;
|
||||
unsigned extern ylookup[256];
|
||||
int extern bordercolor;
|
||||
|
||||
|
||||
void SetScreenMode (grtype mode); // sets graphic mode
|
||||
void WaitVBL (int num); // waits for no sync, then sync
|
||||
|
||||
void LoadPage(char *filename,unsigned dest);
|
||||
|
||||
void EGAPlane (int plane); // read / write from plane 0-4
|
||||
void EGASplitScreen (int linenum); // splits a 200 line screen
|
||||
void CRTCstart (unsigned start); // set crtc high/low registers
|
||||
void EGAVirtualScreen (int width); // sets screen width
|
||||
void ColorBorder (int color); // sets overscan color
|
||||
|
||||
cardtype VideoID (void); // returns the display adapter installed
|
||||
|
||||
void SetDefaultColors(void); // full bright palete
|
||||
void FadeOut (void); // EGA 16 color palette fade
|
||||
void FadeIn (void);
|
||||
|
||||
void XorBar(int xl,int yl,int width,int height);
|
||||
void Bar (int xl,int yl,int width,int height,int fill);
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
IGRAB Graphic file routines
|
||||
|
||||
Based on number reported in GRAPHEXT.H header file!
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width,
|
||||
height,
|
||||
orgx,orgy,
|
||||
xl,yl,xh,yh,
|
||||
shifts;
|
||||
} spritetype;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width,height;
|
||||
} pictype;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int height;
|
||||
int location[256];
|
||||
char width[256];
|
||||
} fontstruct;
|
||||
|
||||
|
||||
extern unsigned screenseg; // normally 0xa000
|
||||
extern unsigned screenofs; // adjustment for panning and buffers
|
||||
// from screenseg for UL corner
|
||||
extern unsigned screenorigin; // first byte viable on screen
|
||||
|
||||
unsigned extern linewidth;
|
||||
|
||||
|
||||
//
|
||||
// cachable locations
|
||||
//
|
||||
|
||||
extern memptr grsegs[NUMCHUNKS];
|
||||
extern char needgr[NUMCHUNKS]; // for caching
|
||||
|
||||
#if NUMPICS>0
|
||||
extern pictype pictable[NUMPICS];
|
||||
#endif
|
||||
|
||||
#if NUMPICM>0
|
||||
extern pictype picmtable[NUMPICS];
|
||||
extern unsigned picmsize[NUMPICS]; // plane size for drawing
|
||||
#endif
|
||||
|
||||
#if NUMSPRITES>0
|
||||
extern spritetype image, spritetable[NUMSPRITES];
|
||||
extern unsigned spritesize[NUMSPRITES]; // plane size for drawing
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// proportional font stuff
|
||||
//
|
||||
#if NUMFONT+NUMFONTM>0
|
||||
extern unsigned fontcolor,pdrawmode;
|
||||
extern unsigned px,py;
|
||||
extern unsigned pxl,pxh,pyl,pyh;
|
||||
extern fontstruct _seg * fontseg;
|
||||
|
||||
void DrawPchar (int picnum);
|
||||
void DrawMPchar (int picnum);
|
||||
#endif
|
||||
|
||||
//
|
||||
// base drawing routines, x in bytes, y in lines
|
||||
//
|
||||
|
||||
void DrawChar (int x, int y, int picnum);
|
||||
void MaskChar (int x, int y, int picnum);
|
||||
void CopyChar (int x, int y);
|
||||
void DrawPic (int x, int y, int picnum);
|
||||
void DrawSprite (int xcoord, int ycoord, int spritenum);
|
||||
void DrawSpriteT (unsigned wide,unsigned height,unsigned source,
|
||||
unsigned dest, unsigned plsize);
|
||||
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
** Mid level graphic routines
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
int extern sx,sy,leftedge, screencenterx ,screencentery, segoffset;
|
||||
|
||||
int Get (void);
|
||||
int Input(char *string,int max);
|
||||
unsigned InputInt(void);
|
||||
void Print (const char *str);
|
||||
void Printxy(int x,int y,char *string);
|
||||
void PrintC(char *string);
|
||||
void PrintHexB(unsigned char value);
|
||||
void PrintHex(unsigned value);
|
||||
void PrintBin(unsigned value);
|
||||
void PrintInt (int val);
|
||||
void PrintLong (long val);
|
||||
|
||||
void PPrint (const char *str);
|
||||
void CPPrint (const char *str);
|
||||
void PPrintInt (int val);
|
||||
void PPrintUnsigned (unsigned val);
|
||||
|
||||
void DrawWindow (int xl, int yl, int xh, int yh);
|
||||
void EraseWindow (void);
|
||||
void CharBar (int xl,int yl, int xh, int yh, int ch);
|
||||
void CenterWindow (int width, int height);
|
||||
void ExpWin (int width, int height);
|
||||
void ExpWinH (int width, int height);
|
||||
void ExpWinV (int width, int height);
|
||||
void DrawFrame(int x1,int y1,int x2,int y2,int type);
|
||||
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
** Game level routines
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
long extern score,highscore;
|
||||
int extern level;
|
||||
|
||||
typedef struct { int width;
|
||||
int height;
|
||||
int planes;
|
||||
int screenx;
|
||||
int screeny;
|
||||
int screenw;
|
||||
int screenh;
|
||||
unsigned planesize;
|
||||
} LevelDef;
|
||||
|
||||
LevelDef extern far *levelheader;
|
||||
unsigned extern far *mapplane[4]; // points into map
|
||||
int extern mapbwide,mapwwide,mapwidthextra,mapheight;
|
||||
|
||||
|
||||
//
|
||||
// get / set a tile value in the map
|
||||
//
|
||||
#define SETTILE(x,y,plane,value) *(mapplane[plane]+((y)*(unsigned)mapwwide+(x)))=value
|
||||
#define GETTILE(x,y,plane) (*(mapplane[plane]+((y)*(unsigned)mapwwide+(x)) ))
|
||||
|
||||
|
||||
void LoadCtrls (void);
|
||||
void SaveCtrls (void);
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
** Needed non library routines
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
void Quit (char *);
|
||||
void PatchPointers (void); // called after the memory manager sorts blocks
|
||||
+8172
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// jm.h
|
||||
// Constants, structs, and function prototypes for my music stuff
|
||||
//
|
||||
|
||||
#ifndef __jm__
|
||||
#define __jm__
|
||||
|
||||
typedef unsigned int word;
|
||||
typedef unsigned long longword;
|
||||
|
||||
#define false 0
|
||||
#define true 1
|
||||
#define nil 0L
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,317 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
** jm_sb.c
|
||||
** Jason's Music routines for games
|
||||
** SoundBlaster Stuff
|
||||
** v1.0d4
|
||||
*/
|
||||
|
||||
#include <dos.h>
|
||||
|
||||
#include "jm_sb.h"
|
||||
|
||||
#pragma warn -pia // Because I use if (x = y) alot...
|
||||
|
||||
// Macros for SoundBlaster stuff
|
||||
#define sbOut(n,b) outportb((n) + sbLocation,b)
|
||||
#define sbIn(n) inportb((n) + sbLocation)
|
||||
#define sbWriteDelay() while (sbIn(sbWriteStat) & 0x80);
|
||||
#define sbReadDelay() while (sbIn(sbDataAvail) & 0x80);
|
||||
|
||||
//
|
||||
// Stuff I need
|
||||
//
|
||||
static boolean sbSamplePlaying = false;
|
||||
static byte sbOldIntMask = -1;
|
||||
static byte huge *sbNextSegPtr;
|
||||
static int sbLocation = -1,sbInterrupt = 7,sbIntVec = 0xf,
|
||||
sbIntVectors[] = {-1,-1,0xa,0xb,-1,0xd,-1,0xf};
|
||||
static longword sbNextSegLen;
|
||||
static SampledSound huge *sbSamples;
|
||||
static void interrupt (*sbOldIntHand)(void);
|
||||
|
||||
//
|
||||
// jmDelay(usec) - Delays for usec micro-seconds
|
||||
//
|
||||
static void
|
||||
jmDelay(int usec)
|
||||
{
|
||||
// DEBUG - use real timing routines
|
||||
int i;
|
||||
|
||||
while (usec--)
|
||||
for (i = 0;i < 1000;i++)
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// SoundBlaster code
|
||||
//
|
||||
|
||||
//
|
||||
// Plays a chunk of sampled sound
|
||||
//
|
||||
static longword
|
||||
jmPlaySeg(byte huge *data,longword length)
|
||||
{
|
||||
unsigned datapage;
|
||||
longword dataofs,uselen;
|
||||
|
||||
uselen = length;
|
||||
datapage = FP_SEG(data) >> 12;
|
||||
dataofs = ( (FP_SEG(data)&0xfff)<<4 ) + FP_OFF(data);
|
||||
if (dataofs>=0x10000)
|
||||
{
|
||||
datapage++;
|
||||
dataofs-=0x10000;
|
||||
}
|
||||
|
||||
if (dataofs + uselen > 0x10000)
|
||||
uselen = 0x10000 - dataofs;
|
||||
|
||||
uselen--; // DEBUG
|
||||
|
||||
// Program the DMA controller
|
||||
outportb(0x0a,5); // Mask off channel 1 DMA
|
||||
outportb(0x0c,0); // Clear byte ptr F/F to lower byte
|
||||
outportb(0x0b,0x49); // Set transfer mode for D/A conv
|
||||
outportb(0x02,(byte)dataofs); // Give LSB of address
|
||||
outportb(0x02,(byte)(dataofs >> 8)); // Give MSB of address
|
||||
outportb(0x83,(byte)datapage); // Give page of address
|
||||
outportb(0x03,(byte)uselen); // Give LSB of length
|
||||
outportb(0x03,(byte)(uselen >> 8)); // Give MSB of length
|
||||
outportb(0x0a,1); // Turn on channel 1 DMA
|
||||
|
||||
// Start playing the thing
|
||||
sbWriteDelay();
|
||||
sbOut(sbWriteCmd,0x14);
|
||||
sbWriteDelay();
|
||||
sbOut(sbWriteData,(byte)uselen);
|
||||
sbWriteDelay();
|
||||
sbOut(sbWriteData,(byte)(uselen >> 8));
|
||||
|
||||
return(++uselen);
|
||||
}
|
||||
|
||||
//
|
||||
// Services the SoundBlaster DMA interrupt
|
||||
//
|
||||
void interrupt
|
||||
jmSBService(void)
|
||||
{
|
||||
longword used;
|
||||
|
||||
sbIn(sbDataAvail);
|
||||
outportb(0x20,0x20);
|
||||
|
||||
if (sbNextSegPtr)
|
||||
{
|
||||
used = jmPlaySeg(sbNextSegPtr,sbNextSegLen);
|
||||
if (sbNextSegLen <= used)
|
||||
sbNextSegPtr = nil;
|
||||
else
|
||||
{
|
||||
sbNextSegPtr += used;
|
||||
sbNextSegLen -= used;
|
||||
}
|
||||
}
|
||||
else
|
||||
jmStopSample();
|
||||
}
|
||||
|
||||
//
|
||||
// Plays a sampled sound. Returns immediately and uses DMA to play the sound
|
||||
//
|
||||
void
|
||||
jmPlaySample(sound)
|
||||
int sound;
|
||||
{
|
||||
byte huge *data,
|
||||
timevalue;
|
||||
longword used;
|
||||
SampledSound sample;
|
||||
|
||||
jmStopSample();
|
||||
|
||||
sample = sbSamples[--sound];
|
||||
|
||||
data = ((byte huge *)sbSamples) + sample.offset;
|
||||
timevalue = 256 - (1000000 / sample.hertz);
|
||||
|
||||
// printf("sample #%d ",sound);
|
||||
// printf("%ld bytes, %ldHz, tc=%d\n",sample.length,sample.hertz,timevalue);
|
||||
|
||||
// printf("setting time constant\n");
|
||||
// Set the SoundBlaster DAC time constant
|
||||
sbWriteDelay();
|
||||
sbOut(sbWriteCmd,0x40);
|
||||
sbWriteDelay();
|
||||
sbOut(sbWriteData,timevalue);
|
||||
|
||||
used = jmPlaySeg(data,sample.length);
|
||||
if (sample.length <= used)
|
||||
sbNextSegPtr = nil;
|
||||
else
|
||||
{
|
||||
sbNextSegPtr = data + used;
|
||||
sbNextSegLen = sample.length - used;
|
||||
}
|
||||
|
||||
// printf("enabling SB irq #%d\n",sbInterrupt);
|
||||
// Save old interrupt status and unmask ours
|
||||
sbOldIntMask = inportb(0x21);
|
||||
outportb(0x21,sbOldIntMask & ~(1 << sbInterrupt));
|
||||
|
||||
// printf("enabling DSP DMA request\n");
|
||||
sbWriteDelay();
|
||||
sbOut(sbWriteCmd,0xd4); // Make sure DSP DMA is enabled
|
||||
|
||||
// printf("sound should be playing\n");
|
||||
sbSamplePlaying = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Stops any active sampled sound and causes DMA to cease
|
||||
//
|
||||
void
|
||||
jmStopSample(void)
|
||||
{
|
||||
extern unsigned SndPriority;
|
||||
byte is;
|
||||
|
||||
if (sbSamplePlaying)
|
||||
{
|
||||
// printf("turning off DSP DMA\n");
|
||||
sbWriteDelay();
|
||||
sbOut(sbWriteCmd,0xd0); // Turn off DSP DMA
|
||||
|
||||
// printf("restoring interrupt\n");
|
||||
is = inportb(0x21); // Restore interrupt mask bit
|
||||
if (sbOldIntMask & (1 << sbInterrupt))
|
||||
is |= (1 << sbInterrupt);
|
||||
else
|
||||
is &= ~(1 << sbInterrupt);
|
||||
outportb(0x21,is);
|
||||
|
||||
|
||||
sbSamplePlaying = false;
|
||||
SndPriority = 0; // JC: hack for playsound
|
||||
}
|
||||
}
|
||||
//
|
||||
// Checks to see if a SoundBlaster resides at a particular I/O location
|
||||
//
|
||||
static boolean
|
||||
jmCheckSB(int port)
|
||||
{
|
||||
int i;
|
||||
|
||||
sbLocation = port << 4; // Initialize stuff for later use
|
||||
|
||||
sbOut(sbReset,true); // Reset the SoundBlaster DSP
|
||||
jmDelay(4); // Wait 4usec
|
||||
sbOut(sbReset,false); // Turn off sb DSP reset
|
||||
jmDelay(100); // Wait 100usec
|
||||
for (i = 0;i < 100;i++)
|
||||
{
|
||||
if (sbIn(sbDataAvail) & 0x80) // If data is available...
|
||||
{
|
||||
if (sbIn(sbReadData) == 0xaa) // If it matches correct value
|
||||
return(true);
|
||||
else
|
||||
{
|
||||
sbLocation = -1; // Otherwise not a SoundBlaster
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
sbLocation = -1; // Retry count exceeded - fail
|
||||
return(false);
|
||||
}
|
||||
|
||||
//
|
||||
// Checks to see if a SoundBlaster is in the system. If the port passed is
|
||||
// -1, then it scans through all possible I/O locations. If the port
|
||||
// passed is 0, then it uses the default (2). If the port is >0, then
|
||||
// it just passes it directly to jmCheckSB()
|
||||
//
|
||||
boolean
|
||||
jmDetectSoundBlaster(int port)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (port == 0) // If user specifies default address, use 2
|
||||
port = 2;
|
||||
if (port == -1)
|
||||
{
|
||||
for (i = 1;i <= 6;i++) // Scan through possible SB locations
|
||||
{
|
||||
if (jmCheckSB(i)) // If found at this address,
|
||||
return(true); // return success
|
||||
}
|
||||
return(false); // All addresses failed, return failure
|
||||
}
|
||||
else
|
||||
return(jmCheckSB(port)); // User specified address or default
|
||||
}
|
||||
|
||||
//
|
||||
// Sets the interrupt number that my code expects the SoundBlaster to use
|
||||
//
|
||||
void
|
||||
jmSetSBInterrupt(int num)
|
||||
{
|
||||
sbInterrupt = num;
|
||||
sbIntVec = sbIntVectors[sbInterrupt];
|
||||
}
|
||||
|
||||
void
|
||||
jmStartSB(void)
|
||||
{
|
||||
// printf("setting interrupt #0x%02x handler\n",sbIntVec);
|
||||
sbOldIntHand = getvect(sbIntVec); // Get old interrupt handler
|
||||
setvect(sbIntVec,jmSBService); // Set mine
|
||||
|
||||
// printf("setting DSP modes\n");
|
||||
sbWriteDelay();
|
||||
sbOut(sbWriteCmd,0xd1); // Turn on DSP speaker
|
||||
}
|
||||
|
||||
void
|
||||
jmShutSB(void)
|
||||
{
|
||||
jmStopSample();
|
||||
|
||||
// printf("restoring interrupt vector\n");
|
||||
setvect(sbIntVec,sbOldIntHand); // Set vector back
|
||||
}
|
||||
|
||||
boolean
|
||||
jmSamplePlaying(void)
|
||||
{
|
||||
return(sbSamplePlaying);
|
||||
}
|
||||
|
||||
void
|
||||
jmSetSamplePtr(s)
|
||||
SampledSound huge *s;
|
||||
{
|
||||
sbSamples = s;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// jm_sb.h
|
||||
// Constants, structs, and function prototypes for my SoundBlaster stuff
|
||||
//
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned boolean;
|
||||
|
||||
|
||||
#ifndef __jm__
|
||||
#include "jm.h"
|
||||
#endif
|
||||
|
||||
// Registers for the Sound Blaster card - needs to be offset by n0
|
||||
#define sbReset 0x206
|
||||
#define sbReadData 0x20a
|
||||
#define sbWriteCmd 0x20c
|
||||
#define sbWriteData 0x20c
|
||||
#define sbWriteStat 0x20c
|
||||
#define sbDataAvail 0x20e
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
longword offset,length,
|
||||
hertz;
|
||||
byte bits,
|
||||
reference;
|
||||
} SampledSound;
|
||||
|
||||
//
|
||||
// Function prototypes
|
||||
//
|
||||
|
||||
extern void jmStartSB(void),jmStopSB(void),
|
||||
jmSetSBInterrupt(int),
|
||||
jmSetSamplePtr(SampledSound huge *),
|
||||
jmPlaySample(int),jmStopSample(void);
|
||||
extern boolean jmDetectSoundBlaster(int),
|
||||
jmSamplePlaying(void);
|
||||
+2405
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,794 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// MEMMGR.C
|
||||
#include "IDLIB.H"
|
||||
#pragma hdrstop
|
||||
|
||||
#define EMSINT 0x67
|
||||
|
||||
#define EXTRASTACKSIZE 0x1000
|
||||
#define MAXBLOCKS 1500
|
||||
#define LOCKBIT 0x8000 // if set in attributes, block cannot be moved
|
||||
#define PURGEBITS 3 // 0-3 level, 0= unpurgable, 3= purge first
|
||||
|
||||
#define BASEATTRIBUTES 0 // unlocked, non purgable
|
||||
|
||||
unsigned totalmem; // total paragraphs available with 64k EMS
|
||||
int EMSpresent,XMSpresent;
|
||||
|
||||
|
||||
void far *farheap;
|
||||
void *nearheap;
|
||||
|
||||
int numblocks;
|
||||
struct {
|
||||
unsigned start; // in paragraphs
|
||||
unsigned length;
|
||||
unsigned attributes;
|
||||
memptr *useptr;
|
||||
} blocks[MAXBLOCKS],tempblock;
|
||||
|
||||
//==========================================================================
|
||||
|
||||
//
|
||||
// local prototypes
|
||||
//
|
||||
void CheckForEMS (void);
|
||||
int FindBlock (memptr *ptr);
|
||||
void RemoveBlock (int block);
|
||||
void InsertBlock (int block);
|
||||
|
||||
|
||||
//
|
||||
// public prototypes
|
||||
//
|
||||
|
||||
void MMStartup (void);
|
||||
void MMShutdown (void);
|
||||
void MMMapEMS (void);
|
||||
void MMGetPtr (memptr *baseptr,long size);
|
||||
void MMFreePtr (memptr *baseptr);
|
||||
void MMSetPurge (memptr *baseptr, int purge);
|
||||
void MMSortMem (void);
|
||||
void MMBlockDump (void);
|
||||
unsigned MMUnusedMemory (void);
|
||||
unsigned MMTotalFree (void);
|
||||
|
||||
//==========================================================================
|
||||
|
||||
|
||||
//
|
||||
// CheckForEMS
|
||||
//
|
||||
// Routine from p36 of Extending DOS
|
||||
//
|
||||
void CheckForEMS (void)
|
||||
{
|
||||
char emmname[9] = "EMMXXXX0";
|
||||
|
||||
asm mov dx,OFFSET emmname
|
||||
asm mov ax,0x3d00
|
||||
asm int 0x21 // try to open EMMXXXX0 device
|
||||
asm jc error
|
||||
|
||||
asm mov bx,ax
|
||||
asm mov ax,0x4400
|
||||
|
||||
asm int 0x21 // get device info
|
||||
asm jc error
|
||||
|
||||
asm and dx,0x80
|
||||
asm jz error
|
||||
|
||||
asm mov ax,0x4407
|
||||
|
||||
asm int 0x21 // get status
|
||||
asm jc error
|
||||
asm or al,al
|
||||
asm jz error
|
||||
|
||||
asm mov ah,0x3e
|
||||
asm int 0x21 // close handle
|
||||
asm jc error
|
||||
|
||||
//
|
||||
// EMS is good
|
||||
//
|
||||
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
//
|
||||
// EMS is bad
|
||||
//
|
||||
EMSpresent = 0;
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
|
||||
//
|
||||
// FindBlock
|
||||
//
|
||||
int FindBlock (memptr *ptr)
|
||||
{
|
||||
int i;
|
||||
for (i=1;i<numblocks;i++)
|
||||
if (blocks[i].useptr == ptr)
|
||||
return i;
|
||||
|
||||
Quit ("Memory manager error: Block not found!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// RemoveBlock
|
||||
// 0 the pointer, close the block array down, and decrement numblocks
|
||||
//
|
||||
void RemoveBlock (int block)
|
||||
{
|
||||
void far *source, far *dest;
|
||||
unsigned length;
|
||||
|
||||
*blocks[block].useptr = NULL;
|
||||
if (block!=numblocks-1)
|
||||
{
|
||||
source = &blocks[block+1];
|
||||
dest = &blocks[block];
|
||||
length = (numblocks-1-block)*sizeof(blocks[0]);
|
||||
movedata (FP_SEG(source),FP_OFF(source),FP_SEG(dest),FP_OFF(dest),length);
|
||||
}
|
||||
numblocks--;
|
||||
}
|
||||
|
||||
//
|
||||
// InsertBlock
|
||||
// Inserts space in the block array AFTER parameter and increments numblocks
|
||||
//
|
||||
void InsertBlock (int block)
|
||||
{
|
||||
unsigned source,dest,length;
|
||||
|
||||
if (block!=numblocks-1)
|
||||
{
|
||||
source = ((unsigned)&blocks[numblocks])-2;
|
||||
dest = ((unsigned)&blocks[numblocks+1])-2;
|
||||
length = (numblocks-1-block)*sizeof(blocks[0])/2;
|
||||
asm mov cx,length
|
||||
asm mov si,source
|
||||
asm mov di,dest
|
||||
asm mov ax,ds
|
||||
asm mov es,ax
|
||||
asm std
|
||||
asm rep movsw
|
||||
asm cld
|
||||
}
|
||||
if (++numblocks>=MAXBLOCKS)
|
||||
Quit ("Memory manager error: Too many blocks!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// check numblocks<MAXBLOCKS
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= MMStartup
|
||||
=
|
||||
= Initializes the memory manager and returns the total
|
||||
= allocatable free space.
|
||||
=
|
||||
= Grabs all space from turbo with farmalloc
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
void MMStartup (void)
|
||||
{
|
||||
unsigned long length;
|
||||
void far *start;
|
||||
unsigned nearstart,farstart,EMSstart,seg;
|
||||
unsigned nearlength,farlength,emslength,xmslength;
|
||||
|
||||
//
|
||||
// get all available near conventional memory
|
||||
//
|
||||
length=coreleft();
|
||||
start = (void far *)(nearheap = malloc(length));
|
||||
|
||||
//
|
||||
// paragraph align it and figure size
|
||||
//
|
||||
length -= 16-(FP_OFF(start)&15);
|
||||
length -= EXTRASTACKSIZE;
|
||||
nearlength = length / 16; // now in paragraphs
|
||||
nearstart = FP_SEG(start)+(FP_OFF(start)+15)/16;
|
||||
|
||||
//
|
||||
// get all available far conventional memory
|
||||
//
|
||||
length=farcoreleft();
|
||||
start = farheap = farmalloc(length);
|
||||
|
||||
//
|
||||
// paragraph align it and figure size
|
||||
//
|
||||
if (FP_OFF(start))
|
||||
{
|
||||
length -= 16-FP_OFF(start);
|
||||
start = (void far *)MK_FP(FP_SEG(start)+1,0);
|
||||
}
|
||||
farlength = length / 16; // now in paragraphs
|
||||
farstart = FP_SEG(start);
|
||||
|
||||
totalmem = nearlength + farlength;
|
||||
|
||||
//
|
||||
// detect EMS and allocate 64K at page frame
|
||||
//
|
||||
CheckForEMS();
|
||||
if (EMSpresent)
|
||||
{
|
||||
EMSstart = 0xffff;
|
||||
totalmem += 0x1000; // 64k of EMS
|
||||
MMMapEMS(); // map in used pages
|
||||
}
|
||||
else
|
||||
{
|
||||
EMSstart = 0xffff;
|
||||
}
|
||||
|
||||
//
|
||||
// set up locked blocks
|
||||
//
|
||||
numblocks = 0;
|
||||
|
||||
blocks[numblocks].start = 0;
|
||||
blocks[numblocks].length = nearstart;
|
||||
blocks[numblocks].attributes = LOCKBIT;
|
||||
|
||||
numblocks++;
|
||||
|
||||
blocks[numblocks].start = nearstart+nearlength;
|
||||
blocks[numblocks].length = farstart-(nearstart+nearlength);
|
||||
blocks[numblocks].attributes = LOCKBIT;
|
||||
|
||||
numblocks++;
|
||||
|
||||
blocks[numblocks].start = farstart+farlength;
|
||||
blocks[numblocks].length = EMSstart-(farstart+farlength);
|
||||
blocks[numblocks].attributes = LOCKBIT;
|
||||
|
||||
numblocks++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= MMShutdown
|
||||
=
|
||||
= Frees all conventional, EMS, and XMS allocated
|
||||
=
|
||||
====================
|
||||
*/
|
||||
|
||||
void MMShutdown (void)
|
||||
{
|
||||
farfree (farheap);
|
||||
free (nearheap);
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= MMMapEMS
|
||||
=
|
||||
= Maps the 64k of EMS used by memory manager into the page frame
|
||||
= for general use.
|
||||
=
|
||||
====================
|
||||
*/
|
||||
|
||||
void MMMapEMS (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= MMGetPtr
|
||||
=
|
||||
= Allocates an unlocked, unpurgable block
|
||||
= Start looking at the top of memory
|
||||
=
|
||||
====================
|
||||
*/
|
||||
|
||||
|
||||
void MMGetPtr (memptr *baseptr,long size)
|
||||
{
|
||||
int i,j,k,try;
|
||||
unsigned start,end;
|
||||
extern int soundblaster;
|
||||
|
||||
//
|
||||
// change size from bytes to paragraphs
|
||||
//
|
||||
size = (size+15)/16;
|
||||
|
||||
//
|
||||
// try a normal scan, then compress if not found
|
||||
//
|
||||
for (try=0;try<2;try++)
|
||||
{
|
||||
for (i=0;i<numblocks-1;i++)
|
||||
{
|
||||
if (blocks[i].attributes & PURGEBITS )
|
||||
continue;
|
||||
//
|
||||
// blocks[i] cannot be written over, so try to allocate the
|
||||
// new block right after it
|
||||
//
|
||||
start = blocks[i].start + blocks[i].length;
|
||||
end = start + size;
|
||||
j=i+1;
|
||||
while (blocks[j].start < end)
|
||||
{
|
||||
if (!(blocks[j].attributes & PURGEBITS))
|
||||
{
|
||||
i = j-1;
|
||||
goto lookmore; // a non purgable block is in the way
|
||||
}
|
||||
j++;
|
||||
}
|
||||
//
|
||||
// purge the blocks in the way
|
||||
//
|
||||
for (k=i+1;k<j;j--)
|
||||
RemoveBlock(k);
|
||||
//
|
||||
// allocate the new block
|
||||
//
|
||||
InsertBlock(i);
|
||||
*(unsigned *)baseptr = start;
|
||||
blocks[i+1].start = start;
|
||||
blocks[i+1].length = size;
|
||||
blocks[i+1].useptr = baseptr;
|
||||
blocks[i+1].attributes = BASEATTRIBUTES;
|
||||
return;
|
||||
lookmore:;
|
||||
}
|
||||
//
|
||||
// didn't find any space, so compress and try again
|
||||
//
|
||||
if (try==0)
|
||||
MMSortMem();
|
||||
}
|
||||
|
||||
//puts("");
|
||||
//MMBlockDump(); // DEBUG
|
||||
if (soundblaster)
|
||||
Quit ("Out of memory! Unload TSRs or run without Sound Blaster!");
|
||||
else
|
||||
Quit ("Memory manager error: Out of memory!");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
=====================
|
||||
=
|
||||
= MMFreePtr
|
||||
=
|
||||
= Frees up a block and NULL's the pointer
|
||||
=
|
||||
=====================
|
||||
*/
|
||||
|
||||
void MMFreePtr (memptr *baseptr)
|
||||
{
|
||||
RemoveBlock(FindBlock (baseptr));
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
=====================
|
||||
=
|
||||
= MMSetPurge
|
||||
=
|
||||
= Sets the purge level for a block
|
||||
=
|
||||
=====================
|
||||
*/
|
||||
|
||||
void MMSetPurge (memptr *baseptr, int purge)
|
||||
{
|
||||
int block;
|
||||
unsigned attr;
|
||||
|
||||
block = FindBlock (baseptr);
|
||||
|
||||
attr = blocks[block].attributes;
|
||||
attr &= 0xffff - PURGEBITS;
|
||||
attr |= purge; // set bits in attributes
|
||||
blocks[block].attributes = attr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
MMSortMem
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
//
|
||||
// MoveParas
|
||||
//
|
||||
void MoveParaBase (unsigned source, unsigned dest, unsigned words)
|
||||
{
|
||||
asm mov cx,words
|
||||
asm xor si,si
|
||||
asm xor di,di
|
||||
asm mov ax,source
|
||||
asm mov bx,dest
|
||||
asm mov ds,source
|
||||
asm mov es,dest
|
||||
asm rep movsw
|
||||
asm mov ax,ss
|
||||
asm mov ds,ax
|
||||
}
|
||||
|
||||
void MoveParaBaseUp (unsigned source, unsigned dest, unsigned words)
|
||||
{
|
||||
asm mov cx,words
|
||||
asm mov si,cx
|
||||
asm dec si
|
||||
asm shl si,1
|
||||
asm mov di,si
|
||||
asm mov ax,source
|
||||
asm mov bx,dest
|
||||
asm mov ds,source
|
||||
asm mov es,dest
|
||||
asm rep movsw
|
||||
asm mov ax,ss
|
||||
asm mov ds,ax
|
||||
}
|
||||
|
||||
|
||||
void MoveParas (unsigned source, unsigned dest, unsigned paragraphs)
|
||||
{
|
||||
if (source>dest)
|
||||
{
|
||||
asm cld
|
||||
while (paragraphs>0xfff)
|
||||
{
|
||||
MoveParaBase (source,dest,0xfff*8);
|
||||
source += 0xfff*8;
|
||||
dest += 0xfff*8;
|
||||
paragraphs -= 0xfff;
|
||||
}
|
||||
MoveParaBase (source,dest,paragraphs*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
asm std
|
||||
source+=paragraphs;
|
||||
dest+=paragraphs;
|
||||
while (paragraphs>0xfff)
|
||||
{
|
||||
source-=0xfff;
|
||||
dest-=0xfff;
|
||||
MoveParaBaseUp (source,dest,0xfff*8);
|
||||
paragraphs -= 0xfff;
|
||||
}
|
||||
source-=paragraphs;
|
||||
dest-=paragraphs;
|
||||
MoveParaBaseUp (source,dest,paragraphs*8);
|
||||
asm cld
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
======================
|
||||
=
|
||||
= MMSortMem
|
||||
=
|
||||
= Sorts all non locked blocks so lower purge levels are lower in memory
|
||||
= and all free space is at the top
|
||||
=
|
||||
======================
|
||||
*/
|
||||
|
||||
int keyblock;
|
||||
|
||||
//
|
||||
// PushUp
|
||||
//
|
||||
// Pushes the block (purgeable) as high in memory as possible
|
||||
// must be BELOW keyblock
|
||||
// If it can't fit above keyblock it will be freed
|
||||
//
|
||||
void PushUp (int move)
|
||||
{
|
||||
unsigned source,dest,size;
|
||||
int i;
|
||||
|
||||
size = blocks[move].length;
|
||||
source = blocks[move].start;
|
||||
|
||||
for (i=numblocks-1;i>keyblock;i--)
|
||||
{
|
||||
//
|
||||
// if the block can fit under this block, move it
|
||||
//
|
||||
dest = blocks[i].start - size;
|
||||
if (blocks[i-1].start+blocks[i-1].length <= dest)
|
||||
{
|
||||
//
|
||||
// make a copy of block 'move' under block 'i'
|
||||
//
|
||||
InsertBlock (i-1);
|
||||
blocks[i] = blocks[move];
|
||||
blocks[i].start = dest;
|
||||
*(blocks[i].useptr) = (void _seg *)dest; // modify the pointer to the new spot
|
||||
MoveParas (source,dest,size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// erase original position
|
||||
//
|
||||
RemoveBlock (move);
|
||||
keyblock--; // because a block below it was removed
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// PushDown
|
||||
//
|
||||
// Push keyblock (unpurgable) as low in memory as possible
|
||||
//
|
||||
void PushDown (void)
|
||||
{
|
||||
unsigned source,dest,size,end,lowblock,checkblock,i;
|
||||
|
||||
size = blocks[keyblock].length;
|
||||
source = blocks[keyblock].start;
|
||||
|
||||
//
|
||||
// find the lowest space it can be moved into
|
||||
//
|
||||
for (lowblock = 0;lowblock<keyblock;lowblock++)
|
||||
if (!(blocks[lowblock].attributes & PURGEBITS) ||
|
||||
blocks[lowblock].attributes & LOCKBIT)
|
||||
{
|
||||
//
|
||||
// found a locked or nonpurgable block below keyblock
|
||||
//
|
||||
// see if there is enough space to move block
|
||||
//
|
||||
dest = blocks[lowblock].start + blocks[lowblock].length;
|
||||
end = dest+size;
|
||||
|
||||
//
|
||||
// see if any of the blocks in the middle can be moved away
|
||||
//
|
||||
checkblock = lowblock+1;
|
||||
while (checkblock < keyblock && blocks[checkblock].start<end)
|
||||
{
|
||||
if (!(blocks[checkblock].attributes & PURGEBITS) )
|
||||
goto nofit; // can't fit between two locked blocks
|
||||
//
|
||||
// push the block up or remove it, in either case dropping
|
||||
// keyblock and changing blocks[checkblock]
|
||||
//
|
||||
PushUp (checkblock);
|
||||
}
|
||||
//
|
||||
// move it!
|
||||
//
|
||||
if (dest != source)
|
||||
{
|
||||
MoveParas (source,dest,size);
|
||||
blocks[keyblock].start = dest;
|
||||
*(blocks[keyblock].useptr) = (void _seg *)dest; // modify the pointer to the new spot
|
||||
if (lowblock<keyblock-1)
|
||||
{
|
||||
//
|
||||
// reorder the block records
|
||||
//
|
||||
tempblock = blocks[keyblock];
|
||||
for (i=keyblock;i>lowblock+1;i--)
|
||||
blocks[i]=blocks[i-1];
|
||||
blocks[lowblock+1] = tempblock;
|
||||
}
|
||||
|
||||
//MMBlockDump(); // DEBUG
|
||||
}
|
||||
return;
|
||||
|
||||
nofit:; // keep looking...
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MMSortMem
|
||||
//
|
||||
|
||||
void MMSortMem (void)
|
||||
{
|
||||
unsigned i,source,dest;
|
||||
|
||||
keyblock = 0;
|
||||
|
||||
do
|
||||
{
|
||||
keyblock++;
|
||||
|
||||
//
|
||||
// non-purgable, unlocked blocks will be pushed low in memory
|
||||
//
|
||||
if ( !(blocks[keyblock].attributes & PURGEBITS) &&
|
||||
!(blocks[keyblock].attributes & LOCKBIT) )
|
||||
PushDown ();
|
||||
|
||||
} while (keyblock<numblocks-1);
|
||||
|
||||
|
||||
for (i=numblocks-2;i>0;i--)
|
||||
{
|
||||
//
|
||||
// push all purgable blocks as high as possible
|
||||
// Currently they are NOT moved around locked blocks!
|
||||
//
|
||||
if ( blocks[i].attributes & PURGEBITS )
|
||||
{
|
||||
source= blocks[i].start;
|
||||
dest= blocks[i+1].start-blocks[i].length;
|
||||
if (source!=dest)
|
||||
{
|
||||
MoveParas (source,dest,blocks[i].length);
|
||||
blocks[i].start = dest;
|
||||
*(blocks[i].useptr) = (void _seg *)dest; // modify the pointer to the new spot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PatchPointers(); // let the main program fix up any
|
||||
// internal references
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
=======================
|
||||
=
|
||||
= MMBlockDump
|
||||
=
|
||||
= Dewbug tool
|
||||
=
|
||||
=======================
|
||||
*/
|
||||
#include <STDIO.H>
|
||||
|
||||
void MMBlockDump (void)
|
||||
{
|
||||
int i;
|
||||
unsigned free;
|
||||
|
||||
fprintf (stdprn,"-------------\n");
|
||||
for (i=0;i<numblocks;i++)
|
||||
{
|
||||
fprintf (stdprn,"Start:%4X\tLength:%4X\tAttr:%4X\tPtr:%p\n"
|
||||
,blocks[i].start,blocks[i].length,blocks[i].attributes,blocks[i].useptr);
|
||||
if (i<numblocks-1)
|
||||
{
|
||||
free = blocks[i+1].start - (blocks[i].start+blocks[i].length);
|
||||
if (free)
|
||||
fprintf (stdprn,"### Free:%X\n",free);
|
||||
}
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
======================
|
||||
=
|
||||
= MMUnusedMemory
|
||||
=
|
||||
= Returns the total free space without purging
|
||||
=
|
||||
======================
|
||||
*/
|
||||
|
||||
unsigned MMUnusedMemory (void)
|
||||
{
|
||||
int i;
|
||||
unsigned free;
|
||||
|
||||
free = 0;
|
||||
|
||||
for (i=0;i<numblocks;i++)
|
||||
{
|
||||
if (i<numblocks-1)
|
||||
free += blocks[i+1].start - (blocks[i].start+blocks[i].length);
|
||||
}
|
||||
|
||||
return free;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
|
||||
/*
|
||||
======================
|
||||
=
|
||||
= MMTotalFree
|
||||
=
|
||||
= Returns the total free space with purging
|
||||
=
|
||||
======================
|
||||
*/
|
||||
|
||||
unsigned MMTotalFree (void)
|
||||
{
|
||||
int i;
|
||||
unsigned free;
|
||||
|
||||
free = 0;
|
||||
|
||||
for (i=0;i<numblocks;i++)
|
||||
{
|
||||
if (blocks[i].attributes & PURGEBITS)
|
||||
free += blocks[i].length;
|
||||
if (i<numblocks-1)
|
||||
free += blocks[i+1].start - (blocks[i].start+blocks[i].length);
|
||||
}
|
||||
|
||||
return free;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
typedef void _seg * memptr;
|
||||
|
||||
extern unsigned totalmem; // total paragraphs available
|
||||
extern int EMSpresent,XMSpresent;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
||||
//
|
||||
// public prototypes
|
||||
//
|
||||
|
||||
void MMStartup (void);
|
||||
void MMShutdown (void);
|
||||
void MMMapEMS (void);
|
||||
void MMGetPtr (memptr *baseptr,long size);
|
||||
void MMFreePtr (memptr *baseptr);
|
||||
void MMSetPurge (memptr *baseptr, int purge);
|
||||
void MMSortMem (void);
|
||||
void MMBlockDump (void);
|
||||
unsigned MMUnusedMemory (void);
|
||||
unsigned MMTotalFree (void);
|
||||
|
||||
|
||||
void PatchPointers (void); // must be present in the main program
|
||||
+660
@@ -0,0 +1,660 @@
|
||||
; Hovertank 3-D Source Code
|
||||
; Copyright (C) 1993-2014 Flat Rock Software
|
||||
;
|
||||
; 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.
|
||||
|
||||
;============================================================================
|
||||
;
|
||||
; DELTA ENGINE CODE
|
||||
;
|
||||
; Call DE_ClearOld to initialize tables
|
||||
;
|
||||
; Repeat:
|
||||
;
|
||||
; Call DE_NewFrame to ready the next frame
|
||||
; Call DE_AddLine to add line segments to the new frame
|
||||
; Call DE_StraightDraw or DE_DeltaDraw to draw the marked lines
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
IDEAL
|
||||
|
||||
MODEL SMALL,C
|
||||
|
||||
;============================================================================
|
||||
;
|
||||
; EGA Graphic routines
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
SC_INDEX = 03C4h
|
||||
SC_RESET = 0
|
||||
SC_CLOCK = 1
|
||||
SC_MAPMASK = 2
|
||||
SC_CHARMAP = 3
|
||||
SC_MEMMODE = 4
|
||||
|
||||
CRTC_INDEX = 03D4h
|
||||
CRTC_H_TOTAL = 0
|
||||
CRTC_H_DISPEND = 1
|
||||
CRTC_H_BLANK = 2
|
||||
CRTC_H_ENDBLANK = 3
|
||||
CRTC_H_RETRACE = 4
|
||||
CRTC_H_ENDRETRACE = 5
|
||||
CRTC_V_TOTAL = 6
|
||||
CRTC_OVERFLOW = 7
|
||||
CRTC_ROWSCAN = 8
|
||||
CRTC_MAXSCANLINE = 9
|
||||
CRTC_CURSORSTART = 10
|
||||
CRTC_CURSOREND = 11
|
||||
CRTC_STARTHIGH = 12
|
||||
CRTC_STARTLOW = 13
|
||||
CRTC_CURSORHIGH = 14
|
||||
CRTC_CURSORLOW = 15
|
||||
CRTC_V_RETRACE = 16
|
||||
CRTC_V_ENDRETRACE = 17
|
||||
CRTC_V_DISPEND = 18
|
||||
CRTC_OFFSET = 19
|
||||
CRTC_UNDERLINE = 20
|
||||
CRTC_V_BLANK = 21
|
||||
CRTC_V_ENDBLANK = 22
|
||||
CRTC_MODE = 23
|
||||
CRTC_LINECOMPARE = 24
|
||||
|
||||
|
||||
GC_INDEX = 03CEh
|
||||
GC_SETRESET = 0
|
||||
GC_ENABLESETRESET = 1
|
||||
GC_COLORCOMPARE = 2
|
||||
GC_DATAROTATE = 3
|
||||
GC_READMAP = 4
|
||||
GC_MODE = 5
|
||||
GC_MISCELLANEOUS = 6
|
||||
GC_COLORDONTCARE = 7
|
||||
GC_BITMASK = 8
|
||||
|
||||
ATR_INDEX = 03c0h
|
||||
ATR_MODE = 16
|
||||
ATR_OVERSCAN = 17
|
||||
ATR_COLORPLANEENABLE = 18
|
||||
ATR_PELPAN = 19
|
||||
ATR_COLORSELECT = 20
|
||||
|
||||
;==================
|
||||
;
|
||||
; View area equates
|
||||
;
|
||||
;==================
|
||||
|
||||
VIEWX = (4*8)
|
||||
VIEWY = (4*8)
|
||||
VIEWWIDTH = (32*8)
|
||||
VIEWHEIGHT = (12*8)
|
||||
VIEWXH = (VIEWX+VIEWWIDTH-1)
|
||||
VIEWYH = (VIEWY+VIEWHEIGHT-1)
|
||||
|
||||
|
||||
;=======================
|
||||
;
|
||||
; The delta tables hold linked line segments to be drawn
|
||||
;
|
||||
;=======================
|
||||
|
||||
FARDATA
|
||||
|
||||
MAXSEGS = 2000
|
||||
|
||||
SG_START = 0
|
||||
SG_END = 2
|
||||
SG_COLOR = 4
|
||||
SG_NEXT = 6
|
||||
|
||||
SEGSIZE = 8
|
||||
|
||||
deltatable1 db SEGSIZE*MAXSEGS dup (?)
|
||||
deltatable2 db SEGSIZE*MAXSEGS dup (?)
|
||||
deltatable3 db SEGSIZE*MAXSEGS dup (?)
|
||||
|
||||
startline dw 0,VIEWX-1,99,redrawline
|
||||
endline dw VIEWXH+1,9999,99,0
|
||||
blankline dw VIEWX,VIEWXH,0,endline
|
||||
redrawline dw VIEWX,VIEWXH,-1,endline
|
||||
|
||||
;==========================
|
||||
;
|
||||
; dataseg
|
||||
;
|
||||
;==========================
|
||||
|
||||
DATASEG
|
||||
|
||||
freesegment dw ? ; pointer to next free spot in deltatable?
|
||||
freestarttable dw deltatable1,deltatable2,deltatable3
|
||||
|
||||
linestart1 dw VIEWHEIGHT dup(?)
|
||||
linestart2 dw VIEWHEIGHT dup(?)
|
||||
linestart3 dw VIEWHEIGHT dup(?)
|
||||
linestartptr dw ? ; pointer to linestart[tableon]
|
||||
linestarttable dw linestart1,linestart2,linestart3
|
||||
|
||||
tableon dw ?
|
||||
|
||||
PUBLIC tableon,linestart1,linestart2,linestart3,linestartptr,freesegment
|
||||
|
||||
;
|
||||
; parameters for AddLine
|
||||
;
|
||||
al_xl dw ?
|
||||
al_xh dw ?
|
||||
al_y dw ?
|
||||
al_color dw ?
|
||||
|
||||
PUBLIC al_xl,al_xh,al_y,al_color
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
;====================
|
||||
;
|
||||
; DE_AddLine
|
||||
;
|
||||
; Adds a new segment to the current line list
|
||||
; Takes globall variables al_??? as parameters
|
||||
;
|
||||
; AX = scratch
|
||||
; BX = previous segment ptr
|
||||
; CX = al_xl
|
||||
; DX = al_xh
|
||||
; SI = start segment ptr
|
||||
; DI = new segment ptr
|
||||
; BP = end segment ptr
|
||||
;
|
||||
;====================
|
||||
|
||||
PROC DE_AddLine
|
||||
PUBLIC DE_AddLine
|
||||
USES si,di,bp
|
||||
|
||||
mov ax,@FARDATA
|
||||
mov es,ax ; es points to tables
|
||||
|
||||
mov cx,[al_xl]
|
||||
mov dx,[al_xh]
|
||||
;
|
||||
; find the first segment on line al_y that contains the new line
|
||||
;
|
||||
mov bx,[al_y]
|
||||
sub bx,VIEWY
|
||||
shl bx,1
|
||||
add bx,[linestartptr]
|
||||
mov bx,[bx] ; bx = prev segment
|
||||
mov si,[es:bx+SG_NEXT] ; si = start pointer
|
||||
@@findfirst:
|
||||
cmp cx,[es:si+SG_END]
|
||||
jle @@gotfirst
|
||||
mov bx,si ; pre = start
|
||||
mov si,[es:si+SG_NEXT] ; start = start->next
|
||||
jmp @@findfirst
|
||||
|
||||
@@gotfirst:
|
||||
mov di,[freesegment] ; new = freesegment++
|
||||
add [freesegment],SEGSIZE
|
||||
mov [es:di+SG_START],cx ; new->start = xl
|
||||
mov [es:di+SG_END],dx ; new->end = xh
|
||||
mov ax,[al_color]
|
||||
mov [es:di+SG_COLOR],ax ; new->color = color
|
||||
|
||||
cmp [es:si+SG_END],dx
|
||||
jge @@isge
|
||||
jmp @@notge
|
||||
;
|
||||
; the entire new segment fits inside start seg
|
||||
; start->end >= xh
|
||||
;
|
||||
@@isge:
|
||||
cmp [es:si+SG_COLOR],ax ; ax still holds [al_color]
|
||||
jne @@different
|
||||
ret ; same color as old line, do nothing
|
||||
@@different:
|
||||
cmp [es:si+SG_START],cx ; if (start->start == xl)
|
||||
jne @@notstarteq ; cover first part of old segment
|
||||
mov [es:bx+SG_NEXT],di ; pre->next = new
|
||||
cmp [es:si+SG_END],dx
|
||||
jne @@notexact ; cover it exactly?
|
||||
mov ax,[es:si+SG_NEXT]
|
||||
mov [es:di+SG_NEXT],ax ; new->next = start->next
|
||||
ret
|
||||
@@notexact:
|
||||
mov [es:di+SG_NEXT],si ; new->next = start
|
||||
mov ax,dx
|
||||
inc ax
|
||||
mov [es:si+SG_START],ax ; start->start = xh+1
|
||||
ret
|
||||
|
||||
@@notstarteq:
|
||||
cmp [es:si+SG_END],dx ; if (start->end == xh)
|
||||
jne @@notendeq ; cover last part of old segment
|
||||
mov ax,[es:si+SG_NEXT]
|
||||
mov [es:di+SG_NEXT],ax ; new->next = start->next
|
||||
mov [es:si+SG_NEXT],di ; start->next = new
|
||||
mov ax,cx
|
||||
dec ax
|
||||
mov [es:si+SG_END],ax ; start->end = xl-1
|
||||
ret
|
||||
@@notendeq:
|
||||
mov bp,[freesegment] ; cover the middle of old segment
|
||||
add [freesegment],SEGSIZE ; end = freesegment++
|
||||
mov ax,dx
|
||||
inc ax
|
||||
mov [es:bp+SG_START],ax ; end->start = xh+1
|
||||
mov ax,[es:si+SG_END]
|
||||
mov [es:bp+SG_END],ax ; end->end = start->end
|
||||
mov ax,[es:si+SG_NEXT]
|
||||
mov [es:bp+SG_NEXT],ax ; end->next = start->next
|
||||
mov ax,[es:si+SG_COLOR]
|
||||
mov [es:bp+SG_COLOR],ax ; end->color = start->color
|
||||
mov ax,cx
|
||||
dec ax
|
||||
mov [es:si+SG_END],ax ; start->end = xl-1
|
||||
mov [es:si+SG_NEXT],di ; start->next = new
|
||||
mov [es:di+SG_NEXT],bp ; new->next = end
|
||||
ret
|
||||
;
|
||||
;
|
||||
; partially cover start seg, and scan ahead to cover more
|
||||
;
|
||||
@@notge:
|
||||
mov bp,[es:si+SG_NEXT] ; end = start->next
|
||||
@@findend:
|
||||
cmp [es:bp+SG_END],dx ; while (end->end <= xh_
|
||||
jg @@endfound
|
||||
mov bp,[es:bp+SG_NEXT] ; end = end->next
|
||||
jmp @@findend
|
||||
@@endfound:
|
||||
cmp [es:bp+SG_END],dx
|
||||
je @@mergeend
|
||||
mov ax,[es:al_color]
|
||||
cmp [es:bp+SG_COLOR],ax
|
||||
jne @@splitend
|
||||
@@mergeend: ; if (end->end == xh || end->color == color)
|
||||
mov ax,[es:bp+SG_NEXT]
|
||||
mov [es:di+SG_NEXT],ax ; new->next = end->next
|
||||
jmp @@enddone
|
||||
@@splitend: ; else
|
||||
mov ax,dx
|
||||
inc ax
|
||||
mov [es:bp+SG_START],ax ; end->start = xh+1
|
||||
mov [es:di+SG_NEXT],bp ; new->next = end
|
||||
@@enddone:
|
||||
cmp [es:si+SG_START],cx
|
||||
je @@mergestart
|
||||
mov ax,[al_color]
|
||||
cmp [es:si+SG_COLOR],ax
|
||||
jne @@splitstart
|
||||
@@mergestart:
|
||||
mov [es:bx+SG_NEXT],si ; pre->next = new
|
||||
ret
|
||||
@@splitstart:
|
||||
mov ax,cx
|
||||
dec ax
|
||||
mov [es:si+SG_END],ax ; start->end = xl-1
|
||||
mov [es:si+SG_NEXT],di ; start->next = new
|
||||
ret
|
||||
ENDP
|
||||
|
||||
|
||||
;=====================
|
||||
;
|
||||
; DE_StraightDraw
|
||||
;
|
||||
; Draws ALL line segments in current frame, with no delta work
|
||||
;
|
||||
;=====================
|
||||
|
||||
DATASEG
|
||||
|
||||
yline dw ?
|
||||
startptr dw ?
|
||||
oldstartptr dw ?
|
||||
newseg dw ?
|
||||
|
||||
CODESEG
|
||||
|
||||
EXTRN DrawLine:PROC
|
||||
|
||||
|
||||
PROC DE_StraightDraw
|
||||
PUBLIC DE_StraightDraw
|
||||
USES SI,DI
|
||||
|
||||
mov dx,GC_INDEX
|
||||
mov ax,GC_MODE + 2*256
|
||||
out dx,ax ; set EGA write mode 2
|
||||
|
||||
mov ax,@FARDATA
|
||||
mov es,ax ; es points to tables
|
||||
|
||||
mov ax,[linestartptr]
|
||||
mov [startptr],ax
|
||||
mov [yline],VIEWY ; for (y=VIEWY;y<=VIEWYH;y++)
|
||||
|
||||
@@lineloop:
|
||||
mov bx,[startptr] ; pointer to first seg on line
|
||||
add [startptr],2 ; point to next line
|
||||
mov bx,[bx] ; point to first pointer
|
||||
mov bx,[es:bx+SG_NEXT] ; first pointer is just junk
|
||||
@@segmentloop:
|
||||
push es
|
||||
push bx ; save it off
|
||||
|
||||
push [es:bx+SG_COLOR]
|
||||
push [yline]
|
||||
push [es:bx+SG_END]
|
||||
push [es:bx+SG_START]
|
||||
call DrawLine ; DrawLine(start,end,y,color)
|
||||
add sp,8
|
||||
|
||||
pop bx ; restore segment pointer
|
||||
pop es
|
||||
|
||||
mov bx,[es:bx+SG_NEXT] ; next pointer
|
||||
cmp [WORD es:bx+SG_START],VIEWXH
|
||||
jle @@segmentloop ; while (seg->start <= VIEWXH)
|
||||
|
||||
inc [yline]
|
||||
cmp [yline],VIEWYH
|
||||
jle @@lineloop
|
||||
|
||||
mov dx,GC_INDEX
|
||||
mov ax,GC_BITMASK+255*256
|
||||
out dx,ax ; no pixel mask
|
||||
|
||||
mov dx,GC_INDEX
|
||||
mov ax,GC_MODE + 2*256
|
||||
out dx,ax ; set EGA write mode 0
|
||||
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
|
||||
;=====================
|
||||
;
|
||||
; DE_DeltaDraw
|
||||
;
|
||||
; Draws only the pieces of the line segments needed to change old frame
|
||||
;
|
||||
; AX : scratch
|
||||
; BX : scratch / line color
|
||||
; CX : start
|
||||
; DX : end
|
||||
; SI : current table
|
||||
; DI : old table
|
||||
; BP : x
|
||||
;
|
||||
;=====================
|
||||
|
||||
PROC DE_DeltaDraw
|
||||
PUBLIC DE_DeltaDraw
|
||||
USES SI,DI,BP
|
||||
|
||||
mov dx,GC_INDEX
|
||||
mov ax,GC_MODE + 2*256
|
||||
out dx,ax ; set EGA write mode 2
|
||||
|
||||
mov ax,@FARDATA
|
||||
mov es,ax ; es points to tables
|
||||
|
||||
mov si,[tableon] ; figure out old table
|
||||
inc si
|
||||
cmp si,3
|
||||
jl @@gottable
|
||||
xor si,si
|
||||
@@gottable:
|
||||
shl si,1
|
||||
mov ax,[linestarttable+si]
|
||||
mov [oldstartptr],ax
|
||||
mov ax,[linestartptr]
|
||||
mov [startptr],ax
|
||||
|
||||
mov [yline],VIEWY ; for (y=VIEWY;y<=VIEWYH;y++)
|
||||
|
||||
;
|
||||
; delta draw one line
|
||||
;
|
||||
@@lineloop:
|
||||
mov bx,[startptr]
|
||||
mov si,[bx] ; pointer to first pointer now
|
||||
add bx,2
|
||||
mov [startptr],bx
|
||||
mov si,[es:si+SG_NEXT] ; first pointer is just junk
|
||||
mov bx,[oldstartptr]
|
||||
mov di,[bx] ; pointer to first pointer then
|
||||
add bx,2
|
||||
mov [oldstartptr],bx
|
||||
mov di,[es:di+SG_NEXT] ; first pointer is just junk
|
||||
|
||||
mov bp,VIEWX ; x = VIEWX
|
||||
|
||||
@@segmentloop:
|
||||
mov ax,[es:si+SG_COLOR]
|
||||
cmp ax,[es:di+SG_COLOR]
|
||||
je @@skipsome ; common line color?
|
||||
;
|
||||
; draw over some old segments
|
||||
;
|
||||
mov bx,[es:si+SG_COLOR]
|
||||
mov cx,bp ; start = x
|
||||
@@checkseg:
|
||||
mov ax,[es:si+SG_END]
|
||||
cmp ax,[es:di+SG_END] ; both end at same place?
|
||||
jne @@notsameend
|
||||
mov dx,ax ; end = newseg->end
|
||||
mov si,[es:si+SG_NEXT]
|
||||
mov di,[es:di+SG_NEXT] ; bump both new and old
|
||||
mov bp,[es:si+SG_START] ; x = newseg->start
|
||||
jmp @@drawseg
|
||||
|
||||
@@notsameend:
|
||||
jg @@newgreater ; new end before old?
|
||||
mov dx,ax ; end = newseg->end
|
||||
mov si,[es:si+SG_NEXT] ; bump si
|
||||
mov bp,[es:si+SG_START] ; x = newseg->start
|
||||
jmp @@drawseg
|
||||
|
||||
@@newgreater:
|
||||
mov dx,[es:di+SG_END] ; end = oldseg->end
|
||||
mov di,[es:di+SG_NEXT] ; bump old
|
||||
mov bp,[es:di+SG_START] ; x = oldseg->start
|
||||
cmp bp,VIEWXH
|
||||
jg @@drawseg ; if at end of line, draw, else
|
||||
mov ax,[es:si+SG_COLOR] ; if next old is still different
|
||||
cmp ax,[es:di+SG_COLOR] ; color, keep extending segment
|
||||
jne @@checkseg
|
||||
;
|
||||
; Draw a line segment
|
||||
;
|
||||
@@drawseg:
|
||||
push es ; drawline will save and restore SI/DI
|
||||
|
||||
push bx
|
||||
push [yline]
|
||||
push dx
|
||||
push cx
|
||||
call DrawLine ; DrawLine(start,end,y,color)
|
||||
add sp,8
|
||||
|
||||
pop es
|
||||
|
||||
jmp @@while
|
||||
|
||||
;
|
||||
; new line is same color as old,
|
||||
; so skip some drawing
|
||||
;
|
||||
@@skipsome:
|
||||
mov ax,[es:si+SG_END]
|
||||
cmp ax,[es:di+SG_END] ; both end at same place?
|
||||
jne @@notsameendsk
|
||||
mov si,[es:si+SG_NEXT]
|
||||
mov di,[es:di+SG_NEXT] ; bump both new and old
|
||||
mov bp,[es:si+SG_START] ; x = newseg->start
|
||||
jmp @@while
|
||||
|
||||
@@notsameendsk:
|
||||
jg @@newgreatersk ; new end before old?
|
||||
mov si,[es:si+SG_NEXT] ; bump si
|
||||
mov bp,[es:si+SG_START] ; x = newseg->start
|
||||
jmp @@while
|
||||
|
||||
@@newgreatersk:
|
||||
mov di,[es:di+SG_NEXT] ; bump old
|
||||
mov bp,[es:di+SG_START] ; x = oldseg->start
|
||||
|
||||
;
|
||||
; is line done ?
|
||||
;
|
||||
@@while:
|
||||
cmp bp,VIEWXH
|
||||
jg @@segdone
|
||||
jmp @@segmentloop
|
||||
@@segdone:
|
||||
|
||||
inc [yline]
|
||||
cmp [yline],VIEWYH
|
||||
jg @@done
|
||||
jmp @@lineloop
|
||||
|
||||
@@done:
|
||||
;
|
||||
; all lines are done
|
||||
;
|
||||
mov dx,GC_INDEX
|
||||
mov ax,GC_BITMASK+255*256
|
||||
out dx,ax ; no pixel mask
|
||||
|
||||
mov dx,GC_INDEX
|
||||
mov ax,GC_MODE + 2*256
|
||||
out dx,ax ; set EGA write mode 0
|
||||
|
||||
ret
|
||||
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
;=====================
|
||||
;
|
||||
; DE_ClearOld
|
||||
;
|
||||
; Resets all frame segments so next two frames are completely drawn
|
||||
;
|
||||
; SI = table number clearing * 2
|
||||
; DI = linestart pointer
|
||||
;
|
||||
;=====================
|
||||
|
||||
PROC DE_ClearOld
|
||||
PUBLIC DE_ClearOld
|
||||
USES SI,DI
|
||||
|
||||
mov ax,ds
|
||||
mov es,ax
|
||||
|
||||
xor si,si
|
||||
@@tableloop:
|
||||
mov di,[linestarttable + si] ; di points to start of pointer table
|
||||
|
||||
mov ax,OFFSET startline
|
||||
mov cx,VIEWHEIGHT ; for (y=0;y<VIEWHEIGHT;y++)
|
||||
rep stosw ; linestart[tableon][y] = redraw
|
||||
|
||||
inc si
|
||||
inc si
|
||||
cmp si,6
|
||||
jl @@tableloop
|
||||
|
||||
mov [tableon],0 ; next frame will start on table 1
|
||||
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
;=====================
|
||||
;
|
||||
; DE_NewFrame
|
||||
;
|
||||
; Bumps tableon and set up default values for new frame
|
||||
;
|
||||
; di = freesegment pointer
|
||||
; bx = linestart pointer
|
||||
;
|
||||
;=====================
|
||||
|
||||
DATASEG
|
||||
|
||||
stubline dw 0,VIEWX-1,99,0, VIEWX,VIEWXH,0,endline
|
||||
|
||||
CODESEG
|
||||
|
||||
PROC DE_NewFrame
|
||||
PUBLIC DE_NewFrame
|
||||
USES si,di
|
||||
|
||||
mov ax,@FARDATA
|
||||
mov es,ax ; es points to tables
|
||||
|
||||
mov si,[tableon]
|
||||
inc si
|
||||
cmp si,3
|
||||
jl @@gottable
|
||||
xor si,si
|
||||
@@gottable:
|
||||
mov [tableon],si
|
||||
shl si,1
|
||||
mov di,[freestarttable+si] ; di = pointer to free segments
|
||||
mov bx,[linestarttable+si] ; bx = pointer to line start list
|
||||
mov [linestartptr],bx
|
||||
|
||||
mov dx,VIEWHEIGHT ; for (y=viewheight;y>0;y--)
|
||||
@@yloop:
|
||||
;
|
||||
; copy two segments to each line
|
||||
;
|
||||
mov [bx],di
|
||||
inc bx
|
||||
inc bx ; linestartptr++ = new
|
||||
mov si,OFFSET stubline
|
||||
mov ax,di
|
||||
add ax,SEGSIZE
|
||||
mov [si+SG_NEXT],ax ; patch pointer
|
||||
mov cx,(SEGSIZE*2)/2
|
||||
rep movsw ; copy two new segments
|
||||
|
||||
dec dx
|
||||
jnz @@yloop
|
||||
|
||||
mov [freesegment],di
|
||||
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Hovertank 3-D
|
||||
=============
|
||||
|
||||
This repository contains the source code for Hovertank 3-D. The source code is
|
||||
designed for Borland C++ 2.0, but compiled fine with Borland C++ 3.1 at the
|
||||
time of this release.
|
||||
|
||||
It is released under the GNU GPLv2. Please see COPYING for license details.
|
||||
|
||||
This release does not affect the game data files. You will need to legally
|
||||
acquire the game data in order to use the exe built from this source code.
|
||||
@@ -0,0 +1,42 @@
|
||||
/* Hovertank 3-D Source Code
|
||||
* Copyright (C) 1993-2014 Flat Rock Software
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// From Sound Editor v1.31 by Lane Roath
|
||||
//
|
||||
|
||||
#define FIRESND 1
|
||||
#define BUMPWALLSND 2
|
||||
#define AFTERBURNSND 3
|
||||
#define SHOOTWALLSND 4
|
||||
#define SHOOTTHINGSND 5
|
||||
#define SAVEHOSTAGESND 6
|
||||
#define HOSTAGEDEADSND 7
|
||||
#define LOWTIMESND 8
|
||||
#define TAKEDAMAGESND 9
|
||||
#define NUKESND 10
|
||||
#define WARPGATESND 11
|
||||
#define PLAYERDEADSND 12
|
||||
#define GUNREADYSND 13
|
||||
#define MAXPOWERSND 14
|
||||
#define LASTHOSTAGESND 15
|
||||
#define ARMORUPSND 16
|
||||
#define TIMESCORESND 17
|
||||
#define GUYSCORESND 18
|
||||
#define STARTGAMESND 19
|
||||
#define HIGHSCORESND 20
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user