SDL Conversion, 2.9.1

This commit is contained in:
Vince Weaver 2000-09-04 23:57:00 -04:00
parent a276e7e57a
commit 6314d373e4
56 changed files with 4285 additions and 8693 deletions

6
BUGS
View File

@ -1,6 +0,0 @@
Known Bugs:
% sound sounds wrong on linux > 2.1.95 or so
% svgalib needs -force8bpp option
% weird colors at times in 8bpp X mode
% Enlightenment window manager screws up 8bpp colors
% game is not finished

13
CHANGES
View File

@ -1,3 +1,10 @@
4 September 2000
+ Have about 90% of the game running now on SDL. What a fun
way to spend labor day weekend.
24 June 2000
+ Started converting to the SDL lib. Got the title screen up
7 March 1998
* Added Level 2, mostly working
@ -42,3 +49,9 @@
* 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.
1994-1996
Wrote Tom Bombem in pascal and inline assembly, using the
"Flying Toaster" demo from PCGPE as a starting point.
Used Ethan Brodsky's sound libs, in addition to my own
"Paintpro" graphics program/loader.

View File

@ -1,29 +0,0 @@
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-980403.tar.gz
* save it
* uncompress it "tar -xzvf ggi-980226.tar.gz"
* "cd ggi" "cd lib" "cd libggi" "make"
* Select the "TARGETS" option on the menu
* this brings up a menu. be sure to choose "xserv","xlib", "svga","multi"
and "mem" you can choose others if you wish, but these are the ones I use.
* 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

View File

@ -1,54 +1,30 @@
##############################################################
# Makefile for Tom Bombem -- 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
INCLUDE= -Wall -I/usr/local/include/SDL -I/usr/local/include
LIBS= -lSDL -lSDL_mixer -L/usr/X11R6/lib -lX11 -lpthread
######################################################################
# THERE IS NO NEED TO EDIT ANYTHING BELOW THIS LINE #
######################################################################
all: tb1
all: tb1
tb1: tb1.o sdl_svmwgraph.o vmw_sprite.o tblib.o level_1.o sound.o
gcc -o tb1 tb1.o sdl_svmwgraph.o vmw_sprite.o tblib.o level_1.o sound.o $(LIBS)
tb1.o: tb1.c
gcc -c tb1.c $(INCLUDE)
tblib.o: tblib.c
gcc -c tblib.c $(INCLUDE)
sdl_svmwgraph.o: sdl_svmwgraph.c
gcc -c sdl_svmwgraph.c $(INCLUDE)
vmw_sprite.o: vmw_sprite.c
gcc -c vmw_sprite.c $(INCLUDE)
level_1.o: level_1.c
gcc -c level_1.c $(INCLUDE)
sound.o: sound.c
gcc -c sound.c $(INCLUDE)
clean:
rm -f *.o
rm -f tb1
rm -f *~
tb1: tb1.o svmwgrap.o gtblib.o tblib.o level1.o level2.o soundIt.o
$(CC) $(C_OPTS) -o tb1 tb1.o svmwgrap.o gtblib.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
gtblib.o: gtblib.c
$(CC) $(C_OPTS) -c gtblib.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
rm tb1 *.o *~

333
README
View File

@ -1,319 +1,14 @@
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
For now, just compiling info.
You need the SDL game development library, 1.1.3 or newer:
http://www.libsdl.org/download-1.1.html
You also need the "SDL_mixer library" from
http://www.libsdl.org/projects/SDL_mixer/index.html
To compile SDL_Mixer you need the smpeg library:
http://www.lokigames.com/development/smpeg.php3
Then a "make" should compile it.

4
TODO
View File

@ -2,3 +2,7 @@ Finish the game [or at least get it on-par with the dos version]
Requires:
Levels2-4
Highscore list
Save Games
Implement Shield Color
Scrolling Credits
Finish Story

BIN
data/tb_ahh.wav Normal file

Binary file not shown.

BIN
data/tb_bonk.wav Normal file

Binary file not shown.

BIN
data/tb_cc.wav Normal file

Binary file not shown.

BIN
data/tb_click.wav Normal file

Binary file not shown.

BIN
data/tb_kapow.wav Normal file

Binary file not shown.

BIN
data/tb_ow.wav Normal file

Binary file not shown.

BIN
data/tb_zrrp.wav Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

BIN
data/vmwfan.mod Normal file

Binary file not shown.

BIN
data/weave1.mod Normal file

Binary file not shown.

191
gtblib.c
View File

@ -1,191 +0,0 @@
/* Generic tblib stuff usable by other apps */
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/stat.h>
#include <ggi/libggi.h>
#include "svmwgrap.h"
#include "levels.h"
extern vmw_font *tb1_font;
extern ggi_visual_t vis;
extern ggi_visual_t vaddr;
extern ggi_visual_t vaddr2;
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 stride_factor;
extern char path_to_data[256];
extern int read_only_mode;
extern ggi_color eight_bit_pal[256];
extern ggi_pixel tb1_pal[256];
extern int color_depth;
#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 get_input() {
int evmask;
ggi_event ev;
struct timeval t={0,0};
evmask=emKeyPress|emKeyRelease|emPointer;
while (ggiEventPoll(vis,evmask,&t)) {
do {
ggiEventRead(vis,&ev,evmask);
} while(! ( (1 << ev.any.type) & evmask ) );
if (ev.any.type==evKeyPress) {
switch(KTYP(U(ev.key.sym))) {
case KT_LATIN:
case KT_LETTER:
return (KVAL(U(ev.key.sym))); break;
default: switch(U(ev.key.sym)) {
case K_UP: /* CrSr up */
case K_P8: /* Keypad 8 */
return TB_UP;break;
case K_DOWN: /* CrSr down */
case K_P2: /* Keypad 2 */
return TB_DOWN;break;
case K_RIGHT: /* CrSr right */
case K_P6: /* CrSr right */
return TB_RIGHT;break;
case K_LEFT: /* CrSr left */
case K_P4: /* CrSr left */
return TB_LEFT;break;
case K_F1:
return TB_F1;break;
case K_F2:
return TB_F2;break;
case K_ENTER: /* enter */
return TB_ENTER;break;
default:
/*printf("sym=%4x code=%4x\n",ev.key.sym,ev.key.code);*/break;
}
}
}
}
return 0;
}
void clear_keyboard_buffer()
{
while (get_input()!=0) ;
}
void drawsquare(int x1,int y1,int x2,int y2,int col,ggi_visual_t page)
{
ggiSetGCForeground(page,tb1_pal[col]);
/*ggiDrawHLine(page,x1,y1,(x2-x1));
* ggiDrawHLine(page,x1,y2,(x2-x1));
* ggiDrawVLine(page,x1,y1,(y2-y1));
* ggiDrawVLine(page,x2,y1,(y2-y1));*/
ggiDrawLine(page,x1,y1,x1,y2);
ggiDrawLine(page,x2,y1,x2,y2);
ggiDrawLine(page,x1,y1,x2,y1);
ggiDrawLine(page,x1,y2,x2,y2);
}
void coolbox(int x1,int y1,int x2,int y2,int fill,ggi_visual_t page)
{
int i;
for(i=0;i<5;i++) {
/*ggiSetGCForeground(page,31-i);
ggiDrawBox(page,x1+i,y1+i,(x2-x1-i-i),(y2-y1-i-i));*/
drawsquare(x1+i,y1+i,x2-i,y2-i,31-i,page);
}
if (fill) {
ggiSetGCForeground(page,tb1_pal[7]);
for(i=y1+5;i<y2-4;i++) ggiDrawHLine(page,x1+5,i,(x2-x1-9));
}
}
int close_graphics()
{
int err=0;
err=ggiClose(vis);
err+=ggiClose(vaddr);
err+=ggiClose(vaddr2);
if (err) fprintf(stderr,"Probelms shutting down GGI!\n");
else fprintf(stderr,"Shutting down GGI...\n");
ggiExit();
return 0;
}
int quit()
{
int barpos=0,ch=0,ch2;
coolbox(90,75,230,125,1,vis);
VMWtextxy("QUIT??? ARE YOU",97,82,tb1_pal[9],tb1_pal[7],0,tb1_font,vis);
VMWtextxy("ABSOLUTELY SURE?",97,90,tb1_pal[9],tb1_pal[7],0,tb1_font,vis);
while (ch!=TB_ENTER){
if (barpos==0) VMWtextxy("YES-RIGHT NOW!",97,98,tb1_pal[150],tb1_pal[0],1,tb1_font,vis);
else VMWtextxy("YES-RIGHT NOW!",97,98,tb1_pal[150],tb1_pal[7],1,tb1_font,vis);
if (barpos==1) VMWtextxy("NO--NOT YET.",97,106,tb1_pal[150],tb1_pal[0],1,tb1_font,vis);
else VMWtextxy("NO--NOT YET.",97,106,tb1_pal[150],tb1_pal[7],1,tb1_font,vis);
while ( (ch=get_input())==0);
ch2=toupper(ch);
if ((ch==TB_UP)||(ch==TB_DOWN)||(ch==TB_LEFT)||(ch==TB_RIGHT)) barpos++;
if (ch2=='Y') barpos=0;
if (ch2=='N') barpos=1;
if (barpos==2) barpos=0;
}
if (barpos==0){
close_graphics();
exit(1);
}
else return 6;
/*move(imagedata,screen,4000); textcolor(7);*/
}
int pauseawhile(int howlong)
{
struct timeval bob;
struct timezone mree;
long begin_s,begin_u;
int ch=0;
clear_keyboard_buffer();
gettimeofday(&bob,&mree);
begin_s=bob.tv_sec; begin_u=bob.tv_usec;
while(( (bob.tv_sec-begin_s)<howlong) && ( (ch=get_input())==0)) {
usleep(30);
gettimeofday(&bob,&mree);
}
return ch;
}
void shadowrite(char *st,int x5,int y5,int forecol,int backcol,
ggi_visual_t vis)
{
VMWtextxy(st,x5+1,y5+1,tb1_pal[backcol],0,0,tb1_font,vis);
VMWtextxy(st,x5,y5,tb1_pal[forecol],0,0,tb1_font,vis);
}

View File

@ -1,19 +0,0 @@
#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 get_input();
void coolbox(int x1,int y1,int x2,int y2,int fill,ggi_visual_t page);
int close_graphics();
int quit();
void clear_keyboard_buffer();
void shadowrite(char *st,int x,int y,int forecol,int backcol,ggi_visual_t vis);
void pauseawhile(int howlong);

View File

@ -1,20 +0,0 @@
Vince!;!
Vince;
Vince
KEVIN
KEVIN!@#%&
Vince
Vince
KEVIN
MREE
kevin
2210
2000
1900
1860
1860
1850
1810
1790
1790
1790

View File

@ -1,3 +1,6 @@
what follows is the old dos readme... I'll update it one of these days..
ーーーーーイ ーーーーーイ ーイ ーイ ーーーーイ ーーーーーイ ーイ ーイ ーーーーイ ーーーーーイ ーイ ーイ
ーイ ーイ ーイ ーーイーーイ ーイ ーイ ーイ ーイ ーーイーーイ ーイ ーイ ーイ ーーイーーイ
ーイ ーイ ーイ ーイーイーイ ーーーーイ ーイ ーイ ーイーイーイ ーーーーイ ーーーーイ ーイーイーイ

114
legacy_pascal/graph32.asm Normal file
View File

@ -0,0 +1,114 @@
.Model Medium,Pascal
.CODE
PUBLIC cls32,flipd320,flipd240,flipd50
cls32 PROC FAR pascal
.386
push di
cld
mov ax, [bp+6]
mov es, ax
xor di,di
mov bl,[bp+8]
mov bh,bl
mov ax,bx
shl eax,16
mov ax,bx
mov cx,320*200/4
rep stosd
pop di
ret
cls32 ENDP
;procedure flip32(source,dest:Word);
;This copies the entire screen at "source" to destination
flipd320 PROC FAR PASCAL
.386
push ds
mov ax, [bp+6]
mov es, ax
mov ax, [bp+8]
mov ds, ax
xor si, si
xor di, di
mov cx, 16000
rep movsd
pop ds
ret
flipd320 ENDP
;procedure flipd240(hm,va,va2:word);
;label gus;
; { This copies 240 columns from vaddr2 to vaddr }
flipd240 PROC FAR PASCAL
.386
push ds
mov ax, [bp+8]
mov es, ax
mov ax, [bp+6]
mov bx,[bp+10]
mov cx,bx
shl bx,4
sub bx,cx
add ax,bx
mov ds, ax
xor si,si
xor di, di
mov ax,200
gus:
mov cx, 60
rep movsd
add di,80
dec ax
jnz gus
pop ds
ret
flipd240 ENDP
;procedure flip50(fromwhere,off1,whereto,off2:word);
;label gus;
; { This copies 240 columns from vaddr2 to vaddr }
flipd50 PROC FAR PASCAL
.386
push ds
mov ax, [bp+8] ;whereto
add ax, [bp+6] ;off2
mov es, ax
mov ax, [bp+12] ;fromwhere
add ax,[bp+10] ;off1
mov ds, ax
xor si,si
xor di, di
mov ax,50
gus2:
mov cx, 60
rep movsd
dec ax
jnz gus2
pop ds
ret
flipd50 ENDP
END

View File

@ -0,0 +1,25 @@
var background:array[0..11,0..100] of byte;
i,j:integer;
f:text;
begin
for i:=0 to 11 do
for j:=0 to 100 do
background[i,j]:=0;
assign(f,'level2.tbx');
rewrite(f);
for j:=0 to 100 do begin
for i:=0 to 10 do write(f,background[i,j],' ');
writeln(f,background[11,j]);
end;
close(f);
assign(f,'level2.tbx');
reset(f);
for j:=0 to 100 do
for i:=0 to 10 do read(f,background[i,j]);
close(f);
for j:=0 to 100 do for i:=0 to 10 do write(background[i,j],' ');
end.

View File

@ -0,0 +1,22 @@
program developnewvmwtpu;
uses nvmwgraph,crt;
var error:byte;
ch:char;
i:integer;
begin
setmcga;
{for i:=0 to 39 do
horizontalline(0,319,i*5,i,vga);}
for i:=0 to 319 do
verticalline(0,199,i,i mod 215,vga);
error:=loadpicsuperpacked(0,0,vga,true,true,'t2tract.tb1');
{error:=savepicsuperpacked(0,0,239,50,256,vga,'t2tract.tb1');}
readln;
for i:=0 to 319 do
verticalline(0,199,i,i mod 215,vga);
readln;
settext;
end.

949
legacy_pascal/tb1sb.pas Normal file
View File

