first commit

This commit is contained in:
2026-07-14 19:31:07 +02:00
commit fb01ea5ba8
30 changed files with 28540 additions and 0 deletions
+339
View File
@@ -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
View File
@@ -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
View File
@@ -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!
//
+1368
View File
File diff suppressed because it is too large Load Diff
+1550
View File
File diff suppressed because it is too large Load Diff
+1156
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+271
View File
@@ -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);
+1085
View File
File diff suppressed because it is too large Load Diff
+1408
View File
File diff suppressed because it is too large Load Diff
+530
View File
@@ -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;
}
+196
View File
@@ -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
View File
@@ -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();
}
}
//===========================================================================
+1378
View File
File diff suppressed because it is too large Load Diff
+1653
View File
File diff suppressed because it is too large Load Diff
+494
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+2288
View File
File diff suppressed because it is too large Load Diff
+34
View File
@@ -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
+1176
View File
File diff suppressed because it is too large Load Diff
+317
View File
@@ -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;
}
+57
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+794
View File
@@ -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;
}
//==========================================================================
+43
View File
@@ -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
View File
@@ -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
+11
View File
@@ -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.
+42
View File
@@ -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
View File
Binary file not shown.