mirror of
https://github.com/deater/tb1.git
synced 2024-05-31 22:41:30 +00:00
Import of version 2.9.0
This commit is contained in:
parent
6d72b8cbfd
commit
e1c4761d2d
5
BUGS
Normal file
5
BUGS
Normal file
|
@ -0,0 +1,5 @@
|
|||
Known Bugs:
|
||||
% svgalib needs -force8bpp option
|
||||
% weird colors at times in 8bpp X mode
|
||||
% Enlightenment window manager screws up 8bpp colors
|
||||
% game is not finished
|
44
CHANGES
Normal file
44
CHANGES
Normal file
|
@ -0,0 +1,44 @@
|
|||
7 March 1998
|
||||
* Added Level 2, mostly working
|
||||
|
||||
6 March 1998
|
||||
* Added load game support
|
||||
|
||||
5 March 1998
|
||||
* Fixed typo in credits [Yes I had "linux torvalds" by mistake]. Thanks
|
||||
to my friend John C. for catching that one.
|
||||
* Added save game support.
|
||||
|
||||
3 March 1998
|
||||
* Really cleaned up level1.c Mostly cleaned
|
||||
* Modularized and actually re-wrote some code, instead of translating it.
|
||||
* Lots of really minor tweaks trying to up performance.
|
||||
|
||||
1 March 1998
|
||||
* Got little opener slowed down
|
||||
* Got credits working
|
||||
* Got pause to work
|
||||
* Got sidebar reporting hiscore.
|
||||
|
||||
29 February 1998
|
||||
* OK, there was no 29th. But I did more work later and it felt
|
||||
like a new day.
|
||||
* Cleaned up the tb1.c majorly
|
||||
* Added support for having the data files searched for in many directories.
|
||||
* Cleaned out the directory structure and removed cruft.
|
||||
* Got sound support working!
|
||||
* added -force8bpp option so SVGA target works
|
||||
* Other miscelaneous things
|
||||
|
||||
28 February 1998
|
||||
* AWESOME!! WORKING BETTER THAN IT WAS BEFORE!
|
||||
* Moved over to fast DirectBuffer Calls. FAST!
|
||||
* Got gameplay working, GETTING SCROLLING STARS
|
||||
* added vmwCrossBlit functions. FAST! Thanks to andy at the ggi-list
|
||||
* Fixed lots of minor bugs
|
||||
|
||||
27 February 1998
|
||||
* Started this file
|
||||
* Today converted from 320x600 virtual to 3 320x200s [2 are in memory]
|
||||
* Added support so it can (almost) run in both 8bpp and 16bpp mode.
|
||||
* Broke a lot more than I fixed.
|
28
COMPILING
Normal file
28
COMPILING
Normal file
|
@ -0,0 +1,28 @@
|
|||
First you have to get the ggi graphics library.
|
||||
* for newest updates/info check out http://www.ggi-project.org
|
||||
* Get a new snapshot from ftp://synergy.caltech.edu/pub/ggi/ggi-snapshots
|
||||
* Get a newer one --> I developed it with ggi-980226.tar.gz
|
||||
* save it
|
||||
* uncompress it "tar -xzvf ggi-980226.tar.gz"
|
||||
* "cd ggi" "cd lib" "cd libggi" "make"
|
||||
* this brings up a menu. be sure to choose "xserv","svga" and "mem"
|
||||
you can choose others if you wish, but these are all needed.
|
||||
* exit the menu
|
||||
* "make"
|
||||
* should compile w/o problems [hopefully]
|
||||
* "su" "make install"
|
||||
* link your ~/ggi/include/ggi directory to /usr/local/include/ggi
|
||||
[or however you want to get the files in the right place]
|
||||
* copy the files ~/ggi/lib/libggi/include/ggi/*.h into
|
||||
/usr/local/include/ggi
|
||||
* should be all set up
|
||||
|
||||
Now compile TB1
|
||||
* Uncompress the .tar.gz file
|
||||
* "make"
|
||||
* all should go OK.. you will get errors on some of the sound stuff,
|
||||
but as long as the "tb1" file is created, you are good to go.
|
||||
* It is known to work under 8bpp and 16bpp x-targets. Let me know if
|
||||
it doesn't work under all of them
|
||||
|
||||
Vince Weaver weave@eng.umd.edu http://www.glue.umd.edu/~weave/tb1
|
51
Makefile
Normal file
51
Makefile
Normal file
|
@ -0,0 +1,51 @@
|
|||
##############################################################
|
||||
# Makefile for Seabattle 1.0 -- by Vince Weaver #
|
||||
# #
|
||||
# Written on Linux 2.1.35 #
|
||||
# #
|
||||
# To modify for your configuration, add or remove the # #
|
||||
# #
|
||||
##############################################################
|
||||
|
||||
#Your compiler. If gcc doesn't work, try CC
|
||||
CC = gcc
|
||||
#CC = cc
|
||||
|
||||
#On Linux, uncomment the following
|
||||
#
|
||||
PLATFORM = Linux
|
||||
C_OPTS = -O2 -Wall -DHAVE_LINUX_SOUND
|
||||
L_OPTS = -lggi
|
||||
|
||||
######################################################################
|
||||
# THERE IS NO NEED TO EDIT ANYTHING BELOW THIS LINE #
|
||||
######################################################################
|
||||
|
||||
all: tb1
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f tb1
|
||||
rm -f *~
|
||||
|
||||
tb1: tb1.o svmwgrap.o tblib.o level1.o level2.o soundIt.o
|
||||
$(CC) $(C_OPTS) -o tb1 tb1.o svmwgrap.o tblib.o level1.o level2.o soundIt.o $(L_OPTS)
|
||||
@strip tb1
|
||||
|
||||
soundIt.o: soundIt.c
|
||||
$(CC) $(C_OPTS) -c soundIt.c
|
||||
|
||||
tb1.o: tb1.c
|
||||
$(CC) $(C_OPTS) -c tb1.c
|
||||
|
||||
tblib.o: tblib.c
|
||||
$(CC) $(C_OPTS) -c tblib.c
|
||||
|
||||
level1.o: level1.c
|
||||
$(CC) $(C_OPTS) -c level1.c
|
||||
|
||||
level2.o: level2.c
|
||||
$(CC) $(C_OPTS) -c level2.c
|
||||
|
||||
svmwgrap.o: svmwgrap.c
|
||||
$(CC) $(C_OPTS) -c svmwgrap.c
|
319
README
Normal file
319
README
Normal file
|
@ -0,0 +1,319 @@
|
|||
what follows is the old dos readme... I'll update it one of these days..
|
||||
|
||||
|
||||
°°°°°² °°°°°² °² °² °°°°² °°°°°² °² °² °°°°² °°°°°² °² °²
|
||||
°² °² °² °°²°°² °² °² °² °² °°²°°² °² °² °² °°²°°²
|
||||
°² °² °² °²°²°² °°°°² °² °² °²°²°² °°°°² °°°°² °²°²°²
|
||||
°² °² °² °² °² °² °² °² °² °² °² °² °² °² °² °²
|
||||
°² °°°°°² °² °² °°°°² °°°°°² °² °² °°°°² °°°°°² °² °²
|
||||
AND THE INVASION OF THE INANIMATE OBJECTS
|
||||
|
||||
by
|
||||
|
||||
Vince Weaver
|
||||
|
||||
Version 2.4a
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Contents
|
||||
--------
|
||||
1.0 SYSTEM REQUIREMENTS
|
||||
2.0 STARTING THE GAME
|
||||
3.0 THE STORY
|
||||
4.0 GAME PLAY
|
||||
5.0 SAVING/LOADING GAMES
|
||||
6.0 TROUBLESHOOTING
|
||||
7.0 REGISTERING
|
||||
8.0 ACKNOWLEDGEMENTS
|
||||
9.0 CURRENT BUGS (FEATURES)
|
||||
10.0 PRAISE/ACCOMPLISHMENTS
|
||||
|
||||
|
||||
1.0 SYSTEM REQUIREMENTS
|
||||
---------------------------------------------------------------------
|
||||
Bare Minimum:
|
||||
286/ 400K RAM/ 500K disk space
|
||||
To run at a reasonable speed:
|
||||
386 33Mhz or better
|
||||
For Digitized Sound:
|
||||
XMS RAM, Sound Blaster or Compatible sound card
|
||||
|
||||
(I have been developing this on a 386 33Mhz and it runs
|
||||
passibly. It runs so much smoother on a 486. I'll try
|
||||
to optimize the code some more...)
|
||||
|
||||
|
||||
2.0 STARTING THE GAME
|
||||
---------------------------------------------------------------------
|
||||
Make sure all the files are in the same directory (list below)
|
||||
[if any are missing, you will get a run-time error]
|
||||
|
||||
Run the TBSETUP configuration utility. Pick the appropriate
|
||||
options.
|
||||
|
||||
Type TB1 to run the game. See "TROUBLESHOOTING" if you encounter
|
||||
any errors.
|
||||
|
||||
|
||||
To run Tom Bombem off of a CD-ROM:
|
||||
Either type "tb1 -cdrom" to start the program in read-only
|
||||
mode, or say "y" when prompted if you want read-only mode.
|
||||
In this mode there are no saved games and the high score
|
||||
list will not change.
|
||||
|
||||
Files Needed:
|
||||
TB1.EXE - Main executable
|
||||
TBSETUP.EXE - Setup Program
|
||||
CONFIG.TB1 - Config File Created by Setup Program
|
||||
TBSOUND.EXE - Cool sound tester
|
||||
MOON2.TB1 ¿
|
||||
REGISTER.TB1 ³
|
||||
TBGORG.TB1 ³
|
||||
TBCRASH.TB1 ³
|
||||
TBSOBJ.TB1 ³
|
||||
SHIPS.TB1 Ã Graphics files in PAINTPRO 5.0 format
|
||||
TBOMB1.TB1 ³
|
||||
TBMA1.TB1 ³
|
||||
VIEWSCR.TB1 ³
|
||||
TBSHAPES.TB1 ³
|
||||
TBCOBJ.TB1 ³
|
||||
TBCHIEF.TB1 ³
|
||||
TBASHIP.TB1 ³
|
||||
TBL2SHIP.TB1 ³
|
||||
TBLEV3.TB1 ³
|
||||
TBL3INTR.TB1 ³
|
||||
TBEERM.TB1 ³
|
||||
TBCONSOL.TB1 ³
|
||||
TBPIT.TB1 ³
|
||||
TBASH.TB1 ³
|
||||
TBCOBJ.TB1 ³
|
||||
TBTRACT.TB1 Ù
|
||||
LEVEL2.TB1 - Level Two Database
|
||||
LEVEL4.TB1 - Level Four Database
|
||||
FILE_ID.DIZ - Info file for BBS's
|
||||
TBFONT.TB1 - Fonts for the game (a standard VGA font)
|
||||
HISCORE.TB1 - The High Score List
|
||||
TB1.DOC - The file you're reading
|
||||
SOUNDS.TB1 - Sound effects
|
||||
SGx.TB1 - Where x is a number... these are saved games
|
||||
|
||||
|
||||
3.0 THE STORY
|
||||
---------------------------------------------------------------------
|
||||
|
||||
To understand the game, pick the "Story" option off of the
|
||||
main menu. This part of the game took a lot of time in
|
||||
itself, and is fun to read.
|
||||
|
||||
The "Audio Error!" is not a real error. I just saved myself
|
||||
the trouble of recording a voice-track for the game. As many
|
||||
friends have said, "That's cheating!" but anyway unless I had
|
||||
a lot of time and a CD-ROM, it is not practical.
|
||||
|
||||
Anyway in the story, any key will speed up most scenes, and
|
||||
escape will quit the whole thing.
|
||||
|
||||
4.0 GAME PLAY
|
||||
--------------------------------------------------------------------
|
||||
To begin the game, select "NEW GAME" at the main menu.
|
||||
|
||||
A little humorous movie will show; press <esc> to skip.
|
||||
|
||||
The game itself is pretty simplistic as of yet. Basically
|
||||
shoot the things coming at you. The arrow keys manuever...
|
||||
the manuevering takes a little bit of practice to master.
|
||||
Space shoots. You can shoot up to two missiles at once.
|
||||
"S" toggles sound. "P" pauses. If the game play is too fast,
|
||||
try the "+" and "-" keys to adjust. Sorry, if it runs too
|
||||
slow at the onset, then your computer is too slow.
|
||||
|
||||
The first level culminates with a "boss" character. Read the
|
||||
story and see what happens. The dialog will clue you into
|
||||
what's happening.
|
||||
|
||||
The second level is now totally finished. Be sure to save
|
||||
your games whenever you start a new level!
|
||||
|
||||
Levels three and four are currently under development. In
|
||||
level three, use the arrow keys to "walk" around. The space
|
||||
bar will fire a weapon if you've picked one up. To activate/
|
||||
pick up things, walk into them.
|
||||
|
||||
Level four is similar to level two. (Actually they are based
|
||||
on the same game engine). They will be finished by version 2.5.
|
||||
|
||||
An undocumented featue: when your score reaches a multiple of
|
||||
400 your shields are increased by one.
|
||||
|
||||
Basic Summary of Keyboard Commands:
|
||||
|
||||
ARROWS Manuever
|
||||
SPACE Fires
|
||||
<ESC> Exits
|
||||
P Pauses
|
||||
S Toggles sound on/off
|
||||
+ Slows down game speed
|
||||
- Increases game speed
|
||||
F1 Shows help message
|
||||
F2 Saves the Game (see "SAVING/LOADING GAMES")
|
||||
|
||||
5.0 SAVING/ LOADING GAMES
|
||||
---------------------------------------------------------------------
|
||||
You can save games. However the only part that is saved is
|
||||
how you begin the level. Therefore there is no real purpose
|
||||
to saving your game until you reach level two.
|
||||
|
||||
This might seem annoying, but at this point it is the only
|
||||
practical way to implement saved games.
|
||||
|
||||
|
||||
6.0 TROUBLESHOOTING
|
||||
---------------------------------------------------------------------
|
||||
This program usually runs fine on most computers. Occasionally
|
||||
it will lock up on my brother for some inexplicable reason.
|
||||
If it locks up frequently, try playing without sound blaster
|
||||
sounds.
|
||||
|
||||
Possible Problems:
|
||||
|
||||
RUNTIME ERRORS: (Characterized by a "Rumtime Error at 4454:3434"
|
||||
message.) Either a genuine bug or else one of
|
||||
the ".TB1" graphics files is missing.
|
||||
|
||||
LOCKING UP : If you have a sound blaster, try configuring
|
||||
without SOUND, using the "TBSETUP" utility.
|
||||
|
||||
MEMORY ERRORS : If you want soundblaster sound, HIMEM.SYS must
|
||||
be loaded. Check DOS documentation.
|
||||
|
||||
SOUND ERRORS : If you have a sound blaster and you are not
|
||||
getting sound, be sure your "SET BLASTER"
|
||||
command in your autoexec.bat is set properly.
|
||||
|
||||
HARSH GRATING SOUND: This has happened occassionally at a
|
||||
certain point on level two. I've tried to
|
||||
fix it. If it's annoying, turn the sound
|
||||
off.
|
||||
|
||||
MISC ERRORS : Contact me at vmweaver@wam.umd.edu
|
||||
|
||||
|
||||
7.0 REGISTERING
|
||||
---------------------------------------------------------------------
|
||||
My game is freeware. There is no copy protection. Hopefully
|
||||
if you like it you will let me know, by mail or by e-mail.
|
||||
A donation is not required, but if you want to you can send
|
||||
me one.
|
||||
|
||||
I will be attending college soon (Fall of 1996) so my e-mail
|
||||
address, has changed from what it was earlier to:
|
||||
vmweaver@wam.umd.edu
|
||||
|
||||
You can get Tom Bombem at its web site,
|
||||
|
||||
http://www.wam.umd.edu/~vmweaver/tb1/
|
||||
|
||||
Also, a college education is expensive, so any donations would
|
||||
be a big help.
|
||||
|
||||
Vince Weaver vmweaver@wam.umd.edu
|
||||
[real home]
|
||||
326 Foster Knoll Dr.
|
||||
Joppa, MD 21085-4706
|
||||
|
||||
|
||||
8.0 ACKNOWLEDGEMENTS
|
||||
---------------------------------------------------------------------
|
||||
I would like to thank many people who helped on this project.
|
||||
|
||||
Ethan Brodsky for his excelent sound blaster routines.
|
||||
Get them at http://www.pobox.com/~ebrodsky/smix/smix.html
|
||||
There would be no sound blaster sound without them.
|
||||
|
||||
The authors of PCGPE. This program started out as a
|
||||
"flying toaster" demonstration from the Asphixia
|
||||
VGA tutorials. I gradually replaced most of their code,
|
||||
but I still use their putpixel, waitretrace, setmcga and
|
||||
settext routines.
|
||||
|
||||
I would also like to thank all my friends who have supported
|
||||
me, especially Gus Thompson, because she went to Spain and
|
||||
gave me time to work on this. Also Marie Prosser for
|
||||
inspiration, and she also went away for three weeks
|
||||
allowing me to work on this. Thanks to Nick Attanasio
|
||||
who actually plays this game a lot, and whose comments
|
||||
have hastened work on level 3.
|
||||
|
||||
FUTURE ENHANCEMENTS:
|
||||
I am going to learn how to use Mode X vga programming.
|
||||
Supposedly this will speed up the code. Unless you
|
||||
have a 386 like me, you probably won't notice.
|
||||
|
||||
I'm also going to try to get some music in the
|
||||
background, and of course add more levels.
|
||||
|
||||
Also watch for a SGI gl port and possibly some
|
||||
sort of Linux port. The only problem is that
|
||||
they'll have to be in C. ( :-( )
|
||||
|
||||
|
||||
9.0 CURRENT BUGS (FEATURES)
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Level One: No Known Ones
|
||||
Level Two: Locks up for no reason near end sometimes?
|
||||
Level Three: Many. This level still is under development.
|
||||
Sometimes doors will not activate, sometimes
|
||||
they send you to the wrong room.
|
||||
Laser doesn't work, nor do enemies or
|
||||
radioactive flooring. It is possible to
|
||||
beat it though.
|
||||
Level Four:Not done. Right now is level two with different
|
||||
shape table.
|
||||
|
||||
LOOK FOR NEWER RELEASES TO HAVE FEWER BUGS.
|
||||
|
||||
If you find a unique bug, e-mail me describing it.
|
||||
|
||||
|
||||
10.0 PRAISE/ACCOMPLISHMENTS OF TOM BOMBEM
|
||||
___________________________________________________________________
|
||||
|
||||
Supposedly it will be on one of Pacific Hi-Tech's
|
||||
"Gamehead" CD's. We'll see.
|
||||
|
||||
A German book company has offered to put it in a CD included
|
||||
with a Shareware Games book.
|
||||
|
||||
Now Praise:
|
||||
|
||||
|
||||
"I just like it when it says 'Ahhh... Mr. Bombem.'"
|
||||
----Greg Grabowski, Bel Air, MD
|
||||
|
||||
"It's simplicity reminded me of the early computer
|
||||
shooters... Kind of nostalgic... But the nice
|
||||
side [is] the very clever cinematic text."
|
||||
---->> Delance <<
|
||||
|
||||
"The game is well designed but does not fit
|
||||
our current product line."
|
||||
----Apogee Software Productions
|
||||
|
||||
|
||||
Remember: Watch for the newest version of Tom Bombem... and have fun.
|
||||
|
||||
Vince Weaver 14 July 1996 18:12:59 EDT
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
4
TODO
Normal file
4
TODO
Normal file
|
@ -0,0 +1,4 @@
|
|||
Finish the game [or at least get it on-par with the dos version]
|
||||
Requires:
|
||||
Levels2-4
|
||||
Highscore list
|
0
data/data_files_here
Normal file
0
data/data_files_here
Normal file
|
@ -1,22 +1,22 @@
|
|||
31 31 31 31 31 31 31 31 31 31 31 31
|
||||
5 7 5 5 5 5 5 5 5 5 7 5
|
||||
5 5 3 5 30 30 30 30 5 3 5 5
|
||||
5 5 5 5 4 4 4 4 5 5 5 5
|
||||
15 15 15 15 31 31 31 31 15 15 15 15
|
||||
17 17 17 17 16 16 16 16 17 17 17 17
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
7 9 9 9 9 9 9 9 9 9 9 7
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
12 9 9 9 12 9 9 12 9 9 9 12
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
9 9 9 9 9 9 9 9 9 9 9 9
|
||||
0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0
|
||||
15 15 15 15 0 0 0 0 15 15 15 15
|
||||
0 0 0 0 0 0 0 0 0 0 0 0
|
||||
30 30 30 30 30 30 30 30 30 30 30 30
|
||||
5 5 5 5 5 5 5 5 5 5 5 5
|
||||
5 5 5 5 5 5 5 5 5 5 5 5
|
||||
5 4 5 5 5 5 5 5 5 5 5 5
|
||||
5 5 5 5 5 5 5 5 5 5 5 5
|
||||
5 5 5 5 5 4 5 5 5 5 5 5
|
||||
5 12 5 5 5 5 5 5 5 5 12 5
|
||||
5 5 5 5 14 5 14 5 5 5 5 5
|
||||
5 5 5 5 5 5 5 5 5 5 5 5
|
||||
12 5 5 5 12 5 5 12 5 5 5 12
|
||||
5 5 5 5 5 5 5 5 5 5 5 5
|
||||
5 5 5 5 5 5 5 5 5 5 5 5
|
||||
31 31 31 31 31 31 31 31 31 31 31 31
|
||||
0 0 0 0 0 0 0 0 0 0 0 0
|
||||
2 2 18 19 0 0 0 0 19 18 2 2
|
||||
0 0 0 0 0 0 0 0 0 0 0 0
|
||||
|
|
BIN
data/moon2.tb1
BIN
data/moon2.tb1
Binary file not shown.
Binary file not shown.
BIN
data/ships.tb1
BIN
data/ships.tb1
Binary file not shown.
BIN
data/tb_cc.wav
BIN
data/tb_cc.wav
Binary file not shown.
Binary file not shown.
1
data/tbahh.raw
Normal file
1
data/tbahh.raw
Normal file
File diff suppressed because one or more lines are too long
BIN
data/tbash.tb1
BIN
data/tbash.tb1
Binary file not shown.
BIN
data/tbaship.tb1
BIN
data/tbaship.tb1
Binary file not shown.
1
data/tbbonk.raw
Normal file
1
data/tbbonk.raw
Normal file
File diff suppressed because one or more lines are too long
1
data/tbcc.raw
Normal file
1
data/tbcc.raw
Normal file
File diff suppressed because one or more lines are too long
BIN
data/tbchief.tb1
BIN
data/tbchief.tb1
Binary file not shown.
BIN
data/tbclick.raw
Normal file
BIN
data/tbclick.raw
Normal file
Binary file not shown.
BIN
data/tbcobj.tb1
BIN
data/tbcobj.tb1
Binary file not shown.
Binary file not shown.
BIN
data/tbcrash.tb1
BIN
data/tbcrash.tb1
Binary file not shown.
BIN
data/tbeerm.tb1
BIN
data/tbeerm.tb1
Binary file not shown.
BIN
data/tbgorg.tb1
BIN
data/tbgorg.tb1
Binary file not shown.
1
data/tbkapow.raw
Normal file
1
data/tbkapow.raw
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
BIN
data/tblev3.tb1
BIN
data/tblev3.tb1
Binary file not shown.
BIN
data/tbma1.tb1
BIN
data/tbma1.tb1
Binary file not shown.
BIN
data/tbomb1.tb1
BIN
data/tbomb1.tb1
Binary file not shown.
1
data/tbow.raw
Normal file
1
data/tbow.raw
Normal file
File diff suppressed because one or more lines are too long
BIN
data/tbpit.tb1
BIN
data/tbpit.tb1
Binary file not shown.
BIN
data/tbscream.raw
Normal file
BIN
data/tbscream.raw
Normal file
Binary file not shown.
Binary file not shown.
BIN
data/tbsobj.tb1
BIN
data/tbsobj.tb1
Binary file not shown.
BIN
data/tbtract.tb1
BIN
data/tbtract.tb1
Binary file not shown.
BIN
data/tbzrrp.raw
Normal file
BIN
data/tbzrrp.raw
Normal file
Binary file not shown.
BIN
data/viewscr.tb1
BIN
data/viewscr.tb1
Binary file not shown.
BIN
data/vmwfan.mod
BIN
data/vmwfan.mod
Binary file not shown.
BIN
data/weave1.mod
BIN
data/weave1.mod
Binary file not shown.
20
hiscore.tb1
Normal file
20
hiscore.tb1
Normal file
|
@ -0,0 +1,20 @@
|
|||
Vince!;!
|
||||
Vince;
|
||||
Vince
|
||||
KEVIN
|
||||
KEVIN!@#%&
|
||||
Vince
|
||||
Vince
|
||||
KEVIN
|
||||
MREE
|
||||
kevin
|
||||
2210
|
||||
2000
|
||||
1900
|
||||
1860
|
||||
1860
|
||||
1850
|
||||
1810
|
||||
1790
|
||||
1790
|
||||
1790
|
703
level1.c
Normal file
703
level1.c
Normal file
|
@ -0,0 +1,703 @@
|
|||
/*
|
||||
Level 1 Engine Code for Tom Bombem
|
||||
*/
|
||||
|
||||
/* The Includes */
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <ggi/libggi.h>
|
||||
#include <stdlib.h>
|
||||
#include "svmwgrap.h"
|
||||
#include "levels.h"
|
||||
#include "tblib.h"
|
||||
#include "soundIt.h"
|
||||
|
||||
/* Define this to get a frames per second readout */
|
||||
/* #define DEBUG_ON */
|
||||
|
||||
/* The sounds */
|
||||
#define NUM_SAMPLES 4
|
||||
#define SND_CC 0
|
||||
#define SND_BONK 1
|
||||
#define SND_KAPOW 2
|
||||
#define SND_ZRRP 3
|
||||
|
||||
/* The global variables ;) I like global variables hehe */
|
||||
extern vmw_font *tb1_font;
|
||||
extern ggi_visual_t vis;
|
||||
extern ggi_visual_t vaddr;
|
||||
extern ggi_visual_t vaddr2;
|
||||
extern ggi_color eight_bit_pal[256];
|
||||
extern ggi_pixel tb1_pal[256];
|
||||
extern ggi_directbuffer_t dbuf_vis;
|
||||
extern ggi_directbuffer_t dbuf_vaddr;
|
||||
extern ggi_directbuffer_t dbuf_vaddr2;
|
||||
extern ggi_pixellinearbuffer *plb_vis;
|
||||
extern ggi_pixellinearbuffer *plb_vaddr;
|
||||
extern ggi_pixellinearbuffer *plb_vaddr2;
|
||||
extern int sound_possible;
|
||||
extern int sound_enabled;
|
||||
extern int color_depth;
|
||||
extern int stride_factor;
|
||||
|
||||
/* I like structures also ;) */
|
||||
struct enemyinfo {
|
||||
int x,y;
|
||||
int kind;
|
||||
int out,exploding,boundarycheck,dead;
|
||||
int explodeprogress;
|
||||
int minx,maxx,xspeed,yspeed;
|
||||
int hitsneeded;
|
||||
};
|
||||
|
||||
struct bulletinfo {
|
||||
int out,x,y;
|
||||
};
|
||||
|
||||
/* Define how many sound effects there are */
|
||||
Sample sound_effects[NUM_SAMPLES];
|
||||
|
||||
/* o/~ more structures o/~ */
|
||||
struct enemyinfo enemy[5];
|
||||
struct bulletinfo bullet[3];
|
||||
struct timeval timing_info;
|
||||
struct timezone dontcare;
|
||||
|
||||
/* This seemed like a good idea to modularize things */
|
||||
int level_one_wave_behavior[]=
|
||||
{0,0,0,0,0, 1,1,1,1,1,
|
||||
1,1,2,2,2, 2,2,2,2,2,
|
||||
3,3,3,3,3, 3,3,3,3,3,
|
||||
2,2,2,2,2, 2,3,3,3,3,
|
||||
3,3,3,3,3, 3,1,1,1,1,
|
||||
1,3,3,3,3, 3,3,3,3,3,
|
||||
3,2,2,2,2, 2,2,2,2,2,
|
||||
2,2,2,2,2, 2,1,1,1,1,
|
||||
1,1,1,3,3, 3,2,2,2,2,
|
||||
2,2,2,2,2, 2,1,1,1,1,
|
||||
1,4,4,4,4};
|
||||
|
||||
/* Yes I was too lazy to re-arrange the order of the functions */
|
||||
void beforeboss();
|
||||
|
||||
/* Defines the behavior of the objects in level 1 */
|
||||
int level_one_behavior(int reset)
|
||||
{
|
||||
int what,temp,whichone,need_to_pause=0;
|
||||
static int wave=0;
|
||||
static int saucersout=0;
|
||||
|
||||
if (reset) {
|
||||
wave=0;
|
||||
saucersout=0;
|
||||
}
|
||||
|
||||
if (level_one_wave_behavior[wave]!=4) wave++;
|
||||
saucersout--;
|
||||
if (saucersout<0) saucersout=0;
|
||||
if (saucersout>5) saucersout=5;
|
||||
|
||||
/* **START NEW WAVE ***/
|
||||
|
||||
switch(level_one_wave_behavior[wave]) {
|
||||
|
||||
/* STANDARD */
|
||||
case 0: if (saucersout==0) {
|
||||
saucersout=5;
|
||||
what=(3+rand()%8);
|
||||
for(temp=0; temp<5; temp++) {
|
||||
enemy[temp].kind=what;
|
||||
enemy[temp].x=0;
|
||||
enemy[temp].y=0;
|
||||
enemy[temp].xspeed=5;
|
||||
enemy[temp].x=temp*20;
|
||||
enemy[temp].minx=(temp*20);
|
||||
enemy[temp].maxx=(temp*20)+120;
|
||||
enemy[temp].boundarycheck=1;
|
||||
enemy[temp].yspeed=10;
|
||||
enemy[temp].out=1;
|
||||
enemy[temp].exploding=0;
|
||||
enemy[temp].hitsneeded=1;
|
||||
enemy[temp].dead=0;
|
||||
}
|
||||
} break;
|
||||
/* *FALLING STRAIGHT* */
|
||||
case 3:
|
||||
for (temp=0; temp<5;temp++)
|
||||
if (!enemy[temp].out) {
|
||||
enemy[temp].kind=rand()%8+3;
|
||||
enemy[temp].x=rand()%200+1;
|
||||
enemy[temp].y=0;
|
||||
enemy[temp].xspeed=0;
|
||||
enemy[temp].minx=enemy[temp].x;
|
||||
enemy[temp].maxx=enemy[temp].x;
|
||||
enemy[temp].boundarycheck=1;
|
||||
enemy[temp].yspeed=5+(wave/40);
|
||||
enemy[temp].out=1;
|
||||
enemy[temp].exploding=0;
|
||||
enemy[temp].hitsneeded=1;
|
||||
enemy[temp].dead=0;
|
||||
saucersout++;
|
||||
} break;
|
||||
|
||||
/* *FALLING GRADUALLY SIDEWAYS* */
|
||||
case 2:
|
||||
for(temp=0;temp<5;temp++)
|
||||
if (!enemy[temp].out) {
|
||||
enemy[temp].kind=rand()%8+3;
|
||||
enemy[temp].y=0;
|
||||
enemy[temp].xspeed=5;
|
||||
enemy[temp].minx=rand()%100;
|
||||
enemy[temp].maxx=rand()%100+120;
|
||||
enemy[temp].x=enemy[temp].minx;
|
||||
enemy[temp].boundarycheck=0;
|
||||
enemy[temp].yspeed=1;
|
||||
enemy[temp].out=1;
|
||||
enemy[temp].exploding=0;
|
||||
enemy[temp].hitsneeded=1;
|
||||
enemy[temp].dead=0;
|
||||
saucersout++;
|
||||
} break;
|
||||
|
||||
/**ZIG-ZAG**/
|
||||
case 1: if (!saucersout) {
|
||||
saucersout=5;
|
||||
whichone=rand()%8+3;
|
||||
for(temp=0;temp<5;temp++)
|
||||
if (!enemy[temp].out) {
|
||||
enemy[temp].kind=whichone;
|
||||
enemy[temp].y=temp*10;
|
||||
enemy[temp].xspeed=5;
|
||||
enemy[temp].minx=0;
|
||||
enemy[temp].maxx=220;
|
||||
enemy[temp].x=temp*20;
|
||||
enemy[temp].boundarycheck=0;
|
||||
enemy[temp].yspeed=1;
|
||||
enemy[temp].out=1;
|
||||
enemy[temp].exploding=0;
|
||||
enemy[temp].hitsneeded=1;
|
||||
enemy[temp].dead=0;
|
||||
}
|
||||
} break;
|
||||
|
||||
/* Beginning of Boss */
|
||||
case 4:
|
||||
if (!saucersout) {
|
||||
beforeboss();
|
||||
need_to_pause=1;
|
||||
enemy[0].kind=15;
|
||||
enemy[1].kind=15;
|
||||
enemy[2].kind=14;
|
||||
for(temp=0;temp<3;temp++) {
|
||||
enemy[temp].x=(temp*20)+10;
|
||||
enemy[temp].y=0;
|
||||
enemy[temp].xspeed=5;
|
||||
enemy[temp].minx=0;
|
||||
enemy[temp].maxx=220;
|
||||
enemy[temp].boundarycheck=1;
|
||||
enemy[temp].yspeed=0;
|
||||
enemy[temp].out=1;
|
||||
enemy[temp].exploding=0;
|
||||
enemy[temp].hitsneeded=3;
|
||||
enemy[temp].dead=0;
|
||||
saucersout++;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
/* Objects Cast off by the Boss */
|
||||
if (enemy[1].kind==15) {
|
||||
/* Detect if Level One is Over */
|
||||
if ((enemy[0].dead) && (enemy[1].dead) && (enemy[2].dead)) return 9;
|
||||
for(temp=3;temp<5;temp++) {
|
||||
saucersout++;
|
||||
if ((!enemy[temp].out) && (enemy[temp-3].out)) {
|
||||
enemy[temp].kind=rand()%8+3;
|
||||
enemy[temp].x=enemy[temp-3].x;
|
||||
enemy[temp].y=20;
|
||||
enemy[temp].xspeed=0;
|
||||
enemy[temp].minx=enemy[temp].x;
|
||||
enemy[temp].maxx=enemy[temp].x;
|
||||
enemy[temp].boundarycheck=0;
|
||||
enemy[temp].yspeed=4;
|
||||
enemy[temp].out=1;
|
||||
enemy[temp].exploding=0;
|
||||
enemy[temp].hitsneeded=1;
|
||||
enemy[temp].dead=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return need_to_pause;
|
||||
}
|
||||
|
||||
/* The little Sequence Before you hit the Boss */
|
||||
void beforeboss()
|
||||
{
|
||||
char *tempst[300];
|
||||
|
||||
clear_keyboard_buffer();
|
||||
GGILoadPicPacked(0,0,vaddr,0,1,
|
||||
tb1_data_file("viewscr.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
ggiSetGCForeground(vis,0);
|
||||
ggiDrawBox(vis,0,0,320,200);
|
||||
vmwArbitraryCrossBlit(plb_vaddr->read,0,5,58,37,
|
||||
plb_vis->write,10,10,plb_vis->stride,stride_factor);
|
||||
VMWsmalltextxy("HUMAN!",70,10,tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("WHAT ARE YOU DOING?!",70,20,tb1_pal[2],
|
||||
tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("YOUR SPECIES MUST BE TERMINATED!",70,30,tb1_pal[2],
|
||||
tb1_pal[0],1,tb1_font,vis);
|
||||
pauseawhile(5);
|
||||
vmwArbitraryCrossBlit(plb_vaddr->read,0,42,58,37,
|
||||
plb_vis->write,10,50,plb_vis->stride,stride_factor);
|
||||
VMWsmalltextxy("I'M SORRY.",70,50,tb1_pal[9],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("WE DIDN'T MEAN TO DESTROY YOUR ENVOY.",70,60,tb1_pal[9],
|
||||
tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("WILL YOU FORGIVE US AND TRY PEACE?",70,70,tb1_pal[9],
|
||||
tb1_pal[0],1,tb1_font,vis);
|
||||
pauseawhile(5);
|
||||
vmwArbitraryCrossBlit(plb_vaddr->read,0,5,58,37,
|
||||
plb_vis->write,10,90,plb_vis->stride,stride_factor);
|
||||
VMWsmalltextxy("NO! YOU MUST BE DESTROYED!",70,90,tb1_pal[2],
|
||||
tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("OUR FUNDING ... OUR ENVOY WAS DAMAGED BY",70,100,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("YOU! VENGEANCE WILL BE OURS! YOUR PUNY",70,110,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("PRIMITIVE SPACECRAFT WITH ITS INFERIOR",70,120,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("WEAPONS WOULD HAVE TO SCORE 9 DIRECT HITS",70,130,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("TO DESTROY MY SHIP! DIE EARTH SCUM!!!!",70,140,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
pauseawhile(5);
|
||||
}
|
||||
|
||||
/* The Sequence After You Defeat (hopefully) the Boss */
|
||||
void afterboss()
|
||||
{
|
||||
char *tempst[300];
|
||||
|
||||
GGILoadPicPacked(0,0,vaddr,0,1,
|
||||
tb1_data_file("viewscr.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
ggiDrawBox(vis,0,0,320,200);
|
||||
vmwArbitraryCrossBlit(plb_vaddr->read,0,42,58,37,
|
||||
plb_vis->write,10,10,plb_vis->stride,stride_factor);
|
||||
VMWsmalltextxy("HMM.. THEY DON'T BUILD SUPERIOR",70,10,
|
||||
tb1_pal[9],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("TECHNOLOGY LIKE THEY USED TO.",70,20,
|
||||
tb1_pal[9],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("I GUESS I CAN GO HOME NOW.",70,30,
|
||||
tb1_pal[9],tb1_pal[0],1,tb1_font,vis);
|
||||
pauseawhile(5);
|
||||
vmwArbitraryCrossBlit(plb_vaddr->read,0,5,58,37,
|
||||
plb_vis->write,10,50,plb_vis->stride,stride_factor);
|
||||
VMWsmalltextxy("NOT SO FAST! YOU JUST DESTROYED AN ANTIQUATED",70,50,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("DEFENSE SYSTEM THAT WAS PROGRAMMED BY A 16",70,60,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("YEAR OLD! OUR MAIN DEFENSE PROGRAMMER HAS ",70,70,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("MUCH MORE SKILL NOW! UNLESS YOU DESTROY OUR",70,80,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("ENTIRE XENOCIDE... I MEAN PEACE... ENVOY",70,90,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("WE WILL STILL DESTROY YOUR HOME PLANET.",70,100,
|
||||
tb1_pal[2],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("NICE TRY PUNY EARTHLING!",70,110,tb1_pal[2],
|
||||
tb1_pal[0],1,tb1_font,vis);
|
||||
pauseawhile(7);
|
||||
vmwArbitraryCrossBlit(plb_vaddr->read,0,42,58,37,
|
||||
plb_vis->write,10,130,plb_vis->stride,stride_factor);
|
||||
VMWsmalltextxy("HMM.. I GUESS I BETTER SAVE THE EARTH.",70,130,
|
||||
tb1_pal[9],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("I'D BETTER SAVE MY GAME TOO.",70,140,
|
||||
tb1_pal[9],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("D'OH! I''M OUT OF BIG MISSILES! ",70,150,
|
||||
tb1_pal[9],tb1_pal[0],1,tb1_font,vis);
|
||||
VMWsmalltextxy("WELL AT LEAST I HAVE SOME SMALLER SPARES.",70,160,
|
||||
tb1_pal[9],tb1_pal[0],1,tb1_font,vis);
|
||||
pauseawhile(5);
|
||||
}
|
||||
|
||||
/* The Main Level One */
|
||||
void levelone(int *level,int *shields,int *score)
|
||||
{
|
||||
int ch=0;
|
||||
int i,j,grapherror;
|
||||
char tempst[300];
|
||||
int itemp,whatdelay=1,levelover=0;
|
||||
int shipx=36,shipadd=0,shipframe=1;
|
||||
int bigship1[1500],bigship2[1500],bigship3[1500];
|
||||
int shapetable[20][400];
|
||||
long oldsec,oldusec,time_spent;
|
||||
int howmuchscroll=0;
|
||||
int speed_factor=1,game_paused=0;
|
||||
int beginscore,beginshield;
|
||||
|
||||
/* Set this up for Save Game */
|
||||
beginscore=*score;
|
||||
beginshield=*shields;
|
||||
|
||||
/* Load All The Sounds */
|
||||
if (sound_possible) {
|
||||
Snd_loadRawSample(tb1_data_file("tbcc.raw",(char *)&tempst),
|
||||
&sound_effects[0],0);
|
||||
Snd_loadRawSample(tb1_data_file("tbbonk.raw",(char *)&tempst),
|
||||
&sound_effects[1],0);
|
||||
Snd_loadRawSample(tb1_data_file("tbkapow.raw",(char *)&tempst),
|
||||
&sound_effects[2],0);
|
||||
Snd_loadRawSample(tb1_data_file("tbzrrp.raw",(char *)&tempst),
|
||||
&sound_effects[3],0);
|
||||
|
||||
/* Initialize Sound, if Possible */
|
||||
if (Snd_init( NUM_SAMPLES,sound_effects,22050,4,
|
||||
"/dev/dsp")==EXIT_FAILURE) {
|
||||
printf("ERROR! Cannot init sound.\n");
|
||||
sound_enabled=0;
|
||||
}
|
||||
}
|
||||
/* Load Sprites (or whatever you want to call them) */
|
||||
grapherror=GGILoadPicPacked(0,0,vaddr,1,1,
|
||||
tb1_data_file("ships.tb1",(char *)&tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
vmwGetSprite(vaddr,0,0,48,30,(int *)&bigship1);
|
||||
vmwGetSprite(vaddr,0,32,48,30,(int *)&bigship2);
|
||||
vmwGetSprite(vaddr,0,64,48,30,(int *)&bigship3);
|
||||
|
||||
grapherror=GGILoadPicPacked(0,0,vaddr,1,1,
|
||||
tb1_data_file("tbshapes.tb1",(char *)&tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
for(j=0;j<2;j++)
|
||||
for(i=0;i<10;i++)
|
||||
vmwGetSprite(vaddr,1+(i*19),1+(j*19),18,20,
|
||||
(int *)&shapetable[(j*10)+i]);
|
||||
|
||||
/* Set up initial Enemy Structs */
|
||||
for(i=0;i<5;i++) {
|
||||
enemy[i].exploding=0;
|
||||
enemy[i].out=0;
|
||||
enemy[i].dead=0;
|
||||
}
|
||||
for(i=0;i<2;i++) {
|
||||
bullet[i].out=0;
|
||||
bullet[i].x=0;
|
||||
bullet[i].y=0;
|
||||
}
|
||||
/* Setup and draw the sidebar */
|
||||
setupsidebar(*score,0,*shields);
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
vmwCrossBlit(plb_vaddr->write,plb_vaddr2->read,plb_vaddr->stride,200);
|
||||
sprintf(tempst,"%d",*level);
|
||||
ggiDrawBox(vaddr2,251,52,63,7);
|
||||
VMWtextxy(tempst,307,51,tb1_pal[12],tb1_pal[0],0,tb1_font,vaddr2);
|
||||
|
||||
/* Clear the screen and draw the stars */
|
||||
ggiSetGCForeground(vaddr2,tb1_pal[0]);
|
||||
ggiDrawBox(vaddr2,0,0,320,400);
|
||||
for(i=0;i<100;i++) {
|
||||
vmwPutSprite(shapetable[11],18,18,stride_factor,
|
||||
plb_vaddr2->write,rand()%238,
|
||||
rand()%400,plb_vaddr2->stride);
|
||||
vmwPutSprite(shapetable[12],18,18,stride_factor,
|
||||
plb_vaddr2->write,rand()%238,
|
||||
rand()%400,plb_vaddr2->stride);
|
||||
}
|
||||
change_shields(shields);
|
||||
|
||||
/* Draw the Little Box announcing the Start of the Level */
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
ggiDrawBox(vis,0,0,320,200);
|
||||
coolbox(70,85,240,120,1,vis);
|
||||
VMWtextxy(" LEVEL ONE:",84,95,tb1_pal[4],tb1_pal[7],0,tb1_font,vis);
|
||||
VMWtextxy("INANIMATE OBJECTS",84,105,tb1_pal[4],tb1_pal[7],0,tb1_font,vis);
|
||||
|
||||
/* Initiate some last variables */
|
||||
level_one_behavior(1);
|
||||
pauseawhile(5);
|
||||
gettimeofday(&timing_info,&dontcare);
|
||||
oldsec=timing_info.tv_sec; oldusec=timing_info.tv_usec;
|
||||
|
||||
/* MAIN GAME LOOP */
|
||||
while(!levelover) {
|
||||
ch=0;
|
||||
/* Scroll the Stars */
|
||||
if (speed_factor>1) howmuchscroll-=speed_factor;
|
||||
else howmuchscroll--;
|
||||
if (howmuchscroll<0) howmuchscroll=399;
|
||||
if (howmuchscroll>199) {
|
||||
vmwArbitraryCrossBlit(plb_vaddr2->read,0,howmuchscroll,240,
|
||||
400-howmuchscroll,
|
||||
plb_vaddr->write,0,0,plb_vaddr->stride,
|
||||
stride_factor);
|
||||
vmwArbitraryCrossBlit(plb_vaddr2->read,0,0,240,howmuchscroll-200,
|
||||
plb_vaddr->write,0,400-howmuchscroll,
|
||||
plb_vaddr->stride,
|
||||
stride_factor);
|
||||
}
|
||||
else {
|
||||
vmwArbitraryCrossBlit(plb_vaddr2->read,0,howmuchscroll,240,200,
|
||||
plb_vaddr->write,0,0,plb_vaddr->stride,
|
||||
stride_factor);
|
||||
}
|
||||
|
||||
|
||||
/* Check for Collisions */
|
||||
for(i=0;i<5;i++) {
|
||||
if (!enemy[i].dead) {
|
||||
for(itemp=0;itemp<2;itemp++) {
|
||||
if (bullet[itemp].out)
|
||||
if (collision(bullet[itemp].x,bullet[itemp].y,10,10,
|
||||
enemy[i].x,enemy[i].y,9,9)) {
|
||||
if (sound_enabled) Snd_effect(SND_KAPOW,2);
|
||||
enemy[i].hitsneeded--;
|
||||
if (enemy[i].hitsneeded<1) enemy[i].dead=1;
|
||||
else enemy[i].dead=0;
|
||||
enemy[i].exploding=1;
|
||||
enemy[i].explodeprogress=0;
|
||||
bullet[itemp].out=0;
|
||||
(*score)+=10;
|
||||
changescore(*score,shields);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Explode the things that are exploding */
|
||||
for(i=0;i<5;i++) {
|
||||
if (enemy[i].exploding) {
|
||||
enemy[i].explodeprogress++;
|
||||
if (enemy[i].explodeprogress<=5)
|
||||
vmwPutSprite(shapetable[enemy[i].explodeprogress+14],
|
||||
18,18,stride_factor,
|
||||
plb_vaddr->write,enemy[i].x,enemy[i].y,
|
||||
plb_vaddr->stride);
|
||||
else if (enemy[i].dead) {
|
||||
enemy[i].out=0;
|
||||
enemy[i].exploding=0;
|
||||
game_paused=level_one_behavior(0);
|
||||
}
|
||||
else enemy[i].exploding=0;
|
||||
}
|
||||
}
|
||||
/* Move the Missiles */
|
||||
for(i=0;i<2;i++) {
|
||||
if (bullet[i].out) {
|
||||
if (speed_factor>1) bullet[i].y-=(5*speed_factor);
|
||||
else bullet[i].y-=5;
|
||||
if (bullet[i].y<5) bullet[i].out=0;
|
||||
else vmwPutSprite(shapetable[0],18,18,stride_factor,
|
||||
plb_vaddr->write,bullet[i].x,bullet[i].y,
|
||||
plb_vaddr->stride);
|
||||
}
|
||||
}
|
||||
|
||||
/* MOVE ENEMIES */
|
||||
for(i=0;i<5;i++) {
|
||||
if ((enemy[i].out) && (!enemy[i].dead)) {
|
||||
vmwPutSprite(shapetable[enemy[i].kind-1],18,18,stride_factor,
|
||||
plb_vaddr->write,enemy[i].x,enemy[i].y,
|
||||
plb_vaddr->stride);
|
||||
if (speed_factor==1) enemy[i].x+=enemy[i].xspeed;
|
||||
else enemy[i].x+=(enemy[i].xspeed*speed_factor);
|
||||
/* Check Position */
|
||||
/* Check Position */
|
||||
if (!enemy[i].boundarycheck)
|
||||
if (speed_factor>1) enemy[i].y+=(enemy[i].yspeed*speed_factor);
|
||||
else enemy[i].y+=enemy[i].yspeed;
|
||||
if ((enemy[i].x<=enemy[i].minx) || (enemy[i].x>=enemy[i].maxx)) {
|
||||
enemy[i].xspeed=-enemy[i].xspeed;
|
||||
if (speed_factor>1) enemy[i].x+=(enemy[i].xspeed*speed_factor);
|
||||
else enemy[i].x+=enemy[i].xspeed;
|
||||
if (speed_factor>1) enemy[i].y+=(enemy[i].yspeed*speed_factor);
|
||||
else enemy[i].y+=enemy[i].yspeed;
|
||||
}
|
||||
/* Too Low */
|
||||
|
||||
/* Too Low */
|
||||
if (enemy[i].y>179) {
|
||||
enemy[i].out=0;
|
||||
game_paused=level_one_behavior(0);
|
||||
}
|
||||
if (enemy[i].y>140) {
|
||||
if (collision(shipx,165,24,15,enemy[i].x,enemy[i].y,9,9)) {
|
||||
if (sound_enabled) Snd_effect(SND_BONK,1);
|
||||
enemy[i].hitsneeded--;
|
||||
if (enemy[i].hitsneeded==0) enemy[i].dead=1;
|
||||
else enemy[i].dead=0;
|
||||
enemy[i].exploding=1;
|
||||
enemy[i].explodeprogress=0;
|
||||
(*shields)--;
|
||||
if (*shields<0) levelover=1;
|
||||
if (*shields>0) change_shields(shields);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* See if beat the level. Yes, bad variable name. Oh well */
|
||||
if (game_paused==9) {
|
||||
afterboss();
|
||||
*level=2;
|
||||
levelover=1;
|
||||
}
|
||||
|
||||
/* **READ KEYBOARD** */
|
||||
if ( (ch=get_input())!=0) {
|
||||
switch(ch){
|
||||
case TB_ESC: levelover=1; break;
|
||||
case TB_RIGHT: if (shipadd>=0) shipadd+=3; else shipadd=0; break;
|
||||
case TB_LEFT: if (shipadd<=0) shipadd-=3; else shipadd=0; break;
|
||||
case TB_F1: game_paused=1; help(); break;
|
||||
case '+': whatdelay++; if (whatdelay>25) whatdelay=25; break;
|
||||
case 'P': case 'p': game_paused=1;
|
||||
coolbox(65,85,175,110,1,vis);
|
||||
VMWtextxy("GAME PAUSED",79,95,tb1_pal[4],tb1_pal[7],
|
||||
0,tb1_font,vis);
|
||||
while (get_input()==0) {
|
||||
usleep(30000);
|
||||
}
|
||||
break;
|
||||
case '-': whatdelay--; if (whatdelay<1) whatdelay=1; break;
|
||||
case 'S':
|
||||
case 's': if(sound_possible) sound_enabled=!(sound_enabled); break;
|
||||
case TB_F2: game_paused=1; savegame(*level,beginscore,beginshield);
|
||||
break;
|
||||
case ' ': for(j=0;j<2;j++)
|
||||
if (!bullet[j].out) {
|
||||
if (sound_enabled) Snd_effect(SND_CC,0);
|
||||
bullet[j].out=1;
|
||||
bullet[j].x=shipx+15;
|
||||
bullet[j].y=165;
|
||||
vmwPutSprite(shapetable[0],18,18,stride_factor,
|
||||
plb_vaddr->write,bullet[j].x,
|
||||
bullet[j].y,plb_vaddr->stride);
|
||||
j=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* **MOVE SHIP** */
|
||||
if (speed_factor>1) shipx+=(shipadd*speed_factor);
|
||||
else shipx+=shipadd;
|
||||
if (shipx<1) shipx=1;
|
||||
if (shipx>190) shipx=190;
|
||||
switch(shipframe) {
|
||||
case 1: vmwPutSprite(bigship1,48,30,stride_factor,
|
||||
plb_vaddr->write,shipx,165,
|
||||
plb_vaddr->stride); break;
|
||||
case 3: vmwPutSprite(bigship2,48,30,stride_factor,
|
||||
plb_vaddr->write,shipx,165,
|
||||
plb_vaddr->stride); break;
|
||||
case 2:
|
||||
case 4: vmwPutSprite(bigship3,48,30,stride_factor,
|
||||
plb_vaddr->write,shipx,165,
|
||||
plb_vaddr->stride); break;
|
||||
}
|
||||
shipframe++;
|
||||
if (shipframe==5) shipframe=1;
|
||||
|
||||
/* Flip Pages */
|
||||
vmwCrossBlit(plb_vis->write,plb_vaddr->read,plb_vis->stride,200);
|
||||
ggiFlush(vis);
|
||||
|
||||
/* Calculate how much time has passed */
|
||||
gettimeofday(&timing_info,&dontcare);
|
||||
time_spent=timing_info.tv_usec-oldusec;
|
||||
if (timing_info.tv_sec-oldsec) time_spent+=1000000;
|
||||
#ifdef DEBUG_ON
|
||||
printf("%f\n",1000000/(float)time_spent);
|
||||
#endif
|
||||
/* If time passed was too little, wait a bit */
|
||||
while (time_spent<33000){
|
||||
gettimeofday(&timing_info,&dontcare);
|
||||
usleep(5);
|
||||
time_spent=timing_info.tv_usec-oldusec;
|
||||
if (timing_info.tv_sec-oldsec) time_spent+=1000000;
|
||||
}
|
||||
/* It game is paused, don't keep track of time */
|
||||
if (!game_paused) speed_factor=(time_spent/30000);
|
||||
oldusec=timing_info.tv_usec;
|
||||
oldsec=timing_info.tv_sec;
|
||||
if (game_paused) {
|
||||
gettimeofday(&timing_info,&dontcare);
|
||||
oldusec=timing_info.tv_usec;
|
||||
oldsec=timing_info.tv_sec;
|
||||
game_paused=0;
|
||||
}
|
||||
}
|
||||
/* All Done. Close up sound */
|
||||
Snd_restore();
|
||||
}
|
||||
|
||||
/* The little opener before Level 1 */
|
||||
void littleopener()
|
||||
{
|
||||
int ship1[400],ship2[400];
|
||||
int i;
|
||||
char *tempst[300];
|
||||
|
||||
ggiSetGCForeground(vaddr,tb1_pal[0]);
|
||||
ggiDrawBox(vaddr,0,0,320,200);
|
||||
GGILoadPicPacked(0,0,vaddr,1,1,
|
||||
tb1_data_file("moon2.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
GGILoadPicPacked(0,0,vis,1,0,
|
||||
tb1_data_file("moon2.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
vmwGetSprite(vaddr,9,178,15,18,ship1);
|
||||
vmwGetSprite(vaddr,30,178,15,18,ship2);
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
ggiDrawBox(vaddr,0,178,319,21);
|
||||
vmwCrossBlit(plb_vis->write,plb_vaddr->read,plb_vis->stride,200);
|
||||
vmwCrossBlit(plb_vaddr2->write,plb_vaddr->read,plb_vaddr->stride,200);
|
||||
for(i=100;i>0;i--) {
|
||||
vmwArbitraryCrossBlit(plb_vaddr2->read,0,95,320,40,
|
||||
plb_vaddr->write,0,95,
|
||||
plb_vaddr->stride,stride_factor);
|
||||
vmwPutSprite(ship2,15,18,stride_factor,
|
||||
plb_vaddr->write,i*2,100,plb_vaddr->stride);
|
||||
vmwArbitraryCrossBlit(plb_vaddr->read,0,95,320,40,
|
||||
plb_vis->write,0,95,plb_vaddr->stride,
|
||||
stride_factor);
|
||||
usleep(30000);
|
||||
if (get_input()!=0) break;
|
||||
}
|
||||
vmwCrossBlit(plb_vis->write,plb_vaddr2->read,plb_vis->stride,200);
|
||||
VMWtextxy(">KCHK< TOM! WHERE ARE YOU GOING?",5,180,tb1_pal[15],tb1_pal[0],1,tb1_font,vis);
|
||||
ggiFlush(vis);
|
||||
pauseawhile(3);
|
||||
ggiDrawBox(vis,0,178,319,21);
|
||||
VMWtextxy("Ooops. ",5,180,tb1_pal[24],tb1_pal[0],1,tb1_font,vis);
|
||||
pauseawhile(3);
|
||||
for(i=0;i<151;i++) {
|
||||
vmwArbitraryCrossBlit(plb_vaddr2->read,0,95,320,40,
|
||||
plb_vaddr->write,0,95,plb_vaddr->stride,
|
||||
stride_factor);
|
||||
vmwPutSprite(ship1,15,18,stride_factor,
|
||||
plb_vaddr->write,i*2,100,plb_vaddr->stride);
|
||||
vmwArbitraryCrossBlit(plb_vaddr->read,0,95,320,40,
|
||||
plb_vis->write,0,95,plb_vaddr->stride,
|
||||
stride_factor);
|
||||
usleep(30000);
|
||||
if (get_input()!=0) break;
|
||||
}
|
||||
vmwCrossBlit(plb_vis->write,plb_vaddr2->read,plb_vis->stride,200);
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
ggiDrawBox(vis,0,0,320,200);
|
||||
GGILoadPicPacked(0,0,vis,1,0,
|
||||
tb1_data_file("tbgorg.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
|
||||
}
|
608
level2.c
Normal file
608
level2.c
Normal file
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* Level 2 Engine Code for Tom Bombem
|
||||
* */
|
||||
|
||||
/* The Includes */
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <ggi/libggi.h>
|
||||
#include <stdlib.h>
|
||||
#include "svmwgrap.h"
|
||||
#include "levels.h"
|
||||
#include "tblib.h"
|
||||
#include "soundIt.h"
|
||||
|
||||
/* Define this to get a frames per second readout */
|
||||
/* #define DEBUG_ON */
|
||||
|
||||
/* The sounds */
|
||||
#define NUM_SAMPLES 4
|
||||
#define SND_CC 0
|
||||
#define SND_BONK 1
|
||||
#define SND_KAPOW 2
|
||||
#define SND_ZRRP 3
|
||||
|
||||
/* The global variables ;) I like global variables hehe */
|
||||
extern vmw_font *tb1_font;
|
||||
extern ggi_visual_t vis;
|
||||
extern ggi_visual_t vaddr;
|
||||
extern ggi_visual_t vaddr2;
|
||||
extern ggi_color eight_bit_pal[256];
|
||||
extern ggi_pixel tb1_pal[256];
|
||||
extern ggi_directbuffer_t dbuf_vis;
|
||||
extern ggi_directbuffer_t dbuf_vaddr;
|
||||
extern ggi_directbuffer_t dbuf_vaddr2;
|
||||
extern ggi_pixellinearbuffer *plb_vis;
|
||||
extern ggi_pixellinearbuffer *plb_vaddr;
|
||||
extern ggi_pixellinearbuffer *plb_vaddr2;
|
||||
extern int sound_possible;
|
||||
extern int sound_enabled;
|
||||
extern int color_depth;
|
||||
extern int stride_factor;
|
||||
|
||||
struct enemyinfo {
|
||||
int x,y;
|
||||
int kind;
|
||||
int out,exploding,boundarycheck,dead;
|
||||
int explodeprogress;
|
||||
int minx,maxx,xspeed,yspeed;
|
||||
int hitsneeded;
|
||||
};
|
||||
|
||||
struct bulletinfo {
|
||||
int out,x,y;
|
||||
};
|
||||
|
||||
struct obstruction {
|
||||
int x,y;
|
||||
int shooting,dead,exploding;
|
||||
int explodeprogress;
|
||||
int howmanyhits;
|
||||
int kind,lastshot;
|
||||
};
|
||||
|
||||
/* Define how many sound effects there are */
|
||||
Sample sound_effects[NUM_SAMPLES];
|
||||
|
||||
|
||||
void leveltwoengine(int *level, int *shields, int *score)
|
||||
{
|
||||
int ch,i;
|
||||
char tempst[300];
|
||||
int k,game_paused=0,speed_factor=1;
|
||||
int shipx=36;
|
||||
int whatdelay=1,beginscore,beginshield;
|
||||
FILE *f=NULL;
|
||||
int levelover=0,j,backrow=0;
|
||||
int background[201][13];
|
||||
struct enemyinfo enemy[10];
|
||||
struct bulletinfo bullet[4];
|
||||
struct timeval timing_info;
|
||||
struct timezone dontcare;
|
||||
|
||||
long oldsec,oldusec,time_spent;
|
||||
int howmuchscroll=0;
|
||||
struct obstruction passive[50];
|
||||
int shipadd=0,shipframe=1;
|
||||
int our_row,our_shape,rows_goneby=0;
|
||||
|
||||
int ship_shape[3][1600];
|
||||
int shape_table[40][200];
|
||||
int enemies_drawn[200];
|
||||
|
||||
/* Set this up for Save Game */
|
||||
beginscore=*score;
|
||||
beginshield=*shields;
|
||||
|
||||
/* Load All The Sounds */
|
||||
if (sound_possible) {
|
||||
Snd_loadRawSample(tb1_data_file("tbcc.raw",(char *)&tempst),
|
||||
&sound_effects[0],0);
|
||||
Snd_loadRawSample(tb1_data_file("tbbonk.raw",(char *)&tempst),
|
||||
&sound_effects[1],0);
|
||||
Snd_loadRawSample(tb1_data_file("tbkapow.raw",(char *)&tempst),
|
||||
&sound_effects[2],0);
|
||||
Snd_loadRawSample(tb1_data_file("tbzrrp.raw",(char *)&tempst),
|
||||
&sound_effects[3],0);
|
||||
|
||||
/* Initialize Sound, if Possible */
|
||||
if (Snd_init( NUM_SAMPLES,sound_effects,22050,4,
|
||||
"/dev/dsp")==EXIT_FAILURE) {
|
||||
printf("ERROR! Cannot init sound.\n");
|
||||
sound_enabled=0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load Sprites (or whatever you want to call them) */
|
||||
GGILoadPicPacked(0,0,vaddr,1,1,
|
||||
tb1_data_file("ships.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
|
||||
vmwGetSprite(vaddr,0,0,48,30,(int *)&ship_shape[0]);
|
||||
vmwGetSprite(vaddr,0,32,48,30,(int *)&ship_shape[1]);
|
||||
vmwGetSprite(vaddr,0,64,48,30,(int *)&ship_shape[2]);
|
||||
|
||||
if (*level==2) GGILoadPicPacked(0,0,vaddr,1,1,
|
||||
tb1_data_file("tbaship.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
if (*level==4) GGILoadPicPacked(0,0,vaddr,1,1,
|
||||
tb1_data_file("tbeerm.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
|
||||
for(j=0;j<4;j++)
|
||||
for(i=0;i<10;i++)
|
||||
vmwGetSprite(vaddr,1+i*21,1+j*11,20,10,(int *)&shape_table[j*10+i]);
|
||||
|
||||
/* Load Background Data */
|
||||
if (*level==2) f=fopen(tb1_data_file("level2.dat",(char *)tempst),"r");
|
||||
if (*level==4) f=fopen(tb1_data_file("level4.dat",(char *)tempst),"r");
|
||||
if (f==NULL) printf("ERROR! Could't open level %d data!\n",*level);
|
||||
|
||||
for(j=0;j<200;j++)
|
||||
for(i=0;i<12;i++) fscanf(f,"%d",&background[j][i]);
|
||||
fclose(f);
|
||||
|
||||
/* Initialize Structures for enemy, bullets, and background */
|
||||
for(i=0;i<50;i++) {
|
||||
passive[i].dead=1;
|
||||
passive[i].exploding=0;
|
||||
}
|
||||
for(i=0;i<10;i++) enemy[i].out=0;
|
||||
for(i=0;i<3;i++) {
|
||||
bullet[i].out=0;
|
||||
bullet[i].x=0;
|
||||
bullet[i].y=0;
|
||||
}
|
||||
for(i=0;i<200;i++) enemies_drawn[i]=0;
|
||||
|
||||
/* Setup and draw the sidebar */
|
||||
setupsidebar(*score,0,*shields);
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
vmwCrossBlit(plb_vaddr->write,plb_vaddr2->read,plb_vaddr->stride,200);
|
||||
sprintf(tempst,"%d",*level);
|
||||
ggiDrawBox(vaddr2,251,52,63,7);
|
||||
VMWtextxy(tempst,307,51,tb1_pal[12],tb1_pal[0],0,tb1_font,vaddr2);
|
||||
|
||||
/* Clear the screen and draw the stars */
|
||||
ggiSetGCForeground(vaddr2,tb1_pal[0]);
|
||||
ggiDrawBox(vaddr2,0,0,320,400);
|
||||
for(i=0;i<100;i++) {
|
||||
vmwPutSprite(shape_table[32],20,10,stride_factor,
|
||||
plb_vaddr2->write,rand()%238,
|
||||
rand()%400,plb_vaddr2->stride);
|
||||
vmwPutSprite(shape_table[33],20,10,stride_factor,
|
||||
plb_vaddr2->write,rand()%238,
|
||||
rand()%400,plb_vaddr2->stride);
|
||||
}
|
||||
change_shields(shields);
|
||||
|
||||
/* Announce the Start of the Level */
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
ggiDrawBox(vis,0,0,320,200);
|
||||
coolbox(70,85,240,120,1,vis);
|
||||
if (*level==2) {
|
||||
VMWtextxy(" LEVEL TWO:",84,95,tb1_pal[4],tb1_pal[7],0,tb1_font,vis);
|
||||
VMWtextxy("THE \"PEACE ENVOY\"",84,105,tb1_pal[4],tb1_pal[7],0,tb1_font,vis);
|
||||
}
|
||||
if (*level==4) {
|
||||
VMWtextxy(" LEVEL FOUR:",84,95,tb1_pal[4],tb1_pal[7],0,tb1_font,vis);
|
||||
VMWtextxy(" THE PLANET EERM",84,105,tb1_pal[4],tb1_pal[7],0,tb1_font,vis);
|
||||
}
|
||||
clear_keyboard_buffer();
|
||||
pauseawhile(5);
|
||||
|
||||
gettimeofday(&timing_info,&dontcare);
|
||||
oldsec=timing_info.tv_sec; oldusec=timing_info.tv_usec;
|
||||
|
||||
/**** GAME LOOP ****/
|
||||
while (!levelover) {
|
||||
ch=0;
|
||||
/* Scroll the Background */
|
||||
if (speed_factor>1) howmuchscroll-=speed_factor;
|
||||
else howmuchscroll--;
|
||||
if (howmuchscroll<0) {
|
||||
howmuchscroll=200+howmuchscroll;
|
||||
ggiCopyBox(vaddr2,0,0,240,200,0,200);
|
||||
for(i=0;i<12;i++)
|
||||
for(j=19;j>=0;j--) {
|
||||
our_shape=background[backrow+(19-j)][i];
|
||||
vmwPutSprite(shape_table[our_shape],
|
||||
20,10,stride_factor,
|
||||
plb_vaddr2->write,i*20,j*10,
|
||||
plb_vaddr2->stride);
|
||||
}
|
||||
backrow+=20;
|
||||
}
|
||||
/* Setup Obstructions */
|
||||
our_row=rows_goneby/10;
|
||||
if (!enemies_drawn[our_row]) {
|
||||
enemies_drawn[our_row]=1;
|
||||
for(i=0;i<12;i++) {
|
||||
our_shape=background[our_row][i];
|
||||
if ((our_shape>9)&&(our_shape<20)) {
|
||||
k=0;
|
||||
while ((!passive[k].dead) && (k<40)) k++;
|
||||
passive[k].dead=0;
|
||||
passive[k].kind=our_shape;
|
||||
if ((our_shape>10) && (our_shape<15)) passive[k].shooting=1;
|
||||
else passive[k].shooting=0;
|
||||
passive[k].exploding=0;
|
||||
passive[k].x=i*20;
|
||||
passive[k].y=(rows_goneby%10)-9;
|
||||
passive[k].howmanyhits=1;
|
||||
passive[k].lastshot=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Flip the far background to vaddr */
|
||||
vmwArbitraryCrossBlit(plb_vaddr2->read,0,0+howmuchscroll,240,200,
|
||||
plb_vaddr->write,0,0,plb_vaddr->stride,
|
||||
stride_factor);
|
||||
|
||||
/***Collision Check***/
|
||||
for(i=0;i<40;i++)
|
||||
if ((!passive[i].dead) && (!passive[i].exploding)) {
|
||||
for(j=0;j<3;j++) {
|
||||
if ((bullet[j].out) &&
|
||||
(collision(bullet[j].x,bullet[j].y,3,4,passive[i].x,
|
||||
passive[i].y,10,5))){
|
||||
if (passive[i].kind!=10) {
|
||||
if (sound_enabled) Snd_effect(SND_KAPOW,2);
|
||||
passive[i].exploding=1;
|
||||
passive[i].explodeprogress=0;
|
||||
bullet[j].out=0;
|
||||
*score+=10;
|
||||
changescore(*score,shields);
|
||||
}
|
||||
else {
|
||||
bullet[j].out=0;
|
||||
k=0;
|
||||
while ((!enemy[k].out) && (k<10)) k++;
|
||||
if (k<9) {
|
||||
enemy[k].out=1;
|
||||
enemy[k].y=bullet[j].y;
|
||||
enemy[k].x=bullet[j].x;
|
||||
enemy[k].yspeed=7;
|
||||
enemy[k].kind=21;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See if ship is hitting any Obstructions*/
|
||||
if ((passive[i].y>155) && (passive[i].kind!=10)) {
|
||||
if ((collision(passive[i].x,passive[i].y,10,5,shipx+16,165,5,5))||
|
||||
(collision(passive[i].x,passive[i].y,10,5,shipx+6,175,18,8))) {
|
||||
if (sound_enabled) Snd_effect(SND_BONK,1);
|
||||
passive[i].dead=1;
|
||||
(*shields)--;
|
||||
if(*shields<0) levelover=1;
|
||||
vmwPutSprite(shape_table[34],
|
||||
20,10,stride_factor,plb_vaddr2->write,
|
||||
passive[i].x,passive[i].y+howmuchscroll,
|
||||
plb_vaddr2->stride);
|
||||
change_shields(shields);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* See if hit by lasers */
|
||||
for (i=0;i<10;i++)
|
||||
if (enemy[i].out) {
|
||||
if ((collision(enemy[i].x,enemy[i].y,2,5,shipx+16,165,5,5)) ||
|
||||
(collision(enemy[i].x,enemy[i].y,2,5,shipx+6,175,18,8))) {
|
||||
if (sound_enabled) Snd_effect(SND_BONK,1);
|
||||
enemy[i].out=0;
|
||||
(*shields)--;
|
||||
if (*shields<0) levelover=1;
|
||||
change_shields(shields);
|
||||
}
|
||||
}
|
||||
|
||||
/***DO EXPLOSIONS***/
|
||||
for(i=0;i<40;i++)
|
||||
if (passive[i].exploding) {
|
||||
passive[i].explodeprogress++;
|
||||
vmwPutSprite(shape_table[35+passive[i].explodeprogress],
|
||||
20,10,stride_factor,plb_vaddr2->write,
|
||||
passive[i].x,passive[i].y+howmuchscroll,
|
||||
plb_vaddr2->stride);
|
||||
if (passive[i].explodeprogress>4) {
|
||||
passive[i].dead=1;
|
||||
passive[i].exploding=0;
|
||||
vmwPutSprite(shape_table[34],20,10,stride_factor,
|
||||
plb_vaddr2->write,passive[i].x,
|
||||
passive[i].y+howmuchscroll,
|
||||
plb_vaddr2->stride);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/***MOVE BULLET***/
|
||||
for(i=0;i<3;i++) {
|
||||
if (bullet[i].out) {
|
||||
if (speed_factor>1) bullet[i].y-=(5*speed_factor);
|
||||
else bullet[i].y-=5;
|
||||
if (bullet[i].y<5) bullet[i].out=0;
|
||||
else vmwPutSprite(shape_table[20],20,10,stride_factor,
|
||||
plb_vaddr->write,bullet[i].x,bullet[i].y,
|
||||
plb_vaddr->stride);
|
||||
}
|
||||
}
|
||||
|
||||
/***MOVE ENEMIES***/
|
||||
for(j=0;j<40;j++) {
|
||||
if (!passive[j].dead) {
|
||||
if (speed_factor==1) passive[j].y++;
|
||||
else passive[j].y+=speed_factor;
|
||||
if (passive[j].y>190) passive[j].dead=1;
|
||||
}
|
||||
if (passive[j].lastshot>0) passive[j].lastshot--;
|
||||
if ((!passive[j].dead) && (passive[j].shooting)
|
||||
&& (!passive[j].lastshot) && (passive[j].y>0)) {
|
||||
k=0;
|
||||
while ((enemy[k].out) && (k<10)) k++;
|
||||
if (k<9) {
|
||||
passive[j].lastshot=30;
|
||||
enemy[k].out=1;
|
||||
enemy[k].y=passive[j].y;
|
||||
enemy[k].x=passive[j].x+5;
|
||||
enemy[k].yspeed=5;
|
||||
enemy[k].kind=25;
|
||||
if (passive[j].kind==11) enemy[k].kind=26;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(j=0;j<10;j++) {
|
||||
if (enemy[j].out) {
|
||||
vmwPutSprite(shape_table[enemy[j].kind],20,10,stride_factor,
|
||||
plb_vaddr->write,enemy[j].x,enemy[j].y,
|
||||
plb_vaddr->stride);
|
||||
if (speed_factor==1) enemy[j].y+=enemy[j].yspeed;
|
||||
else enemy[j].y+=(enemy[j].yspeed*speed_factor);
|
||||
if (enemy[j].y>189) enemy[j].out=0;
|
||||
}
|
||||
}
|
||||
|
||||
/***READ KEYBOARD***/
|
||||
if ((ch=get_input())!=0) {
|
||||
switch(ch) {
|
||||
case TB_ESC: levelover=1; break;
|
||||
case TB_RIGHT: if (shipadd>=0) shipadd+=3; else shipadd=0; break;
|
||||
case TB_LEFT: if (shipadd<=0) shipadd-=3; else shipadd=0; break;
|
||||
case TB_F1: game_paused=1; help(); break;
|
||||
case '+': whatdelay++; break;
|
||||
case 'P': case 'p': game_paused=1;
|
||||
coolbox(65,85,175,110,1,vis);
|
||||
VMWtextxy("GAME PAUSED",79,95,tb1_pal[4],tb1_pal[7],
|
||||
0,tb1_font,vis);
|
||||
while (get_input()==0) usleep(30000);
|
||||
break;
|
||||
case '-': whatdelay--; break;
|
||||
case 'S':
|
||||
case 's': if(sound_possible) sound_enabled=!(sound_enabled); break;
|
||||
case TB_F2: game_paused=1; savegame(*level,beginscore,beginshield);
|
||||
break;
|
||||
case ' ': for(j=0;j<3;j++)
|
||||
if (!bullet[j].out) {
|
||||
if (sound_enabled) Snd_effect(SND_CC,0);
|
||||
bullet[j].out=1;
|
||||
bullet[j].x=shipx+21;
|
||||
bullet[j].y=165;
|
||||
vmwPutSprite(shape_table[20],20,10,stride_factor,
|
||||
plb_vaddr->write,bullet[j].x,
|
||||
bullet[j].y,plb_vaddr->stride);
|
||||
j=4;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***MOVE SHIP***/
|
||||
if (speed_factor>1) {
|
||||
shipx+=(shipadd*speed_factor);
|
||||
rows_goneby+=(speed_factor);
|
||||
}
|
||||
else {
|
||||
shipx+=shipadd;
|
||||
rows_goneby++;
|
||||
}
|
||||
if (shipx<1) shipx=1;
|
||||
if (shipx>190) shipx=190;
|
||||
switch(shipframe) {
|
||||
case 1: vmwPutSprite(ship_shape[0],48,30,stride_factor,
|
||||
plb_vaddr->write,shipx,165,
|
||||
plb_vaddr->stride); break;
|
||||
case 3: vmwPutSprite(ship_shape[1],48,30,stride_factor,
|
||||
plb_vaddr->write,shipx,165,
|
||||
plb_vaddr->stride); break;
|
||||
case 2:
|
||||
case 4: vmwPutSprite(ship_shape[2],48,30,stride_factor,
|
||||
plb_vaddr->write,shipx,165,
|
||||
plb_vaddr->stride); break;
|
||||
}
|
||||
shipframe++;
|
||||
if (shipframe==5) shipframe=1;
|
||||
|
||||
/* Flip Pages */
|
||||
vmwCrossBlit(plb_vis->write,plb_vaddr->read,plb_vis->stride,200);
|
||||
ggiFlush(vis);
|
||||
|
||||
/* Calculate how much time has passed */
|
||||
gettimeofday(&timing_info,&dontcare);
|
||||
time_spent=timing_info.tv_usec-oldusec;
|
||||
if (timing_info.tv_sec-oldsec) time_spent+=1000000;
|
||||
#ifdef DEBUG_ON
|
||||
printf("%f\n",1000000/(float)time_spent);
|
||||
#endif
|
||||
/* If time passed was too little, wait a bit */
|
||||
while (time_spent<33000){
|
||||
gettimeofday(&timing_info,&dontcare);
|
||||
usleep(5);
|
||||
time_spent=timing_info.tv_usec-oldusec;
|
||||
if (timing_info.tv_sec-oldsec) time_spent+=1000000;
|
||||
}
|
||||
|
||||
/* It game is paused, don't keep track of time */
|
||||
|
||||
if (game_paused) {
|
||||
gettimeofday(&timing_info,&dontcare);
|
||||
oldusec=timing_info.tv_usec;
|
||||
oldsec=timing_info.tv_sec;
|
||||
game_paused=0;
|
||||
speed_factor=1;
|
||||
}
|
||||
else {
|
||||
speed_factor=(time_spent/30000);
|
||||
oldusec=timing_info.tv_usec;
|
||||
oldsec=timing_info.tv_sec;
|
||||
}
|
||||
|
||||
|
||||
/*printf("%i\n",rows_goneby);*/
|
||||
if (rows_goneby>1950) {
|
||||
printf("%i\n",rows_goneby);
|
||||
/*
|
||||
clearkeyboardbuffer;
|
||||
pauseawhile(200);
|
||||
fade;
|
||||
grapherror:=Mode13LoadPicPacked(0,0,vaddr,false,true,'viewscr.tb1');
|
||||
cls(0,vga);
|
||||
blockmove(0,79,58,116,vaddr,10,10,vga);
|
||||
clearkeyboardbuffer;
|
||||
outsmalltextxy('UNIDENTIFIED SPACECRAFT!',70,10,2,0,vga,true);
|
||||
outsmalltextxy('DO YOU WISH TO DEACTIVATE ',70,20,2,0,vga,true);
|
||||
outsmalltextxy('THIS SHIP''S SECURITY SYSTEMS? (Y/N)',70,30,2,0,vga,true);
|
||||
unfade;
|
||||
clearkeyboardbuffer;
|
||||
ch:='!';
|
||||
repeat
|
||||
if keypressed then ch:=readkey;
|
||||
until (upcase(ch)='Y') or (upcase(ch)='N');
|
||||
|
||||
if upcase(ch)='N' then begin
|
||||
blockmove(0,79,58,116,vaddr,10,50,vga);
|
||||
outsmalltextxy('NO? AFFIRMATIVE. ',70,50,9,0,vga,true);
|
||||
outsmalltextxy('ARMING REMOTE DESTRUCTION RAY.',70,60,9,0,vga,true);
|
||||
outsmalltextxy('GOOD-BYE.',70,70,9,0,vga,true);
|
||||
pauseawhile(400);
|
||||
fade;
|
||||
end;
|
||||
|
||||
if upcase(ch)='Y' then begin
|
||||
blockmove(0,79,58,116,vaddr,10,50,vga);
|
||||
outsmalltextxy('"Y"=CORRECT PASSWORD. ',70,50,2,0,vga,true);
|
||||
outsmalltextxy('WELCOME SUPREME TENTACLEE COMMANDER.',70,60,2,0,vga,true);
|
||||
outsmalltextxy('INITIATING TRACTOR BEAM AND AUTOMATIC',70,70,2,0,vga,true);
|
||||
outsmalltextxy('LANDING PROCEDURE.',70,80,2,0,vga,true);
|
||||
outsmalltextxy('WE WILL BE DEPARTING FOR THE PLANET',70,90,2,0,vga,true);
|
||||
outsmalltextxy('EERM IN THREE MICROCYCLE UNITS.',70,100,2,0,vga,true);
|
||||
pauseawhile(550);
|
||||
level:=3;
|
||||
clearkeyboardbuffer;
|
||||
blockmove(0,42,58,79,vaddr,10,110,vga);
|
||||
outsmalltextxy('Wha? Wait!',70,110,9,0,vga,true);
|
||||
outsmalltextxy('What''s happening?',70,120,9,0,vga,true);
|
||||
pauseawhile(550);
|
||||
fade;
|
||||
end;
|
||||
|
||||
grapherror:=Mode13LoadPicPacked(0,0,vaddr,false,true,'tbtract.tb1');
|
||||
for i:=0 to 239 do
|
||||
for j:=0 to 49 do
|
||||
putpixel240(i,j,getpixel(i,j,vaddr),vaddr2);
|
||||
cls(0,vga);
|
||||
unfade;
|
||||
for howmuchscroll:=50 downto 1 do begin
|
||||
flipd240(howmuchscroll,vaddr,vaddr2);
|
||||
putshape (bigship3off,vaddr,43,30,shipx,165);
|
||||
waitretrace;
|
||||
flipd320(vaddr,vga);
|
||||
end;
|
||||
|
||||
if upcase(ch)='N' then begin
|
||||
clearkeyboardbuffer;
|
||||
line(7,6,shipx+10,180,4,vga);
|
||||
line(shipx+37,180,231,6,4,vga);
|
||||
pauseawhile(50);
|
||||
clearkeyboardbuffer;
|
||||
for i:=shipx to shipx+48 do
|
||||
verticalline(165,195,i,4,vga);
|
||||
pauseawhile(200);
|
||||
flipd240(howmuchscroll,vaddr,vaddr2);
|
||||
flipd320(vaddr,vga);
|
||||
pauseawhile(150);
|
||||
end;
|
||||
|
||||
|
||||
if upcase(ch)='Y' then begin;
|
||||
shipadd:=sgn(shipx-95);
|
||||
shipy:=165;
|
||||
repeat
|
||||
if shipx<>95 then shipx:=shipx-shipadd;
|
||||
if shipy>9 then dec(shipy);
|
||||
flipd240(howmuchscroll,vaddr,vaddr2);
|
||||
line(7,6,shipx+10,shipy+15,2,vaddr);
|
||||
line(shipx+37,shipy+15,231,6,2,vaddr);
|
||||
putshape (bigship3off,vaddr,43,30,shipx,shipy);
|
||||
waitretrace;
|
||||
flipd320(vaddr,vga);
|
||||
until (shipx=95) and (shipy=9);
|
||||
clearkeyboardbuffer;
|
||||
pauseawhile(850);
|
||||
fade;
|
||||
cls(0,vga);
|
||||
|
||||
|
||||
while keypressed do ch:=readkey;
|
||||
if level=4 then begin
|
||||
outsmalltextxy('THE PLANET EERM?',20,20,10,0,vga,true);
|
||||
outsmalltextxy('XENOCIDE FLEET?',20,30,10,0,vga,true);
|
||||
outsmalltextxy('WHAT''S GOING ON?',20,40,10,0,vga,true);
|
||||
outsmalltextxy('A MAJOR GOVERNMENT CONSPIRACY? MASS HALUCINATIONS?',20,50,10,0,vga,true);
|
||||
|
||||
outsmalltextxy('WATCH FOR TOM BOMBEM LEVEL 3 (CURRENTLY IN THE DESIGN PHASE).',10,70,12,0,vga,true);
|
||||
outsmalltextxy('ALL THESE QUESTIONS WILL BE ANSWERED!',10,80,12,0,vga,true);
|
||||
outsmalltextxy('ALSO MORE FEATURES WILL BE ADDED:',10,90,12,0,vga,true);
|
||||
outsmalltextxy(' BETTER GRAPHICS, SOUND AND SPEED.',10,100,12,0,vga,true);
|
||||
|
||||
outsmalltextxy('TO HASTEN COMPLETION, SEND QUESTIONS/COMMENTS/DONATIONS TO ',9,120,9,0,vga,true);
|
||||
outsmalltextxy('THE AUTHOR (SEE THE REGISTER MESSAGE FOR RELEVANT ADDRESSES).',9,130,9,0,vga,true);
|
||||
|
||||
outsmalltextxy('THANK YOU FOR PLAYING TOM BOMBEM',80,150,14,0,vga,true);
|
||||
unfade;
|
||||
pauseawhile(1800);
|
||||
end; */
|
||||
levelover=1;
|
||||
}
|
||||
}
|
||||
Snd_restore();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void littleopener2()
|
||||
{
|
||||
char tempst[300];
|
||||
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
ggiDrawBox(vis,0,0,320,200);
|
||||
ggiSetGCForeground(vaddr,tb1_pal[0]);
|
||||
ggiDrawBox(vaddr,0,0,320,200);
|
||||
GGILoadPicPacked(0,0,vis,1,1,
|
||||
tb1_data_file("tbl2ship.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
VMWtextxy("Hmmmm... ",10,10,tb1_pal[4],tb1_pal[0],0,tb1_font,vis);
|
||||
VMWtextxy("This Might Be Harder Than I Thought.",10,20,tb1_pal[4],tb1_pal[0],0,tb1_font,vis);
|
||||
pauseawhile(13);
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
ggiDrawBox(vis,0,0,320,200);
|
||||
|
||||
}
|
4
levels.h
Normal file
4
levels.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
void levelone(int *level, int *shields,int *score);
|
||||
void littleopener();
|
||||
void leveltwoengine(int *level, int *shields, int *score);
|
||||
void littleopener2();
|
713
soundIt.c
Normal file
713
soundIt.c
Normal file
|
@ -0,0 +1,713 @@
|
|||
|
||||
/* SoundIt library 0.04
|
||||
|
||||
Copyright 1994 Brad Pitzel pitzel@cs.sfu.ca
|
||||
|
||||
Adapted to Solaris/SunOS and HPUX by Peter Ekberg.
|
||||
|
||||
Feel free to use/distribute/modify as long as proper credits
|
||||
are included.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LINUX_SOUND)
|
||||
# include <linux/soundcard.h>
|
||||
|
||||
#elif defined(HAVE_SUN_SOUND)
|
||||
# if defined(HAVE_SYS_AUDIOIO_H)
|
||||
# include <sys/audioio.h>
|
||||
# elif defined(HAVE_SUN_AUDIOIO_H)
|
||||
# include <sun/audioio.h>
|
||||
# endif
|
||||
|
||||
#elif defined(HAVE_HP_SOUND)
|
||||
# include <sys/audio.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "soundIt.h"
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
/*==========================================================================*/
|
||||
/* the mix buff, where the channels are mixed into. The mix buffer is then
|
||||
dumped to the sound device (/dev/dsp). Samples are mixed in
|
||||
Vunclipbuf (buffer of ints), then the values in Vunclipbuf are clipped to
|
||||
values between 0 and 255, and stored into Vclippedbuf (buffer of unsigned
|
||||
chars).
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
#if defined(HAVE_LINUX_SOUND)
|
||||
unsigned char *Vclippedbuf;
|
||||
#elif defined(HAVE_16BIT_SOUND)
|
||||
short *Vclippedbuf;
|
||||
#endif
|
||||
int *Vunclipbuf;
|
||||
int Vsize;
|
||||
} Mix;
|
||||
|
||||
/*==========================================================================*/
|
||||
typedef struct {
|
||||
unsigned char *Vstart, *Vcurrent; /* ptr's into a playing sample */
|
||||
int Vlen; /* length of sample in bytes */
|
||||
int Vleft; /* bytes left of sample to play */
|
||||
int Vloop; /* loop=0 : play sample once */
|
||||
/* loop=1 : loop sample */
|
||||
} Channel;
|
||||
|
||||
/*==========================================================================*/
|
||||
|
||||
/* variables prefixed with S_ are static */
|
||||
/* 0 if mixer isn't initialized or init failed, 1 if mixer is good */
|
||||
static int S_mixerStatus = 0;
|
||||
|
||||
static const Sample *S_sounds = NULL; /* ptr to array of samples */
|
||||
static int S_num_sounds = 0; /* size of 'sounds' array above */
|
||||
static int S_fd_snddev = -1; /* file # for sound device once open */
|
||||
static int S_fd_pipe[2] = { -1, -1 }; /* pipe to talk to child process */
|
||||
static int S_son_pid = -1; /* process ID for the forked sound mixer */
|
||||
static const char *S_snddev = NULL; /* char string for device, ie "/dev/dsp" */
|
||||
static int S_num_channels = 6; /* number of channels to mix */
|
||||
static int S_playback_freq = 0; /* playback frequency (in Hz) */
|
||||
/*==========================================================================*/
|
||||
/* non-public functions, used only within this file*/
|
||||
|
||||
int Snd_init_dev(void);
|
||||
int Snd_restore_dev(void);
|
||||
|
||||
void Chan_reset(Channel *chan); /* init channel structure */
|
||||
|
||||
/* start a sample playing on a channel */
|
||||
void Chan_assign(Channel *chan, const Sample *snd);
|
||||
|
||||
/* mix all channels together into the 'mix' structure */
|
||||
int Chan_mixAll(Mix *mix, Channel *ch);
|
||||
|
||||
/* used by Chan_mixAll to mix the 1st channel */
|
||||
int Chan_copyIn(Channel *chan, Mix *mix);
|
||||
|
||||
/* used by Chan_mixAll to mix a loop in the 1st channel */
|
||||
int Chan_copyIn_loop(Channel *chan, Mix *mix);
|
||||
|
||||
/* used by Chan_mixAll to mix the middle channels */
|
||||
int Chan_mixIn(Channel *chan, Mix *mix);
|
||||
|
||||
/* used by Chan_mixAll to mix the last channel */
|
||||
int Chan_finalMixIn(Channel *chan, Mix *mix);
|
||||
|
||||
|
||||
/* alloc mem for mix buffer, and deallocate function */
|
||||
/* The sound channels are mixed together into the mix buffer */
|
||||
/* then the mix buffer data is sent directly to the sound device */
|
||||
void Mix_alloc(Mix *mix, int size);
|
||||
void Mix_dealloc(Mix *mix);
|
||||
|
||||
/*==========================================================================*/
|
||||
/* justing for testing, normally not called */
|
||||
void
|
||||
dump_snd_list(void)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
for(i=0; i<S_num_sounds; i++) {
|
||||
printf("snd %d: len = %d \n", i, S_sounds[i].len );
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
int
|
||||
Snd_init(int num_snd, const Sample *sa, int frequency,
|
||||
int channels, const char *dev)
|
||||
{
|
||||
int result;
|
||||
|
||||
S_num_sounds = num_snd;
|
||||
S_sounds = sa; /* array of sound samples*/
|
||||
S_playback_freq = frequency;
|
||||
S_num_channels = channels;
|
||||
S_snddev= dev; /* sound device, eg /dev/dsp*/
|
||||
|
||||
if (S_sounds==NULL)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
result=Snd_init_dev();
|
||||
|
||||
if (result==EXIT_SUCCESS) {
|
||||
S_mixerStatus=1;
|
||||
}
|
||||
else {
|
||||
S_mixerStatus=0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
int
|
||||
Snd_restore(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
if(!S_mixerStatus)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
result=Snd_restore_dev();
|
||||
|
||||
if (result==EXIT_SUCCESS) {
|
||||
S_mixerStatus=0;
|
||||
}
|
||||
else {
|
||||
S_mixerStatus=0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* volume control not implemented yet.*/
|
||||
int
|
||||
Snd_effect(int sound_num, int channel)
|
||||
{
|
||||
if(!S_mixerStatus)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* make sure a valid sound # was passed in */
|
||||
if(sound_num<0 || sound_num>=S_num_sounds)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* make sure a valid channel # was passed in */
|
||||
if(channel<0 || channel>=S_num_channels)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
if(S_sounds[sound_num].data != NULL) {
|
||||
write(S_fd_pipe[1], &sound_num, sizeof(sound_num));
|
||||
write(S_fd_pipe[1], &channel, sizeof(channel));
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"Referencing NULL sound entry\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
int
|
||||
Snd_init_dev(void)
|
||||
{
|
||||
int whoami;
|
||||
S_fd_snddev = -1;
|
||||
|
||||
S_son_pid = 0;
|
||||
|
||||
if(access(S_snddev,W_OK) != 0) {
|
||||
perror("no access to sound device");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
S_fd_snddev = open(S_snddev,O_WRONLY);
|
||||
|
||||
if(S_fd_snddev < 0) {
|
||||
perror("cannot open sound device");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
close(S_fd_snddev);
|
||||
|
||||
if(pipe(S_fd_pipe) < 0) {
|
||||
perror("cannot create pipe for sound control");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* now setup 2nd process for writing the data... */
|
||||
if((whoami = fork()) < 0) {
|
||||
perror("cannot fork sound driver\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if(whoami != 0) { /* successfully created son */
|
||||
close(S_fd_pipe[0]); /* close end for reading */
|
||||
S_son_pid = whoami;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* Here is the code for the son... */
|
||||
{
|
||||
int sound_num,ch,i;
|
||||
struct timeval tval = {0L,0L};
|
||||
fd_set readfds,dsp;
|
||||
Mix mix;
|
||||
int fragsize;
|
||||
Channel *chan;
|
||||
|
||||
chan = (Channel *)malloc(sizeof(Channel) * S_num_channels);
|
||||
|
||||
for(i=0; i<S_num_channels; i++)
|
||||
Chan_reset( chan+i );
|
||||
|
||||
S_fd_snddev = open(S_snddev,O_WRONLY);
|
||||
if(S_fd_snddev < 0) {
|
||||
perror("Cannot open sound device");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if defined(HAVE_LINUX_SOUND)
|
||||
{
|
||||
int frag;
|
||||
frag = FRAG_SPEC; /*defined in soundIt.h */
|
||||
|
||||
ioctl(S_fd_snddev, SNDCTL_DSP_SETFRAGMENT, &frag);
|
||||
|
||||
if(ioctl(S_fd_snddev,SNDCTL_DSP_SPEED, &S_playback_freq)==-1)
|
||||
perror("Sound driver ioctl");
|
||||
|
||||
fragsize=0;
|
||||
if(ioctl(S_fd_snddev,SNDCTL_DSP_GETBLKSIZE, &fragsize)==-1)
|
||||
perror("Sound driver ioctl");
|
||||
}
|
||||
#elif defined(HAVE_SUN_SOUND)
|
||||
{
|
||||
audio_info_t ainfo;
|
||||
|
||||
AUDIO_INITINFO(&ainfo);
|
||||
ainfo.play.precision = 16;
|
||||
ainfo.play.sample_rate = S_playback_freq;
|
||||
ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
ainfo.play.channels = 1;
|
||||
ainfo.play.port = AUDIO_LINE_OUT|AUDIO_HEADPHONE|AUDIO_SPEAKER;
|
||||
if(ioctl(S_fd_snddev,AUDIO_SETINFO, &ainfo)==-1)
|
||||
perror("Sound driver ioctl");
|
||||
|
||||
fragsize=512;
|
||||
}
|
||||
#elif defined(HAVE_HP_SOUND)
|
||||
{
|
||||
struct audio_describe adescribe;
|
||||
struct audio_gain again;
|
||||
struct audio_limits alimits;
|
||||
int i;
|
||||
int best_rate;
|
||||
int temp;
|
||||
|
||||
if(ioctl(S_fd_snddev, AUDIO_DESCRIBE, &adescribe)==-1)
|
||||
perror("Sound driver ioctl: Audio Describe");
|
||||
|
||||
/*
|
||||
printf("Audio Device: ");
|
||||
switch(adescribe.audio_id) {
|
||||
case AUDIO_ID_PSB2160:
|
||||
printf("PSB 2160\n");
|
||||
break;
|
||||
case AUDIO_ID_CS4215:
|
||||
printf("CS 4215\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown\n");
|
||||
break;
|
||||
}
|
||||
printf("Samplerates:");
|
||||
for(i=0; i<adescribe.nrates; i++)
|
||||
printf(" %d", adescribe.sample_rate[i]);
|
||||
printf("\nMax bits per sample: %d\n", adescribe.max_bits_per_sample);
|
||||
printf("Channels: %d\n", adescribe.nchannels);
|
||||
*/
|
||||
|
||||
if(adescribe.max_bits_per_sample < 16)
|
||||
printf("Not enough bits\n");
|
||||
|
||||
temp = AUDIO_FORMAT_LINEAR16BIT;
|
||||
if(ioctl(S_fd_snddev, AUDIO_SET_DATA_FORMAT, temp)==-1)
|
||||
perror("Sound driver ioctl: Audio Set Data Format");
|
||||
|
||||
best_rate = 0;
|
||||
for(i=0; i<adescribe.nrates; i++)
|
||||
if(abs(adescribe.sample_rate[i]-S_playback_freq)
|
||||
< abs(best_rate-S_playback_freq))
|
||||
best_rate = adescribe.sample_rate[i];
|
||||
if(abs(best_rate-S_playback_freq) > 1050)
|
||||
printf("No good sample rate\n");
|
||||
if(ioctl(S_fd_snddev, AUDIO_SET_SAMPLE_RATE, best_rate)==-1)
|
||||
perror("Sound driver ioctl: Audio Set Sample Rate");
|
||||
|
||||
/* AUDIO_OUT_LINE | AUDIO_OUT_INTERNAL | AUDIO_OUT_EXTERNAL */
|
||||
if(ioctl(S_fd_snddev, AUDIO_SET_OUTPUT, AUDIO_OUT_EXTERNAL)==-1)
|
||||
perror("Sound driver ioctl: Audio Set Output");
|
||||
|
||||
again.cgain[0].transmit_gain = AUDIO_MAX_GAIN;
|
||||
again.cgain[0].monitor_gain = AUDIO_OFF_GAIN;
|
||||
again.cgain[1].transmit_gain = AUDIO_MAX_GAIN;
|
||||
again.cgain[1].monitor_gain = AUDIO_OFF_GAIN;
|
||||
again.channel_mask = AUDIO_CHANNEL_LEFT | AUDIO_CHANNEL_RIGHT;
|
||||
if(ioctl(S_fd_snddev, AUDIO_SET_GAINS, &again)==-1)
|
||||
perror("Sound driver ioctl: Audio Set Gain");
|
||||
|
||||
/*
|
||||
alimits.max_transmit_buffer_size = 512;
|
||||
alimits.max_receive_buffer_size = 512;
|
||||
if(ioctl(S_fd_snddev, AUDIO_SET_LIMITS, &alimits)==-1)
|
||||
perror("Sound driver ioctl: Audio Set Limits");
|
||||
|
||||
if(ioctl(S_fd_snddev, AUDIO_GET_LIMITS, &alimits)==-1)
|
||||
perror("Sound driver ioctl: Audio Get Limits");
|
||||
|
||||
fragsize=alimits.max_transmit_buffer_size;
|
||||
*/
|
||||
fragsize = 1024;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*printf("after: block size: %d \n", fragsize);*/
|
||||
|
||||
/* init mixer object*/
|
||||
Mix_alloc(&mix, fragsize);
|
||||
|
||||
close(S_fd_pipe[1]); /* close end for writing */
|
||||
|
||||
FD_ZERO(&dsp);
|
||||
FD_SET(S_fd_snddev, &dsp);
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(S_fd_pipe[0], &readfds);
|
||||
|
||||
/* printf("soundIt library v"SOUNDIT_VERS" initialized.\n");*/
|
||||
|
||||
for(;;) {
|
||||
FD_SET(S_fd_pipe[0], &readfds);
|
||||
tval.tv_sec=0L;
|
||||
tval.tv_usec=0L;
|
||||
select(S_fd_pipe[0]+1, &readfds,NULL,NULL,&tval);
|
||||
|
||||
if(FD_ISSET(S_fd_pipe[0], &readfds)) {
|
||||
if(read(S_fd_pipe[0], &sound_num, sizeof(int))==0)
|
||||
break;
|
||||
|
||||
read(S_fd_pipe[0], &ch, sizeof(int));
|
||||
|
||||
/*printf("chan=%d snd=%d len=%d\n",
|
||||
ch, sound_num, S_sounds[sound_num].len);*/
|
||||
Chan_assign(&(chan[ch]), &(S_sounds[sound_num]));
|
||||
}
|
||||
|
||||
Chan_mixAll(&mix,chan);
|
||||
|
||||
#if defined(HAVE_LINUX_SOUND)
|
||||
write(S_fd_snddev, mix.Vclippedbuf, fragsize);
|
||||
#elif defined(HAVE_SUN_SOUND)
|
||||
{
|
||||
int stat;
|
||||
audio_info_t ainfo;
|
||||
static unsigned int samplecount=0;
|
||||
|
||||
do {
|
||||
stat = ioctl(S_fd_snddev, AUDIO_GETINFO, &ainfo);
|
||||
if(samplecount-ainfo.play.samples<fragsize)
|
||||
stat = 1;
|
||||
} while(!stat);
|
||||
write(S_fd_snddev, (char *)mix.Vclippedbuf, sizeof(short)*fragsize);
|
||||
samplecount+=fragsize;
|
||||
}
|
||||
#elif defined(HAVE_HP_SOUND)
|
||||
{
|
||||
struct audio_status astatus;
|
||||
int stat;
|
||||
|
||||
do {
|
||||
stat = ioctl(S_fd_snddev, AUDIO_GET_STATUS, &astatus);
|
||||
if(astatus.transmit_exact_count<2*fragsize)
|
||||
stat = 1;
|
||||
} while(!stat);
|
||||
|
||||
write(S_fd_snddev, (char *)mix.Vclippedbuf, sizeof(short)*fragsize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Mix_dealloc( &mix );
|
||||
/* printf("soundIt process exiting.\n");*/
|
||||
close(S_fd_pipe[0]);
|
||||
close(S_fd_pipe[1]);
|
||||
exit (0);
|
||||
} /* end of child process */
|
||||
}
|
||||
|
||||
|
||||
/*==========================================================================*/
|
||||
int
|
||||
Snd_restore_dev(void)
|
||||
{
|
||||
close(S_fd_pipe[0]);
|
||||
close(S_fd_pipe[1]);
|
||||
|
||||
/* wait for child process to die*/
|
||||
wait(NULL);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* CHANNEL MIXING FUNCTIONS */
|
||||
/*==========================================================================*/
|
||||
void
|
||||
Chan_reset(Channel *chan)
|
||||
{
|
||||
chan->Vstart=NULL;
|
||||
chan->Vcurrent=NULL;
|
||||
chan->Vlen=0;
|
||||
chan->Vleft=0;
|
||||
chan->Vloop=0;
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
void
|
||||
Chan_assign(Channel *chan, const Sample *snd)
|
||||
{
|
||||
chan->Vstart = snd->data;
|
||||
chan->Vcurrent= chan->Vstart;
|
||||
chan->Vlen = snd->len;
|
||||
chan->Vleft = snd->len;
|
||||
chan->Vloop = snd->loop;
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
int
|
||||
Chan_copyIn(Channel *chan, Mix *mix)
|
||||
{
|
||||
int i, *p = mix->Vunclipbuf, result, min;
|
||||
|
||||
result = (chan->Vleft>0) ? 1 : 0;
|
||||
min = (chan->Vleft < mix->Vsize) ? chan->Vleft : mix->Vsize;
|
||||
|
||||
for(i=0; i<min; i++) {
|
||||
*p++ = (int)*chan->Vcurrent++;
|
||||
}
|
||||
chan->Vleft -= i;
|
||||
|
||||
/* fill the remaining (if any) part of the mix buffer with silence */
|
||||
while(i<mix->Vsize) {
|
||||
*p++ = 128;
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
int
|
||||
Chan_copyIn_loop(Channel *chan, Mix *mix)
|
||||
{
|
||||
int i=0;
|
||||
int *p = mix->Vunclipbuf;
|
||||
int left_mix_vsize=mix->Vsize;
|
||||
|
||||
if (chan->Vleft==0)
|
||||
chan->Vleft=chan->Vlen;
|
||||
|
||||
if(left_mix_vsize > chan->Vleft) {
|
||||
|
||||
/* fill the rest of the sample first */
|
||||
for(i=0; i<chan->Vleft; i++)
|
||||
*p++ = (int)*chan->Vcurrent++;
|
||||
|
||||
left_mix_vsize -= chan->Vleft;
|
||||
chan->Vleft = chan->Vlen;
|
||||
|
||||
/* loop the sample by writing it repeatedly */
|
||||
while(left_mix_vsize > chan->Vlen) {
|
||||
chan->Vcurrent=chan->Vstart;
|
||||
for(i=0; i<chan->Vleft; i++)
|
||||
*p++ = (int) *chan->Vcurrent++;
|
||||
|
||||
left_mix_vsize-=chan->Vlen;
|
||||
}
|
||||
|
||||
/* Return to the start of the Sample */
|
||||
chan->Vcurrent=chan->Vstart;
|
||||
|
||||
/* If there is some space left, then fill it up :-) */
|
||||
for(i=0;i<left_mix_vsize;i++)
|
||||
*p++=(int)*chan->Vcurrent++;
|
||||
|
||||
chan->Vleft=chan->Vlen - left_mix_vsize;
|
||||
}
|
||||
else {
|
||||
|
||||
/* fill in all that fits, no looping to be done ! */
|
||||
for(i=0; i<mix->Vsize; i++)
|
||||
*p++ = (int) *chan->Vcurrent++;
|
||||
|
||||
chan->Vleft -= i;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
int
|
||||
Chan_mixIn(Channel *chan, Mix *mix)
|
||||
{
|
||||
int i,*p = mix->Vunclipbuf, result, min;
|
||||
|
||||
result = (chan->Vleft>0) ? 1 : 0;
|
||||
min = (chan->Vleft < mix->Vsize) ? chan->Vleft : mix->Vsize;
|
||||
|
||||
for(i=0; i<min; i++)
|
||||
*p++ += (int)(*chan->Vcurrent++) - 128;
|
||||
|
||||
chan->Vleft -= i;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*========================================================================*/
|
||||
/* clip an int to a value between 0 and 255 */
|
||||
#ifdef HAVE_16BIT_SOUND
|
||||
/*
|
||||
static inline short
|
||||
clip(int i)
|
||||
{
|
||||
return ((i<0) ? 0 : ( (i>255) ? 255 : i )) * 257 - 32768;
|
||||
}
|
||||
*/
|
||||
#define clip(i) ((short)((((i)<0) ? 0 : ( ((i)>255) ? 255 : (i) )) * 257 - 128*257))
|
||||
#else
|
||||
static inline unsigned char
|
||||
clip(int i)
|
||||
{
|
||||
return (i<0) ? 0 : ( (i>255) ? 255 : i );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*==========================================================================*/
|
||||
int
|
||||
Chan_finalMixIn(Channel *chan, Mix *mix)
|
||||
{
|
||||
int i;
|
||||
int *p = mix->Vunclipbuf, result, min;
|
||||
#ifdef HAVE_16BIT_SOUND
|
||||
short *final = mix->Vclippedbuf;
|
||||
#else
|
||||
unsigned char *final = mix->Vclippedbuf;
|
||||
#endif
|
||||
|
||||
result = (chan->Vleft>0) ? 1 : 0;
|
||||
min = (chan->Vleft < mix->Vsize) ? chan->Vleft : mix->Vsize;
|
||||
|
||||
for(i=0; i<min; i++) {
|
||||
*p += (int)(*chan->Vcurrent++) - 128;
|
||||
*final++ = clip(*p);
|
||||
p++;
|
||||
}
|
||||
chan->Vleft -= i;
|
||||
|
||||
/* copy rest of Vunclipbuf over to Vclippedbuf */
|
||||
while (i<mix->Vsize) {
|
||||
*final++ = clip(*p);
|
||||
p++;
|
||||
i++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*==========================================================================*/
|
||||
void
|
||||
Mix_alloc(Mix *mix, int size)
|
||||
{
|
||||
#ifdef HAVE_16BIT_SOUND
|
||||
mix->Vclippedbuf = (short *)calloc( sizeof(short), size);
|
||||
#else
|
||||
mix->Vclippedbuf = (unsigned char *)calloc( sizeof(char), size);
|
||||
#endif
|
||||
mix->Vunclipbuf = (int *)calloc( sizeof(int), size);
|
||||
mix->Vsize = size;
|
||||
|
||||
if((mix->Vclippedbuf==NULL) || (mix->Vunclipbuf==NULL)) {
|
||||
printf("Unable to allocate memory for mixer buffer.\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
void
|
||||
Mix_dealloc(Mix *mix)
|
||||
{
|
||||
if(mix->Vclippedbuf)
|
||||
free(mix->Vclippedbuf);
|
||||
if(mix->Vunclipbuf)
|
||||
free(mix->Vunclipbuf);
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* Mixes together the channels into one sound.
|
||||
Returns # of channels currently playing *any* sound
|
||||
Therefore, return 0 means to channels have a sample, therefore no
|
||||
sound is playing
|
||||
*/
|
||||
int
|
||||
Chan_mixAll(Mix *mix, Channel *chan)
|
||||
{
|
||||
int result=0, i=0;
|
||||
|
||||
/* Loop in the first channel ? */
|
||||
if (chan->Vloop==0)
|
||||
result = Chan_copyIn(chan, mix);
|
||||
else
|
||||
result = Chan_copyIn_loop(chan, mix);
|
||||
|
||||
/* we want to loop for S_num_channels-2 */
|
||||
for(i=2; i<S_num_channels; i++)
|
||||
result += Chan_mixIn(++chan, mix);
|
||||
|
||||
result += Chan_finalMixIn(++chan, mix);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* given the name of a .raw sound file, load it into the Sample struct */
|
||||
/* pointed to by 'sample' */
|
||||
/* Returns -1 couldn't open/read file */
|
||||
/* -2 couldn't alloc memory) */
|
||||
int
|
||||
Snd_loadRawSample(const char *file, Sample *sample, int loop)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
sample->data = NULL;
|
||||
sample->len = 0;
|
||||
sample->loop = loop;
|
||||
|
||||
fp = fopen(file,"r");
|
||||
|
||||
if(fp==NULL)
|
||||
return -1;
|
||||
|
||||
/* get length of the file */
|
||||
sample->len = lseek(fileno(fp), 0, SEEK_END);
|
||||
|
||||
/* go back to beginning of file */
|
||||
lseek(fileno(fp), 0, SEEK_SET);
|
||||
|
||||
/* alloc memory for sample */
|
||||
sample->data = (unsigned char *)malloc(sample->len);
|
||||
|
||||
if(sample->data==NULL) {
|
||||
fclose(fp);
|
||||
return -2;
|
||||
}
|
||||
|
||||
fread(sample->data, 1, sample->len, fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
91
soundIt.h
Normal file
91
soundIt.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
|
||||
/* SoundIt library 0.04
|
||||
|
||||
Copyright 1994 Brad Pitzel pitzel@cs.sfu.ca
|
||||
|
||||
Adapted to Solaris/SunOS by Peter Ekberg.
|
||||
|
||||
Feel free to use/distribute/modify as long as proper credits
|
||||
are included.
|
||||
*/
|
||||
|
||||
/* Designed for digital sound effects in interactive apps (games, drum
|
||||
machines, digital organs, ???)
|
||||
|
||||
Will mix channels of mono 8-bit raw samples, & play back in "real-time".
|
||||
Each channel can only play one sample at a time, but all
|
||||
channels can play a different sample simultaneously.
|
||||
|
||||
If you have sox, use the ' -t .ub ' option to make samples
|
||||
that this library will play properly.
|
||||
*/
|
||||
|
||||
#ifndef SOUNDIT_VERS
|
||||
#define SOUNDIT_VERS "0.04"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
#ifndef EXIT_SUCCESS
|
||||
#define EXIT_SUCCESS 0
|
||||
#endif
|
||||
|
||||
/* 00002 = 2 fragments */
|
||||
/* 00007 = means each fragment is 2^7 or 128 bytes */
|
||||
/* See voxware docs (in /usr/src/linux/drivers/sound) for more info */
|
||||
#define FRAG_SPEC 0x00020007
|
||||
|
||||
/*==========================================================================*/
|
||||
typedef struct {
|
||||
unsigned char *data; /* unsigned 8-bit raw samples */
|
||||
int len; /* length of sample in bytes */
|
||||
int loop; /* loop=0 : play sample once, */
|
||||
/* loop=1 : loop sample */
|
||||
} Sample;
|
||||
|
||||
void dump_snd_list(void);
|
||||
|
||||
/*==========================================================================*/
|
||||
/* given the name of a .raw sound file, load it into the Sample struct */
|
||||
/* pointed to by 'sample' */
|
||||
int
|
||||
Snd_loadRawSample(const char *file, Sample *sample, int loop);
|
||||
|
||||
/*==========================================================================*/
|
||||
/* init sound device, etc.. */
|
||||
/* num_snd = the number of samples in the sample array *sa */
|
||||
/* sa = the sample array */
|
||||
/* freq = the rate (Hz) to play back the samples */
|
||||
/* channels = # of channels to mix */
|
||||
/* sound_device = a char string for the sound device, eg, "/dev/dsp" */
|
||||
/* returns: 0=success, -1=failure.*/
|
||||
int
|
||||
Snd_init(int num_snd, const Sample *sa, int freq,
|
||||
int channels, const char *sound_device);
|
||||
|
||||
|
||||
/* shutdown sample player, free mem, etc/etc..*/
|
||||
int
|
||||
Snd_restore(void);
|
||||
|
||||
|
||||
/* play a sound effect in the given channel 1..n*/
|
||||
/* volume = integers from 0 (off) to 100 (full volume)*/
|
||||
int
|
||||
Snd_effect(int nr, int channel);
|
||||
|
||||
|
||||
/* stop a channel (1..n) from playing*/
|
||||
/*void
|
||||
Snd_reset(enum snd_channel channel);*/
|
||||
|
||||
|
||||
/* stop all channels from playing*/
|
||||
/*void
|
||||
Snd_reset(void);*/
|
||||
|
||||
|
||||
#endif
|
799
svmwgrap.c
Normal file
799
svmwgrap.c
Normal file
|
@ -0,0 +1,799 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <ggi/libggi.h>
|
||||
|
||||
|
||||
/*var unfadered:array[0..255] of byte;
|
||||
unfadeblue:array[0..255] of byte;
|
||||
unfadegreen:array[0..255] of byte;
|
||||
fontline:array[0..255] of byte;
|
||||
charset:array[0..255,0..15] of byte;
|
||||
charheight:byte;
|
||||
fontseg,fontoff:word;
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *font_data;
|
||||
int width;
|
||||
int height;
|
||||
int numchars;
|
||||
} vmw_font;
|
||||
|
||||
|
||||
int vmwCrossBlit(char *dest,char *src,int stride,int ysize)
|
||||
{
|
||||
|
||||
int y;
|
||||
|
||||
for (y = 0; y < ysize; y++) {
|
||||
memcpy (dest, src, stride);
|
||||
src += stride;
|
||||
dest += stride;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vmwCrossBlit240(char *dest,char *src,int stride,int stride_factor,
|
||||
int ysize)
|
||||
{
|
||||
|
||||
int y;
|
||||
|
||||
for (y = 0; y < ysize; y++) {
|
||||
memcpy (dest, src, (240*stride_factor));
|
||||
src += stride;
|
||||
dest += stride;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vmwArbitraryCrossBlit(char *src,int x1,int y1,int w,int h,
|
||||
char *dest,int x2,int y2,int stride,
|
||||
int stride_factor)
|
||||
{
|
||||
int y;
|
||||
src+=(stride*y1);
|
||||
dest+=(stride*y2);
|
||||
|
||||
for(y=0;y<h;y++) {
|
||||
memcpy ((dest+x2),(src+x1),(w*stride_factor));
|
||||
src+=stride;
|
||||
dest+=stride;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
int vmwPutSprite(int *src,int w,int h,int stride_factor,
|
||||
char *dest,int x,int y,int dest_stride)
|
||||
{
|
||||
int xx,yy;
|
||||
dest+=(dest_stride*y);
|
||||
for(yy=0;yy<h;yy++){
|
||||
for(xx=0;xx<w;xx++)
|
||||
if(*(src+xx)) memcpy(dest+(stride_factor*(xx+x)),(src+xx),stride_factor);
|
||||
/**(dest+xx+x)=15;*/
|
||||
src+=w;
|
||||
dest+=dest_stride;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int vmwGetSprite(ggi_visual_t visual,int x,int y,int w,int h,
|
||||
int *sprite)
|
||||
{
|
||||
int width,xx;
|
||||
|
||||
xx=x;
|
||||
while(h--) {
|
||||
x=xx;width=w;
|
||||
while(width--) ggiGetPixel(visual,x++,y,sprite++);
|
||||
y++;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int vmwPutSprite(ggi_visual_t visual,int x,int y,int w,int h,
|
||||
int transparent_color,int *sprite)
|
||||
{
|
||||
int width,xx;
|
||||
|
||||
xx=x;
|
||||
while(h--) {
|
||||
x=xx; width=w;
|
||||
while(width--){
|
||||
if ( *(sprite)!=transparent_color )
|
||||
ggiPutPixel(visual,x,y,*(sprite));
|
||||
x++;
|
||||
sprite++;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
function Mode13SavePicPacked(x1,y1,x2,y2,numcolors:integer;where:word;filename:string):byte;
|
||||
function Mode13LoadPicPacked(x1,y1:integer;where:word;LoadPal,LoadPic:boolean;FileName:string):byte;
|
||||
procedure cls32(col:byte;where:word);
|
||||
procedure flipd320(source,dest:word);
|
||||
procedure flipd240(hm,va,va2:word);
|
||||
procedure flipd50(fromwhere,off1,whereto,off2:word);
|
||||
|
||||
Procedure SetMCGA;
|
||||
Procedure SetText; { This procedure returns you to text mode. }
|
||||
Procedure LoadFont(namest:string);
|
||||
|
||||
Procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
|
||||
Procedure Putpixel240 (X,Y : Integer; Col : Byte; where:word);
|
||||
function getpixel(x,y,where:word):byte;
|
||||
Procedure Pal(Col,R,G,B : Byte);
|
||||
Procedure GetPal(Col : Byte; Var R,G,B : Byte);
|
||||
procedure WaitRetrace;
|
||||
procedure outtextlineover(st:string;x,y:integer;col,background:byte;line:integer;where:word);
|
||||
procedure outtextline(st:string;x,y:integer;col,background:byte;line:integer;where:word);
|
||||
procedure outtextxy(st:string;x,y,col,background:integer;where:word;overwrite:boolean);
|
||||
procedure outsmalltextlineover(st:string;x,y:integer;col,background:byte;line:integer;where:word);
|
||||
procedure outsmalltextline(st:string;x,y:integer;col,background:byte;line:integer;where:word);
|
||||
procedure outsmalltextxy(st:string;x,y,col,background:integer;where:word;overwrite:boolean);
|
||||
function sgn(a:real):integer;
|
||||
procedure line(a,b,c,d,col:integer;where:word);
|
||||
procedure horizontalline(FromX1,ToX2,AtY,col:integer;where:word);
|
||||
procedure verticalline(FromY1,ToY2,AtX,col:integer;where:word);
|
||||
procedure fade;
|
||||
procedure unfade;
|
||||
procedure box(x1,y1,x2,y2,col:integer;where:word);
|
||||
procedure vdelay(howlong:integer);
|
||||
procedure setupvmwgraph;
|
||||
procedure setuptb1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{Errors: 0=No Errors
|
||||
1=File Not Found
|
||||
2=Not a Paintpro File (no PAINTPROVX.XX header)
|
||||
3=Improper Version (less then 6)
|
||||
}
|
||||
*/
|
||||
|
||||
int GGILoadPicPacked(int x1,int y1,ggi_visual_t vis
|
||||
,int LoadPal,int LoadPic,char *FileName,
|
||||
ggi_color *eight_bit_pal,ggi_pixel *tb1_pal,
|
||||
int color_depth)
|
||||
|
||||
|
||||
/*Loads a paintpro image, filename, at location x1,y1 *\
|
||||
\*to offset where (vga=$A000) and loadspal if LOADPAL=true */
|
||||
/*Loadsapicture if Loadpic=true and returns error} */
|
||||
|
||||
{
|
||||
unsigned char temp1,temp2,temp3;
|
||||
int errorlev;
|
||||
int int1,int2,i,x,y;
|
||||
char buffer[300];
|
||||
int lastread=0;
|
||||
int buffpointer=0;
|
||||
int picwidth,picheight;
|
||||
FILE *fff;
|
||||
char header[10];
|
||||
int xsize;
|
||||
int ysize;
|
||||
int numcolors;
|
||||
int col,numacross;
|
||||
|
||||
/* Open the file */
|
||||
fff=fopen(FileName,"rb");
|
||||
if (fff==NULL){
|
||||
printf("PPRO error... File \"%s\" not found.\n",FileName);
|
||||
exit(1);
|
||||
}
|
||||
errorlev=fread(buffer,1,300,fff);
|
||||
/* Check to see if its really a Paintpro File */
|
||||
for (i=0;i<9;i++) {
|
||||
header[i]=buffer[i];
|
||||
}
|
||||
header[9]='\0';
|
||||
if (strcmp(header,"PAINTPROV")) {
|
||||
printf("PPRO error... %s is NOT a paintpro file!\n",FileName);
|
||||
exit(2);
|
||||
}
|
||||
/*printf("Paintpro Confirmed\n");*/
|
||||
/* Check to see if it is the proper version (currently 6.0) */
|
||||
header[0]=buffer[9];
|
||||
header[1]=buffer[10];
|
||||
header[2]=buffer[11];
|
||||
header[3]='\0';
|
||||
if (strcmp(header,"6.0")) {
|
||||
printf("PPRO error... Version %s unsupported, must be >6\n",header);
|
||||
exit(3);
|
||||
}
|
||||
buffpointer=12;
|
||||
/* Read X and Y sizes */
|
||||
temp1=buffer[buffpointer];
|
||||
temp2=buffer[buffpointer+1];
|
||||
temp3=buffer[buffpointer+2];
|
||||
buffpointer+=3;
|
||||
if (buffpointer>=errorlev) {
|
||||
printf("PPRO error... Early end of file.\n");
|
||||
exit(3);
|
||||
}
|
||||
xsize=(temp2>>4)+(temp1<<4);
|
||||
ysize=((temp2-((temp2>>4)<<4))<<16)+temp3;
|
||||
/* being old 6 bytes 2 two int*/
|
||||
temp1=buffer[buffpointer];
|
||||
temp2=buffer[buffpointer+1];
|
||||
temp3=buffer[buffpointer+2];
|
||||
buffpointer+=3;
|
||||
if (buffpointer>=errorlev) {
|
||||
printf("PPRO error... Early end of file.\n");
|
||||
exit(3);
|
||||
}
|
||||
numcolors=(temp2>>4)+(temp1<<4);
|
||||
/*int2=((temp2-((temp2>>4)<<4))*256)+temp3;*/
|
||||
picwidth=xsize+1;
|
||||
picheight=ysize+1;
|
||||
/*Load Palette*/
|
||||
if (numcolors!=256) printf("%d colors is not supported yet.\n",numcolors);
|
||||
for (i=0;i<256;i++) {
|
||||
eight_bit_pal[i].r=(buffer[buffpointer]*0x100);
|
||||
eight_bit_pal[i].g=(buffer[buffpointer+1]*0x100);
|
||||
eight_bit_pal[i].b=(buffer[buffpointer+2]*0x100);
|
||||
buffpointer+=3;
|
||||
if (buffpointer>=errorlev) {
|
||||
if (errorlev==300) {
|
||||
errorlev=fread(buffer,1,300,fff);
|
||||
buffpointer=0;
|
||||
}
|
||||
else {
|
||||
lastread=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(LoadPal) {
|
||||
if(color_depth!=8) {
|
||||
for(i=0;i<256;i++)
|
||||
tb1_pal[i]=ggiMapColor(vis,&eight_bit_pal[i]);
|
||||
}
|
||||
else {
|
||||
for(i=0;i<256;i++) tb1_pal[i]=(ggi_pixel)i;
|
||||
ggiSetPaletteVec(vis,0,256,eight_bit_pal);
|
||||
}
|
||||
}
|
||||
x=x1;
|
||||
y=y1;
|
||||
while ((!lastread)&&(LoadPic)) {
|
||||
temp1=buffer[buffpointer];
|
||||
temp2=buffer[buffpointer+1];
|
||||
temp3=buffer[buffpointer+2];
|
||||
buffpointer+=3;
|
||||
if (buffpointer>=errorlev) {
|
||||
if (errorlev==300) {
|
||||
errorlev=fread(buffer,1,300,fff);
|
||||
buffpointer=0;
|
||||
}
|
||||
else lastread=1;
|
||||
}
|
||||
int1=(temp2>>4)+(temp1<<4);
|
||||
int2=((temp2-((temp2>>4)<<4))*256)+temp3;
|
||||
if (int1>2047) {
|
||||
ggiPutPixel(vis,x,y,tb1_pal[int1-2048]);
|
||||
x++;
|
||||
if (x>xsize+x1) {
|
||||
x=x1; y++;
|
||||
}
|
||||
ggiPutPixel(vis,x,y,tb1_pal[int2-2048]);
|
||||
x++;
|
||||
if (x>xsize+x1){
|
||||
x=x1;y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
col=int1;
|
||||
numacross=int2;
|
||||
while ((x+numacross)>(xsize+x1)) {
|
||||
ggiSetGCForeground(vis,tb1_pal[col]);
|
||||
ggiDrawHLine(vis,x,y,((xsize+x1)-x));
|
||||
numacross=numacross-((xsize+1)-x);
|
||||
x=x1;
|
||||
y++;
|
||||
}
|
||||
if (numacross!=0) {
|
||||
ggiSetGCForeground(vis,tb1_pal[col]);
|
||||
ggiDrawHLine(vis,x,y,numacross);
|
||||
}
|
||||
x=x+numacross;
|
||||
}
|
||||
}
|
||||
ggiFlush(vis);
|
||||
if (fff!=NULL) fclose(fff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vmw_font *LoadVMWFont(char *namest,int xsize,int ysize,int numchars)
|
||||
{
|
||||
unsigned char buff[16];
|
||||
FILE *f;
|
||||
int i,fonty,numloop;
|
||||
vmw_font *font;
|
||||
char *data;
|
||||
|
||||
font=(vmw_font *)malloc(sizeof(vmw_font));
|
||||
data=(char *)calloc(numchars*ysize,(sizeof(char)));
|
||||
|
||||
f=fopen(namest,"r");
|
||||
if (f==NULL) {
|
||||
printf("ERROR loading font file %s.\n",namest);
|
||||
return NULL;
|
||||
}
|
||||
numloop=(numchars*ysize);
|
||||
|
||||
font->width=xsize;
|
||||
font->height=ysize;
|
||||
font->numchars=numchars;
|
||||
font->font_data=data;
|
||||
fonty=0;
|
||||
while ( (!feof(f))&&(fonty<=numloop)) {
|
||||
fread(buff,1,16,f);
|
||||
for(i=0;i<16;i++) font->font_data[fonty+i]=buff[i];
|
||||
fonty+=16;
|
||||
}
|
||||
fclose(f);
|
||||
return font;
|
||||
}
|
||||
|
||||
/*int bit(unsigned char mree,int whichbit)
|
||||
{
|
||||
return mree&(128>>whichbit);
|
||||
}
|
||||
*/
|
||||
|
||||
void VMWtextlineover(char *st,int x,int y,int col,int background,int line,
|
||||
vmw_font *font,ggi_visual_t vis)
|
||||
{
|
||||
int i,xx,len;
|
||||
len=strlen(st);
|
||||
for(i=0;i<len;i++)
|
||||
for(xx=0;xx<8;xx++){
|
||||
if ( (font->font_data[(st[i]*font->height)+line])&(128>>xx) )
|
||||
ggiPutPixel(vis,(x+(i*8)+xx),y,col);
|
||||
else
|
||||
ggiPutPixel(vis,(x+(i*8)+xx),y,background);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VMWtextline(char *st,int x,int y,int col,int background,int line,
|
||||
vmw_font *font,ggi_visual_t vis)
|
||||
{
|
||||
int i,len,xx;
|
||||
len=strlen(st);
|
||||
for(i=0;i<len;i++)
|
||||
for(xx=0;xx<8;xx++)
|
||||
if( ((unsigned char) (font->font_data[(st[i]*16)+line]))
|
||||
&(128>>xx) ) {
|
||||
ggiPutPixel(vis,x+(i*8)+xx,y,col);
|
||||
}
|
||||
}
|
||||
|
||||
void VMWtextxy(char *st,int x,int y,int col,int background,int overwrite,
|
||||
vmw_font *font,ggi_visual_t vis)
|
||||
{
|
||||
int lineon,i,xx,len;
|
||||
|
||||
len=strlen(st);
|
||||
for(lineon=0;lineon<8;lineon++){
|
||||
for(i=0;i<len;i++)
|
||||
for(xx=0;xx<8;xx++){
|
||||
if ( (font->font_data[(st[i]*font->height)+lineon])&(128>>xx) )
|
||||
ggiPutPixel(vis,(x+(i*8)+xx),y+lineon,col);
|
||||
else
|
||||
if(overwrite) ggiPutPixel(vis,(x+(i*8)+xx),y+lineon,background);
|
||||
}
|
||||
}
|
||||
/*VMWtextlineover(st,x,y+lineon,col,background,lineon,font,vis);*/
|
||||
/* VMWtextline(st,x,y+lineon,col,background,lineon,font,vis);*/
|
||||
}
|
||||
|
||||
|
||||
void VMWsmalltextxy(char *st,int x,int y,int col,int background,int overwrite,
|
||||
vmw_font *font,ggi_visual_t vis)
|
||||
{
|
||||
int lineon,i,xx,len;
|
||||
|
||||
/* This will print out a small 4x5 font located in chars */
|
||||
/* 128-255 in a normal VGA font. These are custom made */
|
||||
/* fonts they are non-standard */
|
||||
|
||||
len=strlen(st);
|
||||
for(lineon=0;lineon<5;lineon++) {
|
||||
for(i=0;i<len;i++)
|
||||
for(xx=0;xx<5;xx++) {
|
||||
if ( (font->font_data[((st[i]+128)*font->height)+lineon])&(128>>xx) )
|
||||
ggiPutPixel(vis,(x+(i*5)+xx),y+lineon,col);
|
||||
else
|
||||
if(overwrite) ggiPutPixel(vis,(x+(i*5)+xx),y+lineon,background);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
var i,len:word;
|
||||
|
||||
begin
|
||||
len:=length(St);
|
||||
for i:=1 to (len div 2)+1 do begin
|
||||
fontline[(i-1)*2]:=charset[(ord(st[(i*2)]))+128,line];
|
||||
fontline[((i-1)*2)+1]:=charset[(ord(st[(i*2)-1]))+128,line];
|
||||
end;
|
||||
asm
|
||||
push ds
|
||||
push si
|
||||
push es
|
||||
push di
|
||||
mov ax,[fontseg]
|
||||
mov ds,ax
|
||||
mov ax,[fontoff]
|
||||
mov si,ax
|
||||
mov dh,[col]
|
||||
mov dl,[background]
|
||||
mov ax,[y] {multiplies y value by 320}
|
||||
shl ax,5
|
||||
mov cx,ax
|
||||
shl ax,1
|
||||
shl cx,3
|
||||
add ax,cx
|
||||
add ax,[x] {adds the x-value to get offset}
|
||||
mov di,ax
|
||||
mov ax,[where]
|
||||
mov es,ax
|
||||
mov bx,[len]
|
||||
gus1:
|
||||
xor ax,ax
|
||||
cmp bx,02
|
||||
jnge gus4
|
||||
mov cx,10
|
||||
lodsb
|
||||
push bx
|
||||
mov bl,al
|
||||
xor bh,bh
|
||||
lodsb
|
||||
shl ax,5
|
||||
add ax,bx
|
||||
shl ax,3
|
||||
pop bx
|
||||
jmp gus5
|
||||
gus4:
|
||||
mov cx,5
|
||||
lodsw
|
||||
gus5:
|
||||
shl ax,1
|
||||
push ax
|
||||
jc gus7
|
||||
mov al,dl
|
||||
jmp gus8
|
||||
gus7:
|
||||
mov al,dh
|
||||
gus8:
|
||||
xor ah,ah
|
||||
stosb
|
||||
pop ax
|
||||
loop gus5
|
||||
cmp bx,2
|
||||
jng gus3
|
||||
dec bx
|
||||
dec bx
|
||||
jmp gus1
|
||||
gus3:
|
||||
pop di
|
||||
pop es
|
||||
pop si
|
||||
pop ds
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure outsmalltextline(st:string;x,y:integer;col,background:byte;line:integer;where:word);
|
||||
label gus1,gus4,gus6,gus5,gus7,gus8,gus3;
|
||||
var i,len:word;
|
||||
|
||||
begin
|
||||
len:=length(St);
|
||||
for i:=1 to (len div 2)+1 do begin
|
||||
fontline[(i-1)*2]:=charset[(ord(st[(i*2)]))+128,line];
|
||||
fontline[((i-1)*2)+1]:=charset[(ord(st[(i*2)-1]))+128,line];
|
||||
end;
|
||||
asm
|
||||
push ds
|
||||
push si
|
||||
push es
|
||||
push di
|
||||
mov ax,[fontseg]
|
||||
mov ds,ax
|
||||
mov ax,[fontoff]
|
||||
mov si,ax
|
||||
mov dh,[col]
|
||||
mov bl,[background]
|
||||
mov ax,[y] {multiplies y value by 320}
|
||||
shl ax,5
|
||||
mov cx,ax
|
||||
shl ax,1
|
||||
shl cx,3
|
||||
add ax,cx
|
||||
add ax,[x] {adds the x-value to get offset}
|
||||
mov di,ax
|
||||
mov ax,[where]
|
||||
mov es,ax
|
||||
mov bx,[len]
|
||||
|
||||
gus1:
|
||||
xor ax,ax
|
||||
cmp bx,02
|
||||
jnge gus4
|
||||
mov cx,10
|
||||
lodsb
|
||||
push bx
|
||||
mov bl,al
|
||||
xor bh,bh
|
||||
lodsb
|
||||
shl ax,5
|
||||
add ax,bx
|
||||
shl ax,3
|
||||
pop bx
|
||||
jmp gus5
|
||||
gus4:
|
||||
mov cx,5
|
||||
lodsw
|
||||
gus5:
|
||||
shl ax,1
|
||||
push ax
|
||||
jc gus7
|
||||
inc di
|
||||
jmp gus8
|
||||
gus7:
|
||||
mov al,dh
|
||||
xor ah,ah
|
||||
stosb
|
||||
gus8:
|
||||
pop ax
|
||||
loop gus5
|
||||
cmp bx,2
|
||||
jng gus3
|
||||
dec bx
|
||||
dec bx
|
||||
jmp gus1
|
||||
gus3:
|
||||
pop di
|
||||
pop es
|
||||
pop si
|
||||
pop ds
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure outsmalltextxy(st:string;x,y,col,background:integer;where:word;overwrite:boolean);
|
||||
label l0105;
|
||||
var l,len,i,xadd,yadd,lineon:integer;
|
||||
n,k,o,min,max,qwerty:byte;
|
||||
begin
|
||||
for lineon:=0 to 4 do
|
||||
if overwrite then
|
||||
outsmalltextlineover(st,x,y+lineon,col,background,lineon,where)
|
||||
else
|
||||
outsmalltextline(st,x,y+lineon,col,background,lineon,where);
|
||||
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function sgn(a:real):integer;
|
||||
begin
|
||||
if a>0 then sgn:=+1;
|
||||
if a<0 then sgn:=-1;
|
||||
if a=0 then sgn:=0;
|
||||
end;
|
||||
|
||||
procedure line(a,b,c,d,col:integer;where:word);
|
||||
var u,s,v,d1x,d1y,d2x,d2y,m,n:real;
|
||||
i:integer;
|
||||
begin
|
||||
u:= c - a;
|
||||
v:= d - b;
|
||||
d1x:= SGN(u);
|
||||
d1y:= SGN(v);
|
||||
d2x:= SGN(u);
|
||||
d2y:= 0;
|
||||
m:= ABS(u);
|
||||
n := ABS(v);
|
||||
IF NOT (M>N) then
|
||||
BEGIN
|
||||
d2x := 0 ;
|
||||
d2y := SGN(v);
|
||||
m := ABS(v);
|
||||
n := ABS(u);
|
||||
END;
|
||||
s := INT(m / 2);
|
||||
FOR i := 0 TO round(m) DO
|
||||
BEGIN
|
||||
putpixel(a,b,col,where);
|
||||
s := s + n;
|
||||
IF not (s<m) THEN
|
||||
BEGIN
|
||||
s := s - m;
|
||||
a:= a +round(d1x);
|
||||
b := b + round(d1y);
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
a := a + round(d2x);
|
||||
b := b + round(d2y);
|
||||
END;
|
||||
end;
|
||||
END;
|
||||
|
||||
procedure horizontalline(FromX1,ToX2,AtY,col:integer;where:word);
|
||||
|
||||
begin
|
||||
asm
|
||||
push es
|
||||
push di
|
||||
|
||||
mov ax,[aty] {multiplies y value by 320}
|
||||
shl ax,5
|
||||
mov cx,ax
|
||||
shl ax,1
|
||||
shl cx,3
|
||||
add ax,cx
|
||||
add ax,[fromx1] {adds the x-value to get offset}
|
||||
mov di,ax
|
||||
mov ax,[where]
|
||||
mov es,ax
|
||||
|
||||
mov cx,[tox2]
|
||||
sub cx,[fromx1] {how long line is}
|
||||
|
||||
xor ax,ax {load color}
|
||||
mov ax,col
|
||||
rep stosb {draw it}
|
||||
pop di
|
||||
pop es
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure verticalline(FromY1,ToY2,AtX,col:integer;where:word);
|
||||
label mree2,mree3,mree,mree4;
|
||||
begin
|
||||
asm
|
||||
push es
|
||||
push di
|
||||
xor dx,dx
|
||||
mov bx,[toy2] {this mess saves you}
|
||||
mov ax,[fromy1] {if you put a y1 value}
|
||||
{lower than y2. It is}
|
||||
cmp bx,ax {probably unnecessary}
|
||||
jz mree3
|
||||
jl Mree2
|
||||
sub bx,ax {how long line is}
|
||||
mov dx,bx
|
||||
|
||||
jmp mree3
|
||||
mree2:
|
||||
sub ax,bx
|
||||
mov dx,ax
|
||||
mov ax,[toy2]
|
||||
mree3:
|
||||
|
||||
|
||||
|
||||
{mov ax,[FromY1]} {multiplies y value by 320}
|
||||
shl ax,5
|
||||
mov cx,ax
|
||||
shl ax,1
|
||||
shl cx,3
|
||||
add ax,cx
|
||||
add ax,[atX] {adds the x-value to get offset}
|
||||
mov di,ax
|
||||
mov ax,[where]
|
||||
mov es,ax
|
||||
|
||||
|
||||
mov cx,dx
|
||||
inc cx
|
||||
|
||||
xor ax,ax {load color}
|
||||
mov ax,col
|
||||
|
||||
Mree:
|
||||
stosb {draw it}
|
||||
add di,319
|
||||
loop mree
|
||||
mree4:
|
||||
pop di
|
||||
pop es
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure fade;
|
||||
var i,j:integer;
|
||||
r,g,b:byte;
|
||||
begin
|
||||
for i:=0 to 255 do begin
|
||||
getpal(i,r,g,b);
|
||||
unfadered[i]:=r;
|
||||
unfadeblue[i]:=b;
|
||||
unfadegreen[i]:=g;
|
||||
end;
|
||||
for i:=0 to 63 do begin
|
||||
for j:=0 to 255 do begin
|
||||
getpal(j,r,g,b);
|
||||
if r>0 then dec(r);
|
||||
if g>0 then dec(g);
|
||||
if b>0 then dec(b);
|
||||
pal(j,r,g,b);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure unfade;
|
||||
var i,j:integer;
|
||||
r,g,b:byte;
|
||||
begin
|
||||
for i:=0 to 63 do begin
|
||||
for j:=0 to 255 do begin
|
||||
getpal(j,r,g,b);
|
||||
if r<unfadered[j] then inc(r);
|
||||
if g<unfadegreen[j] then inc(g);
|
||||
if b<unfadeblue[j] then inc(b);
|
||||
pal(j,r,g,b);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
procedure box(x1,y1,x2,y2,col:integer;where:word);
|
||||
begin
|
||||
line(x1,y1,x1,y2,col,where);
|
||||
horizontalline(x1,x2,y2,col,where);
|
||||
line(x2,y2,x2,y1,col,where);
|
||||
horizontalline(x1,x2,y1,col,where);
|
||||
end;
|
||||
|
||||
procedure vdelay(howlong:integer);
|
||||
var i:integer;
|
||||
begin
|
||||
for i:=1 to howlong do waitretrace;
|
||||
end;
|
||||
|
||||
procedure setupvmwgraph;
|
||||
begin
|
||||
loadfont('8x8font.tb1');
|
||||
charheight:=8;
|
||||
fontseg:=seg(fontline[0]);
|
||||
fontoff:=ofs(fontline[0]);
|
||||
end;
|
||||
|
||||
procedure setuptb1;
|
||||
begin
|
||||
loadfont('tbfont.tb1');
|
||||
charheight:=8;
|
||||
fontseg:=seg(fontline[0]);
|
||||
fontoff:=ofs(fontline[0]);
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
end.
|
||||
*/
|
43
svmwgrap.h
Normal file
43
svmwgrap.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
typedef struct {
|
||||
char *font_data;
|
||||
int width;
|
||||
int height;
|
||||
int numchars;
|
||||
} vmw_font;
|
||||
|
||||
int vmwCrossBlit(char *dest,char *src,int stride,int ysize);
|
||||
int vmwCrossBlit240(char *dest,char *src,int stride,int stride_factor,
|
||||
int ysize);
|
||||
int vmwArbitraryCrossBlit(char *src,int x1,int y1,int w,int h,
|
||||
char *dest,int x2,int y2,int stride,
|
||||
int stridesfactor);
|
||||
|
||||
|
||||
|
||||
|
||||
/*int vmwPutSprite(ggi_visual_t visual,int x,int y,int w,int h,
|
||||
int transparent_color,int *sprite);
|
||||
*/
|
||||
int vmwPutSprite(int *src,int w,int h,int stride_factor,
|
||||
char *dest,int x,int y,int dest_stride);
|
||||
|
||||
|
||||
int vmwGetSprite(ggi_visual_t visual,int x,int y,int w,int h,
|
||||
int *sprite);
|
||||
|
||||
|
||||
int GGILoadPicPacked(int x1,int y1,ggi_visual_t vis
|
||||
,int LoadPal,int LoadPic,char *FileName,
|
||||
ggi_color *eight_bit_pal,ggi_pixel *tb1_pal,
|
||||
int color_depth);
|
||||
vmw_font *LoadVMWFont(char *namest,int xsize,int ysize,int numchars);
|
||||
void VMWtextlineover(char *st,int x,int y,int col,int background,int line,
|
||||
vmw_font *font,ggi_visual_t vis);
|
||||
void VMWtextline(char *st,int x,int y,int col,int background,int line,
|
||||
vmw_font *font,ggi_visual_t vis);
|
||||
void VMWtextxy(char *st,int x,int y,int col,int background,int overwrite,
|
||||
vmw_font *font,ggi_visual_t vis);
|
||||
void VMWsmalltextxy(char *st,int x,int y,int col, int background, int overwrite,
|
||||
vmw_font *font,ggi_visual_t vis);
|
||||
|
||||
|
16
tb1-2.9.0.lsm
Normal file
16
tb1-2.9.0.lsm
Normal file
|
@ -0,0 +1,16 @@
|
|||
Begin3
|
||||
Title: tb1
|
||||
Version: 2.9.0
|
||||
Entered-date: 28FEB98
|
||||
Description: A really cool arcade game.
|
||||
Shoot the aliens, save the world.
|
||||
Keywords: tom bombem alien game arcade ggi
|
||||
Author: weave@eng.umd.edu (Vince Weaver)
|
||||
Maintained-by: weave@eng.umd.edu (Vince Weaver)
|
||||
Primary-site: sunsite.unc.edu /pub/Linux/games/arcade
|
||||
100kB tb1-2.9.0.tar.gz
|
||||
Alternate-site: http://www.glue.umd.edu/~weave/tb1
|
||||
Original-site:
|
||||
Platforms: Any that have gcc and support ggi
|
||||
Copying-policy: GPL
|
||||
End
|
418
tb1.c
Normal file
418
tb1.c
Normal file
|
@ -0,0 +1,418 @@
|
|||
/****************************************************************\
|
||||
\* TOM BOMBEM AND THE INVASION OF THE INANIMATE_OBJECTS */
|
||||
/* version 2.9.0 February 28, 1998 *\
|
||||
\* by Vince Weaver weave@eng.umd.edu */
|
||||
/* *\
|
||||
\* Originally written in Pascal and x86 assembly for DOS */
|
||||
/* Ported to Linux, C, and ggi late 1997-early 1998 *\
|
||||
\* This source is released under the GPL */
|
||||
/****************************************************************/
|
||||
|
||||
#define TB1_VERSION "2.9.0"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ggi/libggi.h>
|
||||
|
||||
#include "svmwgrap.h"
|
||||
#include "tblib.h"
|
||||
|
||||
/* Exported Global Variables */
|
||||
ggi_visual_t vis,vaddr,vaddr2;
|
||||
vmw_font *tb1_font;
|
||||
uint white;
|
||||
ggi_color eight_bit_pal[256];
|
||||
ggi_pixel tb1_pal[256];
|
||||
int color_depth;
|
||||
ggi_directbuffer_t dbuf_vis,dbuf_vaddr,dbuf_vaddr2;
|
||||
ggi_pixellinearbuffer *plb_vis = NULL,*plb_vaddr= NULL,*plb_vaddr2=NULL;
|
||||
int stride_factor=1;
|
||||
int sound_enabled=1,sound_possible=1,read_only_mode=0;
|
||||
char path_to_data[256];
|
||||
|
||||
struct timeval time_info;
|
||||
struct timezone dontcare;
|
||||
|
||||
/* Setup the Graphics */
|
||||
int setup_graphics(int force_8bpp)
|
||||
{
|
||||
int err;
|
||||
ggi_mode mode;
|
||||
int vx,vy,sx,sy;
|
||||
|
||||
ggiInit();
|
||||
vis=ggiOpen(NULL);
|
||||
|
||||
if (force_8bpp)
|
||||
err=ggiSetGraphMode(vis,320,200,320,200,GT_8BIT);
|
||||
else
|
||||
err=ggiSetGraphMode(vis,320,200,320,200,GGI_AUTO);
|
||||
if (err) {
|
||||
fprintf(stderr,"ERROR! Problem opening 320x200 vis\n\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
ggiGetMode(vis,&mode);
|
||||
vx=mode.virt.x; vy=mode.virt.y;
|
||||
sx=mode.visible.x;sy=mode.visible.y;
|
||||
switch (mode.graphtype) {
|
||||
case GT_1BIT: color_depth=1;break;
|
||||
case GT_4BIT: color_depth=4;break;
|
||||
case GT_8BIT: color_depth=8;break;
|
||||
case GT_15BIT: color_depth=15;break;
|
||||
case GT_16BIT: color_depth=16;break;
|
||||
case GT_24BIT: color_depth=24;break;
|
||||
case GT_32BIT: color_depth=32;break;
|
||||
default: break;
|
||||
}
|
||||
printf(" + Opened a %d x %d (%d x %d) mode with %d bpp\n",
|
||||
sx,sy,vx,vy,color_depth);
|
||||
|
||||
err = ggiDBGetBuffer (vis, &dbuf_vis);
|
||||
if (err) {
|
||||
printf("Error! Could not get directbuffer\n");
|
||||
return 2;
|
||||
}
|
||||
if (!(ggiDBGetLayout (dbuf_vis) == blPixelLinearBuffer)) {
|
||||
printf("Error! Nonlinear Display Buffer.\n");
|
||||
return 2;
|
||||
}
|
||||
if (!(plb_vis = ggiDBGetPLB (dbuf_vis)) ) {
|
||||
printf("Error! Problem getting pixel linear buffer.\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
vaddr=ggiOpen("display-memory",NULL);
|
||||
err=ggiSetGraphMode(vaddr,320,200,320,200,mode.graphtype);
|
||||
if (err) {
|
||||
printf("ERROR! Problem opening 320x200x%d vaddr\n",color_depth);
|
||||
return 2;
|
||||
}
|
||||
err = ggiDBGetBuffer (vaddr, &dbuf_vaddr);
|
||||
if (err) {
|
||||
printf("Error! Could not get directbuffer\n");
|
||||
return 2;
|
||||
}
|
||||
if (!(ggiDBGetLayout (dbuf_vaddr) == blPixelLinearBuffer)) {
|
||||
printf("Error! Nonlinear Display Buffer.\n");
|
||||
return 2;
|
||||
}
|
||||
if (!(plb_vaddr = ggiDBGetPLB (dbuf_vaddr)) ) {
|
||||
printf("Error! Problem getting pixel linear buffer.\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
vaddr2=ggiOpen("display-memory",NULL);
|
||||
err=ggiSetGraphMode(vaddr2,320,400,320,400,mode.graphtype);
|
||||
if (err){
|
||||
printf("ERROR! Problem opening 320x400x%d vaddr2\n",color_depth);
|
||||
return 2;
|
||||
}
|
||||
err = ggiDBGetBuffer (vaddr2, &dbuf_vaddr2);
|
||||
if (err) {
|
||||
printf("Error! Could not get directbuffer\n");
|
||||
return 2;
|
||||
}
|
||||
if (!(ggiDBGetLayout (dbuf_vaddr2) == blPixelLinearBuffer)) {
|
||||
printf("Error! Nonlinear Display Buffer.\n");
|
||||
return 2;
|
||||
}
|
||||
if (!(plb_vaddr2 = ggiDBGetPLB (dbuf_vaddr2)) ) {
|
||||
printf("Error! Problem getting pixel linear buffer.\n");
|
||||
return 2;
|
||||
}
|
||||
stride_factor=(plb_vis->stride)/320;
|
||||
printf(" + Using a stride factor of %d\n",stride_factor);
|
||||
printf(" + GGI Graphics Initialization successful...\n");
|
||||
printf(" + Running TB1 in %dbpp Mode...\n",color_depth);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int command_line_help(int show_version,char *runas)
|
||||
{
|
||||
if (!show_version) {
|
||||
printf("Usage: %s [-force8bpp] [-nosound] [-readonly]"
|
||||
" [-version] [-?]\n\n",runas);
|
||||
printf(" -force8bpp : force to run in 8bpp mode\n");
|
||||
printf(" -nosound : disables sound within game\n");
|
||||
printf(" -readonly : don't try to write files to disk\n");
|
||||
printf(" -version : print version\n");
|
||||
printf(" -? : print this help message\n");
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
int i,grapherror,reloadpic=0,force_8bpp=0;
|
||||
int ch,ch2,x,barpos,time_sec;
|
||||
char *tempst[300];
|
||||
FILE *fff;
|
||||
|
||||
printf("\nTom Bombem v%s by Vince Weaver weave@eng.umd.edu\n",TB1_VERSION);
|
||||
printf(" http://www.glue.umd.edu/~weave/tb1\n\n");
|
||||
|
||||
/* Parse Command Line Arguments */
|
||||
i=1;
|
||||
while(i<argc) {
|
||||
if (argv[i][0]=='-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'h': case '?':
|
||||
command_line_help(0,argv[0]); return 5; break;
|
||||
case 'v':
|
||||
command_line_help(1,argv[0]); return 5; break;
|
||||
case 'f':
|
||||
force_8bpp=1; break;
|
||||
case 'n':
|
||||
sound_enabled=0;
|
||||
sound_possible=0;
|
||||
printf(" + Sound totally disabled\n");
|
||||
break;
|
||||
case 'r':
|
||||
read_only_mode=1;
|
||||
printf(" + Read Only mode enabled\n");
|
||||
break;
|
||||
default : command_line_help(0,argv[0]);
|
||||
printf("Unknown Option: %s\n\n",argv[i]);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
else {
|
||||
command_line_help(0,argv[0]);
|
||||
printf("Unknown Option: %s\n\n",argv[i]);
|
||||
return 5;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Find the Data */
|
||||
/* FIXME : User Defined Path Info*/
|
||||
if ( (fff=fopen("./data/data_files_here","r"))!=NULL) {
|
||||
strncpy(path_to_data,"./data/",20);
|
||||
}
|
||||
else if ( (fff=fopen("/usr/local/games/tb1/data/data_files_here","r"))
|
||||
!=NULL) {
|
||||
strncpy(path_to_data,"/usr/local/games/tb1/data/",40);
|
||||
}
|
||||
else {
|
||||
char tempst[200];
|
||||
|
||||
sprintf(tempst,"%s/.tb1/data/data_files_here",getenv("HOME"));
|
||||
if ( (fff=fopen(tempst,"r"))!=NULL) {
|
||||
sprintf(path_to_data,"%s/.tb1/data/",getenv("HOME"));
|
||||
}
|
||||
else {
|
||||
printf("ERROR! Could not find tb1 data!\n");
|
||||
printf(" Checked ./data, /usr/local/games/tb1/data\n");
|
||||
printf(" and %s/.tb1/data\n\n",getenv("HOME"));
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
printf(" + Found tb1 data in %s\n",path_to_data);
|
||||
|
||||
/* FIXME : find where writing info out to */
|
||||
|
||||
|
||||
/* REMNANT OPERATION BOTTLECAP STUFF---> *\
|
||||
\* No 9-22-94 Back to yes 10-6-94 uh_oh 2-21-95 */
|
||||
/* gone for real long time 10-12-95 *\
|
||||
\* 11-95 not Amy anymore, but Gus */
|
||||
/* 3-96 oh well... gave up on Gus finally *\
|
||||
\* 5-11-96 Now Marie... what fun life is */
|
||||
|
||||
/* Randomize random number generator */
|
||||
srandom(time(NULL));
|
||||
|
||||
/* Load the tom bombem font */
|
||||
tb1_font=LoadVMWFont(tb1_data_file("tbfont.tb1",(char *)tempst),8,16,256);
|
||||
|
||||
/* Setup Graphics */
|
||||
if (setup_graphics(force_8bpp)==2) {
|
||||
fprintf(stderr,"ERROR: Couldn't get display set up properly.\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Do the VMW Software Production Logo */
|
||||
for(x=0;x<=40;x++){
|
||||
eight_bit_pal[100+x].r=((x+20)*4)*0x100;
|
||||
eight_bit_pal[100+x].g=0;
|
||||
eight_bit_pal[100+x].b=0;
|
||||
|
||||
eight_bit_pal[141+x].r=0;
|
||||
eight_bit_pal[141+x].g=0;
|
||||
eight_bit_pal[141+x].b=((x+20)*4)*0x100;
|
||||
|
||||
eight_bit_pal[182+x].r=0;
|
||||
eight_bit_pal[182+x].g=((x+20)*4)*0x100;;
|
||||
eight_bit_pal[182+x].b=0;
|
||||
|
||||
if (color_depth!=8) {
|
||||
tb1_pal[100+x]=ggiMapColor(vis,&eight_bit_pal[100+x]);
|
||||
tb1_pal[141+x]=ggiMapColor(vis,&eight_bit_pal[141+x]);
|
||||
tb1_pal[182+x]=ggiMapColor(vis,&eight_bit_pal[182+x]);
|
||||
}
|
||||
else {
|
||||
for(i=0;i<256;i++) tb1_pal[i]=(ggi_pixel)i;
|
||||
}
|
||||
}
|
||||
/* Set the white color */
|
||||
eight_bit_pal[15].r=255*0x100;
|
||||
eight_bit_pal[15].g=255*0x100;
|
||||
eight_bit_pal[15].b=255*0x100;
|
||||
|
||||
/* Finalize Pallette Stuff */
|
||||
if (color_depth!=8) {
|
||||
tb1_pal[15]=ggiMapColor(vis,&eight_bit_pal[15]);
|
||||
}
|
||||
else ggiSetPaletteVec(vis,0,256,eight_bit_pal);
|
||||
|
||||
/* Actually draw the stylized VMW */
|
||||
for(x=0;x<=40;x++){
|
||||
ggiSetGCForeground(vis,tb1_pal[100+x]);
|
||||
ggiDrawVLine(vis,x+40,45,2*x);
|
||||
ggiSetGCForeground(vis,tb1_pal[141+x]);
|
||||
ggiDrawVLine(vis,x+120,45,2*x);
|
||||
ggiDrawVLine(vis,x+200,45,2*x);
|
||||
ggiSetGCForeground(vis,tb1_pal[182+x]);
|
||||
ggiDrawVLine(vis,x+80,125-(2*x),2*x);
|
||||
ggiDrawVLine(vis,x+160,125-(2*x),2*x);
|
||||
}
|
||||
for(x=40;x>0;x--){
|
||||
ggiSetGCForeground(vis,tb1_pal[140-x]);
|
||||
ggiDrawVLine(vis,x+80,45,80-(2*x));
|
||||
ggiSetGCForeground(vis,tb1_pal[181-x]);
|
||||
ggiDrawVLine(vis,x+160,45,80-(2*x));
|
||||
ggiDrawVLine(vis,x+240,45,80-(2*x));
|
||||
ggiSetGCForeground(vis,tb1_pal[222-x]);
|
||||
ggiDrawVLine(vis,x+120,45+(2*x),80-(2*x));
|
||||
ggiDrawVLine(vis,x+200,45+(2*x),80-(2*x));
|
||||
}
|
||||
|
||||
ggiSetGCForeground(vis,tb1_pal[15]);
|
||||
VMWtextxy("A VMW SOFTWARE PRODUCTION",60,140,
|
||||
tb1_pal[15],tb1_pal[15],0,tb1_font,vis);
|
||||
ggiFlush(vis);
|
||||
pauseawhile(5);
|
||||
|
||||
/* Clear the Screen and get ready for the Menu */
|
||||
ggiSetGCForeground(vis,tb1_pal[0]);
|
||||
ggiFillscreen(vis);
|
||||
|
||||
/* Load the title screen */
|
||||
grapherror=GGILoadPicPacked(0,0,vis,1,1,
|
||||
tb1_data_file("tbomb1.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
grapherror=GGILoadPicPacked(0,0,vaddr2,1,1,
|
||||
tb1_data_file("tbomb1.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
ggiFlush(vis);
|
||||
ggiFlush(vaddr2);
|
||||
pauseawhile(5);
|
||||
|
||||
/* Main Menu Loop */
|
||||
while (1) {
|
||||
if (reloadpic) {
|
||||
grapherror=GGILoadPicPacked(0,0,vaddr2,1,1,
|
||||
tb1_data_file("tbomb1.tb1",(char *)tempst),
|
||||
(ggi_color *)&eight_bit_pal,
|
||||
(ggi_pixel *)&tb1_pal,color_depth);
|
||||
ggiFlush(vaddr2);
|
||||
reloadpic=0;
|
||||
}
|
||||
vmwCrossBlit(plb_vis->write,plb_vaddr2->read,plb_vis->stride,200);
|
||||
ggiFlush(vis);
|
||||
|
||||
barpos=0;
|
||||
VMWtextxy("F1 HELP",0,190,tb1_pal[9],tb1_pal[7],0,tb1_font,vis);
|
||||
coolbox(117,61,199,140,1,vis);
|
||||
ggiFlush(vis);
|
||||
ch=0;
|
||||
while(ch!=TB_ENTER){
|
||||
if (barpos==0) VMWtextxy("NEW GAME",123,67,
|
||||
tb1_pal[32],tb1_pal[0],1,tb1_font,vis);
|
||||
else VMWtextxy("NEW GAME",123,67,
|
||||
tb1_pal[32],tb1_pal[7],1,tb1_font,vis);
|
||||
if (barpos==1) VMWtextxy("OPTIONS",123,77,
|
||||
tb1_pal[32],tb1_pal[0],1,tb1_font,vis);
|
||||
else VMWtextxy("OPTIONS",123,77,
|
||||
tb1_pal[32],tb1_pal[7],1,tb1_font,vis);
|
||||
if (barpos==2) VMWtextxy("ABOUT",123,87,
|
||||
tb1_pal[32],tb1_pal[0],1,tb1_font,vis);
|
||||
else VMWtextxy("ABOUT",123,87,
|
||||
tb1_pal[32],tb1_pal[7],1,tb1_font,vis);
|
||||
if (barpos==3) VMWtextxy("LOAD GAME",123,97,
|
||||
tb1_pal[32],tb1_pal[0],1,tb1_font,vis);
|
||||
else VMWtextxy("LOAD GAME",123,97,
|
||||
tb1_pal[32],tb1_pal[7],1,tb1_font,vis);
|
||||
if (barpos==4) VMWtextxy("STORY",123,107,
|
||||
tb1_pal[32],tb1_pal[0],1,tb1_font,vis);
|
||||
else VMWtextxy("STORY",123,107,
|
||||
tb1_pal[32],tb1_pal[7],1,tb1_font,vis);
|
||||
if (barpos==5) VMWtextxy("CREDITS",123,117,
|
||||
tb1_pal[32],tb1_pal[0],1,tb1_font,vis);
|
||||
else VMWtextxy("CREDITS",123,117,
|
||||
tb1_pal[32],tb1_pal[7],1,tb1_font,vis);
|
||||
if (barpos==6) VMWtextxy("QUIT",123,127,
|
||||
tb1_pal[32],tb1_pal[0],1,tb1_font,vis);
|
||||
else VMWtextxy("QUIT",123,127,
|
||||
tb1_pal[32],tb1_pal[7],1,tb1_font,vis);
|
||||
ggiFlush(vis);
|
||||
|
||||
/* If at title screen too long, run credits */
|
||||
gettimeofday(&time_info,&dontcare);
|
||||
time_sec=time_info.tv_sec;
|
||||
while( ((ch=get_input())==0)) {
|
||||
usleep(10);
|
||||
gettimeofday(&time_info,&dontcare);
|
||||
if (time_info.tv_sec-time_sec>40) {
|
||||
credits();
|
||||
ch=TB_ENTER;
|
||||
barpos=9;
|
||||
reloadpic=1;
|
||||
gettimeofday(&time_info,&dontcare);
|
||||
time_sec=time_info.tv_sec;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change menu position based on key pressed */
|
||||
ch2=toupper(ch);
|
||||
if ((ch==TB_DOWN)||(ch==TB_RIGHT)) barpos++;
|
||||
if ((ch==TB_UP) || (ch==TB_LEFT)) barpos--;
|
||||
if (ch==TB_F1) {barpos=10; ch=TB_ENTER;} /*F1*/
|
||||
if (ch2=='N') barpos=0; /*N*/
|
||||
if (ch2=='O') barpos=1; /*O*/
|
||||
if (ch2=='A') barpos=2; /*A*/
|
||||
if (ch2=='L') barpos=3; /*L*/
|
||||
if (ch2=='S') barpos=4; /*S*/
|
||||
if (ch2=='C') barpos=5; /*C*/
|
||||
if (ch2=='Q') barpos=6; /*Q*/
|
||||
if (ch==27){ /* escape */
|
||||
barpos=6;
|
||||
ch=TB_ENTER;
|
||||
}
|
||||
if(barpos==7) barpos=0;
|
||||
if(barpos<0) barpos=6;
|
||||
}
|
||||
/* Run whatever it was that the person pressed */
|
||||
switch (barpos) {
|
||||
case 0: playthegame(0,0,12); reloadpic=1; break;
|
||||
case 1: options(vis); reloadpic=1; break;
|
||||
case 2: about(vis); reloadpic=1; break;
|
||||
case 3: loadgame(); reloadpic=1; break;
|
||||
case 4: story(); reloadpic=1; break;
|
||||
case 5: credits(); reloadpic=1; break;
|
||||
case 6: barpos=quit(vis); break;
|
||||
case 10: help(vis); break;
|
||||
}
|
||||
}
|
||||
}
|
34
tblib.h
Normal file
34
tblib.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#define TB_ESC 27
|
||||
#define TB_ENTER 1024
|
||||
#define TB_F1 1025
|
||||
#define TB_F2 1026
|
||||
#define TB_UP 1027
|
||||
#define TB_DOWN 1028
|
||||
#define TB_LEFT 1029
|
||||
#define TB_RIGHT 1030
|
||||
#define TB_PGUP 1031
|
||||
#define TB_PGDOWN 1032
|
||||
|
||||
int change_shields(int *shields);
|
||||
int changescore(int score,int *shields);
|
||||
int collision(int x1,int y1,int xsize,int ysize,int x2,int y2,int x2size,int y2size);
|
||||
char *tb1_data_file(char *name,char *store);
|
||||
int get_input();
|
||||
void coolbox(int x1,int y1,int x2,int y2,int fill,ggi_visual_t page);
|
||||
int close_graphics();
|
||||
int quit();
|
||||
void ReadConfigFile(int CDROMmode);
|
||||
int showhiscore(int showchart);
|
||||
void clear_keyboard_buffer();
|
||||
void write_hs_list(int score,char *hiname);
|
||||
void help();
|
||||
void setupsidebar(int score,int hiscore,int shields);
|
||||
void shadowrite(char *st,int x,int y,int forecol,int backcol,ggi_visual_t vis);
|
||||
void pauseawhile(int howlong);
|
||||
void options();
|
||||
void savegame(int level,int begin_score,int begin_shields);
|
||||
void loadgame();
|
||||
void story();
|
||||
void credits();
|
||||
void about();
|
||||
void playthegame(int level,int sc,int sh);
|
Loading…
Reference in New Issue
Block a user