@ -0,0 +1,949 @@
program TOM_BOMB_EM_AND_INVASION_OF_INANIMATE_OBJECTS;
{by Vincent Weaver....21085-4706}
uses vmwgraph,crt;
{$I c:\vmw\pascal\programs\tb1ans.pas}
{$M $4000,0,$20000} {16k stack, no heap - adjust as needed }
{$L MOD-obj.OBJ} { Link in Object file }
{$F+} { force calls to be 'far'}
procedure modvolume(v1,v2,v3,v4:integer); external ; {Can do while playing}
procedure moddevice(var device:integer); external ;
procedure modsetup(var status:integer;device,mixspeed,pro,loop:integer;var str:string); external ;
procedure modstop; external ;
procedure modinit; external;
{$F-}
type screentype = array [0..3999] of byte;
Type Shipinfo = Record { This is format of of each of our }
x,y:integer; { records for the flying toasters }
speed,frame:integer;
active:boolean;
END;
Virtual = Array [1..64000] of byte; { The size of our Virtual Screen }
VirtPtr = ^Virtual; { Pointer to the virtual screen }
var
dev,mix,stat,pro,loop : integer;
md : string;
VAR Virscr : VirtPtr; { Our first Virtual screen }
VirScr2 : VirtPtr; { Our second Virtual screen }
Vaddr : word; { The segment of our virtual screen}
Vaddr2 : Word; { The segment of our 2nd virt. screen}
ourpal : Array [0..255,1..3] of byte; { A virtual pallette }
shipv : Array [1..1] of shipinfo; { The toaster info }
Sound : Pointer;
Check : BOOLEAN;
frame:array[0..2,0..47,0..29] of byte;
bigflame:array[0..1,0..26,0..18] of byte;
smallflame:array[0..1,0..3,0..4] of byte;
barge:array[0..15,0..18] of byte;
truck:array[0..1,0..5,0..8] of byte;
score,level,lives,energy:integer;
axel_und_carmen:boolean;
tempi,tempj:integer;
scorest:string[8];
var grapherror:byte;
temp:array[1..3] of byte;
palf:text;
i,j:byte;
x,y,barpos:integer;
screen:screentype absolute $B800:0000;
ch:char;
function menuread:char;
var chtemp,ch2:char;
begin
repeat until keypressed;
ch2:=#0;
chtemp:=readkey;
if chtemp=chr(0) then ch2:=readkey;
chtemp:=upcase(chtemp);
if (ord(chtemp)<10) and (ord(chtemp)<128) then begin
if ch2='H' then chtemp:='ß'; {up}
if ch2='M' then chtemp:='Þ'; {right}
if ch2='P' then chtemp:='Ü'; {down}
if ch2='K' then chtemp:='Ý'; {left}
if ch2=';' then chtemp:='¨'; {f1}
if ch2='I' then chtemp:='ô'; {pgup}
if ch2='Q' then chtemp:='õ'; {pgdown}
end;
menuread:=chtemp;
end;
procedure coolbox(x1,y1,x2,y2:integer;fill:boolean;page:word);
begin
for i:=0 to 5 do box(x1+i,y1+i,x2-i,y2-i,31-i,page);
if fill then for i:=y1+5 to y2-5 do line(x1+5,i,x2-5,i,7,page);
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure ShutDown;
{ This frees the memory used by the virtual screen }
BEGIN
FreeMem (VirScr,64000);
FreeMem (VirScr2,64000);
END;
procedure QUIT;
label menu2;
begin
coolbox(90,75,230,125,true,vga);
barpos:=0;
outtextxy('QUIT??? ARE YOU',97,82,15,9,7,vga,false);
outtextxy('ABSOLUTELY SURE?',97,90,15,9,7,vga,false);
repeat
if barpos=0 then outtextxy('YES-RIGHT NOW!',97,98,15,150,0,vga,true)
else outtextxy('YES-RIGHT NOW!',97,98,15,150,7,vga,true);
if barpos=1 then outtextxy('NO--NOT YET.',97,106,15,150,0,vga,true)
else outtextxy('NO--NOT YET.',97,106,15,150,7,vga,true);
ch:=menuread;
if (ord(ch)>219) and (ord(ch)<224) then inc(barpos);
if ch='Y' then barpos:=0;
if ch='N' then barpos:=1;
if barpos=2 then barpos:=0;
until ch=#13;
if barpos=1 then goto menu2;
settext;
move(imagedata,screen,4000);
gotoxy(1,23);
halt;
menu2:
barpos:=6;
end;
Procedure SetUpVirtual;
{ This sets up the memory needed for the virtual screen }
BEGIN
GetMem (VirScr,64000);
vaddr := seg (virscr^);
GetMem (VirScr2,64000);
vaddr2 := seg (virscr2^);
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure drawstars(menu:boolean);
{ This procedure sets up the static background to be used in the program }
CONST circ : Array [1..5,1..5] of byte =
((00,00,30,00,00),
(00,00,26,00,00),
(30,26,18,26,30),
(00,00,26,00,00),
(00,00,30,00,00));
VAR i,x,y:integer;
loop1,loop2,loop3:integer;
tempaddr:word;
procedure makehole(y:integer);
var i:integer;
begin
for i:=10 to 75 do line(239+i,y,239+i,y+9,0,tempaddr);
line(249,y,314,y,24,tempaddr);
line(249,y+10,313,y+10,18,tempaddr);
line(249,y,249,y+9,24,tempaddr);
line(314,y+1,314,y+10,18,tempaddr);
end;
BEGIN
tempaddr:=vaddr;
For loop1:=1 to 200 do BEGIN
x:=random (315);
y:=random (195);
For loop2:=1 to 5 do
For loop3:=1 to 5 do
if circ [loop2,loop3]<>0 then
putpixel (x+loop2,y+loop3,circ [loop2,loop3],tempaddr);
END;
if menu=false then begin
for i:=240 to 319 do line(i,0,i,199,19,tempaddr);
line(240,0,240,199,18,tempaddr);
line(240,0,319,0,18,tempaddr);
line(319,0,319,199,24,tempaddr);
line(241,199,319,199,24,tempaddr);
outtextxy('SCORE',241,1,15,127,0,tempaddr,false);
outtextxy('SCORE',242,2,15,143,0,tempaddr,false);
makehole(10);
outtextxy(' 0',250,12,15,12,0,tempaddr,false);
outtextxy('HI-SCORE',241,21,15,127,0,tempaddr,false);
outtextxy('HI-SCORE',242,22,15,143,0,tempaddr,false);
makehole(30);
outtextxy(' 0',250,32,15,12,0,tempaddr,false);
outtextxy('LEVEL',241,41,15,127,0,tempaddr,false);
outtextxy('LEVEL',242,42,15,143,0,tempaddr,false);
makehole(50);
outtextxy('12345675',251,52,15,12,0,tempaddr,false);
outtextxy('SHIELDS',241,61,15,127,0,tempaddr,false);
outtextxy('SHIELDS',242,62,15,143,0,tempaddr,false);
makehole(70);
for i:=0 to 63 do line(250+i,71,250+i,79,((i div 4)+32),tempaddr);
outtextxy('WEAPONS',241,81,15,127,0,tempaddr,false);
outtextxy('WEAPONS',242,82,15,143,0,tempaddr,false);
makehole(90);
for i:=0 to 65 do line(249+i,111,249+i,189,0,tempaddr);
line(249,111,249,189,24,tempaddr);
line(315,111,315,189,18,tempaddr);
line(249,111,315,111,24,tempaddr);
line(249,189,315,189,18,tempaddr);
outtextxy(' VMW ',251,114,15,15,0,tempaddr,false);
outtextxy('F1-HELP ',251,124,15,15,0,tempaddr,false);
outtextxy('ESC-QUIT',251,135,15,15,0,tempaddr,false);
outtextxy('F2-SAVE ',251,145,15,15,0,tempaddr,false);
end;
if not(menu) then begin
flip (vaddr,vga); { Copy the entire screen at vaddr, our virtual screen }
{ on which we have done all our graphics, onto the }
{ screen you see, VGA }
flip (vaddr,vaddr2);
end;
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure ScreenTrans (x,y,p1,p2:word);
{ This is a small procedure to copy a 30x30 pixel block from coordinates
x,y on the virtual screen to coordinates x,y on the true vga screen }
BEGIN
asm
push ds
push es
mov ax,p1
mov es,ax
mov ax,p2
mov ds,ax
mov bx,[X]
mov dx,[Y]
push bx {; and this again for later}
mov bx, dx {; bx = dx}
mov dh, dl {; dx = dx * 256}
xor dl, dl
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1 {; bx = bx * 64}
add dx, bx {; dx = dx + bx (ie y*320)}
pop bx {; get back our x}
add bx, dx {; finalise location}
mov di, bx {; es:di = where to go}
mov si, di
mov al,60
mov bx, 30 { Hight of block to copy }
@@1 :
mov cx, 24 { Width of block to copy divided by 2 }
rep movsw
add di,110h { 320 - 48 = 272 .. or 110 in hex }
add si,110h
dec bx
jnz @@1
pop es
pop ds
end;
{ I wrote this procedure late last night, so it may not be in it's
most optimised state. Sorry :-)}
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure newship;
{ This adds a new toaster to the screen }
VAR loop1:integer;
BEGIN
loop1:=1;
if not (shipv[1].active) then BEGIN
shipv[1].x:=36;
shipv[1].y:=165;
shipv[1].active:=true;
shipv[1].frame:=1;
shipv[1].speed:=5;
loop1:=10;
END;
END;
procedure putico(x,y,fra:byte;where:word);
var i,j,col:integer;
begin
for i:=0 to 47 do
for j:=0 to 29 do begin
col:=frame[fra,i,j];
if col<>0 then putpixel(i+x,y+j,col,where);
end;
end;
procedure putwave(x,y,fra:byte;where:word);
var i,j,col:integer;
begin
for i:=10 to 30 do
for j:=0 to 5 do begin
col:=frame[fra,i,j];
if col<>0 then putpixel((i+x)-10,y+j,col,where);
end;
end;
procedure changescore;
begin
str(score:8,scorest);
outtextxy(scorest,250,12,15,12,0,vaddr,true);
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure shiproutine;
VAR loop1,loop2:integer;
ch,ch2:char;
shieldcol:integer;
wave1:array[0..5] of boolean;
bulletx,bullety,oldwavex,oldwavey,wavex,wavey,i,waveadd:integer;
bulletout:boolean;
BEGIN
pal(254,0,0,0);
shieldcol:=0;
shipv[1].active:=false;
newship;
ch:=#1; ch2:=#1;
wavex:=0; wavey:=0; waveadd:=5;
oldwavex:=0; oldwavey:=0;
bulletout:=false; bulletx:=0; bullety:=0;
for i:=0 to 4 do wave1[i]:=true;
Repeat
ch2:=#1;
if (bulletout) and (bulletx>wavex) and (bulletx<wavex+100) and
(bullety>wavey) and (bullety<wavey+10) then begin
bulletout:=false;
inc(score,10);
changescore;
wave1[(bulletx-wavex) div 20]:=false;
end;
if bulletout then begin
screentrans(bulletx,bullety,vaddr,vaddr2);
dec(bullety,5);
if bullety<5 then bulletout:=false;
if bulletout then putwave(bulletx,bullety,1,vaddr);
end;
for i:=0 to 5 do
screentrans((oldwavex+20*i),oldwavey,vaddr,vaddr2);
for i:=0 to 5 do
if wave1[i] then putwave(wavex+20*i,wavey,1,vaddr);
oldwavex:=wavex; oldwavey:=wavey;
wavex:=wavex+waveadd;
if (wavex>100) or (wavex<5) then begin
inc(wavey,5);
waveadd:=-waveadd;
end;
if wavey>150 then begin
wavey:=0;
for i:=0 to 5 do if wave1[i]=false then wave1[i]:=true;
end;
if keypressed then BEGIN
ch:=readkey;
if ch=chr(0) then ch2:=readkey;
if ch2='M' then inc(shipv[1].x,5);
if ch2='K' then dec(shipv[1].x,5);
if ch=' ' then begin
bulletout:=true;
bulletx:=shipv[1].x+10;
bullety:=shipv[1].y;
putwave(bulletx,bullety,1,vaddr);
end;
if ch='+' then begin inc(shieldcol,3); pal(254,shieldcol,0,0);
if shieldcol>58 then shieldcol:=59;
end;
if ch='-' then begin dec(shieldcol,3); pal(254,shieldcol,0,0);
if shieldcol<5 then shieldcol:=3;
end;
end;
if shipv[1].active then BEGIN
screentrans (shipv[1].x,shipv[1].y,vaddr,vaddr2);
{ Restore the backgrond the toaster was over }
{ Move the toaster }
if (shipv[1].x<1) then shipv[1].x:=1;
if (shipv[1].x>255) then shipv[1].x:=255;
{ When toaster reaches the edge of the screen, render it inactive
and bring a new one into existance. }
END;
if shipv[1].active then BEGIN
CASE shipv [1].frame of
1 : putico (shipv[1].x,shipv[1].y,0,vaddr);
3 : putico (shipv[1].x,shipv[1].y,1,vaddr);
2,4 : putico (shipv[1].x,shipv[1].y,2,vaddr);
END;
shipv[1].frame:=shipv[1].frame+1;
if shipv[1].frame=5 then shipv[1].frame:=1;
{ Draw all the toasters on the VGA screen }
end;
waitretrace;
flip (vaddr,vga);
until ch=#27;
fade
END;
procedure playthegame(lev:integer);
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
var palloop,paldir:integer;
begin
cls(0,vaddr);
grapherror:=loadpicsuperpacked(0,0,vga,'tbma1.tb1');
outtextxy('MOONBASE ALPHA: EARTH''S LAST CHANCE!',5,5,15,1,0,vga,false);
pal(255,0,0,0);
palloop:=0;
paldir:=1;
repeat
pal(255,palloop,0,0);
if paldir=1 then inc(palloop)
else dec(palloop);
if palloop>62 then paldir:=-1;
if palloop<1 then paldir:=1;
delay(50);
until keypressed;
ch:=readkey;
drawstars(false);
shiproutine;
end;
procedure dographics;
var i,j:integer;
begin
grapherror:=loadpicsuperpacked(0,0,vaddr,'ships.tb1');
for i:=0 to 47 do
for j:=0 to 29 do
frame[0,i,j]:=getpixel(i,j,vaddr);
for i:=0 to 47 do
for j:=0 to 29 do
frame[1,i,j]:=getpixel(i,j+32,vaddr);
for i:=0 to 47 do
for j:=0 to 29 do
frame[2,i,j]:=getpixel(i,j+64,vaddr);
end;
procedure background;
begin
cls(0,vaddr);
drawstars(true);
coolbox(0,0,319,199,false,vaddr);
end;
procedure options;
begin
background;
flip(vaddr,vga);
outtextxy('AS OF YET THERE ARE NO OPTIONS!',10,10,15,9,0,vga,false);
repeat until keypressed;
ch:=readkey;
end;
procedure loadgame;
begin
coolbox(90,75,230,125,true,vga);
outtextxy('LOAD WHICH GAME',97,82,15,9,7,vga,false);
outtextxy(' (0-9) ',97,90,15,9,7,vga,false);
repeat until keypressed;
level:=0;
end;
procedure help;
begin
background;
flip(vaddr,vga);
outtextxy('HELP',10,10,15,9,0,vga,false);
outtextxy('Press ESC to exit most stuff.',10,20,15,9,0,vga,false);
outtextxy('Use the arrows to manuever.',10,30,15,9,0,vga,false);
repeat until keypressed;
ch:=readkey;
end;
procedure story;
var error:byte;
xtemp,ytemp:integer;
thrustcol:integer;
thrust:real;
tempch:char;
procedure putbigflame(xp,yp,frame:integer);
var xtemp,ytemp:integer;
begin
for xtemp:=0 to 26 do
for ytemp:=0 to 18 do
putpixel(xtemp+xp,ytemp+yp,bigflame[frame,xtemp,ytemp],vaddr);
end;
procedure putsmallflame(xp,yp,frame:integer);
var xtemp,ytemp:integer;
begin
for xtemp:=0 to 3 do
for ytemp:=0 to 4 do
putpixel(xtemp+xp,ytemp+yp,smallflame[frame,xtemp,ytemp],vaddr);
end;
procedure putbarge(xp,yp:integer;where:word);
var xtemp,ytemp:integer;
col:byte;
begin
for xtemp:=0 to 15 do
for ytemp:=0 to 18 do begin
if (ytemp+yp>=0) then begin
col:=barge[xtemp,ytemp];
if col<>0 then putpixel(xtemp+xp,ytemp+yp,col,where);
end;
end;
end;
procedure puttruck(xp,yp,frame:integer;where:word);
var xtemp,ytemp:integer;
col:byte;
begin
for xtemp:=0 to 5 do
for ytemp:=0 to 8 do begin
col:=truck[frame,xtemp,ytemp];
if (ytemp+yp>=173) then begin
if col<>0 then putpixel(xtemp+xp,ytemp+yp,col,where);
end;
end;
end;
begin
fade;
error:=loadpicsuperpacked(0,0,vaddr,'tbsobj.tb1');
for xtemp:=0 to 26 do
for ytemp:=0 to 18 do begin
bigflame[0,xtemp,ytemp]:=getpixel(xtemp,ytemp+2,vaddr);
bigflame[1,xtemp,ytemp]:=getpixel(xtemp,ytemp+21,vaddr);
end;
for xtemp:=0 to 3 do
for ytemp:=0 to 4 do begin
smallflame[0,xtemp,ytemp]:=getpixel(xtemp,ytemp+43,vaddr);
smallflame[1,xtemp,ytemp]:=getpixel(xtemp,ytemp+47,vaddr);
end;
for xtemp:=0 to 15 do
for ytemp:=0 to 18 do
barge[xtemp,ytemp]:=getpixel(xtemp+65,ytemp+100,vaddr);
for xtemp:=0 to 5 do
for ytemp:=0 to 8 do begin
truck[0,xtemp,ytemp]:=getpixel(xtemp+85,ytemp+100,vaddr);
truck[1,xtemp,ytemp]:=getpixel(xtemp+95,ytemp+100,vaddr);
end;
{******FIRST MESSAGE*******}
cls(0,vga);
outtextxy('MOON BASE ALPHA:',5,5,15,9,0,vga,false);
outtextxy(' THE FIRST PRIVATELY FINANCED SPACE ',5,15,15,9,0,vga,false);
outtextxy(' VENTURE. FOUNDED IN 2004 BY PIONEER',5,25,15,9,0,vga,false);
outtextxy(' VINCE WEAVER. IN ORDER TO SUPPORT',5,35,15,9,0,vga,false);
outtextxy(' ITSELF, IT DISPOSED OF GARBAGE AND',5,45,15,9,0,vga,false);
outtextxy(' NUCLEAR WASTE FROM EARTH BY LAUNCHING',5,55,15,9,0,vga,false);
outtextxy(' IT INTO DEEP SPACE WITH BARGES. ',5,65,15,9,0,vga,false);
outtextxy('NOW IT IS 2018, AND THE LAST BARGE IS',5,75,15,9,0,vga,false);
outtextxy(' TO BE LAUNCHED. NOW ALL WORK THERE',5,85,15,9,0,vga,false);
outtextxy(' WILL BE CONCENTRATED ON BUILDING A',5,95,15,9,0,vga,false);
outtextxy(' TERRAN SPACE FLEET.',5,105,15,9,0,vga,false);
unfade;
repeat until keypressed; tempch:=readkey;
pal(250,0,0,0);
fade;
{******BARGE TAKING OFF**********}
error:=loadpicsuperpacked(0,0,vaddr2,'tbma1.tb1');
putbarge(141,157,vaddr2);
flip(vaddr2,vaddr);
flip(vaddr,vga);
unfade;
for ytemp:=191 downto 165 do begin
screentrans(145,ytemp,vaddr,vaddr2);
puttruck(145,ytemp,ytemp mod 2,vaddr);
vdelay(7);
flip(vaddr,vga);
end;
error:=loadpicsuperpacked(0,0,vaddr2,'tbma1.tb1');
vdelay(20);
flip(vaddr2,vaddr);
putbarge(141,157,vaddr);
thrustcol:=0;
ytemp:=157;
thrust:=0;
while ytemp>-25 do begin
thrust:=thrust+0.05;
if thrustcol<63 then inc(thrustcol);
screentrans(141,ytemp,vaddr,vaddr2);
putbarge(141,ytemp,vaddr);
vdelay(7);
pal(250,thrustcol,0,0);
flip(vaddr,vga);
ytemp:=ytemp-round(thrust);
end;
vdelay(100);
fade;
{******SECOND MESSAGE*******}
cls(0,vga);
outtextxy('5 YEARS LATER, 1 LIGHT YEAR DISTANT',5,5,15,9,0,vga,false);
outtextxy(' CATASTROPHE STRIKES!! ',5,15,15,9,0,vga,false);
unfade;
vdelay(100);
repeat until keypressed; tempch:=readkey;
fade;
{******ALIEN DELEGATION*****}
error:=loadpicsuperpacked(0,0,vaddr2,'tbcrash.tb1');
flip(vaddr2,vaddr);
unfade;
repeat
putbigflame(213,100,0);
putsmallflame(105,90,1);
putsmallflame(151,71,0);
putsmallflame(218,72,1);
putbarge(160,180,vaddr);
flip(vaddr,vga);
vdelay(5);
putbigflame(213,100,1);
putsmallflame(105,90,0);
putsmallflame(151,71,1);
putsmallflame(218,72,0);
flip(vaddr,vga);
vdelay(5);
until keypressed;
ch:=readkey;
{****ALIEN MESSAGE*****}
fade;
error:=loadpicsuperpacked(0,0,vga,'tbgorg.tb1');
unfade;
outtextxy('GREETINGS EARTHLINGS.',0,162,15,12,0,vga,false);
outtextxy('I AM GORGONZOLA THE REPULSIVE.',0,171,15,12,0,vga,false);
outtextxy('YOU HAVE MADE A BIG MISTAKE.',0,180,15,12,0,vga,false);
readln;
end;
procedure credits;
var j:integer;
sp:integer;
procedure rotate(stri:string;col:integer);
var j1:integer;
begin
if sp=1 then begin
for j1:=0 to 7 do begin
outtextxy(stri,0,198,j1,col,0,vga,false);
Move (mem[vga:320],mem[vga:0],63680);
if keypressed then begin inc(sp); cls(0,vga); end;
end;
end;
if sp<>1 then begin
outtextxy(stri,0,180,15,col,0,vga,true);
Move (mem[vga:3200],mem[vga:0],60800);
end;
end;
procedure skip; begin rotate(' ',0); end;
begin
sp:=1;
cls(0,vaddr);
flip(vaddr,vga);
j:=0;
if keypressed then ch:=readkey;
rotate(' TOM BOMBEM',4);
rotate(' INVASION OF THE INANIMATE OBJECTS',4);
skip; rotate(' PROGRAMMING',9);
skip; rotate(' VINCENT M WEAVER',9);
skip; skip; rotate(' GRAPHICS',10);
skip; rotate(' VINCENT M WEAVER',10);
skip; skip; rotate(' SOUND',11);
skip; rotate(' VINCENT M WEAVER',11);
skip; skip; rotate(' GRAPHICS INSPIRATION',12);
skip; rotate(' JEFF WARWICK',12);
skip; skip; rotate(' UTOPIA BBS 410-557-0868',13);
skip; rotate(' JOHN CLEMENS',13);
skip; rotate(' JASON GRIMM',13);
skip; skip; rotate(' PCGPE AUTHORS, esp',14);
skip; rotate(' GRANT SMITH',14);
skip; skip; rotate(' SOUND BLASTER INFO',15);
skip; rotate(' AXEL STOLZ',15);
skip; skip; rotate(' INSPIRATION',9);
skip; rotate(' DOUGLAS ADAMS',9);
skip; rotate(' GENE RODENBERRY',9);
skip; rotate(' CLIFF STOLL',9);
skip; rotate(' ARTHUR C CLARKE',9);
skip; rotate(' ISAAC ASIMOV',9);
skip; rotate(' GORDON KORMAN',9);
skip; skip; rotate(' THANKS TO ALL THE AGENTS',10);
skip; rotate(' B,D,JL,L,N,P,S,W,PM,E',10);
skip; rotate(' AND ESPECIALLY AGENT G',10);
i:=0;
repeat
move(mem[vaddr2:(i*320)],mem[vga:63680],320);
Move (mem[vga:320],mem[vga:0],63680);
inc(i);
until (keypressed) or (i=299);
if keypressed then ch:=readkey;
end;
procedure shadowrite(st:string;x5,y5,forecol,backcol:integer);
begin
outtextxy(st,x5+1,y5+1,15,backcol,0,vga,false);
outtextxy(st,x5,y5,15,forecol,0,vga,false);
end;
procedure register;
var pagenum,oldpagenum,numpages:integer;
pagest:string;
numst:string[2];
procedure page1;
begin
flip(vaddr,vga);
shadowrite(' TO REGISTER',10,10,9,1);
shadowrite('THIS GAME WAS WRITTEN BY A 16 YEAR OLD',10,30,9,1);
shadowrite(' ENTIRELY IN HIS FREE TIME.',10,40,9,1);
shadowrite('HOPEFULLY YOU FEEL HIS FREE TIME IS',10,50,9,1);
shadowrite(' WORTH SOMETHING.',10,60,9,1);
shadowrite('WARNING:',10,80,12,4);
shadowrite(' VMW SOFTWARE IS NOT AN INCORPORATED',10,90,12,4);
shadowrite(' COMPANY, NOR DOES IT HAVE ANY INCOME',10,100,12,4);
shadowrite(' EXCEPT DONATIONS. NONE OF ITS',10,110,12,4);
shadowrite(' SYMBOLS ARE TRADEMARKED EITHER. (BUT',10,120,12,4);
shadowrite(' I DOUBT YOU''LL NAME A COMPANY AFTER',10,130,12,4);
shadowrite(' MY ININTIALS)',10,140,12,4);
end;
procedure page2;
begin
flip(vaddr,vga);
shadowrite('PLEASE SEND ANY DONATIONS TO:',10,10,10,2);
shadowrite(' VINCENT WEAVER',10,20,10,2);
shadowrite(' 326 FOSTER KNOLL DR.',10,30,10,2);
shadowrite(' JOPPA, MD 21085-4706, USA, ETC.',10,40,10,2);
shadowrite('ANY DONATION OF $5 OR MORE GETS THE',10,60,13,5);
shadowrite(' NEWEST VERSION OF THE GAME, PLUS',10,70,13,5);
shadowrite(' ANY OTHER COOL PROGRAMS I HAVE AT',10,80,13,5);
shadowrite(' THE TIME.',10,90,13,5);
shadowrite('ALSO IF YOU SEND ME A SELF ADDRESSED',10,110,11,3);
shadowrite(' STAMPED ENVELOPE WITH SUFFICIENT',10,120,11,3);
shadowrite(' POSTAGE AND A 3 1/2 INCH DISK IN',10,130,11,3);
shadowrite(' IT, I WILL COPY THE NEWEST VERSION',10,140,11,3);
shadowrite(' OF THE GAME ONTO IT.',10,150,11,3);
end;
procedure page3;
begin
flip(vaddr,vga);
shadowrite('OTHER VMW SOFTWARE PRODUCTIONS:',10,10,15,7);
shadowrite(' PAINTPRO:',10,30,13,5);
shadowrite(' LOAD AND SAVE GRAPHICS PICTURES',10,40,13,5);
shadowrite(' INTO C, PASCAL, BASIC, ETC.',10,50,13,5);
shadowrite(' WITH SCREEN CAPTURE UTILITY.',10,60,13,5);
shadowrite(' SPACEWAR III:',10,70,11,3);
shadowrite(' ALMOST COMPLETE GAME WITH WORKING',10,80,11,3);
shadowrite(' SPACESHIPS. SORT OF COOL.',10,90,11,3);
shadowrite(' AITAS: (ADVENTURES IN TIME AND SPACE)',10,100,12,4);
shadowrite(' THIS GAME WILL BE FINISHED SOMEDAY.',10,110,12,4);
shadowrite(' IT HAS BEEN UNDER WAY FOR 3 YEARS.',10,120,12,4);
shadowrite(' MISC PASCAL/BASIC PROGRAMS:',10,130,9,1);
shadowrite(' OVER 500 PROGRAMS WRITTEN OR TYPED',10,140,9,1);
shadowrite(' IN BY ME....FUN TO LOOK AT.',10,150,9,1);
end;
procedure page4;
begin
flip(vaddr,vga);
shadowrite('DISCLAIMERS:',10,10,12,14);
shadowrite('** THE ABOVE PROGRAMS HAVE NEVER DONE**',5,30,12,4);
shadowrite('** ANYTHING BAD TO MY COMPUTER THAT **',5,40,12,4);
shadowrite('** CTRL-ALT-DEL WOULDN''T FIX. I AM **',5,50,12,4);
shadowrite('** NOT RESPONSIBLE FOR HARD DISK **',5,60,12,4);
shadowrite('** DISSAPPEARANCES, MISSING MODEMS **',5,70,12,4);
shadowrite('** MOUSE BREAKDOWNS, MELTING MONITORS**',5,80,12,4);
SHADOWRITE('** OR ANYTHING ELSE. **',5,90,12,4);
shadowrite('%% ALL VMW SOFTWARE PRODUCTIONS ARE %%',5,110,11,3);
shadowrite('%% CERTIFIED VIRUS FREE!!!!!!!!!!!! %%',5,120,11,3);
end;
begin
background;
pagenum:=1;
oldpagenum:=1;
numpages:=4;
page1;
shadowrite('PAGE 1 of 4: ESC QUITS',50,180,15,7);
repeat
ch:=menuread;
if (ch=' ') or (ch=#13) then inc(pagenum);
if (ch='õ') or (ch='Þ') or (ch='Ü') then inc(pagenum);
if (ch='ô') or (ch='Ý') or (ch='ß') then dec(pagenum);
if pagenum>4 then pagenum:=1;
if pagenum<1 then pagenum:=4;
if oldpagenum<>pagenum then begin
if pagenum=1 then page1;
if pagenum=2 then page2;
if pagenum=3 then page3;
if pagenum=4 then page4;
str(pagenum:2,numst);
pagest:=concat('PAGE ',numst);
str(numpages:2,numst);
pagest:=concat(pagest,' of ',numst,': ESC QUITS');
shadowrite(pagest,50,180,15,7);
oldpagenum:=pagenum;
end;
until ch=#27;
end;
label picloader,menu;
begin
axel_und_carmen:=true; {as_of_9-22-94} {change_back_10-6-94}
randomize;
setupvirtual;
fade;
setmcga;
dographics;
energy:=15;
lives:=2;
score:=0;
level:=0;
for x:=0 to 40 do begin
pal(100+x,x+20,0,0);
pal(141+x,0,0,x+20);
pal(182+x,0,x+20,0);
end;
fade;
modinit;
dev:=7;
md:='vmwfan.tb1';
mix := 10000; {use 10000 normally }
pro := 0; {Leave at 0}
loop :=0; {4 means mod will play forever}
modvolume (255,255,255,255); { Full volume }
modsetup ( stat, dev, mix, pro, loop, md );
case stat of
1: writeln('Not a mod');
2: writeln('Already playing');
4: writeln('Out of memory');
end;
for x:=0 to 40 do begin
line(x+40,45,x+40,45+(2*x),100+x,vga);
line(x+120,45,x+120,45+(2*x),141+x,vga);
line(x+200,45,x+200,45+(2*x),141+x,vga);
line(x+80,125,x+80,125-(2*x),182+x,vga);
line(x+160,125,x+160,125-(2*x),182+x,vga);
end;
for x:=40 downto 0 do begin
line(x+80,45,x+80,125-(2*x),140-x,vga);
line(x+160,45,x+160,125-(2*x),181-x,vga);
line(x+240,45,x+240,125-(2*x),181-x,vga);
line(x+120,125,x+120,45+(2*x),222-x,vga);
line(x+200,125,x+200,45+(2*x),222-x,vga);
end;
unfade;
outtextxy('A VMW SOFTWARE PRODUCTION',60,140,15,15,15,VGA,false);
y:=0;
repeat until keypressed;
ch:=readkey;
modstop;
fade;
cls(0,vga);
assign(palf,'pal.tb1');
reset(palf);
for i:=0 to 255 do begin
for j:=1 to 3 do readln(palf,temp[j]);
pal(i,temp[1],temp[2],temp[3]);
end;
close(palf);
fade;
PICLOADER:
grapherror:=loadpicsuperpacked(0,0,vaddr2,'tbomb1.tb1');
if not(axel_und_carmen) then begin
for tempi:=193 to 199 do
for tempj:=290 to 319 do
putpixel(tempj,tempi,0,vaddr2);
end;
MENU:
modinit;
dev:=7;
md:='weave1.tb1';
mix := 10000; {use 10000 normally }
pro := 0; {Leave at 0}
loop :=0; {4 means mod will play forever}
modvolume (255,255,255,255); { Full volume }
modsetup ( stat, dev, mix, pro, loop, md );
case stat of
1: writeln('Not a mod');
2: writeln('Already playing');
4: writeln('Out of memory');
end;
flip(vaddr2,vga);
unfade;
repeat until keypressed;
ch:=readkey;
barpos:=0;
outtextxy('F1 HELP',0,190,15,9,7,vga,false);
coolbox(117,61,199,140,true,vga);
repeat
if barpos=0 then outtextxy('NEW GAME',123,67,15,32,0,vga,true)
else outtextxy('NEW GAME',123,67,15,32,7,vga,true);
if barpos=1 then outtextxy('OPTIONS',123,77,15,32,0,vga,true)
else outtextxy('OPTIONS',123,77,15,32,7,vga,true);
if barpos=2 then outtextxy('REGISTER',123,87,15,32,0,vga,true)
else outtextxy('REGISTER',123,87,15,32,7,vga,true);
if barpos=3 then outtextxy('LOAD GAME',123,97,15,32,0,vga,true)
else outtextxy('LOAD GAME',123,97,15,32,7,vga,true);
if barpos=4 then outtextxy('STORY',123,107,15,32,0,vga,true)
else outtextxy('STORY',123,107,15,32,7,vga,true);
if barpos=5 then outtextxy('CREDITS',123,117,15,32,0,vga,true)
else outtextxy('CREDITS',123,117,15,32,7,vga,true);
if barpos=6 then outtextxy('QUIT',123,127,15,32,0,vga,true)
else outtextxy('QUIT',123,127,15,32,7,vga,true);
ch:=menuread;
if (ord(ch)=222) or (ord(ch)=220) then inc(barpos);
if (ord(ch)=223) or (ord(ch)=221) then dec(barpos);
if (ord(ch)=168) then begin barpos:=10; ch:=#13; end;
if ch='N' then barpos:=0;
if ch='O' then barpos:=1;
if ch='R' then barpos:=2;
if ch='L' then barpos:=3;
if ch='S' then barpos:=4;
if ch='C' then barpos:=5;
if ch='Q' then barpos:=6;
if ch='A' then axel_und_carmen:=not(axel_und_carmen);
if ch=#27 then begin
barpos:=6;
ch:=#13;
end;
if barpos=7 then barpos:=0;
if barpos=-1 then barpos:=6;
until ch=#13;
modstop;
if barpos=6 then quit;
if barpos=1 then options;
if barpos=2 then register;
if barpos=3 then loadgame;
if barpos=4 then story;
if barpos=5 then credits;
if barpos=10 then help;
if barpos=0 then playthegame(0);
if barpos=0 then goto picloader;
if barpos=4 then goto picloader;
goto menu;
end.

View File

@ -0,0 +1,614 @@
program TOM_BOMB_EM_AND_INVASION_OF_INANIMATE_OBJECTS;
{by Vincent Weaver....21085-4706}
uses vmwgraph,crt;
{$I c:\pascal\tb1ans.pas}
type screentype = array [0..3999] of byte;
Type Toastinfo = Record { This is format of of each of our }
x,y:integer; { records for the flying toasters }
speed,frame:integer;
active:boolean;
END;
icon = Array [1..30*48] of byte; { This is the size of our pictures }
Virtual = Array [1..64000] of byte; { The size of our Virtual Screen }
VirtPtr = ^Virtual; { Pointer to the virtual screen }
CONST frame1 : icon = (
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,01,01,01,
01,01,01,01,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,02,02,02,
02,02,02,02,02,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,03,03,
03,03,03,03,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,04,04,04,
04,04,04,04,04,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,06,06,06,
06,06,06,06,06,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,07,07,
7,07,07,07,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,07,07,07,
7,07,07,07,07,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,07,07,07,
7,07,07,07,07,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,07,07,07,
7,07,07,07,07,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,07,07,07,
7,07,07,07,07,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,07,07,07,
7,07,07,07,07,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,07,07,07,
7,07,07,07,07,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,07,07,07,
7,07,07,07,07,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,07,07,07,
7,07,07,07,07,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,09,07,07,07,
09,09,07,07,07,09,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,07,08,13,14,15,14,15,09,09,09,07,07,07,
08,08,07,07,07,09,09,09,13,14,15,14,15,08,07,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,07,08,09,13,14,15,14,15,09,09,09,07,07,07,
7,07,07,07,07,09,09,09,13,14,15,14,15,09,08,07,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,09,09,09,09,07,07,07,
10,10,07,07,07,09,09,09,09,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,07,08,08,08,08,08,08,08,08,08,08,08,08,07,07,07,
11,11,07,07,07,08,08,08,08,08,08,08,08,08,08,08,08,07,00,00,00,00,00,00,
00,00,00,00,00,00,00,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,
12,12,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,18,
17,17,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,18,19,
20,20,19,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,25,24,
21,21,24,25,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,27,26,25,
22,22,25,27,00,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,27,24,
23,23,24,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,26,27,
24,27,27,27,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,26,25,26,
26,26,27,25,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00);
frame2 : icon = (
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,01,01,01,
01,01,01,01,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,02,02,02,
02,02,02,02,02,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,03,03,
03,03,03,03,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,04,04,04,
04,04,04,04,04,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,06,06,06,
06,06,06,06,06,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,07,07,
07,07,07,07,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,07,07,07,
07,07,07,07,07,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,07,07,07,
07,07,07,07,07,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,07,07,07,
07,07,07,07,07,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,07,07,07,
07,07,07,07,07,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,09,07,07,07,
09,09,07,07,07,09,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,07,08,13,14,15,14,15,09,09,09,07,07,07,
08,08,07,07,07,09,09,09,13,14,15,14,15,08,07,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,07,08,09,13,14,15,14,15,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,13,14,15,14,15,09,08,07,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,09,09,09,09,07,07,07,
10,10,07,07,07,09,09,09,09,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,07,08,08,08,08,08,08,08,08,08,08,08,08,07,07,07,
11,11,07,07,07,08,08,08,08,08,08,08,08,08,08,08,08,07,00,00,00,00,00,00,
00,00,00,00,00,00,00,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,
12,12,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,18,
17,17,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,18,19,
20,20,19,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,25,24,
21,21,25,25,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,27,26,25,
22,22,27,27,00,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,27,24,
24,23,23,27,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,26,27,
24,27,27,27,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,26,25,26,
26,26,27,25,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00);
frame3 : icon = (
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,01,01,01,
01,01,01,01,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,02,02,02,
02,02,02,02,02,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,03,03,
03,03,03,03,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,04,04,04,
04,04,04,04,04,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,06,06,06,
06,06,06,06,06,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,05,05,05,
05,05,05,05,05,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,07,07,
07,07,07,07,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,07,07,07,
07,07,07,07,07,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,07,07,07,
07,07,07,07,07,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,07,07,07,
07,07,07,07,07,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,07,07,07,
07,07,07,07,07,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,09,07,07,07,
09,09,07,07,07,09,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,07,08,13,14,15,14,15,09,09,09,07,07,07,
08,08,07,07,07,09,09,09,13,14,15,14,15,08,07,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,07,08,09,13,14,15,14,15,09,09,09,07,07,07,
07,07,07,07,07,09,09,09,13,14,15,14,15,09,08,07,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,07,08,09,09,09,09,09,09,09,09,09,09,07,07,07,
10,10,07,07,07,09,09,09,09,09,09,09,09,09,09,08,07,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,07,08,08,08,08,08,08,08,08,08,08,08,08,07,07,07,
11,11,07,07,07,08,08,08,08,08,08,08,08,08,08,08,08,07,00,00,00,00,00,00,
00,00,00,00,00,00,00,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,
12,12,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,18,
17,17,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,18,19,
20,20,19,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,25,24,
21,21,24,25,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,27,26,25,
22,22,25,27,00,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,27,24,
23,23,24,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,26,27,
24,27,27,27,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,26,25,26,
26,26,27,25,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
);
VAR Virscr : VirtPtr; { Our first Virtual screen }
VirScr2 : VirtPtr; { Our second Virtual screen }
Vaddr : word; { The segment of our virtual screen}
Vaddr2 : Word; { The segment of our 2nd virt. screen}
ourpal : Array [0..255,1..3] of byte; { A virtual pallette }
toaster : Array [1..1] of toastinfo; { The toaster info }
Sound : Pointer;
Check : BOOLEAN;
var grapherror:byte;
temp:array[1..3] of byte;
palf:text;
i,j:byte;
x,y,barpos:integer;
screen:screentype absolute $B800:0000;
ch:char;
function menuread:char;
var chtemp,ch2:char;
begin
repeat until keypressed;
ch2:=#0;
chtemp:=readkey;
if chtemp=chr(0) then ch2:=readkey;
chtemp:=upcase(chtemp);
if (ord(chtemp)<10) and (ord(chtemp)<128) then begin
if ch2='H' then chtemp:='ß';
if ch2='M' then chtemp:='Þ';
if ch2='P' then chtemp:='Ü';
if ch2='K' then chtemp:='Ý';
end;
menuread:=chtemp;
end;
procedure coolbox(x1,y1,x2,y2:integer);
begin
for i:=0 to 5 do box(x1+i,y1+i,x2-i,y2-i,31-i,vga);
for i:=y1+5 to y2-5 do line(x1+5,i,x2-5,i,7,vga);
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure ShutDown;
{ This frees the memory used by the virtual screen }
BEGIN
FreeMem (VirScr,64000);
FreeMem (VirScr2,64000);
END;
procedure QUIT;
label menu2;
begin
coolbox(90,75,230,125);
barpos:=0;
outtextxy('QUIT??? ARE YOU',97,82,9,7,vga,false);
outtextxy('ABSOLUTELY SURE?',97,90,9,7,vga,false);
repeat
if barpos=0 then outtextxy('YES-RIGHT NOW!',97,98,150,0,vga,true)
else outtextxy('YES-RIGHT NOW!',97,98,150,7,vga,true);
if barpos=1 then outtextxy('NO--NOT YET.',97,106,150,0,vga,true)
else outtextxy('NO--NOT YET.',97,106,150,7,vga,true);
ch:=menuread;
if (ord(ch)>219) and (ord(ch)<224) then inc(barpos);
if ch='Y' then barpos:=0;
if ch='N' then barpos:=1;
if barpos=2 then barpos:=0;
until ch=#13;
if barpos=1 then goto menu2;
settext;
shutdown;
move(imagedata,screen,4000);
gotoxy(1,23);
halt;
menu2:
end;
Procedure SetUpVirtual;
{ This sets up the memory needed for the virtual screen }
BEGIN
GetMem (VirScr,64000);
vaddr := seg (virscr^);
GetMem (VirScr2,64000);
vaddr2 := seg (virscr2^);
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure putico(X,Y:Word;VAR sprt : icon;Where:Word); ASSEMBLER;
{ This puts an icon, EXCEPT it's color 0 (black) pixels, onto the screen
"where", at position X,Y }
label
_Redraw, _DrawLoop, _Exit, _LineLoop, _NextLine, _Store, _NoPaint;
asm
push ds
push es
lds si,Sprt
mov ax,X { ax = x }
mov bx,Y { bx = y }
_Redraw:
push ax
mov ax,[where]
mov es,ax
mov ax, bx {; ax = bx x = y}
mov bh, bl {; y = y * 256 bx = bx * 256}
xor bl, bl
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1 {; y = y * 64 ax = ax * 64}
add bx, ax {; y = (y*256) + (Y*64) bx = bx + ax (ie y*320)}
pop ax {; get back our x}
add ax, bx {; finalise location}
mov di, ax
mov dl,30 { dl = height of sprite }
xor ch,ch
mov cl,48 { cx = width of sprite }
cld
push ax
mov ax,cx
_DrawLoop:
push di { store y adr. for later }
mov cx,ax { store width }
_LineLoop:
mov bl,byte ptr [si]
or bl,bl
jnz _Store
_NoPaint:
inc si
inc di
loop _LineLoop
jmp _NextLine
_Store:
movsb
loop _LineLoop
_NextLine:
pop di
dec dl
jz _Exit
add di,320 { di = next line of sprite }
jmp _DrawLoop
_Exit:
pop ax
pop es
pop ds
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure SetUpScreen;
{ This procedure sets up the static background to be used in the program }
CONST circ : Array [1..5,1..5] of byte =
((00,00,10,00,00),
(00,00,09,00,00),
(10,09,8,09,10),
(00,00,09,00,00),
(00,00,10,00,00));
VAR x,y:integer;
loop1,loop2,loop3:integer;
BEGIN
For loop1:=1 to 200 do BEGIN
x:=random (315);
y:=random (195);
For loop2:=1 to 5 do
For loop3:=1 to 5 do
if circ [loop2,loop3]<>0 then
putpixel (x+loop2,y+loop3,circ [loop2,loop3],vaddr);
END;
flip (vaddr,vga); { Copy the entire screen at vaddr, our virtual screen }
{ on which we have done all our graphics, onto the }
{ screen you see, VGA }
flip (vaddr,vaddr2);
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure ScreenTrans (x,y:word);
{ This is a small procedure to copy a 30x30 pixel block from coordinates
x,y on the virtual screen to coordinates x,y on the true vga screen }
BEGIN
asm
push ds
push es
mov ax,vaddr
mov es,ax
mov ax,vaddr2
mov ds,ax
mov bx,[X]
mov dx,[Y]
push bx {; and this again for later}
mov bx, dx {; bx = dx}
mov dh, dl {; dx = dx * 256}
xor dl, dl
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1 {; bx = bx * 64}
add dx, bx {; dx = dx + bx (ie y*320)}
pop bx {; get back our x}
add bx, dx {; finalise location}
mov di, bx {; es:di = where to go}
mov si, di
mov al,60
mov bx, 30 { Hight of block to copy }
@@1 :
mov cx, 24 { Width of block to copy divided by 2 }
rep movsw
add di,110h { 320 - 48 = 272 .. or 110 in hex }
add si,110h
dec bx
jnz @@1
pop es
pop ds
end;
{ I wrote this procedure late last night, so it may not be in it's
most optimised state. Sorry :-)}
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure NewToaster;
{ This adds a new toaster to the screen }
VAR loop1:integer;
BEGIN
loop1:=0;
repeat
inc (loop1);
if not (toaster[loop1].active) then BEGIN
toaster[loop1].x:=36;
toaster[loop1].y:=165;
toaster[loop1].active:=true;
toaster[loop1].frame:=1;
toaster[loop1].speed:=5;
loop1:=10;
END;
until loop1=10;
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure Fly;
{ This is the procedure where we move and put the toasters }
VAR loop1,loop2:integer;
ch:char;
BEGIN
For loop1:=1 to 10 do
toaster[loop1].active:=FALSE;
ch:=#0;
NewToaster;
Repeat
if keypressed then BEGIN
ch:=readkey;
if ch='+' then inc(toaster[1].x,5);
if ch='-' then dec(toaster[1].x,5); { If '+' is pressed, add a toaster }
end;
for loop1:=1 to 10 do
if toaster[loop1].active then BEGIN
screentrans (toaster[loop1].x,toaster[loop1].y);
{ Restore the backgrond the toaster was over }
{ Move the toaster }
if (toaster[loop1].x<1) or (toaster[loop1].y>170) then BEGIN
toaster[loop1].active:=FALSE;
NewToaster;
END;
{ When toaster reaches the edge of the screen, render it inactive
and bring a new one into existance. }
END;
for loop1:=1 to 10 do
if toaster[loop1].active then BEGIN
CASE toaster [loop1].frame of
1 : putico (toaster[loop1].x,toaster[loop1].y,frame1,vaddr);
3 : putico (toaster[loop1].x,toaster[loop1].y,frame2,vaddr);
2,4 : putico (toaster[loop1].x,toaster[loop1].y,frame3,vaddr);
END;
toaster[loop1].frame:=toaster[loop1].frame+1;
if toaster [loop1].frame=5 then toaster[loop1].frame:=1;
{ Draw all the toasters on the VGA screen }
END;
waitretrace;
flip (vaddr,vga);
until ch=#27;
END;
procedure playthegame;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
begin
cls(0,vaddr);
SetupScreen; { Draw the background screen to VADDR, then flip it to
the VGA screen }
Fly; { Make the toasters fly around the screen }
{ Free the memory taken up by virtual page }
end;
label picloader,menu;
begin
randomize;
setupvirtual;
fade;
setmcga;
for x:=0 to 40 do begin
pal(100+x,x+20,0,0);
pal(141+x,0,0,x+20);
pal(182+x,0,x+20,0);
end;
fade;
for x:=0 to 40 do begin
line(x+40,45,x+40,45+(2*x),100+x,vga);
line(x+120,45,x+120,45+(2*x),141+x,vga);
line(x+200,45,x+200,45+(2*x),141+x,vga);
line(x+80,125,x+80,125-(2*x),182+x,vga);
line(x+160,125,x+160,125-(2*x),182+x,vga);
end;
for x:=40 downto 0 do begin
line(x+80,45,x+80,125-(2*x),140-x,vga);
line(x+160,45,x+160,125-(2*x),181-x,vga);
line(x+240,45,x+240,125-(2*x),181-x,vga);
line(x+120,125,x+120,45+(2*x),222-x,vga);
line(x+200,125,x+200,45+(2*x),222-x,vga);
end;
unfade;
outtextxy('A VMW SOFTWARE PRODUCTION',60,140,15,15,VGA,false);
y:=0;
repeat until keypressed;
ch:=readkey;
fade;
cls(0,vga);
assign(palf,'pal.tb1');
reset(palf);
for i:=0 to 255 do begin
for j:=1 to 3 do readln(palf,temp[j]);
pal(i,temp[1],temp[2],temp[3]);
end;
close(palf);
fade;
PICLOADER:
grapherror:=loadpicsuperpacked(0,0,vaddr,'tbomb1.tb1');
MENU:
flip(vaddr,vga);
unfade;
repeat until keypressed;
ch:=readkey;
barpos:=0;
outtextxy('F1 HELP',0,190,9,7,vga,false);
coolbox(117,61,199,140);
repeat
if barpos=0 then outtextxy('NEW GAME',123,67,32,0,vga,true)
else outtextxy('NEW GAME',123,67,32,7,vga,true);
if barpos=1 then outtextxy('OPTIONS',123,77,32,0,vga,true)
else outtextxy('OPTIONS',123,77,32,7,vga,true);
if barpos=2 then outtextxy('REGISTER',123,87,32,0,vga,true)
else outtextxy('REGISTER',123,87,32,7,vga,true);
if barpos=3 then outtextxy('LOAD GAME',123,97,32,0,vga,true)
else outtextxy('LOAD GAME',123,97,32,7,vga,true);
if barpos=4 then outtextxy('STORY',123,107,32,0,vga,true)
else outtextxy('STORY',123,107,32,7,vga,true);
if barpos=5 then outtextxy('CREDITS',123,117,32,0,vga,true)
else outtextxy('CREDITS',123,117,32,7,vga,true);
if barpos=6 then outtextxy('QUIT',123,127,32,0,vga,true)
else outtextxy('QUIT',123,127,32,7,vga,true);
ch:=menuread;
if (ord(ch)=222) or (ord(ch)=220) then inc(barpos);
if (ord(ch)=223) or (ord(ch)=221) then dec(barpos);
if ch='N' then barpos:=0;
if ch='O' then barpos:=1;
if ch='R' then barpos:=2;
if ch='L' then barpos:=3;
if ch='S' then barpos:=4;
if ch='C' then barpos:=5;
if ch='Q' then barpos:=6;
if ch=#27 then begin
barpos:=6;
ch:=#13;
end;
if barpos=7 then barpos:=0;
if barpos=-1 then barpos:=6;
until ch=#13;
if barpos=6 then quit;
if barpos=0 then playthegame;
if barpos=0 then goto picloader;
goto menu;
end.

