diff --git a/CHANGES b/CHANGES index ec6f279..023ddd2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +16 October 2000 ++ Finished options menu. ++ Fix up documentation, hopefully do a freshmeat release. + 15 October 2000 + Added PCX Save/Load + Added NULL and NCURSES targets to svmwgraph. I must be insane. diff --git a/README b/README index d02ad24..c793e58 100644 --- a/README +++ b/README @@ -1,14 +1,248 @@ -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. - - + +#####| #####| #| #| ####| #####| #| #| ####| #####| #| #| + #| #| #| ##|##| #| #| #| #| ##|##| #| #| #| ##|##| + #| #| #| #|#|#| ####| #| #| #|#|#| ####| ####| #|#|#| + #| #| #| #| #| #| #| #| #| #| #| #| #| #| #| #| + #| #####| #| #| ####| #####| #| #| ####| #####| #| #| + + AND THE INVASION OF THE INANIMATE OBJECTS + + by + + Vince Weaver + +Version 2.9.10 +--------------------------------------------------------------------- + +Contents +-------- + 1.0 COMPILING INSTRUCTIONS + 2.0 SYSTEM REQUIREMENTS + 3.0 THE STORY + 4.0 GAME PLAY + 5.0 SAVING/LOADING GAMES + 6.0 HISTORY + 7.0 ACKNOWLEDGEMENTS + 8.0 PRAISE/ACCOMPLISHMENTS + + + 1.0 Compiling Instructions +--------------------------------------------------------------------- + +Sorry, there is no "configure" file as of yet. + +You need the SDL game development library, 1.1.4 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 + +You also need a recent ncurses library, but that should come with + your distribution hopefully. + +Then a "make" should compile it. + + + 2.0 System Requirements +--------------------------------------------------------------------- + Reccommended Minimum: + 486 66Mhz/ 8MB Ram, 1Meg disk space + + The game was originally written on a 386 33Mhz under DOS. + It has been tested to run fine on my 486 75Mhz laptop + w 12Mb ram and 8bpp display. + + The game has not been verified to run on 64 bit or big-endian machines. + + + 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 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 + 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 HISTORY +--------------------------------------------------------------------- + + Ever since I have had a computer, starting with an Apple IIe + I've always been attempting to write video games. + + Starting around the beginning of high school I actually started + creating ones that were actuallys semi-fun to play. The first + was "s3fight", a space game in CGA mode in gwbasic. Then I + moved on to QBASIC. And then to Turbo Pascal. I wrote a game + called "Under Water Trouble" which was a submarine game + using the .BGI interface. It never ran fast enough [though it + is great fun on a modern machine]. My next game was a + "spacewars" clone, but it too ran a bit too slow, as well as + another game AITAS [Adventures in Time and Space] + + About this time, in 1993, I was an exchange student in + Hildesheim, Germany. And the nice people there showed be + Turbo Pascal 6.0 [which had in-line assembly] and a series + of text files called the PCGPE [PC Game Programmer Encyclopedia]. + + With this new found source of Pascal graphics routines, I started + modifying the "flying toaster" demo to instead draw a spaceship. + And thus was born TB1. + + From the look of the game you can see it is heavily modified after + early-90s share-ware games. I wrote some of the ugliest + Pascal and ix86 assembly you ever saw. But it usually worked. + + During this time I hadn't found the internet yet. I was still + hanging out at local BBS's. But then, my Dad got an e-mail account + and with it access to lynx, and I found the WWW. I found + a Pascal SoundBlaster library written by Ethan Brodsky, who was + close to my age, and suddenly TB1 had sound. By the time I graduated + from high schoool in 1996 the game is much as you see it now + [levels 1-3]. + + Unfortunately, once I got to college things changed. I finally + got my own computer, and gradually I used Linux more and more. + Despite my initial work on the Free Pascal Compiler, I became + convinced the C was the one true language, and Linux the one + true platform. Working on TB1 under dosemu was a pain, + and development stopped. + + In 1998 I gradually ported the game to GGI, but the interface + was ever-changing, and again I ran out of time. + + But finally, in the year 2000, I decided that I would port tb1 + so I could play w it under linux. And so I have. And + hopefully I will finish all 10 levels, and people will play + it for ages to come ;) + + + 7.0 ACKNOWLEDGEMENTS +--------------------------------------------------------------------- + + The following are for the DOS version. I'll add linux ones later. + + 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. + +8.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 16 October 2000 23:05:59 EDT + + + + + + + + + + + + + diff --git a/TB1.FAQ b/TB1.FAQ index 363f244..561bce7 100644 --- a/TB1.FAQ +++ b/TB1.FAQ @@ -50,3 +50,7 @@ A5). You can get the old DOS version off my website, it will run on can be compiled on a windows machine. I don't have nor want a windows box to try this on. If someone does happen to compile up a version, let me know. + +Q6). A curses target? Were you insane? + +A6). No, just very very tired. diff --git a/TODO b/TODO index 4307df3..c54a6eb 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,15 @@ -Finish the game [or at least get it on-par with the dos version] +Finish the game: Requires: - Levels3-4 - Finish Story + Levels3-10. Level 3 is semi-done in pascal. Other aspirations: - Audit all the code - Better Options Menu - Free RAM instead of leaking it. - Re-implement fading in/out + Some sort of "configure" type file + Audit all the code. + Finish plugging mem leaks [still need to fix level_1 and level_2]. + Change all screen-shifts to fades like in original? Implement level editor + +SVMWGraph todo: + Color Averaging in the curses target? + Implement non 320x200x8 PCX loading? diff --git a/data/hiscore.tb1 b/data/hiscore.tb1 index 083d0b3..c9fc859 100644 --- a/data/hiscore.tb1 +++ b/data/hiscore.tb1 @@ -1,13 +1,13 @@ Vince -Hairold -Marie Chipper +Marie +Hairold Kevin Leonard Lizann -VINCECOOL -Vinnels Pete +Jim +Brigid 5000 4500 4000 @@ -15,6 +15,6 @@ Pete 3000 2500 2000 -1570 -1540 1500 +1000 +500 diff --git a/graphic_tools.c b/graphic_tools.c index 1b23364..91f9875 100644 --- a/graphic_tools.c +++ b/graphic_tools.c @@ -37,8 +37,8 @@ char *check_for_tb1_directory(tb1_state *game_state,int try_to_create) char ch; struct stat buf; - vmwFont *tb1_font; - vmwVisual *vis; + vmwFont *tb1_font=NULL; + vmwVisual *vis=NULL; static int initialized=0; static char *dir_name; @@ -48,19 +48,20 @@ char *check_for_tb1_directory(tb1_state *game_state,int try_to_create) initialized=1; } - tb1_font=game_state->graph_state->default_font; - vis=game_state->virtual_3; + if (try_to_create) { + tb1_font=game_state->graph_state->default_font; + vis=game_state->virtual_3; - /* First see if ~/.tb1 exists, and if it doesn't see if */ - /* They want it to be created */ + /* First see if ~/.tb1 exists, and if it doesn't see if */ + /* They want it to be created */ - coolbox(0,0,319,199,1,vis); + coolbox(0,0,319,199,1,vis); // if (read_only_mode) { // vmwTextXY("SORRY! CANNOT SAVE GAME",40,40,4],0],0,tb1_font,vis); // vmwTextXY("WHEN IN READ ONLY MODE",50,50,4],0],0,tb1_font,vis); // } // else { - + } sprintf(dir_name,"%s/.tb1",getenv("HOME")); stat(dir_name,&buf); diff --git a/level_1.c b/level_1.c index 7701297..d9301dc 100644 --- a/level_1.c +++ b/level_1.c @@ -564,7 +564,7 @@ void levelone(tb1_state *game_state) { break; case '-': whatdelay--; if (whatdelay<1) whatdelay=1; break; case 'S': - case 's': if (game_state->sound_enabled) + case 's': if (game_state->sound_possible) game_state->sound_enabled=!(game_state->sound_enabled); break; case VMW_F2: game_paused=1; savegame(game_state); diff --git a/options.c b/options.c index 74862da..51569f1 100644 --- a/options.c +++ b/options.c @@ -5,52 +5,197 @@ #include "tb1_state.h" #include "graphic_tools.h" #include "hiscore.h" +#include "tblib.h" + +void put_on_off(int condition,int highlighted,int x,int y, + vmwFont *tb1_font,vmwVisual *target) { + + if (condition) { + vmwTextXY("ON ",x,y,12,8-highlighted,1,tb1_font,target); + } + else { + vmwTextXY("OFF",x,y,12,8-highlighted,1,tb1_font,target); + } +} + +void put_yes_no(int condition,int highlighted,int x,int y, + vmwFont *tb1_font,vmwVisual *target) { + + if (condition) { + vmwTextXY("YES",x,y,12,8-highlighted,1,tb1_font,target); + } + else { + vmwTextXY("NO ",x,y,12,8-highlighted,1,tb1_font,target); + } +} + +void put_number(int number,int highlighted,int x,int y, + vmwFont *tb1_font,vmwVisual *target) { + + char tempst[2]; + + number=number%10; /* Only works for 0->9 right now */ + number+=48; /* ASCII */ + tempst[0]=number; + tempst[1]='\0'; + + vmwTextXY(tempst,x,y,12,8-highlighted,1,tb1_font,target); +} + +void put_string(char *tempst,int highlighted,int x,int y, + vmwFont *tb1_font,vmwVisual *target) { + + vmwTextXY(tempst,x,y,12,8-highlighted,1,tb1_font,target); +} + void options(tb1_state *game_state) { - int opbarpos,argh=0,ch=0; + int opbarpos=0,ch=0,redraw=1,not_saved=0; + vmwFont *tb1_font; - + char *dir_name; + char file_name[BUFSIZ]; + FILE *fff; + tb1_font=game_state->graph_state->default_font; - vmwClearScreen(game_state->virtual_1,8); - coolbox(0,0,319,199,0,game_state->virtual_1); - vmwTextXY("ESC QUITS",120,175,32,0,1,tb1_font,game_state->virtual_1); - opbarpos=0; while(ch!=VMW_ESCAPE) { - if (game_state->sound_enabled) { - if (opbarpos==0) vmwTextXY("SOUND ON ",30,30,32, - 7,1,tb1_font,game_state->virtual_1); - else vmwTextXY("SOUND ON ",30,30,32, - 0,1,tb1_font,game_state->virtual_1); + if (redraw) { + vmwClearScreen(game_state->virtual_1,8); + coolbox(0,0,319,199,0,game_state->virtual_1); + vmwTextXY("UP,DOWN=MOVE. RIGHT,LEFT=CHANGE.",25,170,32,0,1,tb1_font,game_state->virtual_1); + vmwTextXY("ENTER ACTIVATES. ESC QUITS",80,180,32,0,1,tb1_font,game_state->virtual_1); + redraw=0; } - else { - if (opbarpos==0) vmwTextXY("NO SOUND ",30,30,32, - 7,1,tb1_font,game_state->virtual_1); - else vmwTextXY("NO SOUND ",30,30,32, - 0,1,tb1_font,game_state->virtual_1); - } - if (opbarpos==1) vmwTextXY("VIEW HIGH SCORES",30,40,32, - 7,1,tb1_font,game_state->virtual_1); - else vmwTextXY("VIEW HIGH SCORES",30,40,32, - 0,1,tb1_font,game_state->virtual_1); + + vmwTextXY("SOUND OPTIONS:",10,10,9,8,1,tb1_font,game_state->virtual_1); + vmwTextXY("SOUND FX:",40,20,10,8,1,tb1_font,game_state->virtual_1); + put_on_off(game_state->sound_enabled,(opbarpos==0), + 120,20,tb1_font,game_state->virtual_1); + vmwTextXY("MUSIC :",40,30,10,8,1,tb1_font,game_state->virtual_1); + put_on_off(game_state->music_enabled,(opbarpos==1), + 120,30,tb1_font,game_state->virtual_1); + vmwTextXY("SOUND VOLUME:",40,40,10,8,1,tb1_font,game_state->virtual_1); + put_number(game_state->sound_volume,(opbarpos==2),150,40, + tb1_font,game_state->virtual_1); + vmwTextXY("MUSIC VOLUME:",40,50,10,8,1,tb1_font,game_state->virtual_1); + put_number(game_state->music_volume,(opbarpos==3),150,50, + tb1_font,game_state->virtual_1); + + vmwTextXY("HIGH SCORE LIST:",10,60,9,8,1,tb1_font,game_state->virtual_1); + put_string("VIEW LIST",(opbarpos==4),40,70,tb1_font,game_state->virtual_1); + put_string("WIPE LIST",(opbarpos==5),40,80,tb1_font,game_state->virtual_1); + + vmwTextXY("DEFAULT DISPLAY OPTIONS:",10,90,9,8,1,tb1_font,game_state->virtual_1); + vmwTextXY("RUN FULLSCREEN:",40,100,10,8,1,tb1_font,game_state->virtual_1); + put_yes_no(game_state->default_double_size,(opbarpos==6),180,100, + tb1_font,game_state->virtual_1); + vmwTextXY("RUN DOUBLESIZE:",40,110,10,8,1,tb1_font,game_state->virtual_1); + put_yes_no(game_state->default_fullscreen,(opbarpos==7),180,110, + tb1_font,game_state->virtual_1); + + put_string("SAVE TO DISK AS DEFAULT VALUES", + (opbarpos==8),10,130,tb1_font,game_state->virtual_1); vmwBlitMemToDisplay(game_state->graph_state,game_state->virtual_1); while(!(ch=vmwGetInput()) ) usleep(30); - if ((ch==VMW_RIGHT) || (ch==VMW_DOWN)) opbarpos++; - if ((ch==VMW_LEFT) || (ch==VMW_UP)) opbarpos--; - if ((ch=='M')||(ch=='m')) opbarpos=0; - if ((ch=='V')||(ch=='v')) opbarpos=1; - if ((ch==VMW_ENTER) && (opbarpos==0)) game_state->sound_enabled=!game_state->sound_enabled; - if ((ch==VMW_ENTER) && (opbarpos==1)){ - ch=VMW_ESCAPE; - argh=4; - } - if (opbarpos==2) opbarpos=0; - if (opbarpos==-1) opbarpos=1; + if (ch==VMW_DOWN) opbarpos++; + if (ch==VMW_UP) opbarpos--; + if (ch==VMW_RIGHT) { + switch(opbarpos) { + case 0: game_state->sound_enabled=!game_state->sound_enabled; + break; + case 1: game_state->music_enabled=!game_state->music_enabled; + break; + case 2: game_state->sound_volume++; + if (game_state->sound_volume>9) game_state->sound_volume=9; + break; + case 3: game_state->music_volume++; + if (game_state->music_volume>9) game_state->music_volume=9; + break; + case 6: game_state->default_double_size=!game_state->default_double_size; + break; + case 7: game_state->default_fullscreen=!game_state->default_fullscreen; + break; + + } + } + if (ch==VMW_LEFT){ + switch(opbarpos) { + case 0: game_state->sound_enabled=!game_state->sound_enabled; + break; + case 1: game_state->music_enabled=!game_state->music_enabled; + break; + case 2: game_state->sound_volume--; + if (game_state->sound_volume<0) game_state->sound_volume=0; + break; + case 3: game_state->music_volume--; + if (game_state->music_volume<0) game_state->music_volume=0; + break; + case 6: game_state->default_double_size=!game_state->default_double_size; + break; + case 7: game_state->default_fullscreen=!game_state->default_fullscreen; + break; + + } + } + + if (ch==VMW_ENTER) { + switch(opbarpos) { + case 4: /* View High Score List */ + showhiscore(game_state,1,0); + redraw=1; + break; + case 5: /* Wipe High Score List */ + if (are_you_sure(game_state,"WIPE HIGH SCORES?", + "ARE YOU SURE?", + "YES!", + "NO!") ) + + write_hs_list(game_state,0,"Vince",1); + redraw=1; + break; + + case 8: /* Save Game State */ + /* If ~/.tb1 does not exist, and wasn't made, then exit */ + not_saved=0; + if ((dir_name=check_for_tb1_directory(game_state,1))==NULL) not_saved=1; + + if (!not_saved) { + sprintf(file_name,"%s/options.tb1",dir_name); + fff=fopen(file_name,"w"); + if (fff==NULL) { + not_saved=1; + } + else { + fprintf(fff,"%i\n%i\n%i\n%i\n%i\n%i\n", + game_state->sound_enabled, + game_state->music_enabled, + game_state->sound_volume, + game_state->music_volume, + game_state->default_double_size, + game_state->default_fullscreen); + fclose(fff); + } + } + coolbox(90,75,250,105,1,game_state->virtual_1); + if (not_saved) vmwTextXY("ERROR WHILE SAVING",97,82,9,7,0, + tb1_font,game_state->virtual_1); + else vmwTextXY("OPTIONS SAVED",97,82,9,7,0,tb1_font, + game_state->virtual_1); + vmwBlitMemToDisplay(game_state->graph_state,game_state->virtual_1); + + pauseawhile(15); + + redraw=1; + break; + } + } + if (opbarpos>8) opbarpos=0; + if (opbarpos<0) opbarpos=8; } - if (argh==4) showhiscore(game_state,1,0); } diff --git a/quit.c b/quit.c index 74e99d0..977f3bd 100644 --- a/quit.c +++ b/quit.c @@ -5,41 +5,22 @@ #include "tb1_state.h" #include "graphic_tools.h" #include "sound.h" +#include "tblib.h" int quit(tb1_state *game_state) { - int barpos=0,ch=0; - vmwFont *tb1_font; - vmwVisual *target; + int result=0; - tb1_font=game_state->graph_state->default_font; - target=game_state->virtual_1; - - coolbox(90,75,230,125,1,target); - vmwTextXY("QUIT??? ARE YOU",97,82,9,7,0,tb1_font,target); - vmwTextXY("ABSOLUTELY SURE?",97,90,9,7,0,tb1_font,target); - - while (ch!=VMW_ENTER){ - if (barpos==0) vmwTextXY("YES-RIGHT NOW!",97,98,150,0,1,tb1_font,target); - else vmwTextXY("YES-RIGHT NOW!",97,98,150,7,1,tb1_font,target); - if (barpos==1) vmwTextXY("NO--NOT YET.",97,106,150,0,1,tb1_font,target); - else vmwTextXY("NO--NOT YET.",97,106,150,7,1,tb1_font,target); - vmwBlitMemToDisplay(game_state->graph_state,target); + result=are_you_sure(game_state,"QUIT??? ARE YOU", + "ABSOLUTELY SURE?", + "YES-RIGHT NOW!", + "NO--NOT YET."); - while ( !(ch=vmwGetInput()) ) { - usleep(30); - } - if ((ch==VMW_UP)||(ch==VMW_DOWN)||(ch==VMW_LEFT)||(ch==VMW_RIGHT)) barpos++; - if (ch=='y') barpos=0; - if (ch=='n') barpos=1; - if (barpos==2) barpos=0; - } - if (barpos==0){ + if (result) { shutdownSound(); vmwCloseGraphics(); exit(1); } else return 6; - } diff --git a/sound.c b/sound.c index 7bcb32b..49667ec 100644 --- a/sound.c +++ b/sound.c @@ -2,7 +2,10 @@ #include "sound.h" #include -#include "tblib.h" + + /* Function definition */ +char *tb1_data_file(char *name,char *path); + /* linux only, at the moment */ diff --git a/svmwgraph/curses_svmwgraph.c b/svmwgraph/curses_svmwgraph.c index e0313cd..5cb9a67 100644 --- a/svmwgraph/curses_svmwgraph.c +++ b/svmwgraph/curses_svmwgraph.c @@ -16,6 +16,9 @@ typedef struct { our_color_t our_colors[256]; +int our_lines_stride=25,our_cols_stride=80; +int our_LINES=80,our_COLS=25; + /* Setup the Graphics */ /* Pass '0' to auto-detect bpp */ void *curses_setupGraphics(int *xsize,int *ysize,int *bpp, int fullscreen,int verbose) @@ -43,67 +46,291 @@ void *curses_setupGraphics(int *xsize,int *ysize,int *bpp, int fullscreen,int ve init_pair(13,COLOR_BLACK,COLOR_MAGENTA); init_pair(14,COLOR_BLACK,COLOR_YELLOW); init_pair(15,COLOR_BLACK,COLOR_WHITE); + + /* Calculate how many rows and columns to use that */ + /* Maximize size, but don't cut off too much of the screen */ + + if (LINES>200) { + our_lines_stride=1; + our_LINES=200; + } + else if ( (200%LINES)==0) { + our_lines_stride=200/LINES; + our_LINES=LINES; + } + else { + our_lines_stride=(200/LINES)+1; + our_LINES=(200/our_lines_stride); + } + + if (COLS>320) { + our_cols_stride=1; + our_COLS=320; + } + else if ( (320%COLS)==0) { + our_cols_stride=320/COLS; + our_COLS=COLS; + } + else { + our_cols_stride=(320/COLS)+1; + our_COLS=(320/our_cols_stride); + } + return NULL; } - void lookup_color(int r,int g,int b,int i) { int bitmask; - - if ((r<64) && (g<64) && (b<64)) { - our_colors[i].color=0; - our_colors[i].bold=0; - our_colors[i].character=' '; - return; + FILE *fff; + + /* Black */ + if ((r<85) && (g<85) && (b<85)) { + if (r<64) { + our_colors[i].color=0; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } + else { + our_colors[i].color=8; + our_colors[i].bold=0; + our_colors[i].character='.'; + return; + } } - if ((r>64) && (g<64) && (b<64)) { - our_colors[i].color=12; - our_colors[i].bold=0; - our_colors[i].character=' '; - return; + /* Mostly Red */ + if ((g<85) && (b<85)) { + if (r<120) { + our_colors[i].color=4; + our_colors[i].bold=0; + our_colors[i].character='+'; + return; + } + if (r<160) { + our_colors[i].color=4; + our_colors[i].bold=1; + our_colors[i].character='%'; + return; + } + if (r<200) { + our_colors[i].color=4; + our_colors[i].bold=1; + our_colors[i].character='@'; + return; + } + else { + our_colors[i].color=12; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } } - if ((g>64) && (r<64) && (b<64)) { - our_colors[i].color=10; - our_colors[i].bold=0; - our_colors[i].character=' '; - return; + + /* Mostly Green */ + if ((r<85) && (b<85)) { + if (g<120) { + our_colors[i].color=2; + our_colors[i].bold=0; + our_colors[i].character='+'; + return; + } + if (g<160) { + our_colors[i].color=2; + our_colors[i].bold=1; + our_colors[i].character='%'; + return; + } + if (g<200) { + our_colors[i].color=2; + our_colors[i].bold=1; + our_colors[i].character='@'; + return; + } + else { + our_colors[i].color=10; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } } - if ((b>64) && (r<64) && (g<64)) { - our_colors[i].color=9; - our_colors[i].bold=0; - our_colors[i].character=' '; - return; + /* Mostly Blue */ + if ((r<85) && (g<85)) { + if (b<120) { + our_colors[i].color=1; + our_colors[i].bold=0; + our_colors[i].character='+'; + return; + } + if (b<160) { + our_colors[i].color=1; + our_colors[i].bold=1; + our_colors[i].character='%'; + return; + } + if (b<192) { + our_colors[i].color=1; + our_colors[i].bold=1; + our_colors[i].character='@'; + return; + } + else { + our_colors[i].color=9; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } } - if ((r>64) && (g>64) && (b<64)) { - our_colors[i].color=14; - our_colors[i].bold=0; - our_colors[i].character=' '; - return; + + /* Mostly Yellow */ + if ( (abs(r-g)<32) && (r-b)>64) { + if (r<64) { + our_colors[i].color=6; + our_colors[i].bold=0; + our_colors[i].character='+'; + return; + } + if (r<128) { + our_colors[i].color=14; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } + if (r<200) { + our_colors[i].color=6; + our_colors[i].bold=1; + our_colors[i].character='$'; + return; + } + else { + our_colors[i].color=6; + our_colors[i].bold=1; + our_colors[i].character='@'; + return; + } } - if ((r>64) && (b>64) && (g<64)) { - our_colors[i].color=13; - our_colors[i].bold=0; - our_colors[i].character=' '; - return; + /* Mostly Brown */ + if ((abs(r-g)<100) && ((r-b)>64)) { + if (r<100) { + our_colors[i].color=6; + our_colors[i].bold=0; + our_colors[i].character='+'; + return; + } + if (r<192) { + our_colors[i].color=14; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } + if (r<220) { + our_colors[i].color=6; + our_colors[i].bold=1; + our_colors[i].character='$'; + return; + } + else { + our_colors[i].color=6; + our_colors[i].bold=1; + our_colors[i].character='@'; + return; + } } - if ((g>64) && (b>64) && (r<64)) { - our_colors[i].color=11; - our_colors[i].bold=0; - our_colors[i].character=' '; - return; + + /* Mostly Magenta */ + if ( (abs(r-b)<64) && (r-g>64)) { + if (r<64) { + our_colors[i].color=4; + our_colors[i].bold=0; + our_colors[i].character='+'; + return; + } + if (r<128) { + our_colors[i].color=4; + our_colors[i].bold=1; + our_colors[i].character='@'; + return; + } + else { + our_colors[i].color=13; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } } + /* Mostly Cyan */ + if ( (abs(g-b)<64) && (b-r>64)) { + if (b<64) { + our_colors[i].color=3; + our_colors[i].bold=0; + our_colors[i].character='+'; + return; + } + if (b<128) { + our_colors[i].color=3; + our_colors[i].bold=1; + our_colors[i].character='@'; + return; + } + else { + our_colors[i].color=11; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } + } + + /* Mostly White */ + if ( (abs(r-g)<48) && (abs(r-b)<48) && (abs(b-g)<48)) { + if (r<92) { + our_colors[i].color=0; + our_colors[i].bold=1; + our_colors[i].character='+'; + return; + } + if (r<120) { + our_colors[i].color=0; + our_colors[i].bold=1; + our_colors[i].character='$'; + return; + } + if (r<150) { + our_colors[i].color=7; + our_colors[i].bold=0; + our_colors[i].character='+'; + return; + } + if (r<200) { + our_colors[i].color=7; + our_colors[i].bold=1; + our_colors[i].character='@'; + return; + } + else { + our_colors[i].color=15; + our_colors[i].bold=0; + our_colors[i].character=' '; + return; + } + } + + fff=fopen("temp.temp","a"); + fprintf(fff,"%i: %i %i %i\n",i,r,g,b); + fclose(fff); + + /* When we aren't sure what we are */ bitmask=0; if (r>64) bitmask|=0x4; if (g>64) bitmask|=0x2; if (b>64) bitmask|=0x1; our_colors[i].color=bitmask; - if ((r>128) && - (g>128) && + + if ((r>128) || + (g>128) || (b>128)) our_colors[i].bold=1; else our_colors[i].bold=0; our_colors[i].character='#'; @@ -142,10 +369,10 @@ void curses_BlitMem(vmwSVMWGraphState *target_p, vmwVisual *source) { } */ move(0,0); - for (y=0;y<25;y++) { - s_pointer=source->memory+(y*8*320); - for(x=0;x<80;x++) { - //move(y,x); + for (y=0;ymemory+(y*(our_lines_stride)*320); + for(x=0;xsound_possible=1; game_state->music_enabled=1; game_state->sound_enabled=1; + game_state->default_double_size=0; + game_state->default_fullscreen=0; + + /* Load saved defaults, if any */ + + dir_name=check_for_tb1_directory(game_state,0); + if (dir_name==NULL) { + printf(" + No ~/.tb1 directory. Using default options.\n"); + } + else { + sprintf(options_file,"%s/options.tb1",dir_name); + fff=fopen(options_file,"r"); + if (fff==NULL) { + printf(" + No ~/.tb1/options.tb1 file. Using defaults.\n"); + } + else { + printf(" + Reading options from ~/.tb1/options.tb1\n"); + fscanf(fff,"%i %i %i %i %i %i", + &game_state->sound_enabled, + &game_state->music_enabled, + &game_state->sound_volume, + &game_state->music_volume, + &game_state->default_double_size, + &game_state->default_fullscreen); + fclose(fff); + } + } + /* Parse Command Line Arguments */ i=1; @@ -139,9 +169,11 @@ int main(int argc,char **argv) case 'v': command_line_help(1,argv[0]); return 5; break; case 'f': - fullscreen=1; break; + game_state->default_fullscreen=1; break; + case 'c': + graphics_target=VMW_CURSESTARGET; break; case 'd': - scale=2; break; + game_state->default_double_size=1; break; case 'n': game_state->sound_possible=0; printf(" + Sound totally disabled\n"); @@ -214,20 +246,24 @@ int main(int argc,char **argv) /* Setup Graphics */ - if (scale==1) { + if (!game_state->default_double_size) { if ( (game_state->graph_state= - vmwSetupSVMWGraph(VMW_CURSESTARGET, + vmwSetupSVMWGraph(graphics_target, 320,200, - 0,scale,fullscreen,1))==NULL) { + 0,1, + game_state->default_fullscreen, + 1))==NULL) { fprintf(stderr,"ERROR: Couldn't get display set up properly.\n"); return VMW_ERROR_DISPLAY; } } else { /* We are double-sized */ if ( (game_state->graph_state= - vmwSetupSVMWGraph(VMW_SDLTARGET, + vmwSetupSVMWGraph(graphics_target, 640,480, - 0,scale,fullscreen,1))==NULL) { + 0,2, + game_state->default_fullscreen, + 1))==NULL) { fprintf(stderr,"ERROR: Couldn't get display set up properly.\n"); return VMW_ERROR_DISPLAY; } @@ -373,7 +409,7 @@ int main(int argc,char **argv) /* Run whatever it was that the person pressed */ switch (barpos) { case 0: playthegame(game_state); reloadpic=1; break; - case 1: options(game_state); break; + case 1: options(game_state); reloadpic=1; break; case 2: about(game_state); reloadpic=1; break; case 3: loadgame(game_state); reloadpic=1; break; case 4: story(game_state); reloadpic=1; break; diff --git a/tb1_state.h b/tb1_state.h index a01553a..72b2dfc 100644 --- a/tb1_state.h +++ b/tb1_state.h @@ -14,5 +14,7 @@ typedef struct { int music_enabled; /* Music on or off */ int sound_volume; /* Sound volume */ int music_volume; /* Music volume */ + int default_double_size; /* Start in Double-Size Mode */ + int default_fullscreen; /* Start in Full Screen Mode */ char path_to_data[BUFSIZ]; /* Where our data is */ } tb1_state; diff --git a/tblib.c b/tblib.c index b756dd8..7a333b4 100644 --- a/tblib.c +++ b/tblib.c @@ -3,6 +3,8 @@ #include #include #include "svmwgraph/svmwgraph.h" +#include "tb1_state.h" +#include "graphic_tools.h" void pauseawhile(int howlong) { @@ -46,3 +48,40 @@ char *tb1_data_file(char *name,char *path) snprintf(tempst,BUFSIZ,"%s/%s",path,name); return tempst; } + +int are_you_sure(tb1_state *game_state, + char *warning_1, + char *warning_2, + char *yes_option, + char *no_option) { + + + int barpos=0,ch=0; + + vmwFont *tb1_font; + vmwVisual *target; + + tb1_font=game_state->graph_state->default_font; + target=game_state->virtual_1; + + coolbox(90,75,230,125,1,target); + vmwTextXY(warning_1,97,82,9,7,0,tb1_font,target); + vmwTextXY(warning_2,97,90,9,7,0,tb1_font,target); + + while (ch!=VMW_ENTER){ + if (barpos==0) vmwTextXY(yes_option,97,98,150,0,1,tb1_font,target); + else vmwTextXY(yes_option,97,98,150,7,1,tb1_font,target); + if (barpos==1) vmwTextXY(no_option,97,106,150,0,1,tb1_font,target); + else vmwTextXY(no_option,97,106,150,7,1,tb1_font,target); + vmwBlitMemToDisplay(game_state->graph_state,target); + + while ( !(ch=vmwGetInput()) ) { + usleep(30); + } + if ((ch==VMW_UP)||(ch==VMW_DOWN)||(ch==VMW_LEFT)||(ch==VMW_RIGHT)) barpos++; + if (ch=='y') barpos=0; + if (ch=='n') barpos=1; + if (barpos==2) barpos=0; + } + return !barpos; +} diff --git a/tblib.h b/tblib.h index 37bfd94..a8f7cbe 100644 --- a/tblib.h +++ b/tblib.h @@ -2,3 +2,9 @@ void pauseawhile(int howlong); 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 *path); +int are_you_sure(tb1_state *game_state, + char *warning_1, + char *warning_2, + char *yes_option, + char *no_option); +