22
legacy_pascal/tbetter.pas Normal file
View File

@ -0,0 +1,22 @@
program maketb1better;
uses vmwgraph;
var palf:text;
x,y,i,j:integer;
temp:array[1..3] of byte;
grapherror:byte;
begin
setmcga;
cls(0,vga);
assign(palf,'pal.tb1');
reset(palf);
for i:=0 to 255 do begin
for j:=1 to 3 do readln(palf,temp[j]);
pal(i,temp[1],temp[2],temp[3]);
end;
close(palf);
grapherror:=loadpicsuperpacked(0,0,vga,'tbomb1.tb1');
readln;
settext;
end.

61
legacy_pascal/tbside.pas Normal file
View File

@ -0,0 +1,61 @@
uses crt,vmwgraph;
var i,j:integer;
palf:text;
temp:array[0..3] of byte;
procedure makehole(y:integer);
begin
for i:=10 to 75 do line(239+i,y,239+i,y+9,0,vga);
line(249,y,314,y,24,vga);
line(249,y+10,313,y+10,18,vga);
line(249,y,249,y+9,24,vga);
line(314,y+1,314,y+10,18,vga);
end;
begin
setmcga;
assign(palf,'pal.tb1');
reset(palf);
for i:=0 to 255 do begin
for j:=1 to 3 do readln(palf,temp[j]);
pal(i,temp[1],temp[2],temp[3]);
end;
close(palf);
for i:=240 to 319 do line(i,0,i,199,19,vga);
line(240,0,240,199,18,vga);
line(240,0,319,0,18,vga);
line(319,0,319,199,24,vga);
line(241,199,319,199,24,vga);
outtextxy('SCORE',241,1,127,0,vga,false);
outtextxy('SCORE',242,2,143,0,vga,false);
makehole(10);
outtextxy('00001233',251,12,12,0,vga,false);
outtextxy('HI-SCORE',241,21,127,0,vga,false);
outtextxy('HI-SCORE',242,22,143,0,vga,false);
makehole(30);
outtextxy('12345672',251,32,12,0,vga,false);
outtextxy('LEVEL',241,41,127,0,vga,false);
outtextxy('LEVEL',242,42,143,0,vga,false);
makehole(50);
outtextxy('12345675',251,52,12,0,vga,false);
outtextxy('SHIELDS',241,61,127,0,vga,false);
outtextxy('SHIELDS',242,62,143,0,vga,false);
makehole(70);
for i:=0 to 63 do line(250+i,71,250+i,79,((i div 4)+32),vga);
outtextxy('WEAPONS',241,81,127,0,vga,false);
outtextxy('WEAPONS',242,82,143,0,vga,false);
makehole(90);
for i:=0 to 65 do line(249+i,111,249+i,189,0,vga);
line(249,111,249,189,24,vga);
line(315,111,315,189,18,vga);
line(249,111,315,111,24,vga);
line(249,189,315,189,18,vga);
outtextxy(' VMW ',251,114,15,0,vga,false);
outtextxy('F1-HELP ',251,124,15,0,vga,false);
outtextxy('ESC-QUIT',251,135,15,0,vga,false);
outtextxy('F2-SAVE ',251,145,15,0,vga,false);
readln;
settext;
end.

704
level1.c
View File

@ -1,704 +0,0 @@
/*
Level 1 Engine Code for Tom Bombem
*/
/* The Includes */
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <ggi/ggi.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 0
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);
}
#endif
/* 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);
}

609
level2.c
View File

@ -1,609 +0,0 @@
/*
* 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 "gtblib.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);
}

680
level_1.c Normal file
View File

@ -0,0 +1,680 @@
/*
Level 1 Engine Code for Tom Bombem
*/
/* The Includes */
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include "SDL.h"
#include "sdl_svmwgraph.h"
#include "tb1_state.h"
#include "levels.h"
#include "tblib.h"
#include "vmw_sprite.h"
#include "tb_keypress.h"
#include "sound.h"
/* Define this to get a frames per second readout */
/* #define DEBUG_ON */
/* The sounds */
#define NUM_SAMPLES 8
#define SND_AHH 0
#define SND_CC 1
#define SND_KAPOW 2
#define SND_SCREAM 3
#define SND_BONK 4
#define SND_CLICK 5
#define SND_OW 6
#define SND_ZRRP 7
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 */
/* 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};
/* The little Sequence Before you hit the Boss */
void beforeboss(struct tb1_state *game_state)
{
clear_keyboard_buffer();
vmwLoadPicPacked(0,0,game_state->virtual_3,0,1,
tb1_data_file("viewscr.tb1",game_state->path_to_data));
vmwClearScreen(game_state->virtual_1,0);
vmwArbitraryCrossBlit(game_state->virtual_3,0,5,58,37,
game_state->virtual_1,10,10);
vmwSmallTextXY("HUMAN!",70,10,2,0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("WHAT ARE YOU DOING?!",70,20,2,
0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("YOUR SPECIES MUST BE TERMINATED!",70,30,2,
0,1,game_state->tb1_font,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
pauseawhile(5);
vmwArbitraryCrossBlit(game_state->virtual_3,0,42,58,37,
game_state->virtual_1,10,50);
vmwSmallTextXY("I'M SORRY.",70,50,9,0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("WE DIDN'T MEAN TO DESTROY YOUR ENVOY.",70,60,9,
0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("WILL YOU FORGIVE US AND TRY PEACE?",70,70,9,
0,1,game_state->tb1_font,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
pauseawhile(5);
vmwArbitraryCrossBlit(game_state->virtual_3,0,5,58,37,
game_state->virtual_1,10,90);
vmwSmallTextXY("NO! YOU MUST BE DESTROYED!",70,90,2,
0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("OUR FUNDING ... OUR ENVOY WAS DAMAGED BY",70,100,
2,0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("YOU! VENGEANCE WILL BE OURS! YOUR PUNY",70,110,
2,0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("PRIMITIVE SPACECRAFT WITH ITS INFERIOR",70,120,
2,0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("WEAPONS WOULD HAVE TO SCORE 9 DIRECT HITS",70,130,
2,0,1,game_state->tb1_font,game_state->virtual_1);
vmwSmallTextXY("TO DESTROY MY SHIP! DIE EARTH SCUM!!!!",70,140,
2,0,1,game_state->tb1_font,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
pauseawhile(5);
setupsidebar(game_state);
vmwFlipVirtual(game_state->virtual_1,game_state->virtual_2);
}
/* The Sequence After You Defeat (hopefully) the Boss */
void afterboss(struct tb1_state *game_state)
{
vmw_font *tb1_font;
tb1_font=game_state->tb1_font;
vmwLoadPicPacked(0,0,game_state->virtual_3,0,1,
tb1_data_file("viewscr.tb1",game_state->path_to_data));
vmwDrawBox(0,0,320,200,0,game_state->virtual_1);
vmwArbitraryCrossBlit(game_state->virtual_3,0,42,58,37,
game_state->virtual_1,10,10);
vmwSmallTextXY("HMM.. THEY DON'T BUILD SUPERIOR",70,10,
9,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("TECHNOLOGY LIKE THEY USED TO.",70,20,
9,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("I GUESS I CAN GO HOME NOW.",70,30,
9,0,1,tb1_font,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
pauseawhile(5);
vmwArbitraryCrossBlit(game_state->virtual_3,0,5,58,37,
game_state->virtual_1,10,50);
vmwSmallTextXY("NOT SO FAST! YOU JUST DESTROYED AN ANTIQUATED",70,50,
2,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("DEFENSE SYSTEM THAT WAS PROGRAMMED BY A 16",70,60,
2,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("YEAR OLD! OUR MAIN DEFENSE PROGRAMMER HAS ",70,70,
2,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("MUCH MORE SKILL NOW! UNLESS YOU DESTROY OUR",70,80,
2,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("ENTIRE XENOCIDE... I MEAN PEACE... ENVOY",70,90,
2,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("WE WILL STILL DESTROY YOUR HOME PLANET.",70,100,
2,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("NICE TRY PUNY EARTHLING!",70,110,2,
0,1,tb1_font,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
pauseawhile(7);
vmwArbitraryCrossBlit(game_state->virtual_3,0,42,58,37,
game_state->virtual_1,10,130);
vmwSmallTextXY("HMM.. I GUESS I BETTER SAVE THE EARTH.",70,130,
9,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("I'D BETTER SAVE MY GAME TOO.",70,140,
9,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("D'OH! I''M OUT OF BIG MISSILES! ",70,150,
9,0,1,tb1_font,game_state->virtual_1);
vmwSmallTextXY("WELL AT LEAST I HAVE SOME SMALLER SPARES.",70,160,
9,0,1,tb1_font,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
pauseawhile(5);
}
/* Defines the behavior of the objects in level 1 */
int level_one_behavior(int reset, struct tb1_state *game_state)
{
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(game_state);
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 Main Level One */
void levelone(struct tb1_state *game_state) {
int ch=0,shield_color=0;
int i,j,grapherror;
char tempst[300];
int itemp,whatdelay=1,levelover=0;
int shipx=36,shipadd=0,shipframe=1;
struct vmwSprite *bigship1,*bigship2,*bigship3;
struct vmwSprite *shapetable[20];
long oldsec,oldusec,time_spent;
int howmuchscroll=0;
int speed_factor=1,game_paused=0;
int beginscore,beginshield;
unsigned char *virtual_1,*virtual_2;
vmw_font *tb1_font;
/* For convenience */
tb1_font=game_state->tb1_font;
virtual_1=game_state->virtual_1;
virtual_2=game_state->virtual_2;
/* Set this up for Save Game */
beginscore=game_state->score;
beginshield=game_state->shields;
/* Load Sprites */
grapherror=vmwLoadPicPacked(0,0,virtual_1,1,1,
tb1_data_file("ships.tb1",game_state->path_to_data));
bigship1=vmwGetSprite(0,0,48,30,virtual_1);
bigship2=vmwGetSprite(0,32,48,30,virtual_1);
bigship3=vmwGetSprite(0,64,48,30,virtual_1);
grapherror=vmwLoadPicPacked(0,0,virtual_1,1,1,
tb1_data_file("tbshapes.tb1",game_state->path_to_data));
for(j=0;j<2;j++)
for(i=0;i<10;i++)
shapetable[(j*10)+i]=vmwGetSprite(1+(i*19),1+(j*19),18,18,
virtual_1);
/* 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;
}
/* Draw the Little Box announcing the Start of the Level */
vmwDrawBox(0,0,320,200,0,virtual_1);
coolbox(70,85,240,120,1,virtual_1);
vmwTextXY(" LEVEL ONE:",84,95,4,7,0,tb1_font,virtual_1);
vmwTextXY("INANIMATE OBJECTS",84,105,4,7,0,tb1_font,virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen, virtual_1);
/* Setup and draw the sidebar */
setupsidebar(game_state);
vmwFlipVirtual(virtual_1,virtual_2);
sprintf(tempst,"%d",game_state->level);
vmwDrawBox(251,52,63,7,0,virtual_2);
vmwTextXY(tempst,307,51,12,0,0,tb1_font,virtual_2);
/* Clear the screen and draw the stars */
vmwDrawBox(0,0,320,400,0,virtual_2);
for(i=0;i<100;i++) {
vmwPutSprite(shapetable[11],rand()%238,rand()%380,0,virtual_2);
vmwPutSprite(shapetable[12],rand()%238,rand()%380,0,virtual_2);
}
change_shields(game_state);
/* Initiate some last variables */
level_one_behavior(1,game_state);
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(virtual_2,0,howmuchscroll,240,
400-howmuchscroll,
virtual_1,0,0);
vmwArbitraryCrossBlit(virtual_2,0,0,240,howmuchscroll-200,
virtual_1,0,400-howmuchscroll);
}
else {
vmwArbitraryCrossBlit(virtual_2,0,howmuchscroll,240,200,
virtual_1,0,0);
}
/* 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 (game_state->sound_enabled)
playGameFX(SND_KAPOW);
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;
game_state->score+=10;
changescore(game_state);
}
}
}
}
/* 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],
enemy[i].x,enemy[i].y,0,
virtual_1);
else if (enemy[i].dead) {
enemy[i].out=0;
enemy[i].exploding=0;
game_paused=level_one_behavior(0,game_state);
}
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],
bullet[i].x,bullet[i].y,0,
virtual_1);
}
}
/* MOVE ENEMIES */
for(i=0;i<5;i++) {
if ((enemy[i].out) && (!enemy[i].dead)) {
vmwPutSprite(shapetable[enemy[i].kind-1],
enemy[i].x,enemy[i].y,
0,virtual_1);
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,game_state);
}
if (enemy[i].y>140) {
if (collision(shipx,165,24,15,enemy[i].x,enemy[i].y,9,9)) {
if (game_state->sound_enabled)
playGameFX(SND_BONK);
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;
game_state->shields--;
if (game_state->shields<0) levelover=1;
if (game_state->shields>0) change_shields(game_state);
}
}
}
}
/* See if beat the level. Yes, bad variable name. Oh well */
if (game_paused==9) {
afterboss(game_state);
game_state->level=2;
levelover=1;
}
/* **READ KEYBOARD** */
if ( (ch=vmwGetInput())!=0) {
switch(ch){
case TB_ESCAPE: 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,virtual_1);
vmwTextXY("GAME PAUSED",79,95,4,7,
0,tb1_font,virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,virtual_1);
while (vmwGetInput()==0) {
usleep(30000);
}
break;
case '-': whatdelay--; if (whatdelay<1) whatdelay=1; break;
case 'S':
case 's': if (game_state->sound_enabled)
game_state->sound_enabled=!(game_state->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 (game_state->sound_enabled)
playGameFX(SND_CC);
bullet[j].out=1;
bullet[j].x=shipx+15;
bullet[j].y=165;
vmwPutSprite(shapetable[0],
bullet[j].x,
bullet[j].y,0,virtual_1);
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,shipx,165,shield_color,virtual_1);
break;
case 3: vmwPutSprite(bigship2,shipx,165,shield_color,virtual_1);
break;
case 2:
case 4: vmwPutSprite(bigship3,shipx,165,shield_color,virtual_1);
break;
}
shipframe++;
if (shipframe==5) shipframe=1;
/* Flip Pages */
vmwBlitMemToSDL(game_state->sdl_screen,virtual_1);
/* 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;
}
}
}
/* The little opener before Level 1 */
void littleopener(struct tb1_state *game_state)
{
struct vmwSprite *ship1,*ship2;
int i;
vmwClearScreen(game_state->virtual_2,0);
vmwLoadPicPacked(0,0,game_state->virtual_2,1,1,
tb1_data_file("moon2.tb1",game_state->path_to_data));
vmwLoadPicPacked(0,0,game_state->virtual_2,1,0,
tb1_data_file("moon2.tb1",game_state->path_to_data));
ship1=vmwGetSprite(9,178,15,18,game_state->virtual_2);
ship2=vmwGetSprite(30,178,15,18,game_state->virtual_2);
vmwDrawBox(0,178,319,21,0,game_state->virtual_2);
for(i=100;i>0;i--) {
vmwFlipVirtual(game_state->virtual_1,game_state->virtual_2);
vmwPutSprite(ship2,i*2,100,0,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
usleep(30000);
if (vmwGetInput()) break;
}
vmwFlipVirtual(game_state->virtual_1,game_state->virtual_2);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
vmwTextXY(">KCHK< TOM! WHERE ARE YOU GOING?",5,180,15,0,1,
game_state->tb1_font,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
pauseawhile(3);
vmwDrawBox(0,178,319,21,0,game_state->virtual_1);
vmwTextXY("Ooops. ",5,180,24,0,1,game_state->tb1_font,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
pauseawhile(3);
for(i=0;i<151;i++) {
vmwFlipVirtual(game_state->virtual_1,game_state->virtual_2);
vmwPutSprite(ship1,i*2,100,0,game_state->virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
usleep(15000);
if (vmwGetInput()) break;
}
vmwFlipVirtual(game_state->virtual_1,game_state->virtual_2);
vmwBlitMemToSDL(game_state->sdl_screen,game_state->virtual_1);
vmwDrawBox(0,0,320,200,0,game_state->virtual_1);
vmwLoadPicPacked(0,0,game_state->virtual_1,1,0,
tb1_data_file("tbgorg.tb1",game_state->path_to_data));
}

View File

@ -1,4 +1,4 @@
void levelone(int *level, int *shields,int *score);
void levelone(struct tb1_state *game_state);
void littleopener();
void leveltwoengine(int *level, int *shields, int *score);
void littleopener2();

4142
procs.c

File diff suppressed because it is too large Load Diff

662
sdl_svmwgraph.c Normal file
View File

@ -0,0 +1,662 @@
/* I will finish this game!!! */
/* This is the SDL implementation of the Super VMW graphics library */
/* Which was originally a lot of Turbo-Pascal w inline assembly */
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include "SDL.h"
#include "tb_keypress.h"
/* hard coded for now */
#define X_WIDTH 320
#define Y_HEIGHT 200
#define BPP 2 /* Bytes Per Pixel, ie 16bpp */
//#define DEBUG 1 /* Until we get to Beta */
unsigned int global_palette[256];
int vmwPack3Bytes(int r, int g, int b) {
return ( ( ( (r>>3)&0x1f) <<11)+
( ( (g>>2)&0x3f) <<5)+
( ( (b>>3)&0x1f) ) );
}
void vmwLoadCustomPalette(int pal[256]) {
int i;
for (i=0;i<256;i++) {
global_palette[i]=pal[i];
}
}
void vmwBlitMemToSDL(SDL_Surface *target, unsigned char *source) {
int x,y,Bpp;
unsigned char *s_pointer,*t_pointer;
if ( SDL_MUSTLOCK(target) ) {
if ( SDL_LockSurface(target) < 0 )
return;
}
Bpp= target->format->BytesPerPixel;
s_pointer=source;
t_pointer=((Uint8 *)target->pixels);
for (x=0;x<320;x++)
for (y=0;y<200;y++) {
*((Uint16 *)(t_pointer))=*((Uint16 *)(s_pointer));
s_pointer+=2; t_pointer+=2;
}
/* Update the display */
if ( SDL_MUSTLOCK(target) ) {
SDL_UnlockSurface(target);
}
/* Write this out to the screen */
SDL_UpdateRect(target, 0, 0, 320, 200);
}
/*---------------------------------------------------------------*\
| vmwPutPixel |
\*---------------------------------------------------------------*/
void vmwPutPixel(int x,int y,int color, unsigned char *target) {
Uint8 *bits;
#ifdef DEBUG
if ( (y> (Y_HEIGHT-1) ) || (x> (X_WIDTH-1) ) ) {
printf("Out of bounds with PutPixel %i,%i\n",x,y);
return;
}
#endif
/* Really Ugly SDL Framebuffer stuff */
bits = ((Uint8 *)target)+(y*320+x)*2;
*((Uint16 *)(bits)) = global_palette[color];
}
unsigned char vmwGetPixel(int x,int y, unsigned char *source) {
/* This is really hacked together, based on the old */
/* 256 color palette model used by paintPro graphics */
/* and the old pascal version of this game. I may try */
/* to improve this in the future */
unsigned char i;
for (i=0;i<255;i++) {
if (*(Uint16* )(((Uint8 *)source)+(y*320+x)*2)==global_palette[i])
return i;
}
printf("Unknown color! This shouldn't happen!\n");
return 0;
}
void vmwClearScreen(unsigned char *target, int color) {
int x,y;
if (color==0) memset(target,0,320*200*2);
else { /* Super in-efficient */
for (x=0;x<320;x++)
for (y=0;y<200;y++)
vmwPutPixel(x,y,color,target);
}
}
/*---------------------------------------------------------------*\
| vmwDrawHLine |
| This is really begging to be optimized. I am sure some |
| targets can do this in hardware |
\*---------------------------------------------------------------*/
void vmwDrawHLine(int xstart,int ystart,int how_long,int color,
unsigned char *target) {
int i;
for(i=0;i<how_long;i++) {
vmwPutPixel(xstart+i,ystart,color,target);
}
}
void vmwDrawVLine(int xstart,int ystart,int how_long,int color, unsigned char *target) {
int i;
for(i=0;i<how_long;i++) {
vmwPutPixel(xstart,ystart+i,color,target);
}
}
/*---------------------------------------------------------------*\
| vmwLoadPicPacked |
| There is so much history in this function, I won't get into |
| it here. |
\*---------------------------------------------------------------*/
int vmwLoadPicPacked(int x1,int y1,unsigned char *target,
int LoadPal,int LoadPic,char *FileName)
/* Retro comments */
/*{ 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;
int temp_palette[256];
/* Open the file */
fff=fopen(FileName,"rb"); /* Windows chokes if no "b" */
if (fff==NULL){
printf("PPRO error... File \"%s\" not found.\n",FileName);
return 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 (strncmp(header,"PAINTPROV",9)) {
printf("PPRO error... %s is NOT a paintpro file!\n",FileName);
return 2;
}
/* 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 (strncmp(header,"6.0",3)) {
printf("PPRO error... Version %s unsupported, must be >6\n",header);
return 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");
return 4;
}
/* Split 48 bits into two 32 bit values */
xsize=(temp2>>4)+(temp1<<4);
ysize=((temp2-((temp2>>4)<<4))<<16)+temp3;
temp1=buffer[buffpointer];
temp2=buffer[buffpointer+1];
temp3=buffer[buffpointer+2];
buffpointer+=3;
if (buffpointer>=errorlev) {
printf("PPRO error... Early end of file.\n");
return 4;
}
numcolors=(temp2>>4)+(temp1<<4);
picwidth=xsize+1;
picheight=ysize+1;
/*Load Palette*/
if (numcolors!=256) printf("%d colors is not supported yet.\n",numcolors);
/* Fun and games to convert the 24 bit color in paintpro to */
/* 565 packed 16bit RGB */
for(i=0;i<256;i++) {
temp_palette[i]=vmwPack3Bytes(buffer[buffpointer],
buffer[buffpointer+1],
buffer[buffpointer+2]);
buffpointer+=3;
if (buffpointer>=errorlev) {
if (errorlev==300) {
errorlev=fread(buffer,1,300,fff);
buffpointer=0;
}
else {
lastread=1;
}
}
}
if (LoadPal) {
for (i=0;i<256;i++) global_palette[i]=temp_palette[i];
}
x=x1;
y=y1;
while ((!lastread)&&(LoadPic)&&(y<y1+ysize)) {
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 greater than 2047, we have two single pixels */
/* of color int1-2048 and int2-2048 */
if (int1>2047) {
vmwPutPixel(x,y,int1-2048,target);
x++;
if (x>xsize+x1) {
x=x1; y++;
// if (y>ysize-1) {
// printf("Blargh 1\n"); y--;
// }
}
vmwPutPixel(x,y,int2-2048,target);
x++;
if (x>xsize+x1){
x=x1;y++;
// if (y>ysize) {
// printf("Blargh 2\n");
// y--;
// }
}
}
else { /* Standard paintpro format */
col=int1;
numacross=int2;
while ((x+numacross)>(xsize+x1)) {
vmwDrawHLine(x,y,((xsize+x1)-x),col,target);
numacross=numacross-((xsize+1)-x);
x=x1;
y++;
if (y>y1+ysize-1) {
printf("Blrgh 3\n");
}
}
if ((numacross!=0) && (y<y1+ysize)) {
if (numacross+x>xsize+x-1) numacross--; /* Stupid x overflow */
vmwDrawHLine(x,y,numacross,col,target);
}
x=x+numacross;
}
}
if (fff!=NULL) fclose(fff);
return 0;
}
void clear_keyboard_buffer() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
}
}
void pauseawhile(int howlong) {
struct timeval bob;
struct timezone mree;
long begin_s,begin_u;
SDL_Event event;
clear_keyboard_buffer();
gettimeofday(&bob,&mree);
begin_s=bob.tv_sec; begin_u=bob.tv_usec;
while ((bob.tv_sec-begin_s)<howlong) {
if (SDL_PollEvent(&event)) {
if (event.type==SDL_KEYDOWN) return;
}
usleep(30);
gettimeofday(&bob,&mree);
}
}
typedef struct {
char *font_data;
int width;
int height;
int numchars;
} vmw_font;
void vmwFlipVirtual(unsigned char *destination,
unsigned char *source) {
memcpy(destination,source,320*200*2);
}
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(unsigned char *src,int x1,int y1,int w,int h,
unsigned char *dest,int x2,int y2)
{
int y;
unsigned char *source,*destination;
source=src+(320*2*y1);
destination=dest+(320*2*y2);
for(y=0;y<h;y++) {
memcpy ((destination+x2*2),(source+x1*2),(w*2));
source+=320*2;
destination+=320*2;
}
return 0;
}
int vmwPutPartialSprite(int *src,int w,int h,int stride_factor,
char *dest,int x,int y,int dest_stride,
int x_start,int x_stop,int y_start,int y_stop)
{ /* x_start/stop not implemented yet */
int xx,yy;
/*
dest+=(dest_stride*y);
for(yy=0;yy<h;yy++){
for(xx=0;xx<w;xx++)
if ((*(src+xx)) && ((yy>=y_start) && (yy<=y_stop)) )
memcpy(dest+(stride_factor*(xx+x)),(src+xx),stride_factor);
// **(dest+xx+x)=15;
src+=w;
dest+=dest_stride;
}
*/
return 0;
}
vmw_font *vmwLoadFont(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,unsigned char *target)
{
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) )
vmwPutPixel((x+(i*8)+xx),y,col,target);
else
vmwPutPixel((x+(i*8)+xx),y,background,target);
}
}
void vmwTextLine(char *st,int x,int y,int col,int background,int line,
vmw_font *font,unsigned char *target)
{
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) ) {
vmwPutPixel(x+(i*8)+xx,y,col,target);
}
}
void vmwTextXY(char *st,int x,int y,int col,int background,int overwrite,
vmw_font *font,unsigned char *target)
{
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) )
vmwPutPixel((x+(i*8)+xx),y+lineon,col,target);
else
if(overwrite) vmwPutPixel((x+(i*8)+xx),y+lineon,background,target);
}
}
/*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,unsigned char *target)
{
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) )
vmwPutPixel((x+(i*5)+xx),y+lineon,col,target);
else
if(overwrite) vmwPutPixel((x+(i*5)+xx),y+lineon,background,target);
}
}
}
/*
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;
*/
void vmwFadeToBlack(void) {
}
void vmwUnFade(void) {
}
void vmwDrawBox(int x1,int y1,int xsize,int ysize,int col, unsigned char *where) {
int i;
for(i=0;i<ysize;i++) {
vmwDrawHLine(x1,y1+i,xsize,col,where);
}
}
int vmwGetInput() {
SDL_Event event;
int keypressed;
while ( SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
keypressed=event.key.keysym.sym;
switch (keypressed) {
case SDLK_BACKSPACE: return TB_BACKSPACE;
case SDLK_ESCAPE : return TB_ESCAPE;
case SDLK_RETURN : return TB_ENTER;
case SDLK_UP : return TB_UP;
case SDLK_DOWN : return TB_DOWN;
case SDLK_RIGHT : return TB_RIGHT;
case SDLK_LEFT : return TB_LEFT;
case SDLK_F1 : return TB_F1;
case SDLK_F2 : return TB_F2;
case SDLK_PAGEUP : return TB_PGUP;
case SDLK_PAGEDOWN : return TB_PGDN;
default: return keypressed;
}
default: break;
}
}
return 0;
}

68
sdl_svmwgraph.h Normal file
View File

@ -0,0 +1,68 @@
/* These are more or less the functions you need to implement one of my */
/* games. This has been done before in SDL, GGI, and Turbo Pascal */
/* so it should be easy to do for other targets... */
typedef struct {
char *font_data;
int width;
int height;
int numchars;
} vmw_font;
int vmwPack3Bytes(int r, int g, int b);
int vmwLoadCustomPalette(int pal[256]);
void vmwBlitMemToSDL(SDL_Surface *target, unsigned char *source);
void vmwClearScreen(unsigned char *target, int color);
void vmwPutPixel(int x,int y,int color, unsigned char *target);
unsigned char vmwGetPixel(int x,int y, unsigned char *source);
void vmwDrawHLine(int xstart,int ystart,int how_long,int color,
unsigned char *target);
void vmwDrawVLine(int xstart,int ystart,int how_long,int color, unsigned char *target);
int vmwLoadPicPacked(int x1,int y1,unsigned char *target,
int LoadPal,int LoadPic,char *FileName);
void vmwFlipVirtual(unsigned char *destination, unsigned char *source);
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(unsigned char *src,int x1,int y1,int w,int h,
unsigned char *dest,int x2,int y2);
int vmwPutPartialSprite(int *src,int w,int h,int stride_factor,
char *dest,int x,int y,int dest_stride,
int x_start,int x_stop,int y_start,int y_stop);
vmw_font *vmwLoadFont(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,unsigned char *target);
void vmwTextLine(char *st,int x,int y,int col,int background,int line,
vmw_font *font,unsigned char *target);
void vmwTextXY(char *st,int x,int y,int col,int background,int overwrite,
vmw_font *font,unsigned char *target);
void vmwSmallTextXY(char *st,int x,int y,int col,int background,int overwrite,
vmw_font *font,unsigned char *target);
void line(int a,int b,int c,int d,int col,char *where);
void vmwFadeToBlack(void);
void vmwUnFade(void);
void vmwDrawBox(int x1,int y1,int x2,int y2,int col,unsigned char *where);
int vmwGetInput();
void clear_keyboard_buffer();
void pauseawhile(int howlong);

102
sound.c Normal file
View File

@ -0,0 +1,102 @@
/* "borrowed" from gltron */
#include "sound.h"
#include "SDL.h"
#include "sdl_svmwgraph.h"
#include "tb1_state.h"
#include "tblib.h"
#include <stdlib.h>
/* linux only, at the moment */
static Mix_Music *music;
#define NUM_GAME_FX 8
static Mix_Chunk *game_fx[NUM_GAME_FX];
static char *game_fx_names[] = {
"tb_ahh.wav",
"tb_cc.wav",
"tb_kapow.wav",
"tb_scream.wav",
"tb_bonk.wav",
"tb_click.wav",
"tb_ow.wav",
"tb_zrrp.wav"
};
void loadFX(char *path_to_data) {
int i;
char *path;
for(i = 0; i < NUM_GAME_FX; i++) {
path=tb1_data_file(game_fx_names[i],path_to_data);
if(path) {
game_fx[i] = Mix_LoadWAV(path);
free(path);
}
}
}
int initSound(char *path_to_data) {
/* open the audio device */
if(Mix_OpenAudio(22050, AUDIO_U16, 1, 1024) < 0) {
fprintf(stderr, "can't open audio: %s\n", SDL_GetError());
exit(2);
}
loadFX(path_to_data);
return 0;
}
void shutdownSound() {
Mix_CloseAudio();
}
int loadSound(char *name) {
music = Mix_LoadMUS(name);
return 0;
}
int playSound() {
if( ! Mix_PlayingMusic() )
Mix_PlayMusic(music, -1);
/* todo: remove the following once the bug in SDL_mixer is fixed */
/* we don't want too many references to game objects here */
// setMusicVolume(game->settings->musicVolume);
return 0;
}
int stopSound() {
if( Mix_PlayingMusic() )
Mix_HaltMusic();
return 0;
}
void soundIdle() {
/* sdl_mixer uses pthreads, so no work here */
return;
}
void playGameFX(int fx) {
Mix_PlayChannel(-1, game_fx[fx], 0);
// fprintf(stderr, "fx on channel %d\n", Mix_PlayChannel(-1, game_fx[fx], 0));
}
void setMusicVolume(float volume) {
if(volume > 1) volume = 1;
if(volume < 0) volume = 0;
Mix_VolumeMusic((int)(volume * 128));
}
void setFxVolume(float volume) {
if(volume > 1) volume = 1;
if(volume < 0) volume = 0;
Mix_Volume(-1, (int)(volume * 128));
}

28
sound.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef SOUND_H
#define SOUND_H
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
int initSound();
void shutdownSound();
int loadSound(char *name);
int playSound();
int stopSound();
void deleteSound();
void soundIdle();
void setMusicVolume(float volume);
void setFxVolume(float volume);
void playGameFX(int fx);
void playMenuFX(int fx);
void playEngine();
void stopEngine();
enum game_fx { fx_engine=0, fx_start, fx_crash, fx_win, fx_lose };
enum menu_fx { fx_action=0, fx_highlight };
#endif

713
soundIt.c
View File

@ -1,713 +0,0 @@
/* 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;
}

View File

@ -1,91 +0,0 @@
/* 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

View File

@ -1,799 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <ggi/ggi.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.
*/

View File

@ -1,46 +0,0 @@
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 vmwPutPartialSprite(int *src,int w,int h,int stride_factor,
char *dest,int x,int y,int dest_stride,
int x_start,int x_stop,int y_start,int y_stop);
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);

View File

@ -1,16 +0,0 @@
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

451
tb1.c
View File

@ -1,14 +1,16 @@
/****************************************************************\
\* TOM BOMBEM AND THE INVASION OF THE INANIMATE_OBJECTS */
/* version 2.9.0 February 28, 1998 *\
/* version 2.9.1 5 August 2000 *\
\* 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 *\
/* using the PCGPE code as an example in 1994 *\
\* Ported to Linux, C, and ggi late 1997-early 1998 */
/* Port continued to SDL in June of 2000 *\
\* This source is released under the GPL */
/****************************************************************/
#define TB1_VERSION "2.9.0"
#define TB1_VERSION "2.9.1"
#include <ctype.h>
#include <stdio.h>
@ -18,141 +20,37 @@
#include <unistd.h>
#include <sys/time.h>
#include <ggi/ggi.h>
#include "svmwgrap.h"
#include "SDL.h"
#include "sdl_svmwgraph.h"
#include "tb1_state.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 *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;
#include "tb_keypress.h"
#include "sound.h"
/* Setup the Graphics */
int setup_graphics(int force_8bpp)
int setup_graphics(struct tb1_state *state)
{
int err;
ggi_mode mode;
int vx,vy,sx,sy;
if (ggiInit()) {
fprintf(stderr,"Cannot initialize libGGI!\n");
return 1;
/* Initialize the SDL library */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr,
"Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}
/* Clean up on exit */
atexit(SDL_Quit);
/* Initialize the display in a 640x480 8-bit palettized mode */
state->sdl_screen = SDL_SetVideoMode(320, 200, 16, SDL_SWSURFACE);
if ( state->sdl_screen == NULL ) {
fprintf(stderr, "Couldn't set 320x200x8 video mode: %s\n",
SDL_GetError());
exit(1);
}
vis=ggiOpen(NULL);
if(!vis) {
fprintf(stderr,"Cannot open default visual!\n");
ggiExit();
return 1;
}
/* Do I really want to do this? */
ggiSetFlags(vis, GGIFLAG_ASYNC);
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;
}
mode.frames=3;
if (ggiGetMode(vis,&mode)) {
fprintf(stderr,"Cannot set mode!\n");
ggiClose(vis);
ggiExit();
return 1;
}
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);
/*dbuf_vis=ggiDBGetBuffer(vis,0);*/
/*err = ggiDBGetBuffer (vis, &dbuf_vis);*/
/*if (!(dbuf_vis=ggiDBGetBuffer(vis,0)) ) {
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);
printf(" + SDL Graphics Initialization successful...\n");
printf(" + Running TB1 in %dbpp Mode...\n",16);
return 0;
}
@ -174,14 +72,39 @@ int command_line_help(int show_version,char *runas)
int main(int argc,char **argv)
{
int i,grapherror,reloadpic=0,force_8bpp=0;
int ch,ch2,x,barpos,time_sec;
char *tempst[300];
int i,grapherror,reloadpic=0;
int custom_palette[256];
int ch,x,barpos,time_sec;
FILE *fff;
unsigned char *virtual_1,*virtual_2;
struct tb1_state *game_state;
vmw_font *tb1_font;
struct timeval time_info;
struct timezone dontcare;
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");
/* Setup the game state */
if ( (game_state=calloc(1,sizeof(struct tb1_state)))==NULL) {
printf("You are seriously low on RAM!\n");
return 3;
}
/* Some sane defaults */
game_state->level=0;
game_state->shields=0;
game_state->score=0;
game_state->virtual_1=NULL;
game_state->virtual_2=NULL;
game_state->virtual_3=NULL;
game_state->sdl_screen=NULL;
game_state->sound_enabled=1;
game_state->tb1_font=NULL;
/* Parse Command Line Arguments */
i=1;
while(i<argc) {
@ -191,15 +114,14 @@ int main(int argc,char **argv)
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;
game_state->sound_enabled=0;
// sound_possible=0;
printf(" + Sound totally disabled\n");
break;
case 'r':
read_only_mode=1;
// read_only_mode=1;
printf(" + Read Only mode enabled\n");
break;
default : command_line_help(0,argv[0]);
@ -218,18 +140,18 @@ int main(int argc,char **argv)
/* Find the Data */
/* FIXME : User Defined Path Info*/
if ( (fff=fopen("./data/data_files_here","r"))!=NULL) {
strncpy(path_to_data,"./data/",20);
strncpy(game_state->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);
strncpy(game_state->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"));
sprintf(game_state->path_to_data,"%s/.tb1/data/",getenv("HOME"));
}
else {
printf("ERROR! Could not find tb1 data!\n");
@ -238,7 +160,7 @@ int main(int argc,char **argv)
return 9;
}
}
printf(" + Found tb1 data in %s\n",path_to_data);
printf(" + Found tb1 data in %s\n",game_state->path_to_data);
/* FIXME : find where writing info out to */
@ -252,152 +174,146 @@ int main(int argc,char **argv)
/* Randomize random number generator */
srandom(time(NULL));
printf(" + Seeding random number generator...\n");
/* Load sounds */
initSound(game_state->path_to_data);
loadSound(tb1_data_file("vmwfan.mod",game_state->path_to_data));
printf(" + Loaded sounds...\n");
/* Load the tom bombem font */
tb1_font=LoadVMWFont(tb1_data_file("tbfont.tb1",(char *)tempst),8,16,256);
game_state->tb1_font=vmwLoadFont(tb1_data_file("tbfont.tb1",game_state->path_to_data),8,16,256);
printf(" + Loaded tb1 font...\n");
/* Setup Graphics */
if (setup_graphics(force_8bpp)==2) {
if (setup_graphics(game_state)) {
fprintf(stderr,"ERROR: Couldn't get display set up properly.\n");
return 2;
}
if ((game_state->virtual_1=calloc(320*200,2))==NULL) {
fprintf(stderr,"ERROR: Couldn't get RAM for virtual screen 1!\n");
return 3;
}
if ((game_state->virtual_2=calloc(320*400,2))==NULL) {
fprintf(stderr,"ERROR: Couldn't get RAM for virtual screen 2!\n");
return 3;
}
if ((game_state->virtual_3=calloc(320*200,2))==NULL) {
fprintf(stderr,"ERROR: Couldn't get RAM for virtual screen 3!\n");
return 3;
}
printf(" + Allocated virtual screens...\n");
/* To ease typing burden */
virtual_1=game_state->virtual_1;
virtual_2=game_state->virtual_2;
tb1_font=game_state->tb1_font;
/* 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;
}
for(x=0;x<=40;x++) {
custom_palette[100+x]=vmwPack3Bytes( ((x+20)*4),0,0);
custom_palette[141+x]=vmwPack3Bytes(0,0, ( (x+20)*4 ));
custom_palette[182+x]=vmwPack3Bytes(0, ( (x+20)*4),0);
}
/* 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;
custom_palette[15]=vmwPack3Bytes(0xff,0xff,0xff);
/* Finalize Pallette Stuff */
/*if (color_depth!=8) {
tb1_pal[15]=ggiMapColor(vis,&eight_bit_pal[15]);
}
else ggiSetPaletteVec(vis,0,256,eight_bit_pal);
*/
vmwLoadCustomPalette(custom_palette);
SDL_UpdateRect(game_state->sdl_screen, 0, 0, 0, 0);
/* 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);
vmwDrawVLine(x+40,45,2*x,100+x,virtual_1);
vmwDrawVLine(x+120,45,2*x,141+x,virtual_1);
vmwDrawVLine(x+200,45,2*x,141+x,virtual_1);
vmwDrawVLine(x+80,125-(2*x),2*x,182+x,virtual_1);
vmwDrawVLine(x+160,125-(2*x),2*x,182+x,virtual_1);
}
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));
vmwDrawVLine(x+80,45,80-(2*x),140-x,virtual_1);
vmwDrawVLine(x+160,45,80-(2*x),181-x,virtual_1);
vmwDrawVLine(x+240,45,80-(2*x),181-x,virtual_1);
vmwDrawVLine(x+120,45+(2*x),80-(2*x),222-x,virtual_1);
vmwDrawVLine(x+200,45+(2*x),80-(2*x),222-x,virtual_1);
}
ggiSetGCForeground(vis,tb1_pal[15]);
VMWtextxy("A VMW SOFTWARE PRODUCTION",60,140,
tb1_pal[15],tb1_pal[15],0,tb1_font,vis);
ggiFlush(vis);
vmwTextXY("A VMW SOFTWARE PRODUCTION",60,140,
15,15,0,game_state->tb1_font,virtual_1);
playSound();
vmwBlitMemToSDL(game_state->sdl_screen,virtual_1);
pauseawhile(5);
stopSound();
loadSound(tb1_data_file("weave1.mod",game_state->path_to_data));
/* Clear the Screen and get ready for the Menu */
ggiSetGCForeground(vis,tb1_pal[0]);
ggiFillscreen(vis);
vmwClearScreen(virtual_1,0);
/* 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);
grapherror=vmwLoadPicPacked(0,0,virtual_1,1,1,
tb1_data_file("tbomb1.tb1",game_state->path_to_data));
grapherror=vmwLoadPicPacked(0,0,virtual_2,1,1,
tb1_data_file("tbomb1.tb1",game_state->path_to_data));
vmwBlitMemToSDL(game_state->sdl_screen,virtual_1);
/* 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);
grapherror=vmwLoadPicPacked(0,0,virtual_2,1,1,
tb1_data_file("tbomb1.tb1",game_state->path_to_data));
reloadpic=0;
}
/*vmwCrossBlit(plb_vis->write,plb_vaddr2->read,plb_vis->stride,200);*/
ggiFlush(vis);
vmwFlipVirtual(virtual_1,virtual_2);
playSound();
while (!vmwGetInput()) usleep(300);
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);
vmwTextXY("F1 HELP",0,190,9,7,0,tb1_font,virtual_1);
coolbox(117,61,199,140,1,virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,virtual_1);
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 (barpos==0) vmwTextXY("NEW GAME",123,67,32,0,1,tb1_font,virtual_1);
else vmwTextXY("NEW GAME",123,67,32,7,1,tb1_font,virtual_1);
if (barpos==1) vmwTextXY("OPTIONS",123,77,32,0,1,tb1_font,virtual_1);
else vmwTextXY("OPTIONS",123,77,32,7,1,tb1_font,virtual_1);
if (barpos==2) vmwTextXY("ABOUT",123,87,32,0,1,tb1_font,virtual_1);
else vmwTextXY("ABOUT",123,87,32,7,1,tb1_font,virtual_1);
if (barpos==3) vmwTextXY("LOAD GAME",123,97,32,0,1,tb1_font,virtual_1);
else vmwTextXY("LOAD GAME",123,97,32,7,1,tb1_font,virtual_1);
if (barpos==4) vmwTextXY("STORY",123,107,32,0,1,tb1_font,virtual_1);
else vmwTextXY("STORY",123,107,32,7,1,tb1_font,virtual_1);
if (barpos==5) vmwTextXY("CREDITS",123,117,32,0,1,tb1_font,virtual_1);
else vmwTextXY("CREDITS",123,117,32,7,1,tb1_font,virtual_1);
if (barpos==6) vmwTextXY("QUIT",123,127,32,0,1,tb1_font,virtual_1);
else vmwTextXY("QUIT",123,127,32,7,1,tb1_font,virtual_1);
vmwBlitMemToSDL(game_state->sdl_screen,virtual_1);
/* If at title screen too long, run credits */
gettimeofday(&time_info,&dontcare);
time_sec=time_info.tv_sec;
while( ((ch=get_input())==0)) {
while( ((ch=vmwGetInput())==0)) {
usleep(10);
gettimeofday(&time_info,&dontcare);
if (time_info.tv_sec-time_sec>40) {
credits();
stopSound();
credits(game_state);
ch=TB_ENTER;
barpos=9;
reloadpic=1;
@ -407,34 +323,35 @@ int main(int argc,char **argv)
}
/* 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 */
if (ch=='n') barpos=0; /*N*/
if (ch=='o') barpos=1; /*O*/
if (ch=='a') barpos=2; /*A*/
if (ch=='l') barpos=3; /*L*/
if (ch=='s') barpos=4; /*S*/
if (ch=='c') barpos=5; /*C*/
if (ch=='q') barpos=6; /*Q*/
if (ch==TB_ESCAPE){ /* escape */
barpos=6;
ch=TB_ENTER;
}
if(barpos==7) barpos=0;
if(barpos<0) barpos=6;
}
stopSound();
/* 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;
case 0: playthegame(game_state); reloadpic=1; break;
case 1: options(game_state); reloadpic=1; break;
case 2: about(game_state); reloadpic=1; break;
case 3: loadgame(); reloadpic=1; break;
case 4: story(game_state); reloadpic=1; break;
case 5: credits(game_state); reloadpic=1; break;
case 6: barpos=quit(game_state); break;
case 10: help(game_state); break;
}
}
}

13
tb1_state.h Normal file
View File

@ -0,0 +1,13 @@
struct tb1_state {
int level;
int shields;
int shield_color;
int score;
unsigned char *virtual_1;
unsigned char *virtual_2;
unsigned char *virtual_3;
SDL_Surface *sdl_screen;
int sound_enabled;
vmw_font *tb1_font;
char path_to_data[BUFSIZ];
};

11
tb_keypress.h Normal file
View File

@ -0,0 +1,11 @@
#define TB_BACKSPACE 1024
#define TB_ESCAPE 27
#define TB_ENTER 1025
#define TB_UP 1026
#define TB_DOWN 1027
#define TB_RIGHT 1028
#define TB_LEFT 1029
#define TB_F1 1030
#define TB_F2 1031
#define TB_PGUP 1032
#define TB_PGDN 1033

1257
tblib.c

File diff suppressed because it is too large Load Diff

20
tblib.h
View File

@ -1,16 +1,22 @@
int change_shields(int *shields);
int changescore(int score,int *shields);
int change_shields(struct tb1_state *game_state);
int changescore(struct tb1_state *game_state);
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);
char *tb1_data_file(char *name,char *path);
int get_input();
void coolbox(int x1,int y1,int x2,int y2,int fill,unsigned char *target);
int close_graphics();
int quit(struct tb1_state *game_state);
void ReadConfigFile(int CDROMmode);
int showhiscore(int showchart);
int showhiscore(struct tb1_state *game_state,int showchart);
void write_hs_list(int score,char *hiname);
void help();
void setupsidebar(int score,int hiscore,int shields);
void setupsidebar(struct tb1_state *game_state);
void shadowrite(char *st,int x,int y,int forecol,int backcol,vmw_font *tb1_font,unsigned char *target);
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);
void about(struct tb1_state *game_state);
void playthegame(struct tb1_state *game_state);

BIN
tbomb1.tb1 Normal file

Binary file not shown.

52
vmw_sprite.c Normal file
View File

@ -0,0 +1,52 @@
#include "SDL.h"
#include "sdl_svmwgraph.h"
#include "vmw_sprite.h"
#include <stdlib.h>
extern unsigned int global_palette[256];
struct vmwSprite *vmwGetSprite(int x, int y,
int xsize, int ysize,unsigned char *screen) {
struct vmwSprite *temp_sprite;
int xtemp,ytemp;
temp_sprite=calloc(1,sizeof(struct vmwSprite));
temp_sprite->spritedata=calloc(1,xsize*ysize);
temp_sprite->xsize=xsize;
temp_sprite->ysize=ysize;
/* The following is very slow and can be easily optimized */
for(ytemp=0;ytemp<ysize;ytemp++)
for(xtemp=0;xtemp<xsize;xtemp++)
*((temp_sprite->spritedata)+ytemp*xsize+xtemp)=
vmwGetPixel(xtemp+x,ytemp+y,screen);
return temp_sprite;
}
void vmwPutSprite(struct vmwSprite *sprite,int x,int y,int shield_color,
unsigned char *screen) {
unsigned char *temp_source,*temp_destination;
int i=0,xx,yy;
temp_source=sprite->spritedata;
temp_destination= ((Uint8 *)screen)+(y*320+x)*2;
for (yy=0;yy<sprite->ysize;yy++) {
for (xx=0;xx<sprite->xsize;xx++) {
if (*temp_source!=0) {
*((Uint16 *)(temp_destination))=global_palette[*(temp_source)];
}
temp_source++;
temp_destination+=2;
}
temp_destination+=((320-sprite->xsize)*2);
}
}

10
vmw_sprite.h Normal file
View File

@ -0,0 +1,10 @@
struct vmwSprite {
int xsize;
int ysize;
unsigned char *spritedata;
};
struct vmwSprite *vmwGetSprite(int x, int y, int xsize, int ysize, unsigned char *source);
void vmwPutSprite(struct vmwSprite *sprite,int x,int y,int shield_color,
unsigned char *screen);