diff options
author | uruk | 2013-06-17 10:38:38 +0200 |
---|---|---|
committer | uruk | 2013-06-17 10:38:38 +0200 |
commit | a2adda516bdf790651283201a666f253a8bfcc49 (patch) | |
tree | bdc6479a6889d15d1b25e47e28f0c86f093a9610 /engines/avalanche | |
parent | 2f0e43bb2e402bbcf65175934d21ade6febaad60 (diff) | |
download | scummvm-rg350-a2adda516bdf790651283201a666f253a8bfcc49.tar.gz scummvm-rg350-a2adda516bdf790651283201a666f253a8bfcc49.tar.bz2 scummvm-rg350-a2adda516bdf790651283201a666f253a8bfcc49.zip |
AVALANCHE: Initial PtoC output.
Diffstat (limited to 'engines/avalanche')
206 files changed, 42098 insertions, 0 deletions
diff --git a/engines/avalanche/1stoff.cpp b/engines/avalanche/1stoff.cpp new file mode 100644 index 0000000000..99198b4638 --- /dev/null +++ b/engines/avalanche/1stoff.cpp @@ -0,0 +1,57 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ +/*#include "Dos.h"*/ + + +matrix<1,7,1,3,byte> cols; +byte fv; + +void adjust() +{ + registers r; +; + {; + ax=0x1012; + bx=1; + cx=2; + es=seg(cols); + dx=ofs(cols); + + } + + intr(0x10,r); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + textattr=0; + clrscr; + + fillchar(cols,sizeof(cols),'\0'); + adjust(); + + gotoxy(29,10); textattr=1; output << "Thorsoft of Letchworth"; + gotoxy(36,12); textattr=2; output << "presents"; + + for( fv=1; fv <= 77; fv ++) + {; + delay(77); + if (fv<64) fillchar(cols[1],3,chr(fv)); + if (fv>14) fillchar(cols[2],3,chr(fv-14)); + adjust(); + } + + delay(100); + + for( fv=63; fv >= 1; fv --) + {; + fillchar(cols,sizeof(cols),chr(fv)); + delay(37); + adjust(); + } + +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/access.cpp b/engines/avalanche/access.cpp new file mode 100644 index 0000000000..37c9649193 --- /dev/null +++ b/engines/avalanche/access.cpp @@ -0,0 +1,170 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + ACCESS The temporary Sez handler. */ + +#define __access_implementation__ + + +#include "access.h" + + +/*#include "Gyro.h"*/ +/*#include "Scrolls.h"*/ +/*#include "Acci.h"*/ +/*#include "Trip5.h"*/ +/*#include "Lucerna.h"*/ + + +boolean int_say_went_ok; + +void int_say(string filename, boolean bubble) + /* Internal use ONLY! */ +{ + untyped_file f; +; + /*$I-*/ + assign(f,filename); + reset(f,1); + if (ioresult!=0) + {; + int_say_went_ok=false; + return; + } + bufsize=filesize(f); + blockread(f,buffer,bufsize); + if (bubble) + {; + bufsize += 1; + buffer[bufsize]='\2'; + } + close(f); + /*$I+*/ + + calldrivers; + + int_say_went_ok=true; +} + +void dixi(char p, byte n) +{; exit(153); + int_say(string('s')+p+strf(n)+".raw",false); +} + +void talkto(byte whom) +{ + byte fv; + boolean no_matches; +; exit(153); + if (person==pardon) + {; + person=chr(subjnumber); + subjnumber=0; + } + + switch (chr(whom)) { + case pspludwick: + + if ((dna.lustie_is_asleep) & (~ dna.obj[potion])) + {; + dixi('q',68); + dna.obj[potion]=true; + objectlist; points(3); return; + } else + {; + if (dna.talked_to_crapulus) + switch (dna.given2spludwick) { /* Spludwick - what does he need? */ + /* 0 - let it through to use normal routine. */ + case RANGE_2(1,2): {; + display(string("Can you get me ")+ + get_better(spludwick_order[dna.given2spludwick])+", please?"+ + "\232\2"); + return; + } + break; + case 3: {; + dixi('q',30); /* need any help with the game? */ + return; + } + break; + } + else dixi('q',42); /* Haven't talked to Crapulus. Go and talk to him. */ + } + break; + + case pibythneth: if (dna.givenbadgetoiby) + {; + dixi('q',33); /* Thanks a lot! */ + return; /* And leave the proc. */ + } + break; /* Or... just continue, 'cos he hasn't got it. */ + case pdogfood: if (dna.wonnim) + {; /* We've won the game. */ + dixi('q',6); /* "I'm Not Playing!" */ + return; /* Zap back. */ + } + break; + case payles: if (~ dna.ayles_is_awake) + {; + dixi('q',43); /* He's fast asleep! */ + return; + } + break; + case pgeida: if (dna.geida_given_potion) + dna.geida_follows=true; else + {; + dixi('u',17); + return; + } + break; + } + + if (whom>149) whom -= 149; + + no_matches=true; + for( fv=1; fv <= numtr; fv ++) + if (tr[fv].a.accinum==whom) + {; + display(string('\23')+chr(fv+48)+'\4'); + no_matches=false; + flush(); + } + + if (no_matches) display("\23\23\4"); + + if (subjnumber==0) /* For the moment... later we'll parse "say". */ + int_say(string("ss")+strf(whom)+".raw",true); + else + {; + int_say(string("ss")+strf(whom)+'-'+strf(subjnumber)+".raw",true); + if (! int_say_went_ok) /* File not found! */ + dixi('n',whom); + } + + switch (chr(whom+149)) { + case pcrapulus: + {; /* Crapulus: get the badge - first time only */ + dna.obj[badge]=true; + objectlist; + dixi('q',1); /* Circular from Cardiff. */ + dna.talked_to_crapulus=true; + + whereis[pcrapulus]=177; /* Crapulus walks off. */ + + tr[2].vanishifstill=true; + tr[2].walkto(4); /* Walks away. */ + + points(2); + } + break; + + case payles: dixi('q',44); break; /* Can you get me a pen? */ + + } +} + + diff --git a/engines/avalanche/access.h b/engines/avalanche/access.h new file mode 100644 index 0000000000..825deeb59d --- /dev/null +++ b/engines/avalanche/access.h @@ -0,0 +1,9 @@ +#ifndef __access_h__ +#define __access_h__ + + +void dixi(char p, byte n); + +void talkto(byte whom); + +#endif diff --git a/engines/avalanche/acci.cpp b/engines/avalanche/acci.cpp new file mode 100644 index 0000000000..86fac18585 --- /dev/null +++ b/engines/avalanche/acci.cpp @@ -0,0 +1,1671 @@ +#include "ptoc.h" + +/* $D-*/ +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + ACCIDENCE II The parser. */ +#define __acci_implementation__ + + +/*$V-*/ + +#include "acci.h" + +/*#include "Gyro.h"*/ +/*#include "Lucerna.h"*/ +/*#include "Scrolls.h"*/ +/*#include "Pingo.h"*/ +/*#include "Trip5.h"*/ +/*#include "Visa.h"*/ +/*#include "Enid.h"*/ +/*#include "NimUnit.h"*/ +/*#include "Timeout.h"*/ +/*#include "Celer.h"*/ +/*#include "Highs.h"*/ +/*#include "Helper.h"*/ +/*#include "Sequence.h"*/ + + +byte fv; + +string wordnum(string x); +static char whatsit; +static word fv; +static boolean gotcha; + +static void checkword(string& x) /* Checks word "fv". */ +{ + { + vocab& with = words[fv]; + + if ((with.w==x) || ((copy(with.w,1,length(x))==x) && ! gotcha)) + whatsit=chr(with.n); + if (with.w==x) gotcha=true; + } +} + +string wordnum(string x) + +{ + string wordnum_result; + if (x=="") { wordnum_result=""; return wordnum_result; } + whatsit=pardon; gotcha=false; + for( fv=nowords; fv >= 1; fv --) checkword(x); + wordnum_result=whatsit; + return wordnum_result; +} + +void replace(string old1,string new1) +{ + byte q; + + q=pos(old1,thats); + while (q!=0) + { + thats=copy(thats,1,q-1)+new1+copy(thats,q+length(old1),255); + q=pos(old1,thats); + } +} + +/*procedure ninetydump; +var f:file; y:integer; bit:byte; a:byte absolute $A000:800; +begin + off; + assign(f,'avvydump.avd'); + rewrite(f,1); + blockwrite(f,dna,177); { just anything } + for bit:=0 to 3 do + begin + port[$3c4]:=2; port[$3ce]:=4; port[$3C5]:=1 shl bit; port[$3CF]:=bit; + blockwrite(f,a,12080); + end; + close(f); on; + display('Dumped.'); +end;*/ + +string rank() +{ + byte fv; + + string rank_result; + for( fv=1; fv <= 8; fv ++) + if ((dna.score>=ranks[fv].score) + && (dna.score<ranks[fv+1].score)) + { + rank_result=ranks[fv].title; + return rank_result; + } + return rank_result; +} + +string totaltime() +{ + const real ticks_in_1_sec = (real)(65535)/3600; + word h,m,s; varying_string<70> a; + + /* There are 65535 clock ticks in a second, + 1092.25 in a minute, and + 65535 in an hour. */ + string totaltime_result; + h=trunc(dna.total_time/ticks_in_1_sec); /* No. of seconds. */ + m=h % 3600; h=h / 3600; + s=m % 60; m=m / 60; + + a="You've been playing for "; + + if (h>0) a=a+strf(h)+" hours, "; + if ((m>0) || (h!=0)) a=a+strf(m)+" minutes and "; + a=a+strf(s)+" seconds."; + + totaltime_result=a; + return totaltime_result; +} + +void cheatparse(string codes); +static word num; +static integer e; + +static void number(string& codes) +{ + val(codes,num,e); +} + +void cheatparse(string codes) +{ + char cmd;integer se,sx,sy; + + if (~ cheat) + { /* put them off the scent! */ + display("Have you gone dotty\??!"); + return; + } + cmd=upcase(codes[2]); Delete(codes,1,2); /* strip header */ + display("\6Ninety: \22\4"); + switch (cmd) { + case 'R': { + number(codes); if (e!=0) return; + display(string("room swap to ")+codes+'.'); + fliproom(num,1); + } + break; + case 'Z': { zonk; display("Zonk OK!"); } break; + case 'W': { wobble; display("Ow my head!"); } break; + case 'A': { + tr[1].done; + tr[1].init(1,true); + dna.user_moves_avvy=true; + alive=true; + display("Reincat."); + } + break; + case 'B': { + sx=tr[1].x; + sy=tr[1].y; + se=tr[1].face; + delavvy; + number(codes); + { + void& with = tr[1]; + + done; + init(num,true); + display(string("Become ")+codes+':'+"\r\r"+a.name+'\15'+a.comment); + appear(sx,sy,se); + } + } + break; +/* 'D': ninetydump;*/ + case 'G': play_nim; break; + case '±': display("\232\25"); break; + default: display("unknown code!"); + } +} + +void punctustrip(string& x) /* Strips punctuation from x. */ +{ + const varying_string<32> punct = "~`!@#$%^&*()_+-={}[]:\"|;'\\,./<>?"; + byte fv,p; + + for( fv=1; fv <= 32; fv ++) + do { + p=pos(punct[fv-1],x); + if (p==0) flush(); /* <<< The first time I've ever used it! */ + Delete(x,p,1); + } while (!false); +} + +boolean do_pronouns(); +static boolean ambiguous; + +static void displaywhat(char ch, boolean animate) /* << it's an adjective! */ +{ + byte ff; string z; + + if (ch==pardon) + { + ambiguous=true; + if (animate) display("Whom?"); else display("What?"); + } else + { + if (animate) display(string("{ ")+getname(ch)+" }"); + else + { + z=get_better(ch); + if (z!="") display(string("{ ")+z+" }"); + } + } +} + +boolean do_pronouns() +{ + byte fv; + + boolean do_pronouns_result; + ambiguous=false; + for( fv=1; fv <= length(thats); fv ++) + switch (thats[fv]) { + case '\310': { + displaywhat(him,true); + thats[fv]=him; + } + break; + case '\311': { + displaywhat(her,true); + thats[fv]=her; + } + break; + case '\312': { + displaywhat(it,false); + thats[fv]=it; + } + break; + } + do_pronouns_result=ambiguous; + return do_pronouns_result; +} + +void store_interrogation(byte interrogation); + + +static void lowercase() +{ + byte fv; + + for( fv=1; fv <= length(current); fv ++) + if (set::of(range('A','Z'), eos).has(current[fv])) + current[fv] += 32; +} + + + +static void propernouns() +{ + byte fv; + + lowercase(); + for( fv=2; fv <= length(current)-1; fv ++) + if (current[fv]==' ') + current[fv+1]=upcase(current[fv+1]); + current[1]=upcase(current[1]); +} + + + +static void sayit() /* This makes Avalot say the response. */ +{ + string x; + + x=current; x[1]=upcase(x[1]); + display(string("\231")+x+'.'+'\2'+'\23'+'2'); +} + +void store_interrogation(byte interrogation) +{ + byte fv; + + + if (current=="") return; + + /* Strip current: */ + while ((current[1]==' ') && (current!="")) Delete(current,1,1); + while ((current[length(current)]==' ') && (current!="")) current[0] -= 1; + + lose_timer(reason_cardiffsurvey); /* if you want to use any other timer, + put this into the case statement. */ + switch (interrogation) { + case 1: { + lowercase(); sayit(); + like2drink=current; + dna.cardiff_things=2; + } + break; + case 2: { + propernouns(); sayit(); + favourite_song=current; + dna.cardiff_things=3; + } + break; + case 3: { + propernouns(); sayit(); + worst_place_on_earth=current; + dna.cardiff_things=4; + } + break; + case 4: { + lowercase(); sayit(); + fillchar(spare_evening,sizeof(spare_evening),'\261'); + spare_evening=current; + dixi('z',5); /* His closing statement... */ + tr[2].walkto(4); /* The end of the drawbridge */ + tr[2].vanishifstill=true; /* Then go away! */ + magics[2].op=nix; + dna.cardiff_things=5; + } + break; + + case 99: store_high(current); break; + } + if (interrogation<4) cardiff_survey; +} + +void clearwords() +{ + fillchar(realwords,sizeof(realwords),'\0'); +} + +void parse() +{ + byte n,fv,ff; string c,cc,thisword; varying_string<1> answer; boolean notfound; + + /* first parsing - word identification */ + + thats=""; c=current+'\40'; n=1; polite=false; + verb=pardon; thing=pardon; thing2=pardon; person=pardon; + clearwords(); + if (current[1]=='.') + { /* a cheat mode attempt */ + cheatparse(current); thats=nowt; return; + } /* not our department! Otherwise... */ + + /* Are we being interrogated right now? */ + + if (interrogation>0) + { + store_interrogation(interrogation); + weirdword=true; + return; + } + + cc=c; for( fv=1; fv <= length(c); fv ++) c[fv]=upcase(c[fv]); + while (c!="") + { + while ((c[1]=='\40') && (c!="")) + { Delete(c,1,1); Delete(cc,1,1); } + thisword=copy(c,1,pos("\40",c)-1); + realwords[n]=copy(cc,1,pos("\40",cc)-1); + punctustrip(c); + + notfound=true; + + if (thisword!="") + { + for( ff=1; ff <= 30; ff ++) + { /* Check Also, FIRST! */ + if (pos(string(',')+thisword,also[ff][0])>0) + { + thats=thats+chr(99+ff); + notfound=false; + } + } + } + + if (notfound) + { + answer=wordnum(thisword); + if (answer==pardon) + { + notfound=true; + thats=thats+pardon; + } else + thats=thats+wordnum(thisword); + n += 1; + } + Delete(c,1,pos("\40",c)); Delete(cc,1,pos("\40",cc)); + } + + if (pos("\376",thats)>0) unknown=realwords[pos("\376",thats)]; else unknown=""; replace("\377",""); /* zap noise words */ + replace(string('\15')+'\342',"\1"); /* "look at" = "examine" */ + replace(string('\15')+'\344',"\1"); /* "look in" = "examine" */ + replace(string('\4')+'\343',"\21"); /* "get up" = "stand" */ + replace(string('\4')+'\347',"\21"); /* "get down" = "stand"... well, why not? */ + replace(string('\22')+'\344',"\2"); /* "go in" = "open [door]" */ + replace(string('\34')+'\345',"\375"); /* "P' off" is a swear word */ + replace(string('\4')+'\6',"\6"); /* "Take inventory" (remember Colossal Adventure?) */ + replace(string('\50')+'\350',"\25"); /* "put on" = "don" */ + replace(string('\4')+'\345',"\24"); /* "take off" = "doff" */ + + /* Words that could mean more than one person */ + { + if (room==r__nottspub) replace("\314","\244"); /* Barman = Port */ + else replace("\314","\232"); /* Barman = Malagauche */ + switch (room) { + case r__aylesoffice: replace("\313","\243"); break; /* Monk = Ayles */ + case r__musicroom: replace("\313","\246"); break; /* Monk = Jacques */ + default: replace("\313","\242"); /* Monk = Ibythneth */ + } + } + + if (do_pronouns()) + { + weirdword=true; + thats=nowt; + return; + } + + /* second parsing - accidence */ + + subject=""; subjnumber=0; /* Find subject of conversation. */ + for( fv=1; fv <= 11; fv ++) + if (set::of('`','\'', eos).has(realwords[fv][1])) + { + subjnumber=ord(thats[fv]); + thats[fv]=moved; + flush(); /* Only the second time I've used that! */ + } + if (subjnumber==0) /* Still not found. */ + for( fv=1; fv <= 10; fv ++) + if (thats[fv]=='\374') /* the word is "about", or something similar */ + { + subjnumber=ord(thats[fv+1]); + thats[fv+1]='\0'; + flush(); /* ...Third! */ + } + if (subjnumber==0) /* STILL not found! Must be the word after "say". */ + for( fv=1; fv <= 10; fv ++) + if ((thats[fv]=='\7') && ! (set::of('\0',range('\341','\345'), eos).has(thats[fv+1]))) + { /* SAY not followed by a preposition */ + subjnumber=ord(thats[fv+1]); + thats[fv+1]='\0'; + flush(); /* ...Fourth! */ + } + + for( fv=length(thats); fv >= 1; fv --) /* Reverse order- so first'll be used */ + switch (thats[fv]) { + case '\1' ... '\61':case '\375':case '\371': verb=thats[fv]; break; + case '\62' ... '\225': { thing2=thing; thing=thats[fv]; } break; + case '\226' ... '\307': person=thats[fv]; break; + case '\373': polite=true; break; + } + + if ((unknown!="") && ! + (set::of(vb_exam,vb_talk,vb_save,vb_load,vb_dir, eos).has(verb))) + { + display(string("Sorry, but I have no idea what `")+unknown+ + "\" means. Can you rephrase it?"); + weirdword=true; + } else weirdword=false; + if (thats=="") thats=nowt; + + if (thing!=pardon) it=thing; + if (person!=pardon) + { + if (person<'\257') him=person; else her=person; + } +} + +void examobj() /* Examine a standard object-thing */ +{ + if (thing!=thinks) thinkabout(thing,a_thing); + switch (thing) { + case wine : switch (winestate) { + /* 4 is perfect wine. 0 is not holding the wine. */ + case 1: dixi('t',1); break; /* Normal examine wine scroll */ + case 2: dixi('d',6); break; /* Bad wine */ + case 3: dixi('d',7); break; /* Vinegar */ + } + break; + case onion: if (rotten_onion) + dixi('q',21); /* Yucky onion. */ + else + dixi('t',18); + break; /* Normal onion scroll */ + default: + dixi('t',ord(thing)); /* <<< Ordinarily */ + } +} + +boolean personshere() /* Person equivalent of "holding" */ +{ + boolean personshere_result; + if ((person==pardon) || (person=='\0') + || (whereis[person]==dna.room)) personshere_result=true; + else { + if (person<'\257') display("H\4"); else display("Sh\4"); + display("e isn't around at the moment."); + personshere_result=false; + } + return personshere_result; +} + +void exampers() +{ + if (personshere()) + { + if (thing!=thinks) thinkabout(person,a_person); + person -= 149; + switch (person) { /* Special cases */ + case '\13': if (wonnim) + { + dixi('Q',8); /* "I'm Not Playing!" */ + return; + } + break; + case '\11': if (lustie_is_asleep) + { dixi('Q',65); /* He's asleep. (65! Wow!) */ return; } + break; + } + /* Otherwise... */ dixi('p',ord(person)); + } /* And afterwards... */ + switch (person) { + case '\16': if (~ dna.ayles_is_awake) dixi('Q',13); break; /* u.f.s.? */ + } +} + +boolean holding() +{ + boolean holding_result; + if (set::of(range('\63','\143'), eos).has(thing)) { holding_result=true; return holding_result; } /* Also */ + holding_result=false; + if (thing>'\144') display("Be reasonable!"); else + if (~ dna.obj[thing]) /* verbs that need "thing" to be in the inventory */ + display("You're not holding it, Avvy."); else + holding_result=true; + return holding_result; +} + +void examine(); + +static void special(boolean before) +{ + switch (dna.room) { + case r__yours: switch (thing) { + case '\66': if (before) show_one(5); else show_one(6); break; + } + break; + } +} + +void examine() +{ + /* Examine. EITHER it's an object OR it's an Also OR it's a person OR + it's something else. */ + if ((person==pardon) && (thing!=pardon)) + { + if (holding()) + switch (thing) { /* remember it's been Slipped- ie subtract 49 */ + case '\1' ... '\61' : examobj(); break; /* Standard object */ + case '\62' ... '\144' : { + special(true); + display(also[ord(thing)-50][1]); /* Also thing */ + special(false); + } + break; + } + } else + if (person!=pardon) exampers(); + else display("It's just as it looks on the picture."); /* don't know- guess */ +} + +void inv() /* the time-honoured command... */ +{ + char fv; byte q; + + q=0; display(string("You're carrying ")+'\4'); + { + for( fv='\1'; fv <= numobjs; fv ++) + if (obj[fv]) + { + q += 1; if (q==carrying) display(string("and ")+'\4'); + display(get_better(fv)+'\4'); + if (fv==wearing) display(string(", which you're wearing")+'\4'); + if (q<carrying) display(string(", ")+'\4'); + } + if (wearing==nowt) display("...\r\r...and you're stark naked!"); else + display('.'); + } +} + +void swallow() /* Eat something. */ +{ + switch (thing) { + case wine: switch (dna.winestate) { + /* 4 is perfect */ + case 1: { + if (dna.teetotal) { dixi('D',6); return; } + dixi('U',1); wobble; dixi('U',2); + dna.obj[wine]=false; objectlist; + have_a_drink(); + } + break; + case 2:case 3: dixi('d',8); break; /* You can't drink it! */ + } + break; + case potion: { background(4); dixi('U',3); gameover; background(0); } break; + case ink: dixi('U',4); break; + case chastity: dixi('U',5); break; + case mushroom: { + dixi('U',6); + gameover; + } + break; + case onion: if (dna.rotten_onion) dixi('U',11); + else { + dixi('U',8); + dna.obj[onion]=false; + objectlist; + } + break; + default: + if (set::of(r__argentpub,r__nottspub, eos).has(dna.room)) + display("Try BUYing things before you drink them!"); + else + display("The taste of it makes you retch!"); + /* Constant- leave this one */ + } +} + +void others() + /* This lists the other people in the room. */ +{ + char fv; + byte num_people,this_person,here; + + + num_people=0; + this_person=0; + here=dna.room; + + for( fv='\227'; fv <= '\262'; fv ++) /* Start at 151 so we don't list Avvy himself! */ + if (whereis[fv]==here) + num_people += 1; + + /* If nobody's here, we can cut out straight away. */ + + if (num_people==0) return; /* Leave the procedure. */ + + for( fv='\227'; fv <= '\262'; fv ++) + if (whereis[fv]==here) + { + this_person += 1; + if (this_person==1) /* First on the list. */ + display(getname(fv)+'\4'); else + if (this_person<num_people) /* The middle... */ + display(string(", ")+getname(fv)+'\4'); else + display(string(" and ")+getname(fv)+'\4'); /* The end. */ + } + + if (num_people==1) display(" is\4"); else display(" are\4"); + + display(" here."); /* End and display it. */ +} + +void lookaround() +/* This is called when you say "look." */ +{ + display(also[0][1]); + switch (dna.room) { + case r__spludwicks: if (dna.avaricius_talk>0) dixi('q',23); else others(); break; + case r__robins: { + if (dna.tied_up) dixi('q',38); + if (dna.mushroom_growing) dixi('q',55); + } + break; + case r__insidecardiffcastle: if (~ dna.taken_pen) dixi('q',49); break; + case r__lustiesroom: if (dna.lustie_is_asleep) dixi('q',65); break; + case r__catacombs: switch (dna.cat_y*256+dna.cat_x) { + case 258 : dixi('q',80); break; /* Inside art gallery */ + case 514 : dixi('q',81); break; /* Outside ditto */ + case 260 : dixi('q',82); break; /* Outside Geida's room. */ + } + break; + default: others(); + } +} + +void opendoor() /* so whaddya THINK this does?! */ +{ + byte fv; + + switch (dna.room) { /* Special cases. */ + case r__yours: if (infield(2)) + { /* Opening the box. */ + thing='\66'; /* The box. */ person=pardon; + examine(); + return; + } + break; + case r__spludwicks: if (thing=='\75') { + dixi('q',85); + return; + } + break; + } + + + if ((~ dna.user_moves_avvy) & (dna.room!=r__lusties)) + return; /* No doors can open if you can't move Avvy. */ + for( fv=9; fv <= 15; fv ++) + if (infield(fv)) + { + { void& with = portals[fv]; + switch (op) { + case exclaim: { tr[1].bounce; dixi('x',data); } break; + case transport: fliproom(hi(data),lo(data)); break; + case unfinished: { + tr[1].bounce; + display("\7Sorry.\3\rThis place is not available yet!"); + } + break; + case special: call_special(data); break; + case mopendoor: open_the_door(hi(data),lo(data),fv); break; + }} + return; + } + if (dna.room==r__map) + display(string("Avvy, you can complete the whole game without ever going ")+ + "to anywhere other than Argent, Birmingham, Cardiff, "+ + "Nottingham and Norwich."); + else display("Door? What door?"); +} + +void putproc(); + + +static void silly() +{ + display("Don't be silly!"); +} + +void putproc() /* Called when you call vb_put. */ +{ + char temp; + + + if (! holding()) return; + thing2 -= 49; /* Slip the second object */ + temp=thing; thing=thing2; if (! holding()) return; + thing=temp; + + /* Thing is the thing which you're putting in. Thing2 is where you're + putting it. */ + /* Convenience thing. */ + switch (thing2) { + case wine: if (thing==onion) + { + if (dna.rotten_onion) + display(string("That's a bit like shutting the stable door after the ")+ + "horse has bolted!"); + else { /* Put onion into wine? */ + if (dna.winestate!=3) + display("\6Oignon au vin\22 is a bit too strong for your tastes!"); + else { /* Put onion into vinegar! Yes! */ + onion_in_vinegar=true; + points(7); + dixi('u',9); + } + } + } else silly(); + break; + + case '\66': if (room==1) /* Put something into the box. */ + { + if (box_contents!=nowt) + display(string("There's something in the box already, Avvy. Try taking")+ + " that out first."); + else + switch (thing) { + case money: display("You'd better keep some ready cash on you!"); break; + case bell: display("That's a silly place to keep a bell."); break; + case bodkin: display("But you might need it!"); break; + case onion: display("Just give it to Spludwick, Avvy!"); break; + default: + { /* Put the object into the box... */ + if (wearing==thing) + display(string("You'd better take ")+get_better(thing)+" off first!"); + else + { + show_one(5); /* Open box. */ + box_contents=thing; + dna.obj[thing]=false; + objectlist; + display("OK, it's in the box."); + show_one(6); /* Shut box. */ + } + } + } + } else silly(); + break; + + default: silly(); + } +} + +boolean give2spludwick(); + + /* The result of this fn is whether or not he says "Hey, thanks!" */ +static void not_in_order() +{ + display(string("Sorry, I need the ingredients in the right order for this potion.")+ + " What I need next is "+ + get_better(spludwick_order[dna.given2spludwick])+".\232\2"); +} + + + +static void go_to_cauldron() +{ + tr[2].call_eachstep=false; /* Stops Geida_Procs. */ + set_up_timer(1,procspludwick_goes_to_cauldron,reason_spludwalk); + tr[2].walkto(2); +} + +boolean give2spludwick() + +{ + boolean give2spludwick_result; + { + + give2spludwick_result=false; + + if (spludwick_order[given2spludwick]!=thing) + { + not_in_order(); + return give2spludwick_result; + } + + switch (thing) { + case onion: + { + obj[onion]=false; + if (rotten_onion) + dixi('q',22); + else { + given2spludwick += 1; + dixi('q',20); + go_to_cauldron(); + points(3); + } + objectlist; + } + break; + case ink: { + obj[ink]=false; + objectlist; + given2spludwick += 1; + dixi('q',24); + go_to_cauldron(); + points(3); + } + break; + case mushroom: { + obj[mushroom]=false; + dixi('q',25); + points(5); + given2spludwick += 1; + go_to_cauldron(); + obj[potion]=true; + objectlist; + } + break; + default: give2spludwick_result=true; + } + } + return give2spludwick_result; +} + +void have_a_drink() +{ + { + alcohol += 1; + if (alcohol==5) + { + obj[key]=true; /* Get the key. */ + teetotal=true; + avvy_is_awake=false; + avvy_in_bed=true; + objectlist; + dusk; + hang_around_for_a_while; + fliproom(1,1); + background(14); + new_game_for_trippancy; /* Not really */ + } + } +} + +void cardiff_climbing() +{ + if (dna.standing_on_dais) + { /* Clamber up. */ + display("You climb down, back onto the floor."); + dna.standing_on_dais=false; + apped(1,3); + } else + { /* Clamber down. */ + if (infield(1)) + { + display("You clamber up onto the dais."); + dna.standing_on_dais=true; + apped(1,2); + } else + display("Get a bit closer, Avvy."); + } +} + +void stand_up(); + + /* Called when you ask Avvy to stand. */ +static void already() +{ + display("You're already standing!"); +} + +void stand_up() +{ + switch (dna.room) { + case r__yours: /* Avvy isn't asleep. */ + if (avvy_in_bed) /* But he's in bed. */ + { + if (teetotal) + { + dixi('d',12); + background(0); + dixi('d',14); + } + tr[1].visible=true; + user_moves_avvy=true; + apped(1,2); + dna.rw=left; + show_one(4); /* Picture of empty pillow. */ + points(1); + avvy_in_bed=false; + lose_timer(reason_arkata_shouts); + } else already(); + break; + + case r__insidecardiffcastle: cardiff_climbing(); break; + + case r__nottspub: if (sitting_in_pub) { + show_one(4); /* Not sitting down. */ + tr[1].visible=true; /* But standing up. */ + apped(1,4); /* And walking away. */ + sitting_in_pub=false; /* Really not sitting down. */ + user_moves_avvy=true; /* And ambulant. */ + } else already(); + break; + default: already(); + } +} + +void getproc(char thing) +{ + switch (room) { + case r__yours: + if (infield(2)) + { + if (box_contents==thing) + { + show_one(5); + display("OK, I've got it."); + obj[thing]=true; objectlist; + box_contents=nowt; + show_one(6); + } else + display(string("I can't see ")+get_better(thing)+" in the box."); + } else dixi('q',57); + break; + case r__insidecardiffcastle: + switch (thing) { + case pen: + { + if (infield(2)) + { /* Standing on the dais. */ + + if (dna.taken_pen) + display("It's not there, Avvy."); + else + { /* OK: we're taking the pen, and it's there. */ + show_one(4); /* No pen there now. */ + call_special(3); /* Zap! */ + dna.taken_pen=true; + dna.obj[pen]=true; + objectlist; + display("Taken."); + } + } else if (dna.standing_on_dais) dixi('q',53); else dixi('q',51); + } + break; + case bolt: dixi('q',52); break; + default: dixi('q',57); + } + break; + case r__robins: if ((thing==mushroom) & (infield(1)) & (dna.mushroom_growing)) + { + show_one(3); + display("Got it!"); + dna.mushroom_growing=false; + dna.taken_mushroom=true; + dna.obj[mushroom]=true; + objectlist; + points(3); + } else dixi('q',57); + break; + default: dixi('q',57); + } +} + +void give_geida_the_lute() +{ + { + if (room!=r__lustiesroom) + { + display("Not yet. Try later!\232\2"); + return; + } + dna.obj[lute]=false; + objectlist; + dixi('q',64); /* She plays it. */ + + /* And the rest has been moved to Timeout... under give_lute_to_Geida. */ + + set_up_timer(1,procgive_lute_to_geida,reason_geida_sings); + back_to_bootstrap(4); + } +} + +void play_harp() +{ + if (infield(7)) + musical_scroll; + else display("Get a bit closer to it, Avvy!"); +} + +void winsequence() +{ + dixi('q',78); + first_show(7); then_show(8); then_show(9); + start_to_close; + set_up_timer(30,procwinning,reason_winning); +} + +void person_speaks() +{ + boolean found; byte fv; char cfv; + + + if ((person==pardon) || (person=='\0')) + { + if ((him==pardon) || (whereis[him]!=dna.room)) person=her; + else person=him; + } + + if (whereis[person]!=dna.room) + { + display("\231\4"); /* Avvy himself! */ + return; + } + + found=false; /* The person we're looking for's code is in Person. */ + + for( fv=1; fv <= numtr; fv ++) + if (tr[fv].quick & (chr(tr[fv].a.accinum+149)==person)) + { + display(string('\23')+chr(fv+48)+'\4'); + found=true; + } + + if (! found) + for( fv=10; fv <= 25; fv ++) + { void& with = quasipeds[fv]; + if ((who==person) && (room==dna.room)) + { + display(string('\23')+chr(fv+55)+'\4'); + }} +} + +void do_that(); + +static void heythanks() +{ + person_speaks(); + display("Hey, thanks!\2(But now, you've lost it!)"); + dna.obj[thing]=false; +} + +void do_that() +{ + const array<'\63','\72',varying_string<6> > booze = {{"Bitter","GIED","Whisky","Cider","","","","Mead"}}; + byte fv,ff; integer sx,sy; boolean ok; + + + if (thats==nowt) { thats=""; return; } + if (weirdword) return; + if (thing<'\310') thing -= 49; /* "Slip" */ + + if ((~ alive) & + ! (set::of(vb_load,vb_save,vb_quit,vb_info,vb_help,vb_larrypass, + vb_phaon,vb_boss,vb_cheat,vb_restart,vb_dir,vb_score, + vb_highscores,vb_smartalec, eos).has(verb))) + { + display(string("You're dead, so don't talk. What are you, a ghost ")+ + "or something? Try restarting, or restoring a saved game!"); return; + } + + if ((~ dna.avvy_is_awake) & + ! (set::of(vb_load,vb_save,vb_quit,vb_info,vb_help,vb_larrypass, + vb_phaon,vb_boss,vb_cheat,vb_restart,vb_dir,vb_die,vb_score, + vb_highscores,vb_smartalec,vb_expletive,vb_wake, eos).has(verb))) + { + display("Talking in your sleep? Try waking up!"); return; + } + + + switch (verb) { + case vb_exam: examine(); break; + case vb_open: opendoor(); break; + case vb_pause: display(string("Game paused.")+'\3'+'\15'+'\15'+"Press Enter, Esc, or click "+ + "the mouse on the `O.K.\" box to continue."); + break; + case vb_get: { + if (thing!=pardon) + { /* Legitimate try to pick something up. */ + if (dna.carrying>=maxobjs) display("You can't carry any more!"); + else getproc(thing); + + } else + { /* Not... ditto. */ + if (person!=pardon) + display("You can't sweep folk off their feet!"); else + display("I assure you, you don't need it."); + } + } + break; + case vb_drop: display(string("Two years ago you dropped a florin in the street. Three days ")+ + "later it was gone! So now you never leave ANYTHING lying around. OK?"); + break; +/* begin dna.obj[thing]:=false; objectlist; end;*/ + case vb_inv: inv(); break; + case vb_talk: if (person==pardon) + { + if (subjnumber==99) /* They typed "say password". */ + display("Yes, but what \6is\22 the password?"); + else if (set::of(range(1,49),253,249, eos).has(subjnumber)) + { + Delete(thats,1,1); + move(realwords[2],realwords[1],sizeof(realwords)-sizeof(realwords[1])); + verb=chr(subjnumber); + do_that(); return; + } else + { + person=chr(subjnumber); subjnumber=0; + if (set::of(pardon,'\0', eos).has(person)) display("Talk to whom?"); + else if (personshere()) talkto(ord(person)); + } + } else if (person==pardon) display("Talk to whom?"); + else if (personshere()) talkto(ord(person)); + break; + + case vb_give: if (holding()) + { + if (person==pardon) display("Give to whom?"); else + if (personshere()) + { + switch (thing) { + case money : display("You can't bring yourself to give away your moneybag."); break; + case bodkin:case bell:case clothes:case habit : + display("Don't give it away, it might be useful!"); + break; + default: switch (person) { + case pcrapulus: switch (thing) { + case wine: { + display("Crapulus grabs the wine and gulps it down."); + dna.obj[wine]=false; + } + break; + default: heythanks(); + } + break; + case pcwytalot: if (set::of(crossbow,bolt, eos).has(thing)) + display(string("You might be able to influence ")+ + "Cwytalot more if you used it!"); + else heythanks(); + break; + case pspludwick: if (give2spludwick()) heythanks(); break; + case pibythneth: if (thing==badge) + { + dixi('q',32); /* Thanks! Wow! */ + points(3); + dna.obj[badge]=false; + dna.obj[habit]=true; + dna.givenbadgetoiby=true; + show_one(8); show_one(9); + } else heythanks(); + break; + case payles: if (dna.ayles_is_awake) + { + if (thing==pen) + { + dna.obj[pen]=false; + dixi('q',54); + dna.obj[ink]=true; + dna.given_pen_to_ayles=true; + objectlist; + points(2); + } else heythanks(); + } else + display("But he's asleep!"); + break; + case pgeida: switch (thing) { + case potion : { + dna.obj[potion]=false; + dixi('u',16); /* She drinks it. */ + points(2); + dna.geida_given_potion=true; + objectlist; + } + break; + case lute: give_geida_the_lute(); break; + default: heythanks(); + } + break; + case parkata: switch (thing) { + case potion: if (dna.geida_given_potion) + winsequence(); + else dixi('q',77); + break; /* That Geida woman! */ + default: heythanks(); + } + break; + default: heythanks(); + } + } + } + objectlist; /* Just in case... */ + } + break; + + case vb_eat:case vb_drink: if (holding()) swallow(); break; + case vb_load: edna_load(realwords[2]); break; + case vb_save: if (alive) edna_save(realwords[2]); + else display("It's a bit late now to save your game!"); + break; + case vb_pay: display("No money need change hands."); break; + case vb_look: lookaround(); break; + case vb_break: display("Vandalism is prohibited within this game!"); break; + case vb_quit: { /* quit */ + if (demo) + { + dixi('q',31); + close(demofile); + exit(0); /* Change this later!!! */ + } + if (! polite) display("How about a `please\", Avvy?"); else + if (ask("\23C\26Do you really want to quit?")) lmo=true; + } + break; + case vb_go: display("Just use the arrow keys to walk there."); break; + case vb_info: { + aboutscroll=true; +/* display('Thorsoft of Letchworth presents:'+^c+^m+^m+ + 'The medi‘val descendant of'+^m+ + 'Denarius Avaricius Sextus'+^m+'in:'+ + ^m+^m+'LORD AVALOT D''ARGENT'+ + ^m+'version '+vernum+^m+^m+'Copyright ï ' + +copyright+', Mark, Mike and Thomas Thurman.');*/ + display(string("\r\r\r\r\r\r\r")+"LORD AVALOT D'ARGENT"+"\3\r"+ + "The medi‘val descendant of"+'\15'+ + "Denarius Avaricius Sextus"+ + '\15'+'\15'+"version "+vernum+'\15'+'\15'+"Copyright ï " + +copyright+", Mark, Mike and Thomas Thurman."+'\23'+'Y'+'\26'); + aboutscroll=false; + } + break; + case vb_undress: if (dna.wearing==nowt) display("You're already stark naked!"); + else + if (dna.avvys_in_the_cupboard) + { + display(string("You take off ")+get_better(dna.wearing)+'.'); + dna.wearing=nowt; objectlist; + } else + display("Hadn't you better find somewhere more private, Avvy?"); + break; + case vb_wear: if (holding()) + { /* wear something */ + switch (thing) { + case chastity: display("Hey, what kind of a weirdo are you\??!"); break; + case clothes:case habit: { /* Change this! */ + if (dna.wearing!=nowt) + { + if (dna.wearing==thing) + display("You're already wearing that."); + else + display(string("You'll be rather warm wearing two ")+ + "sets of clothes!"); + return; + } else + dna.wearing=thing; objectlist; + if (thing==habit) fv=3; else fv=0; + { void& with = tr[1]; + if (whichsprite!=fv) + { + sx=tr[1].x; sy=tr[1].y; + done; + init(fv,true); + appear(sx,sy,left); + tr[1].visible=false; + }} + } + break; + default: display(what); + } + } + break; + case vb_play: if (thing==pardon) + switch (dna.room) { /* They just typed "play"... */ + case r__argentpub: play_nim; break; /* ...in the pub, => play Nim. */ + case r__musicroom: play_harp(); break; + } + else if (holding()) + { + switch (thing) { + case lute : { + dixi('U',7); + if (whereis[pcwytalot]==dna.room) dixi('U',10); + if (whereis[pdulustie]==dna.room) dixi('U',15); + } + break; + case '\64' : if (dna.room==r__musicroom) play_harp(); + else display(what); + break; + case '\67' : if (dna.room==r__argentpub) play_nim; + else display(what); + break; + default: display(what); + } + } + break; + case vb_ring: if (holding()) + { + if (thing==bell) + { + display("Ding, dong, ding, dong, ding, dong, ding, dong..."); + if ((dna.ringing_bells) & (flagset('B'))) + display("(Are you trying to join in, Avvy\?\?!)"); + } else display(what); + } + break; + case vb_help: boot_help; break; + case vb_larrypass: display("Wrong game!"); break; + case vb_phaon: display("Hello, Phaon!"); break; + case vb_boss: bosskey; break; + case vb_pee: if (flagset('P')) + { + display("Hmm, I don't think anyone will notice..."); + set_up_timer(4,procurinate,reason_gototoilet); + } else display("It would be \6VERY\22 unwise to do that here, Avvy!"); + break; + case vb_cheat: { + display(string('\6')+"Cheat mode now enabled."); + cheat=true; + } + break; + case vb_magic: if (dna.avaricius_talk>0) + dixi('q',19); + else { + if ((dna.room==12) & (infield(2))) + { /* Avaricius appears! */ + dixi('q',17); + if (whereis['\227']==12) + dixi('q',18); + else + { + tr[2].init(1,false); /* Avaricius */ + apped(2,4); + tr[2].walkto(5); + tr[2].call_eachstep=true; + tr[2].eachstep=procback_and_forth; + dna.avaricius_talk=14; + set_up_timer(177,procavaricius_talks,reason_avariciustalks); + } + } else display("Nothing appears to happen..."); + } + break; + case vb_smartalec: display("Listen, smart alec, that was just rhetoric."); break; + case vb_expletive: { + switch (swore) { + case 0: display(string("Avvy! Do you mind? There might be kids playing!\r\r")+ + "(I shouldn't say it again, if I were you!)"); + break; + case 1: display(string("You hear a distant rumble of thunder. Must you always ")+ + "do things I tell you not to?\r\rDon't do it again!"); + break; + default: + { + zonk; + display(string("A crack of lightning shoots from the sky, ")+ + "and fries you.\r\r(`Such is the anger of the gods, Avvy!\")"); + gameover; + } + } + swore += 1; + } + break; + case vb_listen: if ((dna.ringing_bells) & (flagset('B'))) + display(string("All other noise is drowned out by the ringing of ")+ + "the bells."); + else + if (listen=="") + display("You can't hear anything much at the moment, Avvy."); + else display(listen); + break; + case vb_buy: { + /* What are they trying to buy? */ + switch (dna.room) { + case r__argentpub: if (infield(6)) + { /* We're in a pub, and near the bar. */ + switch (thing) { + case '\63':case '\65':case '\66':case '\72': { /* Beer, whisky, cider or mead */ + if (dna.malagauche==177) /* Already getting us one. */ + { dixi('D',15); return; } + if (dna.teetotal) { dixi('D',6); return; } + if (dna.alcohol==0) points(3); + show_one(12); + display(booze[thing]+", please.\231\2"); + dna.drinking=thing; + + show_one(10); + dna.malagauche=177; + set_up_timer(27,procbuydrinks,reason_drinks); + } + break; + case '\64': examine(); break; /* We have a right one here- buy Pepsi??! */ + case wine: if (dna.obj[wine]) /* We've already got the wine! */ + dixi('D',2); /* 1 bottle's shufishent! */ + else { + if (dna.malagauche==177) /* Already getting us one. */ + { dixi('D',15); return; } + if (dna.carrying>=maxobjs) + { display("Your hands are full."); return; } + show_one(12); display("Wine, please.\231\2"); + if (dna.alcohol==0) points(3); + show_one(10); + dna.malagauche=177; + + set_up_timer(27,procbuywine,reason_drinks); + } + break; + } + } else dixi('D',5); + break; /* Go to the bar! */ + + case r__outsideducks: if (infield(6)) + { + if (thing==onion) + { + if (dna.obj[onion]) + dixi('D',10); /* not planning to juggle with the things! */ + else + if (dna.carrying>=maxobjs) + display("Before you ask, you remember that your hands are full."); + else + { + if (dna.bought_onion) + dixi('D',11); else + { dixi('D',9); points(3); } + pennycheck(3); /* It costs thruppence. */ + dna.obj[onion]=true; + objectlist; + dna.bought_onion=true; + dna.rotten_onion=false; /* It's OK when it leaves the stall! */ + dna.onion_in_vinegar=false; + } + } else dixi('D',0); + } else dixi('D',0); + break; + + case r__nottspub: dixi('n',15); break; /* Can't sell to southerners. */ + default: dixi('D',0); /* Can't buy that. */ + } + } + break; + case vb_attack: { + if ((dna.room==r__brummieroad) && + ((person=='\235') || (thing==crossbow) || (thing==bolt)) + && (whereis['\235']==dna.room)) + { + switch (ord(dna.obj[bolt])+ord(dna.obj[crossbow])*2) { + /* 0 = neither, 1 = only bolt, 2 = only crossbow, + 3 = both. */ + case 0: { + dixi('Q',10); + display("(At the very least, don't use your bare hands!)"); + } + break; + case 1: display(string("Attack him with only a crossbow bolt? Are you ")+ + "planning on playing darts?!"); + break; + case 2: display(string("Come on, Avvy! You're not going to get very far ")+ + "with only a crossbow!"); + break; + case 3: { + dixi('Q',11); + dna.cwytalot_gone=true; + dna.obj[bolt]=false; dna.obj[crossbow]=false; + objectlist; + magics[12].op=nix; + points(7); + tr[2].walkto(2); + tr[2].vanishifstill=true; + tr[2].call_eachstep=false; + whereis['\235']=177; + } + break; + default: dixi('Q',10); /* Please try not to be so violent! */ + } + } else dixi('Q',10); + } + break; + case vb_password: if (dna.room!=r__bridge) + dixi('Q',12); else + { + ok=true; + for( ff=1; ff <= length(thats); ff ++) + for( fv=1; fv <= length(words[dna.pass_num+first_password].w); fv ++) + if (words[dna.pass_num+first_password].w[fv] != + upcase(realwords[ff][fv])) + ok=false; + if (ok) + { + if (dna.drawbridge_open!=0) + display("Contrary to your expectations, the drawbridge fails to close again."); + else + { + points(4); + display("The drawbridge opens!"); + set_up_timer(7,procopen_drawbridge,reason_drawbridgefalls); + dna.drawbridge_open=1; + } + } else dixi('Q',12); + } + break; + case vb_dir: dir(realwords[2]); break; + case vb_die: gameover; break; + case vb_score: display(string("Your score is ")+strf(dna.score)+",\3\rout of a "+ + "possible 128.\r\rThis gives you a rank of "+rank()+ + ".\r\r"+totaltime()); + break; + case vb_put: putproc(); break; + case vb_stand: stand_up(); break; + + case vb_kiss: if (person==pardon) + display("Kiss whom?"); + else if (personshere()) + switch (person) { + case '\226' ... '\256': display("Hey, what kind of a weirdo are you??"); break; + case parkata: dixi('U',12); break; + case pgeida: dixi('U',13); break; + case pwisewoman: dixi('U',14); break; + default: dixi('U',5); /* You WHAT? */ + } + break; + + case vb_climb: if (dna.room==r__insidecardiffcastle) cardiff_climbing(); + else /* In the wrong room! */ + display("Not with your head for heights, Avvy!"); + break; + + case vb_jump: { + set_up_timer(1,procjump,reason_jumping); + dna.user_moves_avvy=false; + } + break; + + case vb_highscores: show_highs; break; + + case vb_wake: if (personshere()) + switch (person) { + case pardon:case pavalot:case '\0': if (~ avvy_is_awake) + { + avvy_is_awake=true; + points(1); + avvy_in_bed=true; + show_one(3); /* Picture of Avvy, awake in bed. */ + if (teetotal) dixi('d',13); + } else display("You're already awake, Avvy!"); + break; + case payles: if (~ ayles_is_awake) display("You can't seem to wake him by yourself."); break; + case pjacques: display(string("Brother Jacques, Brother Jacques, are you asleep?\231\2")+ + "Hmmm... that doesn't seem to do any good..."); + break; + default: display("It's difficult to awaken people who aren't asleep...!"); + } + break; + + case vb_sit: if (dna.room==r__nottspub) + { + if (dna.sitting_in_pub) + display("You're already sitting!"); + else + { + tr[1].walkto(4); /* Move Avvy to the place, and sit him down. */ + set_up_timer(1,procavvy_sit_down,reason_sitting_down); + } + } else + { /* Default doodah. */ + dusk; + hang_around_for_a_while; + dawn; + display("A few hours later...\20nothing much has happened..."); + } + break; + + case vb_restart: if (ask("Restart game and lose changes?")) { + dusk; + newgame; + dawn; + } + break; + + case pardon: display("Hey, a verb would be helpful!"); break; + + case vb_hello: { person_speaks(); display("Hello.\2"); } break; + case vb_thanks: { person_speaks(); display("That's OK.\2"); } break; + default: display(string('\7')+"Parser bug!"); + } +} + +void verbopt(char n, string& answer, char& anskey) +{ + switch (n) { + case vb_exam: { answer="Examine"; anskey='x'; } break; /* the ubiqutous one */ + /* vb_give isn't dealt with by this procedure, but by ddm__with */ + case vb_drink: { answer="Drink"; anskey='D'; } break; + case vb_wear: { answer="Wear"; anskey='W'; } break; + case vb_ring: { answer="Ring"; anskey='R'; } break; /* only the bell! */ + case vb_play: { answer="Play"; anskey='P'; } break; + case vb_eat: { answer="Eat"; anskey='E'; } break; + default: { answer="? Unknown!"; anskey='?'; } /* Bug! */ + } +} + +class unit_acci_initialize { + public: unit_acci_initialize(); +}; +static unit_acci_initialize acci_constructor; + +unit_acci_initialize::unit_acci_initialize() { + weirdword=false; +} diff --git a/engines/avalanche/acci.h b/engines/avalanche/acci.h new file mode 100644 index 0000000000..f9d1265b32 --- /dev/null +++ b/engines/avalanche/acci.h @@ -0,0 +1,223 @@ +#ifndef __acci_h__ +#define __acci_h__ + + +/* verb codes */ +const char vb_exam = '\1'; const char vb_open = '\2'; const char vb_pause = '\3'; const char vb_get = '\4'; const char vb_drop = '\5'; +const char vb_inv = '\6'; const char vb_talk = '\7'; const char vb_give = '\10'; const char vb_drink = '\11'; const char vb_load = '\12'; +const char vb_save = '\13'; const char vb_pay = '\14'; const char vb_look = '\15'; const char vb_break = '\16'; const char vb_quit = '\17'; +const char vb_sit = '\20'; const char vb_stand = '\21'; const char vb_go = '\22'; const char vb_info = '\23'; const char vb_undress = '\24'; +const char vb_wear = '\25'; const char vb_play = '\26'; const char vb_ring = '\27'; const char vb_help = '\30'; +const char vb_larrypass = '\31'; const char vb_phaon = '\32'; const char vb_boss = '\33'; const char vb_pee = '\34'; +const char vb_cheat = '\35'; const char vb_magic = '\36'; const char vb_restart = '\37'; const char vb_eat = '\40'; +const char vb_listen = '\41'; const char vb_buy = '\42'; const char vb_attack = '\43'; const char vb_password = '\44'; +const char vb_dir = '\45'; const char vb_die = '\46'; const char vb_score = '\47'; const char vb_put = '\50'; +const char vb_kiss = '\51'; const char vb_climb = '\52'; const char vb_jump = '\53'; const char vb_highscores = '\54'; +const char vb_wake = '\55'; const char vb_hello = '\56'; const char vb_thanks = '\57'; + +const char vb_smartalec = '\371'; const char vb_expletive = '\375'; + +const char pardon = '\376'; /* =didn't understand / wasn't given. */ + +struct vocab { + byte n; varying_string<11> w; +}; + +struct ranktype { + word score; varying_string<12> title; +}; + + +const integer nowords = 277; /* how many words does the parser know? */ +const char nowt = '\372'; +const char moved = '\0'; /* This word was moved. (Usually because it was the subject of + conversation.) */ + +const integer first_password = 89; /* Words[first_password] should equal "TIROS". */ + +const array<1,nowords,vocab> words = + +/* Verbs, 1-49 */ +{{{1, "EXAMINE"}, {1, "READ"}, {1, "XAM"}, /* short */ + {2, "OPEN"}, {2, "LEAVE"}, {2, "UNLOCK"}, + {3, "PAUSE"}, {47, "TA"}, /* Early to avoid Take and Talk. */ + {4, "TAKE"}, {4, "GET"}, {4, "PICK"}, + {5, "DROP"}, {6, "INVENTORY"}, {7, "TALK"}, + {7, "SAY"}, {7, "ASK"}, + {8, "GIVE"}, {9, "DRINK"}, {9, "IMBIBE"}, + {9, "DRAIN"}, {10, "LOAD"}, {10, "RESTORE"}, + {11, "SAVE"}, {12, "BRIBE"}, {12, "PAY"}, + {13, "LOOK"}, {14, "BREAK"}, {15, "QUIT"}, + {15, "EXIT"}, {16, "SIT"}, {16, "SLEEP"}, + {17, "STAND"}, + + {18, "GO"}, {19, "INFO"}, {20, "UNDRESS"}, + {20, "DOFF"}, + {21, "DRESS"}, {21, "WEAR"}, {21, "DON"}, + {22, "PLAY"}, + {22, "STRUM"}, {23, "RING"}, {24, "HELP"}, + {25, "KENDAL"}, {26, "CAPYBARA"}, {27, "BOSS"}, + {255,"NINET"}, /* block for NINETY */ + {28, "URINATE"}, {28, "MINGITE"}, {29, "NINETY"}, + {30,"ABRACADABRA"},{30, "PLUGH"}, {30, "XYZZY"}, + {30, "HOCUS"}, {30, "POCUS"}, {30, "IZZY"}, + {30, "WIZZY"}, {30, "PLOVER"}, + {30,"MELENKURION"},{30, "ZORTON"}, {30, "BLERBI"}, + {30, "THURB"}, {30, "SNOEZE"}, {30, "SAMOHT"}, + {30, "NOSIDE"}, {30, "PHUGGG"}, {30, "KNERL"}, + {30, "MAGIC"}, {30, "KLAETU"}, {30, "VODEL"}, + {30, "BONESCROLLS"},{30, "RADOF"}, + + {31, "RESTART"}, + {32, "SWALLOW"}, {32, "EAT"}, {33, "LISTEN"}, + {33, "HEAR"}, {34, "BUY"}, {34, "PURCHASE"}, + {34, "ORDER"}, {34, "DEMAND"}, + {35, "ATTACK"}, {35, "HIT"}, {35, "KILL"}, + {35, "PUNCH"}, {35, "KICK"}, {35, "SHOOT"}, + {35, "FIRE"}, + + /* Passwords, 36: */ + + {36, "TIROS"}, {36, "WORDY"}, {36, "STACK"}, + {36, "SHADOW"}, {36, "OWL"}, {36, "ACORN"}, + {36, "DOMESDAY"}, {36, "FLOPPY"}, {36, "DIODE"}, + {36, "FIELD"}, {36, "COWSLIP"}, {36, "OSBYTE"}, + {36, "OSCLI"}, {36, "TIMBER"}, {36, "ADVAL"}, + {36, "NEUTRON"}, {36, "POSITRON"}, {36, "ELECTRON"}, + {36, "CIRCUIT"}, {36, "AURUM"}, {36, "PETRIFY"}, + {36, "EBBY"}, {36, "CATAPULT"}, {36, "GAMERS"}, + {36, "FUDGE"}, {36, "CANDLE"}, {36, "BEEB"}, + {36, "MICRO"}, {36, "SESAME"}, {36, "LORDSHIP"}, + + {37, "DIR"}, {37, "LS"}, {38, "DIE"}, + {39, "SCORE"}, + {40, "PUT"}, {40, "INSERT"}, {41, "KISS"}, + {41, "SNOG"}, {41, "CUDDLE"}, {42, "CLIMB"}, + {42, "CLAMBER"}, {43, "JUMP"}, {44, "HIGHSCORES"}, + {44, "HISCORES"}, {45, "WAKEN"}, {45, "AWAKEN"}, + {46, "HELLO"}, {46, "HI"}, {46, "YO"}, + {47, "THANKS"}, /* = 47, "ta", which was defined earlier. */ + + +/* Nouns - Objects: 50-100. */ + + {50, "WINE"}, {50, "BOOZE"}, {50,"NASTY"}, + {50, "VINEGAR"}, {51, "MONEYBAG"}, + {51, "BAG"}, {51, "CASH"}, {51,"DOSH"}, + {51, "WALLET"}, + {52, "BODKIN"}, {52, "DAGGER"}, {53,"POTION"}, + {54, "CHASTITY"}, {54, "BELT"}, {55,"BOLT"}, + {55, "ARROW"}, {55, "DART"}, + {56, "CROSSBOW"}, {56, "BOW"}, {57,"LUTE"}, + {58, "PILGRIM"}, {58, "BADGE"}, {59,"MUSHROOMS"}, + {59, "TOADSTOOLS"},{60, "KEY"}, {61,"BELL"}, + {62, "PRESCRIPT"}, {62, "SCROLL"}, {62,"MESSAGE"}, + {63, "PEN"}, {63, "QUILL"}, {64,"INK"}, + {64, "INKPOT"}, {65, "CLOTHES"}, {66,"HABIT"}, + {66, "DISGUISE"}, {67, "ONION"}, + + {99,"PASSWORD"}, + +/* Objects from Also are placed between 101 and 131. */ + +/* Nouns - People - Male, 150-174 */ + {150, "AVVY"}, {150,"AVALOT"}, {150,"YOURSELF"}, + {150, "ME"}, {150,"MYSELF"}, {151,"SPLUDWICK"}, + {151, "THOMAS"}, {151,"ALCHEMIST"}, {151,"CHEMIST"}, + {152, "CRAPULUS"}, {152,"SERF"}, {152,"SLAVE"}, + {158, "DU"}, /* <<< Put in early for Baron DU Lustie to save confusion with Duck & Duke.*/ + {152, "CRAPPY"}, {153,"DUCK"}, {153,"DOCTOR"}, + {154, "MALAGAUCHE"}, + {155, "FRIAR"}, {155,"TUCK"}, {156,"ROBIN"}, + {156, "HOOD"}, {157,"CWYTALOT"}, {157,"GUARD"}, + {157, "BRIDGEKEEP"},{158,"BARON"}, {158,"LUSTIE"}, + {159, "DUKE"}, {159,"GRACE"}, {160,"DOGFOOD"}, + {160, "MINSTREL"}, {161,"TRADER"}, {161,"SHOPKEEPER"}, + {161,"STALLHOLDER"}, + {162, "PILGRIM"}, {162,"IBYTHNETH"}, {163,"ABBOT"}, + {163, "AYLES"}, {164,"PORT"}, {165,"SPURGE"}, + {166, "JACQUES"}, {166,"SLEEPER"}, {166,"RINGER"}, + +/* Nouns- People - Female: 175-199 */ + {175, "WIFE"}, {175,"ARKATA"}, {176,"GEDALODAVA"}, + {176, "GEIDA"}, {176,"PRINCESS"}, {178,"WISE"}, + {178, "WITCH"}, + +/* Pronouns, 200-224 */ + {200, "HIM"}, {200,"MAN"}, {200,"GUY"}, + {200, "DUDE"}, {200,"CHAP"}, {200,"FELLOW"}, + {201, "HER"}, {201,"GIRL"}, {201,"WOMAN"}, + {202, "IT"}, {202,"THING"}, + + {203,"MONK"}, {204,"BARMAN"}, {204,"BARTENDER"}, + +/* Prepositions, 225-249 */ + {225, "TO"}, {226,"AT"}, {227,"UP"}, + {228, "INTO"}, {228,"INSIDE"}, {229,"OFF"}, + {230, "UP"}, {231,"DOWN"}, {232,"ON"}, + + +/* Please, 251 */ + {251, "PLEASE"}, + +/* About, 252 */ + {252, "ABOUT"}, {252, "CONCERNING"}, + +/* Swear words, 253 */ + /* I M P O R T A N T M E S S A G E + + DO *NOT* READ THE LINES BELOW IF YOU ARE OF A SENSITIVE + DISPOSITION. THOMAS IS *NOT* RESPONSIBLE FOR THEM. + GOODNESS KNOWS WHO WROTE THEM. + READ THEM AT YOUR OWN RISK. BETTER STILL, DON'T READ THEM. + WHY ARE YOU SNOOPING AROUND IN MY PROGRAM, ANYWAY? */ + + {253, "SHIT"}, {28 ,"PISS"}, {28 ,"PEE"}, + {253, "FART"}, {253,"FUCK"}, {253,"BALLS"}, + {253, "BLAST"}, {253,"BUGGER"}, {253,"KNICKERS"}, + {253, "BLOODY"}, {253,"HELL"}, {253,"DAMN"}, + {253, "SMEG"}, + /* and other even ruder words. You didn't read them, did you? Good. */ + +/* Answer-back smart-alec words, 249 */ + {249, "YES"}, {249,"NO"}, {249,"BECAUSE"}, + +/* Noise words, 255 */ + {255, "THE"}, {255,'A'}, {255,"NOW"}, + {255, "SOME"}, {255,"AND"}, {255,"THAT"}, + {255, "POCUS"}, {255,"HIS"}, + {255, "THIS"}, {255,"SENTINEL"}}}; /* for "Ken SENT Me" */ + +const char what[] = "That's not possible!"; + +const array<1,9,ranktype> ranks = +{{{0, "Beginner"}, {10, "Novice"}, +{20, "Improving"}, {35, "Not bad"}, +{50, "Passable"}, {65, "Good"}, +{80, "Experienced"}, {108, "The BEST!"}, +{maxint, "copyright'93"}}}; + + +#ifdef __acci_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN varying_string<11> thats; +EXTERN varying_string<20> unknown; +EXTERN array<1,11,varying_string<20> > realwords; +EXTERN char verb,person,thing,thing2; +EXTERN boolean polite; +#undef EXTERN +#define EXTERN extern + + +void clearwords(); +void parse(); +void lookaround(); +void opendoor(); +void do_that(); +void verbopt(char n, string& answer, char& anskey); +void have_a_drink(); + +#endif diff --git a/engines/avalanche/also.cpp b/engines/avalanche/also.cpp new file mode 100644 index 0000000000..17853e6189 --- /dev/null +++ b/engines/avalanche/also.cpp @@ -0,0 +1,1028 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Rodent.h"*/ +/*#include "Crt.h"*/ + +/*$R+,V-*/ + +typedef matrix<0,255,0,15,byte> fonttype; + +class fieldtype { +public: + integer x1,y1,x2,y2; +}; + +class linetype : public fieldtype { +public: + byte col; +}; + +struct pedtype { + integer x,y; byte dir; +}; + +struct magictype { + byte op; /* one of the operations */ + word data; /* data for them */ +}; + +const integer numlines = 50; const integer up = 0; const integer right = 1; const integer down = 2; const integer left = 3; const integer ur = 4; const integer dr = 5; const integer dl = 6; const integer ul = 7; +const integer still = 8; + +const integer nay = maxint; + +/* Magic commands are */ + +/*N*/ const integer nix = 0; /* ignore it if this line is touched */ +/*B*/ const integer bounce = 1; /* bounce off this line */ +/*E*/ const integer exclaim = 2; /* put up a chain of scrolls */ +/*T*/ const integer transport = 3; /* enter new room */ +/*U*/ const integer unfinished = 4; /* unfinished connection */ +/*S*/ const integer special = 5; /* special call */ +/*O*/ const integer opendoor = 6; /* slowly opening door. */ + +integer gd,gm; +array<1,numlines,linetype> lines; +array<1,numlines,fieldtype> fields; +boolean do1; +byte current; +string n; +matrix<0,29,1,2,string> names; +file<fonttype> f; +fonttype skinny; +byte tx,ty; +matrix<0,79,0,22,char> chars; +byte cursorflash; +array<1,15,pedtype> peds; +array<1,15,magictype> magics; +array<9,15,magictype> portals; +varying_string<26> flags; +string listen; + +const graphcursmasktype crosshairs = +{ + ((63551,63807,63807,63807,61727,257,897,32765,897,257,61727,63807,63807,63807,63551,65535), + (4368,21140,8840,53910,640,640,31868,33026,31868,640,640,53910,8840,21140,4368,0)), + 7, + 7}; + +const graphcursmasktype hook = +{ + ((32831,32831,49279,49279,57599,61695,61471,61447,63491,57089,36801,32771,49159,57375,63743,65535), + (0,16256,7936,7936,3584,1536,1792,2016,248,28,8220,12344,8160,1792,0,0)), + 2, + 9}; + +const graphcursmasktype tthand = +{ + ((62463,57855,57855,57855,57471,49167,32769,0,0,0,0,32768,49152,57344,61441,61443), + (3072,4608,4608,4608,4992,12912,21070,36937,36873,36865,32769,16385,8193,4097,2050,4092)), + 4, + 0}; + +string strf(longint x) +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +void glimpse(byte ret) /* glimpse of screen 3 */ +{ + char sink; +; + hidemousecursor; setvisualpage(3); setcrtpagenumber(3); showmousecursor; + do {; } while (!(~ anymousekeypressed)); + do {; } while (!anymousekeypressed); + hidemousecursor; setvisualpage(ret); setcrtpagenumber(ret); showmousecursor; + while (keypressed()) sink=readkey(); +} + +void newline(byte t, integer p,integer q,integer r,integer s, byte c) +{; + { + linetype& with = lines[t]; + ; + x1=p; y1=q; x2=r; y2=s; with.col=c; + } +} + +void newfield(byte t, integer p,integer q,integer r,integer s) +{; { + fieldtype& with = fields[t]; ; with.x1=p; with.y1=q; with.x2=r; with.y2=s; } } + +void drawped(byte p) +{; + { pedtype& with = peds[p]; + if (with.dir<177) + {; + setcolor(p); circle(with.x,with.y,5); moveto(with.x,with.y); + switch (with.dir) { + case up: linerel(0,-5); break; case down: linerel(0,5); break; + case left: linerel(-7,0); break; case right: linerel(7,0); break; + case ul: linerel(-7,-5); break; case dl: linerel(-7, 5); break; + case ur: linerel( 7,-5); break; case dr: linerel( 7, 5); break; + } + }} +} + +void drawup() +{ + byte fv; +; + cleardevice(); + for( fv=1; fv <= numlines; fv ++) + { linetype& with = lines[fv]; + if (x1!=nay) + {; + setcolor(with.col); + line(x1,y1,x2,y2); + }} + for( fv=1; fv <= numlines; fv ++) + { fieldtype& with = fields[fv]; + if (with.x1!=nay) + {; + setcolor(fv); + rectangle(with.x1,with.y1,with.x2,with.y2); + }} + for( fv=1; fv <= 15; fv ++) drawped(fv); +} + +void addped() +{ + byte n,fv; +; + n=0; do { n += 1; } while (!((n==16) || (peds[n].dir==177))); + setcrtpagenumber(0); setactivepage(0); setvisualpage(0); + drawup(); setgraphicscursor(tthand); showmousecursor; + do { + if (rightmousekeypressed) return; + if (keypressed()) glimpse(0); + } while (!leftmousekeypressed); + hidemousecursor; + { + pedtype& with = peds[n]; + ; + with.x=mousex; with.y=mousey; + } + cleardevice(); setfillstyle(6,9); for( fv=1; fv <= 3; fv ++) bar(200*fv,0,200*fv,200); + for( fv=1; fv <= 2; fv ++) bar(0,60*fv,640,60*fv); + showmousecursor; + do { if (rightmousekeypressed) return; } while (!leftmousekeypressed); + hidemousecursor; + { pedtype& with = peds[n]; + switch (((mousex / 200)*10)+(mousey / 60)) { + case 0: with.dir=ul; break; case 10: with.dir=up; break; case 20: with.dir=ur; break; + case 1: with.dir=left; break; case 11: with.dir=still; break; case 21: with.dir=right; break; + case 2: with.dir=dl; break; case 12: with.dir=down; break; case 22: with.dir=dr; break; + }} +} + +void addline(byte ccc) +{ + byte fv; +; + do { + for( fv=1; fv <= numlines; fv ++) + { linetype& with = lines[fv]; + if (x1==nay) + {; + x1=fv*17; x2=x1; y1=200; y2=190; with.col=ccc; + return; /* bad style! */ + }} + } while (!false); +} + +byte colour() +{ + byte fv; +byte colour_result; +; + setactivepage(0); setvisualpage(0); setcrtpagenumber(0); + outtextxy(0,0,"Select a colour, please..."); + for( fv=1; fv <= 15; fv ++) + {; + setfillstyle(1,fv); + bar(fv*40,27,39+fv*40,200); + } + showmousecursor; + do { + if (rightmousekeypressed) {; hidemousecursor; return colour_result; } + if (keypressed()) glimpse(2); + } while (!leftmousekeypressed); + hidemousecursor; + colour_result=getpixel(mousex,mousey); cleardevice(); +return colour_result; +} + +void addfield() +{ + byte fv; boolean ok; +; + do { + fv=colour(); + ok=fields[fv].x1==nay; + if (! ok) output << '\7'; + } while (!ok); + { + fieldtype& with = fields[fv]; + ; + with.x1=300+fv*17; with.x2=with.x1+1; with.y1=200; with.y2=177; + } +} + +byte checkline() +{ + byte fv,ans; +byte checkline_result; +; + setgraphicscursor(crosshairs); + setcrtpagenumber(0); setactivepage(0); setvisualpage(0); drawup(); + do { + showmousecursor; + do { + if (rightmousekeypressed) {; checkline_result=255; return checkline_result; } + if (keypressed()) glimpse(0); + } while (!leftmousekeypressed); + hidemousecursor; + setactivepage(1); ans=177; + for( fv=1; fv <= numlines; fv ++) /* */ + {; + { linetype& with = lines[fv]; + if (x1!=nay) + {; + setcolor( 9); line(x1,y1,x2,y2); + if (getpixel(mousex,mousey)==9) ans=fv; + setcolor( 0); line(x1,y1,x2,y2); + }} + { fieldtype& with = fields[fv]; + if (with.x1!=nay) + {; + setcolor( 9); rectangle(with.x1,with.y1,with.x2,with.y2); + if (getpixel(mousex,mousey)==9) ans=fv+100; + setcolor( 0); rectangle(with.x1,with.y1,with.x2,with.y2); + }} + } + setactivepage(0); + } while (!(ans!=177)); + checkline_result=ans; +return checkline_result; +} + +void chooseside(); +static boolean itsaline; + +static void plotline() +{; + if (itsaline) + { linetype& with = lines[gd]; + if (do1) line(mousex,mousey,x2,y2); else + line(x1,y1,mousex,mousey);} + else + { fieldtype& with = fields[gd]; + if (do1) rectangle(mousex,mousey,with.x2,with.y2); else + rectangle(with.x1,with.y1,mousex,mousey);} +} + +void chooseside() +{ + byte clicol,savelcol;fieldtype current; integer temp; +; + do { + gd=checkline(); itsaline=gd<100; + if (gd==255) {; hidemousecursor; return; } + if (! itsaline) gd -= 100; + setactivepage(2); setvisualpage(2); cleardevice(); + setgraphicscursor(tthand); setcrtpagenumber(2); + if (itsaline) + {; + current=lines[gd]; + savelcol=lines[gd].col; + } else current=fields[gd]; + {; + setcolor(9); + if (itsaline) line(current.x1,current.y1,current.x2,current.y2); else rectangle(current.x1,current.y1,current.x2,current.y2); + setcolor(9); + setfillstyle(1,red); bar(current.x1-3,current.y1-3,current.x1+3,current.y1+3); + setfillstyle(1,green); bar(current.x2-3,current.y2-3,current.x2+3,current.y2+3); + do {; } while (!(~ anymousekeypressed)); + clicol=177; showmousecursor; + do { + if (anymousekeypressed) + {; + hidemousecursor; + clicol=getpixel(mousex,mousey); + showmousecursor; + } + if (rightmousekeypressed) + {; hidemousecursor; return; } + if (keypressed()) glimpse(2); + } while (!(set::of(red,green, eos).has(clicol))); + do1=clicol==red; hidemousecursor; + setgraphicscursor(hook); setcrtpagenumber(0); + setactivepage(0); setvisualpage(0); setcolor(0); + if (itsaline) + { + linetype& with1 = lines[gd]; ; line(current.x1,current.y1,current.x2,current.y2); setcolor(with1.col); } else + { + fieldtype& with1 = fields[gd]; ; rectangle(with1.x1,with1.y1,with1.x2,with1.y2); setcolor(gd); } + setwritemode(xorput); + while (~ anymousekeypressed) + {; + plotline(); + showmousecursor; delay(1); hidemousecursor; + plotline(); + if (rightmousekeypressed) {; hidemousecursor; return; } + if (keypressed()) glimpse(0); + } + /* update "current" rec */ + if (do1) {; current.x1=mousex; current.y1=mousey; } + else {; current.x2=mousex; current.y2=mousey; } + if (! itsaline) + {; + if (current.x1>current.x2) {; temp=current.x2; current.x2=current.x1; current.x1=temp; } + if (current.y1>current.y2) {; temp=current.y2; current.y2=current.y1; current.y1=temp; } + } + /* copy "current" to line/field */ + if (itsaline) + { + linetype& with1 = lines[gd]; + ; + current.x1=current.x1; current.x2=current.x2; current.y1=current.y1; current.y2=current.y2; + with1.col=savelcol; + } else fields[gd]=current; + } + setwritemode(0); + } while (!false); +} + +void delped() +{; + setcrtpagenumber(0); setactivepage(0); setvisualpage(0); + drawup(); setgraphicscursor(tthand); showmousecursor; + do {; } while (!leftmousekeypressed); peds[colour()].dir=177; +} + +byte menu(); + +static void say(byte y, string x) +{; + setfillstyle(1,y); + bar(0,y*17,100,y*17+15); outtextxy(123,y*17,x); +} + +byte menu() +{ + byte clicol; +byte menu_result; +; + setcolor(15); settextstyle(0,0,2); clicol=0; setgraphicscursor(tthand); + setvisualpage(2); setactivepage(2); setcrtpagenumber(2); cleardevice(); + say(3,"Move lines around"); + say(4,"Add a new line"); + say(5,"Delete a line"); + say(6,"Add a ped"); + say(7,"Delete a ped"); + say(8,"Add a field"); + say(10,"Return to Also."); + showmousecursor; + do { + if (leftmousekeypressed) + {; + hidemousecursor; + clicol=getpixel(mousex,mousey); + showmousecursor; + } + if (rightmousekeypressed) {; hidemousecursor; return menu_result; } + if (keypressed()) glimpse(2); + } while (!(clicol>0)); + do {; } while (!(~ anymousekeypressed)); + hidemousecursor; + menu_result=clicol; +return menu_result; +} + +void removeline() +{; + gd=checkline(); if (gd==255) {; hidemousecursor; return; } + if (gd>100) + fields[gd-100].x1=nay; + else lines[gd].x1=nay; /* cancels it out */ + cleardevice(); drawup(); +} + +void lino() +{; + resetmouse; + do { + switch (menu()) { + case 3: chooseside(); break; + case 4: addline(colour()); break; + case 5: removeline(); break; + case 6: addped(); break; + case 7: delped(); break; + case 8: addfield(); break; + case 10: return; break; + } + } while (!false); +} + +void loadscreen() /* load2 */ +{ + byte a /*absolute $A000:246560*/; + byte bit; + untyped_file f; +; + setactivepage(3); setvisualpage(3); + assign(f,string("c:\\avalot\\place")+n+".avd"); reset(f,1); seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a,12080); + } + close(f); + setvisualpage(0); + outtextxy(0,190,"Look carefully, and then press any key..."); + setactivepage(0); +} + +void ctrlsout(string& x) /* Replace real ctrls with caret codes */ +{ + byte fv; string xx; +; + xx=""; + for( fv=1; fv <= length(x); fv ++) + if (x[fv]>'\37') xx=xx+x[fv]; else xx=xx+'^'+chr(ord(x[fv])+64); + x=xx; +} + +void ctrlsin(string& x) /* Opposite of ctrlsout */ +{ + byte fv; string xx; boolean ctrlwas; +; + xx=""; ctrlwas=false; + for( fv=1; fv <= length(x); fv ++) + if (ctrlwas) /* last char was a caret */ + {; + xx=xx+chr(ord(upcase(x[fv]))-64); + ctrlwas=false; + } + else + {; /* last char wasn't a caret... */ + if (x[fv]=='^') ctrlwas=true; else /* ...but this one is */ + xx=xx+x[fv]; /* ...but this one isn't */ + } + x=xx; +} + +void flipover() /* temp view other screen */ +{ + char r; +; + setvisualpage(3); r=readkey(); setvisualpage(0); +} + +void plotchar(byte x,byte y, char n) +{ + byte fv; +; + if (chars[x][y]==n) return; + for( fv=0; fv <= 15; fv ++) + mem[0xa000*y*1200+(fv+3)*80+x]=skinny[ord(n)][fv]; + chars[x][y]=n; +} + +void cursor() +{ + byte fv; +; + cursorflash += 1; + switch (cursorflash) { + case 1:case 127: for( fv=12; fv <= 14; fv ++) + mem[0xa000*ty*1200+(3+fv)*80+tx]=~(mem[0xa000*ty*1200+(3+fv)*80+tx]); + break; + case 255: cursorflash=0; break; + } +} + +void losecursor() +{; + if (cursorflash<127) {; cursorflash=126; cursor(); } + cursorflash=0; +} + +void gwrite(string x) +{ + byte fv; +; + for( fv=1; fv <= length(x); fv ++) + {; + plotchar(tx,ty,x[fv]); + tx += 1; + if (tx==80) {; ty += 1; tx=0; } + } +} + +string typein(string x) +{ + const char marker = '\2'; + byte p; char r; +string typein_result; +; + setvisualpage(0); setactivepage(0); cleardevice(); + settextstyle(0,0,1); setcolor(15); + outtextxy( 0, 0,"Press TAB to see the room..."); + outtextxy( 0, 20,"You may use any of these Control Codes:"); + outtextxy(30, 30,"Anywhere: ^M = new line, ^P = new scroll, |1 fix to speaker 1."); + outtextxy(90, 40,"^B = new bubble"); + outtextxy(30, 50,"At end of line: ^C = centre line, ^L = left justify."); + outtextxy(30, 60,"At end of scroll: ^D = Don't add automatic ^P here."); + outtextxy( 0, 80,"(Use by typing in (eg for ^P) ^ then P, not Ctrl-P.)"); + p=0; ctrlsout(x); fillchar(chars,sizeof(chars),'\40'); + do { + tx=0; ty=6; gwrite(x+'\4'+'\40'); + tx=(p % 80); ty=(p / 80)+6; + while (! keypressed()) {; delay(1); cursor(); } losecursor(); + r=readkey(); + switch (r) { + case '\10': if (p>0) {; x=copy(x,1,p-1)+copy(x,p+1,255); p -= 1; } break; /* backspace */ + case '\11': flipover(); break; + case '\40' ... '\377': {; x=copy(x,1,p)+r+copy(x,p+1,255); p += 1; } break; + case '\0': switch (readkey()) { /* extd. keystroke */ + case 'G': p=0; break; /* Home */ + case 'K': if (p>0) p -= 1; break; /* left */ + case 'M': if (p<length(x)) p += 1; break; /* right */ + case 'H': if (p>80) p -= 80; break; /* up */ + case 'P': if (p<length(x)-80) p += 80; break; /* down */ + case 'O': p=length(x); break; /* End */ + case 'S': x=copy(x,1,p)+copy(x,p+2,255); break; /* Del */ + } + break; + } + } while (!(r=='\15')); + ctrlsin(x); typein_result=x; +return typein_result; +} + +byte typeno(string title) +{ + varying_string<2> x; char r; integer e; word p; +byte typeno_result; +; + cleardevice(); x="000"; + settextstyle(0,0,3); setcolor(9); outtextxy(0,0,title); + setfillstyle(1,0); setcolor(10); fillchar(chars,sizeof(chars),'\40'); + do { + bar(100,100,150,125); + outtextxy(100,100,x); + do { r=readkey(); } while (!(set::of(range('0','9'),'\33','\15', eos).has(r))); + if (r=='\33') {; typeno_result=255; return typeno_result; } + if (r!='\15') x=string(x[2])+r; + } while (!(r=='\15')); + val(x,p,e); typeno_result=p; +return typeno_result; +} + +void showallnames() +{ + byte fv; varying_string<2> s; char r; +; + settextstyle(0,0,2); cleardevice(); setcolor(13); outtextxy(0,0,"Descriptions start..."); + settextstyle(0,0,1); setcolor(7); + for( fv=1; fv <= 29; fv ++) + {; + str(fv,2,s); + outtextxy((fv / 15)*320,((fv % 15)*10)+30,s+'='+copy(names[fv][1],0,33)); + } + setcolor(15); outtextxy(500,190,"Press any key..."); + r=readkey(); +} + +void showallassoc(); + + +static void saascreen() +{; + settextstyle(0,0,2); cleardevice(); setcolor(10); outtextxy(0,0,"Everything..."); + settextstyle(0,0,1); setcolor(2); + outtextxy(17,20,"(Format: <number> : <start of names> : <start of desc.>)"); +} + +void showallassoc() +{ + byte fv; varying_string<2> s; char r; + +; + saascreen(); + for( fv=1; fv <= 30; fv ++) + {; + str(fv-1,2,s); + outtextxy(0,(((fv-1) % 10)*10)+30, + s+':'+copy(names[fv-1][1],1,7)+':'+copy(names[fv-1][2],1,70)); + if ((fv % 10)==0) {; r=readkey(); saascreen(); } + } + setcolor(15); outtextxy(500,190,"Press any key..."); + r=readkey(); +} + +void clear() +{ + byte fv; +; + fillchar(names ,sizeof(names ), '\0'); + for( fv=1; fv <= numlines; fv ++) {; lines[fv].x1=nay; fields[fv].x1=nay; } + fillchar(peds ,sizeof(peds ),'\261'); +} + +void scramble(); + +static void scram1(string& x) +{ + byte fz; +; + for( fz=1; fz <= length(x); fz ++) + x[fz]=chr(ord(x[fz]) ^ 177); +} + +void scramble() /* Works both ways. */ +{ + byte fv,ff; +; + for( fv=0; fv <= 29; fv ++) + for( ff=1; ff <= 2; ff ++) + scram1(names[fv][ff]); + scram1(listen); + scram1(flags); +} + +void save() +{ + string x; untyped_file f; byte minnames,minlines,minpeds,minfields,fv,ff; +; + minnames =0; for( fv=0; fv <= 29; fv ++) if (names[fv][1]!="") minnames =fv; + minlines =0; for( fv=1; fv <= numlines; fv ++) + if (lines[fv].x1!=nay) minlines =fv; + minpeds =0; for( fv=1; fv <= 15; fv ++) if (peds[fv].dir<177) minpeds =fv; + minfields=0; for( fv=1; fv <= 30; fv ++) if (fields[fv].x1!=nay) minfields=fv; + assign(f,string("c:\\avalot\\also")+n+".avd"); + rewrite(f,1); + x=string("This is an Also .AVD file, which belongs to AVALOT.EXE. Its contents")+ + '\15'+'\12'+"are subject to copyright, so there. Have fun!"+'\32'+" *Minstrel* "; + blockwrite(f,x[1],128); + scramble(); + blockwrite(f,minnames,1); + for( fv=0; fv <= minnames; fv ++) + for( ff=1; ff <= 2; ff ++) + blockwrite(f,names[fv][ff],length(names[fv][ff])+1); + blockwrite(f,minlines,1); + blockwrite(f,lines,sizeof(lines[1])*minlines); + blockwrite(f,minpeds,1); + blockwrite(f,peds,sizeof(peds[1])*minpeds); + blockwrite(f,minfields,1); + blockwrite(f,fields,sizeof(fields[1])*minfields); + blockwrite(f,magics,sizeof(magics)); + blockwrite(f,portals,sizeof(portals)); + blockwrite(f,flags,sizeof(flags)); + blockwrite(f,listen[0],1); + blockwrite(f,listen[1],length(listen)); + close(f); + scramble(); +} + +void load(); +static untyped_file f; + + +static string nextstring() +{ + byte l; string x; +string nextstring_result; +; + x=""; blockread(f,l,1); blockread(f,x[1],l); x[0]=chr(l); nextstring_result=x; +return nextstring_result; +} + +void load() +{ + byte minnames,minlines,minpeds,minfields; byte ff,fv; + +; + clear(); + assign(f,string("c:\\avalot\\also")+n+".avd"); +/*$I-*/ reset(f,1); /*$I+*/ if (ioresult!=0) return; /* no Also file */ + seek(f,128); blockread(f,minnames,1); + for( fv=0; fv <= minnames; fv ++) + for( ff=1; ff <= 2; ff ++) + names[fv][ff]=nextstring(); + blockread(f,minlines,1); + blockread(f,lines,sizeof(lines[1])*minlines); + blockread(f,minpeds,1); + blockread(f,peds,sizeof(peds[1])*minpeds); + blockread(f,minfields,1); + blockread(f,fields,sizeof(fields[1])*minfields); + blockread(f,magics,sizeof(magics)); + blockread(f,portals,sizeof(portals)); + blockread(f,flags,sizeof(flags)); + blockread(f,listen[0],1); + blockread(f,listen[1],length(listen)); + close(f); + scramble(); +} + +void editmagics(); +const array<1,15,char> codes = "123456789ABCDEF"; + +static integer y; + + +static void display() +{ + byte fv; +; + cleardevice(); + settextstyle(0,0,2); setcolor(15); outtextxy(0,0,"Magics."); + settextstyle(0,0,1); + for( fv=1; fv <= 15; fv ++) + {; + y=23+fv*10; + setcolor(fv); outtextxy(100,y,string('$')+codes[fv-1]); + { + magictype& with = magics[fv]; + ; + switch (with.op) { + case nix: {; setcolor(8); outtextxy(140,y,"Nix"); } break; + case bounce: {; setcolor(10); outtextxy(143,y,"Bounce!"); } break; + case exclaim: {; + setcolor(14); outtextxy(143,y,string("Exclaim: ")+strf(with.data)); + } + break; + case transport: {; + setcolor(12); + outtextxy(143,y,string("Transport to ")+strf(hi(with.data))+ + ", ped "+strf(lo(with.data))); + } + break; + case unfinished: {; + setcolor(15); outtextxy(143,y,"*** UNFINISHED! ***"); + } + break; + case special: {; + setcolor(6); outtextxy(143,y,string("Special call no. ")+strf(with.data)); + } + break; + case opendoor: {; + setcolor(11); + outtextxy(143,y,string("Opening door to ")+strf(hi(with.data))+ + ", ped "+strf(lo(with.data))); + } + break; + } + } + } + outtextxy(177,190,"Which do you want to change\? (Esc=Exit) $"); +} + + + +static word ask(string x) +{ + string q; word thomaswashere; integer e; +word ask_result; +; + cleardevice(); + setcolor(10); settextstyle(0,0,3); outtextxy(0,100,x); + do { + input >> q >> NL; val(q,thomaswashere,e); + } while (!(e==0)); ask_result=thomaswashere; +return ask_result; +} + +void editmagics() +{ + char r,rr; byte p; + +; + do { + display(); + do { + r=upcase(readkey()); + if (r=='\33') return; + p=pos(r,codes); /* which are we editing? */ + } while (!(p>0)); /* it must BE there... */ + setcolor(p); cleardevice(); + outtextxy(177,17,string("Editing magic $")+r+'.'); + outtextxy(0,30,"New operation ( (N)ix, (B)ounce, (E)xclaim, (T)ransport, (U)nfinished),"); + outtextxy(30,40,"(S)pecial, (O)pening Door?"); + do { rr=upcase(readkey()); } while (!(set::of('N','B','E','T','U','S','O','\33', eos).has(rr))); + { magictype& with = magics[p]; + switch (rr) { + case '\33': return; break; /* cancelling code */ + case 'N': with.op=nix; break; + case 'B': with.op=bounce; break; + case 'E': {; with.op=exclaim; with.data=ask("Which scroll?"); } break; + case 'T': {; with.op=transport; with.data=ask("Ped no.?")+ask("Whither?")*256; } break; + case 'U': with.op=unfinished; break; + case 'S': {; with.op=special; with.data=ask("Which call?"); } break; + case 'O': {; with.op=opendoor; with.data=ask("Ped no.?")+ask("Whither?")*256; } break; + }} + } while (!false); +} + +void editportals(); +const array<9,15,char> codes1 = "9ABCDEF"; + +static integer y2; + + +static void display1() +{ + byte fv; +; + cleardevice(); + settextstyle(0,0,2); setcolor(15); outtextxy(0,0,"Portals."); + settextstyle(0,0,1); + for( fv=9; fv <= 15; fv ++) + {; + y2=fv*10-53; + setcolor(fv); outtextxy(100,y2,string('$')+codes1[fv-1]); + { + magictype& with = portals[fv]; + ; + switch (with.op) { + case nix: {; setcolor(8); outtextxy(140,y2,"Nix"); } break; + case exclaim: {; + setcolor(14); outtextxy(143,y2,string("Exclaim: ")+strf(with.data)); + } + break; + case transport: {; + setcolor(12); + outtextxy(143,y2,string("Transport to ")+strf(hi(with.data))+ + ", ped "+strf(lo(with.data))); + } + break; + case unfinished: {; + setcolor(15); outtextxy(143,y2,"*** UNFINISHED! ***"); + } + break; + case special: {; + setcolor(6); outtextxy(143,y2,string("Special call no. ")+strf(with.data)); + } + break; + case opendoor: {; + setcolor(11); + outtextxy(143,y2,string("Opening door to ")+strf(hi(with.data))+ + ", ped "+strf(lo(with.data))); + } + break; + } + } + } + outtextxy(177,190,"Which do you want to change\? (Esc=Exit) $"); +} + + + +static word ask1(string x) +{ + string q; word thomaswashere; integer e; +word ask1_result; +; + cleardevice(); + setcolor(10); settextstyle(0,0,3); outtextxy(0,100,x); + do { + input >> q >> NL; val(q,thomaswashere,e); + } while (!(e==0)); ask1_result=thomaswashere; +return ask1_result; +} + +void editportals() /* much t'same as editmagics */ +{ + char r,rr; byte p; + +; + do { + display1(); + do { + r=upcase(readkey()); + if (r=='\33') return; + p=pos(r,codes1); /* which are we editing? */ + } while (!(p>0)); /* it must BE there... */ + p += 8; setcolor(p); cleardevice(); + outtextxy(177,17,string("Editing portal $")+r+'.'); + outtextxy(0,30,"New operation ( (N)ix, (E)xclaim, (T)ransport, (U)nfinished),"); + outtextxy(30,40,"(S)pecial, (O)pening Door?"); + do { rr=upcase(readkey()); } while (!(set::of('N','E','T','U','S','O','\33', eos).has(rr))); + { magictype& with = portals[p]; + switch (rr) { + case '\33': return; break; /* cancelling code */ + case 'N': with.op=nix; break; + case 'E': {; with.op=exclaim; with.data=ask1("Which scroll?"); } break; + case 'T': {; with.op=transport; with.data=ask1("Ped no.?")+ask1("Whither?")*256; } break; + case 'U': with.op=unfinished; break; + case 'S': {; with.op=special; with.data=ask1("Which call?"); } break; + case 'O': {; with.op=opendoor; with.data=ask1("Ped no.?")+ask1("Whither?")*256; } break; + }} + } while (!false); +} + +void editflags() +{ + char r; +; + cleardevice(); + settextstyle(0,0,2); setcolor(15); outtextxy(0,0,"Flags."); + settextstyle(0,0,1); setcolor(10); + outtextxy(100,30,"Press the letter of the flag you want to toggle."); + outtextxy(100,40,"Tab = flip screens, Esc/Enter = return to menu."); + setcolor(14); setfillstyle(1,0); + for( r='A'; r <= 'Z'; r ++) + if (pos(r,flags)>0) outtextxy(ord(r)*20-1223,77,r); + do { + do { r=upcase(readkey()); } while (!(set::of(range('A','Z'),'\33','\15','\11', eos).has(r))); + switch (r) { + case RANGE_26('A','Z'): {; + if (pos(r,flags)>0) + {; /* flag is on- switch it off */ + Delete(flags,pos(r,flags),1); + bar(ord(r)*20-1223,77,ord(r)*20-1213,87); + sound(1777); delay(7); nosound; + } else + {; /* flag is off- switch it on */ + flags=flags+r; + outtextxy(ord(r)*20-1223,77,r); + sound(177); delay(7); nosound; + } + } + break; + case '\33':case '\15': return; break; + case '\11': flipover(); break; + } + } while (!false); +} + +void alsomenu() +{ + char r; byte t; +; + do { + setactivepage(0); setvisualpage(0); + cleardevice(); setcolor(15); settextstyle(0,0,2); + outtextxy(0,0,"Also... Main Menu"); + settextstyle(0,0,1); setcolor(10); + outtextxy(100, 40,"1) Edit the names of an object"); + outtextxy(100, 50,"2) View all names"); + outtextxy(100, 60,"3) Edit the description of this object"); + outtextxy(100, 70,"4) View all associations."); + outtextxy(100, 80,"5) Enter Lino mode."); + outtextxy(100, 90,"6) Edit magics."); + outtextxy(100,100,"7) Edit portals."); + outtextxy(100,110,"8) Edit flags."); + outtextxy(100,120,"9) Edit listen field."); + outtextxy(100,160,"S) Save"); + outtextxy(100,170,"L) Load"); + outtextxy( 80,180,"Tab) View other screen"); + if (current==0) outtextxy(0,140,"< Main description of room >"); else + outtextxy(0,140,string('<')+names[current][1]+'>'); + do { + r=upcase(readkey()); if (r=='\11') flipover(); + } while (!(set::of(range('1','9'),'S','L','\0', eos).has(r))); + switch (r) { + case '1': {; + do { + t=typeno("Which object\? (0-30)"); + } while (!((t<30) || (t==255))); + if ((t!=255) && (t!=0)) names[t][1]=typein(names[t][1]); + current=t; + } + break; + case '2': showallnames(); break; + case '3': names[current][2]=typein(names[current][2]); break; + case '4': showallassoc(); break; + case '5': lino(); break; + case '6': editmagics(); break; + case '7': editportals(); break; + case '8': editflags(); break; + case '9': listen=typein(listen); break; + case 'S': save(); break; + case 'L': load(); break; + case '\0': if (readkey()=='\55') return; break; + } + } while (!false); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + output << "*** ALSO ***" << NL; + output << NL; + output << "No. of screen to edit?"; input >> n >> NL; load(); + assign(f,"v:avalot.fnt"); reset(f); f >> skinny; close(f); + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); current=0; + loadscreen(); + alsomenu(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/andexor.cpp b/engines/avalanche/andexor.cpp new file mode 100644 index 0000000000..03cedfdfcc --- /dev/null +++ b/engines/avalanche/andexor.cpp @@ -0,0 +1,122 @@ +#include "ptoc.h" + + /* Trippancy IV - original file */ +#include "graph.h" + +const integer taboo = cyan; + +struct adxtype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of all the pictures */ +}; + + +integer gd,gm; +adxtype adx; +matrix<1,24,0,1,pointer> adxpic; /* the pictures themselves */ +untyped_file f; string x; byte n; + +void load(string nam) +{ + byte z; + array<1,4,pointer> a; + untyped_file f; word s; + varying_string<40> xxx; + string check; + +; + assign(f,nam); + reset(f,1); + blockread(f,xxx,41); + blockread(f,check,13); + blockread(f,check,31); + s=imagesize(0,0,getmaxx(),75); + for( z=1; z <= 2; z ++) + {; + getmem(a[z],s); + blockread(f,a[z],s); + putimage(0,15+(z-1)*75,a[z],0); + freemem(a[z],s); + } + close(f); +} + +void silhouette() +{ + byte x,y,c; +; + setvisualpage(1); setactivepage(1); setfillstyle(1,15); + for( gm=0; gm <= 3; gm ++) + for( gd=1; gd <= 6; gd ++) + {; /* 26,15 */ +/* bar((gm div 2)*320+gd*40,20+(gm mod 2)*40,(gm div 2)*320+gd*40+35,(gm mod 2)*40+60); */ + for( y=1; y <= adx.yl; y ++) + for( x=1; x <= adx.xl; x ++) + {; + setactivepage(0); + c=getpixel((gm / 2)*320+gd*40+x,20+(gm % 2)*40+y); + setactivepage(1); +/* if c<>taboo then putpixel((gm div 2)*320+gd*40+x,20+(gm mod 2)*40+y,0); */ + if (c==taboo) putpixel((gm / 2)*320+gd*40+x,20+(gm % 2)*40+y,15); + } + getmem(adxpic[gm*6+gd][0],adx.size); + getimage((gm / 2)*320+gd*40+1,20+(gm % 2)*40+1, + (gm / 2)*320+gd*40+adx.xl,20+(gm % 2)*40+adx.yl, + adxpic[gm*6+gd][0]); + } +} + +void standard() +{ + byte x,y,c; +; + setvisualpage(2); setactivepage(2); + for( gm=0; gm <= 3; gm ++) + for( gd=1; gd <= 6; gd ++) + {; /* 26,15 */ + for( y=1; y <= adx.yl; y ++) + for( x=1; x <= adx.xl; x ++) + {; + setactivepage(0); + c=getpixel((gm / 2)*320+gd*40+x,20+(gm % 2)*40+y); + setactivepage(2); + if (c!=taboo) putpixel((gm / 2)*320+gd*40+x,20+(gm % 2)*40+y,c); + } + getmem(adxpic[gm*6+gd][1],adx.size); + getimage((gm / 2)*320+gd*40+1,20+(gm % 2)*40+1, + (gm / 2)*320+gd*40+adx.xl,20+(gm % 2)*40+adx.yl, + adxpic[gm*6+gd][1]); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); fillchar(adxpic,sizeof(adxpic),'\261'); + load("v:avalots.avd"); +/* getmem(adxpic[1,1,1],adx.size); getimage(40,20,75,60,adxpic[1,1,1]^); + putimage(100,100,adxpic[1,1,1]^,0); */ + {; + adx.name="Avalot"; + adx.num=24; adx.seq=6; + adx.xl=32; adx.yl=35; /* 35,40 */ + + adx.size=imagesize(40,20,40+adx.xl,60+adx.yl); + } + silhouette(); + standard(); + x=string("Sprite file for Avvy - Trippancy IV. Subject to copyright.")+'\32'; + assign(f,"v:sprite1.avd"); + rewrite(f,1); + blockwrite(f,x[1],59); + blockwrite(f,adx,sizeof(adx)); + for( gd=1; gd <= adx.num; gd ++) + for( gm=0; gm <= 1; gm ++) + blockwrite(f,adxpic[gd][gm],adx.size); /* next image */ + close(f); + closegraph(); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/andexor2.cpp b/engines/avalanche/andexor2.cpp new file mode 100644 index 0000000000..41f27af209 --- /dev/null +++ b/engines/avalanche/andexor2.cpp @@ -0,0 +1,133 @@ +#include "ptoc.h" + + /* Trippancy IV - original file */ +#include "graph.h" + +const integer taboo = cyan; + +struct adxtype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of all the pictures */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + + +integer gd,gm; +adxtype adx; +array<0,1,pointer> adxpic; /* the pictures themselves */ +untyped_file f; string x; byte n; integer side2; word bigsize; + +void load(string n) +{ + byte z; + array<1,4,pointer> a; + untyped_file f; word s; + varying_string<40> xxx; + string check; + +; + assign(f,n); + reset(f,1); + blockread(f,xxx,41); + blockread(f,check,13); + blockread(f,check,31); + s=imagesize(0,0,getmaxx(),75); + for( z=1; z <= 2; z ++) + {; + getmem(a[z],s); + blockread(f,a[z],s); + putimage(0,15+(z-1)*75,a[z],0); + freemem(a[z],s); + } + close(f); +} + +void silhouette() +{ + byte x,y,c; +; + setvisualpage(1); setactivepage(1); setfillstyle(1,15); + {; + for( gm=0; gm <= 3; gm ++) + for( gd=1; gd <= 6; gd ++) + {; /* 26,15 */ + side2=adx.xl*6; + for( y=1; y <= adx.yl; y ++) + for( x=1; x <= adx.xl; x ++) + {; + setactivepage(0); + c=getpixel((gm / 2)*320+gd*40+x,20+(gm % 2)*40+y); + setactivepage(1); + if (c==taboo) + putpixel((gm / 2)*side2+gd*adx.xl+x,20+(gm % 2)*adx.yl+y,15); + } + } + bigsize=imagesize(adx.xl+1,21,adx.xl*13,20+adx.yl*2); + getmem(adxpic[0],bigsize); + getimage(adx.xl+1,21,adx.xl*13,20+adx.yl*2,adxpic[0]); + putimage(adx.xl+1,21,adxpic[0],notput); + } +} + +void standard() +{ + byte x,y,c; +; + setvisualpage(2); setactivepage(2); + {; + for( gm=0; gm <= 3; gm ++) + for( gd=1; gd <= 6; gd ++) + {; /* 26,15 */ + for( y=1; y <= adx.yl; y ++) + for( x=1; x <= adx.xl; x ++) + {; + setactivepage(0); + c=getpixel((gm / 2)*320+gd*40+x,20+(gm % 2)*40+y); + setactivepage(2); + if (c!=taboo) + putpixel((gm / 2)*side2+gd*adx.xl+x,20+(gm % 2)*adx.yl+y,c); + } +/* getmem(adxpic[gm*6+gd,1],adx.size); + getimage((gm div 2)*side2+gd*xl+x,20+(gm mod 2)*yl+y, + (gm div 2)*side2+gd*xl*2+x,20+(gm mod 2)*yl*2+y, + adxpic[gm*6+gd,1]^); */ + } + getmem(adxpic[1],bigsize); + getimage(adx.xl+1,21,adx.xl*13,20+adx.yl*2,adxpic[1]); + putimage(adx.xl+1,21,adxpic[1],notput); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); fillchar(adxpic,sizeof(adxpic),'\261'); + load("v:avalots.avd"); + {; + adx.name="Avalot"; + adx.num=24; adx.seq=6; + adx.xl=33; adx.yl=35; /* 35,40 */ + adx.fgc=yellow; adx.bgc=red; + + adx.size=imagesize(40,20,40+adx.xl,60+adx.yl); + } + silhouette(); + standard(); + x=string("Sprite file for Avvy - Trippancy IV. Subject to copyright.")+'\32'; + assign(f,"v:sprite1.avd"); + rewrite(f,1); + blockwrite(f,x[1],59); + blockwrite(f,adx,sizeof(adx)); + blockwrite(f,bigsize,2); + for( gm=0; gm <= 1; gm ++) + {; + putimage(0,0,adxpic[gm],0); + blockwrite(f,adxpic[gm],bigsize); /* next image */ + } + close(f); + closegraph(); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/andextst.cpp b/engines/avalanche/andextst.cpp new file mode 100644 index 0000000000..8aff7172d3 --- /dev/null +++ b/engines/avalanche/andextst.cpp @@ -0,0 +1,64 @@ +#include "ptoc.h" + + +#include "graph.h" + + +typedef matrix<1,24,0,1,pointer> adxtype; + +integer gd,gm; +word s; untyped_file f; byte n,anim,cp,t; +array<0,0,adxtype> adx; +array<0,1,pointer> back; +integer x; +array<0,1,integer> ox; + +void andex(integer x,integer y, byte n,byte num) +{; + putimage(x,y,adx[num][n][0],andput); + putimage(x,y,adx[num][n][1],xorput); +} + +void loadadx(byte num, string x) +{ + byte n; +; + assign(f,x); + reset(f,1); seek(f,59); + blockread(f,n,1); /* No. of images... */ + for( gd=1; gd <= n; gd ++) + for( gm=0; gm <= 1; gm ++) + {; + blockread(f,s,2); /* size of next image... */ + getmem(adx[num][gd][gm],s); + blockread(f,adx[num][gd][gm],s); /* next image */ + } + close(f); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + loadadx(0,"d:sprite0.avd"); + loadadx(1,"d:sprite0.avd"); + gd=3; gm=0; initgraph(gd,gm,""); + for( gd=0; gd <= 1; gd ++) + {; + setactivepage(gd); setfillstyle(6,1); bar(0,0,640,200); + getmem(back[gd],s); + } + x=0; anim=1; cp=0; t=2; setactivepage(0); + do { + setactivepage(cp); setvisualpage(1-cp); + for( gm=0; gm <= 1; gm ++) + {; + if (t>0) t -= 1; else + putimage(ox[cp],77,back[cp],copyput); + getimage(x,77,x+31,77+35,back[cp]); + andex(x,177,anim+6,gm); + ox[gm][cp]=x; x += 5; + } + anim += 1; if (anim==7) anim=1;cp=1-cp; + } while (!false); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/arch.cpp b/engines/avalanche/arch.cpp new file mode 100644 index 0000000000..1ff2f1fd2d --- /dev/null +++ b/engines/avalanche/arch.cpp @@ -0,0 +1,122 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + ENID Edna's manager. */ + +#define __arch_implementation__ + /* Loads/ saves files. */ + +#include "arch.h" + + +/*#include "Dos.h"*/ +#include "scrolls.h" + + +struct ednahead { /* Edna header */ + /* This header starts at byte offset 177 in the .ASG file. */ + array<1,9,char> id; /* signature */ + word revision; /* EDNA revision, here 2 (1=dna256) */ + varying_string<50> game; /* Long name, eg Lord Avalot D'Argent */ + varying_string<15> shortname; /* Short name, eg Avalot */ + word number; /* Game's code number, here 2 */ + word ver; /* Version number as integer (eg 1.00 = 100) */ + varying_string<5> verstr; /* Vernum as string (eg 1.00 = "1.00" */ + varying_string<12> filename; /* Filename, eg AVALOT.EXE */ + byte os; /* Saving OS (here 1=DOS. See below for others.) */ + + /* Info on this particular game */ + + varying_string<8> fn; /* Filename (not extension ('cos that's .ASG)) */ + byte d,m; /* D, M, Y are the Day, Month & Year this game was... */ + word y; /* ...saved on. */ + varying_string<40> desc; /* Description of game (same as in Avaricius!) */ + word len; /* Length of DNA (it's not going to be above 65535!) */ + + /* Quick reference & miscellaneous */ + + word saves; /* no. of times this game has been saved */ + integer cash; /* contents of your wallet in numerical form */ + varying_string<20> money; /* ditto in string form (eg 5/-, or 1 denarius)*/ + word points; /* your score */ + + /* DNA values follow, then footer (which is ignored) */ +}; + /* Possible values of edhead.os: + 1 = DOS 4 = Mac + 2 = Windows 5 = Amiga + 3 = OS/2 6 = ST */ +const string crlf = string('\15')+'\12'; + +const array<1,177,char> ednafirst = + string("This is an EDNA-based file, saved by a Thorsoft game. Good luck!")+crlf+ + '\32'+ /* 67 bytes... */ + crlf+crlf+ /* 71 bytes... */ + "12345678901234567890123456789012345678901234567890"+ + "12345678901234567890123456789012345678901234567890"+ + "123456"; + +const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; +const string ednaid = string("TT")+'\261'+'\60'+'\1'+'\165'+'\261'+'\231'+'\261'; + +const integer ttage = 18; +const char ttwashere[] = "Thomas was here "; + +void save(string name) +{ + untyped_file f; + edhead eh; + word groi; + string groi2; +; + fillchar(eh,sizeof(eh),'\261'); /* Fill up the edhead */ + + dna.saves += 1; /* It's been saved one more time... */ + + {; + + /* Info about this program */ + + id=ednaid; /* Edna's signature */ + revision=2; /* Second revision of .ASG format */ + game="Lord Avalot d'Argent"; /* Title of game */ + shortname="Avalot"; + number=2; /* Second Avvy game */ + ver=100; /* Version 1.00 */ + verstr="1.00"; /* ditto */ + filename="AVALOT.EXE"; /* program's filename */ + os=1; /* Saved under DOS */ + + /* Info on this particular game */ + + fsplit(name,groi2,fn,groi2); /* fn = filename of this game */ + getdate(d,m,y,groi); /* Day, month & year when the game was saved */ + desc=roomname; /* Description of game (same as in Avaricius!) */ + len=sizeof(dna); /* Length of DNA (it's not going to be above 65535!) */ + + /* Quick reference & miscellaneous */ + + saves=dna.saves; /* no. of times this game has been saved */ + cash=dna.pence; /* contents of your wallet in numerical form */ + money=lsd(); /* ditto in string form (eg 5/-, or 1 denarius)*/ + points=dna.score; /* your score */ + } + + assign(f,name); + rewrite(f,1); + + blockwrite(f,ednafirst,177); + blockwrite(f,eh,sizeof(eh)); + blockwrite(f,dna,sizeof(dna)); + + for( groi=1; groi <= ttage; groi ++) + blockwrite(f,ttwashere,sizeof(ttwashere)); + + close(f); +} + + diff --git a/engines/avalanche/arch.h b/engines/avalanche/arch.h new file mode 100644 index 0000000000..cb0960f9dd --- /dev/null +++ b/engines/avalanche/arch.h @@ -0,0 +1,10 @@ +#ifndef __arch_h__ +#define __arch_h__ + + +#include "gyro.h" + + +void save(string name); + +#endif diff --git a/engines/avalanche/avalot9.cpp b/engines/avalanche/avalot9.cpp new file mode 100644 index 0000000000..a439f87455 --- /dev/null +++ b/engines/avalanche/avalot9.cpp @@ -0,0 +1,114 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + AVALOT The kernel of the program. */ + + +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Trip5.h"*/ +/*#include "Gyro.h"*/ +/*#include "Lucerna.h"*/ +/*#include "Scrolls.h"*/ +/*#include "Basher.h"*/ +/*#include "Dropdown.h"*/ +/*#include "Pingo.h"*/ +/*#include "Logger.h"*/ +/*#include "Timeout.h"*/ +/*#include "Celer.h"*/ +/*#include "Enid.h"*/ +/*#include "Incline.h"*/ +/*#include "Closing.h"*/ +/*#include "Visa.h"*/ + + +void setup() +{ + integer gd,gm; + + checkbreak=false; visible=m_no; to_do=0; lmo=false; resetscroll; + Randomize(); setup_vmc; on_virtual; + gd=3; gm=0; initgraph(gd,gm,""); + holdthedawn=true; dusk; + cmp=177; mouse_init; /*on;*/ dropsok=true; ctrl=ckey; oldjw=177; + mousetext=""; c=999; settextjustify(0,0); ddmnow=false; load_digits; + cheat=false; cp=0; curpos=1; + quote=true; ledstatus=177; defaultled=2; +/* TSkellern:=0; { Replace with a more local variable sometime }*/ + dna.rw=stopped; enid_filename=""; /* undefined. */ + toolbar; state(2); copy03; lastscore="TJA"; + +/* for gd:=0 to 1 do + begin + setactivepage(gd); outtextxy(7,177,chr(48+gd)); + end;*/ + + loadtrip; + + if ((filetoload=="") & (~ reloaded)) + newgame; /* no game was requested- load the default */ + else { + if (~ reloaded) avvy_background; + standard_bar; sprite_run; + if (reloaded) edna_reload; else + { /* Filename given on the command line (or loadfirst) */ + edna_load(filetoload); + if (there_was_a_problem) + { + display("So let's start from the beginning instead..."); + holdthedawn=true; dusk; newgame; + } + } + } + + if (~ reloaded) + { + soundfx=~ soundfx; fxtoggle; + thinkabout(money,a_thing); + } + + get_back_loretta; gm=getpixel(0,0); setcolor(7); + holdthedawn=false; dawn; cursoron=false; cursor_on; newspeed; + + if (~ reloaded) + dixi('q',83); /* Info on the game, etc. */ +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + setup(); + + do { + + clock; + keyboard_link; + menu_link; + readstick; + force_numlock; + get_back_loretta; + trippancy_link; + pics_link; + checkclick; + + if (visible==m_virtual) plot_vmc(mx,my,cp); + flip_page; /* <<<! */ + slowdown; + if (visible==m_virtual) wipe_vmc(cp); + + one_tick; + + } while (!lmo); + + restorecrtmode(); + if (logging) close(logfile); + + end_of_program; + return EXIT_SUCCESS; +} + +/* typein; commanded; last:=current; */ diff --git a/engines/avalanche/avbkgrnd.cpp b/engines/avalanche/avbkgrnd.cpp new file mode 100644 index 0000000000..13e6ceaef8 --- /dev/null +++ b/engines/avalanche/avbkgrnd.cpp @@ -0,0 +1,88 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + /* Screen size: Starts at $A000:$320 (coords 0,10). + Length: 12000 (150*80) bytes. + If we divide it into sets of 5 lines (400 bytes) each, there are 30. + There are 40 words on a line. + + Patterns: + 4AAA = "AVVY" + AAAE + EAA4 + A444 + + A4AA = "YAVV" + AEAA + 4EAA + 4A44 */ +/* + asm + mov bx,$A000; + mov es,bx; { The segment to copy it to... } + mov di,$370; { The offset (10 pixels down, plus 1 offset.) } + + mov cx,10; + mov ax,$AA4A; call @sameline; { Print "AVVY" } + mov ax,$AEAA; call @sameline; + mov ax,$A4EA; call @sameline; + mov ax,$44A4; call @sameline; + + mov cx,9; + mov ax,$AAA4; call @sameline; { Print "YAVV" } + mov ax,$AAEA; call @sameline; + mov ax,$AA4E; call @sameline; + mov ax,$444A; call @sameline; + + mov ax,$4AAA; call @sameline; { Print "VYAV" } + mov ax,$AAAE; call @sameline; + mov ax,$EAA4; call @sameline; + mov ax,$A444; call @sameline; + + mov ax,$A4AA; call @sameline; { Print "VVYA" } + mov ax,$EAAA; call @sameline; + mov ax,$4EAA; call @sameline; + mov ax,$4A44; call @sameline; + + jmp @the_end; + + { Replicate the same line many times. } + + @sameline: + { Requires: + what to copy in AX, + how many lines in CX, and + original offset in DI. } + push cx; + push di; + + @samelineloop: + + push cx; + mov cx,40; { No. of times to repeat it on one line. } + + repz stosw; { Fast word-copying } + + pop cx; + + add di,1200; { The next one will be 16 lines down. } + + loop @samelineloop; + pop di; + add di,80; + pop cx; + + ret; + + @the_end: + end; +*/ +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/avmenu.cpp b/engines/avalanche/avmenu.cpp new file mode 100644 index 0000000000..3cfff7d8b6 --- /dev/null +++ b/engines/avalanche/avmenu.cpp @@ -0,0 +1,312 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Tommys.h"*/ + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +fonttype font; +word storage_seg,storage_ofs; +byte result; +string registrant; + +void icons() +{ + untyped_file f; + word gd,gm; byte bit; + byte v; + + assign(f,"menu.avd"); + reset(f,1); + + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( gd=70; gd <= 266; gd ++) + blockread(f,mem[0xa000*gd*80+6],9); + + for( gd=0; gd <= 32; gd ++) + { + blockread(f,v,1); + for( gm=0; gm <= 5; gm ++) + mem[0xa000*73+((70+gd+gm*33)*80)]=v; /* 79 */ + } + + } + close(f); + + bit=getpixel(0,0); + + setfillstyle(1, 7); for( gd=0; gd <= 5; gd ++) bar(114, 73+gd*33,583, 99+gd*33); + setfillstyle(1,15); for( gd=0; gd <= 5; gd ++) bar(114, 70+gd*33,583, 72+gd*33); + setfillstyle(1, 8); for( gd=0; gd <= 5; gd ++) bar(114,100+gd*33,583,102+gd*33); + +} + +void load_regi_info(); + + +static char decode1(char c) +{ + byte b; + + char decode1_result; + b=ord(c)-32; + decode1_result=chr(( (b & 0xf) << 3) + ((cardinal)(b & 0x70) >> 4)); + return decode1_result; +} + + + +static char decode2(char c) +{ + char decode2_result; + decode2_result=chr( ((ord(c) & 0xf) << 2) + 0x43); + return decode2_result; +} + + + +static boolean checker(string proper,string check) +{ + byte fv; boolean ok; + + boolean checker_result; + ok=true; + for( fv=1; fv <= length(proper); fv ++) + if ((ord(proper[fv]) & 0xf)!=((cardinal)(ord(check[fv])-0x43) >> 2)) + ok=false; + + checker_result=ok; + return checker_result; +} + +void load_regi_info() +{ + text t; + byte fv; + string x; + byte namelen,numlen; + string namechk,numchk; + string reginum; + + + /*$I-*/ + assign(t,"register.dat"); reset(t); + /*$I+*/ + + if (ioresult!=0) + { + registrant="(Unregistered evaluation copy.)"; + return; + } + + for( fv=1; fv <= 53; fv ++) t >> NL; + t >> x >> NL; + close(t); + + namelen=107-ord(x[1]); numlen=107-ord(x[2]); + + registrant=copy(x,3,namelen); + reginum=copy(x,4+namelen,numlen); + namechk=copy(x,4+namelen+numlen,namelen); + numchk=copy(x,4+namelen+numlen+namelen,numlen); + + for( fv=1; fv <= namelen; fv ++) registrant[fv]=decode1(registrant[fv]); + for( fv=1; fv <= numlen; fv ++) reginum[fv]=decode1(reginum[fv]); + + if ((! checker(registrant,namechk)) || (! checker(reginum,numchk))) + registrant="\?\"!\? ((.)"; + else + registrant=registrant+" ("+reginum+")."; + +} + +void flesh_colours() {; /* assembler; +asm + mov ax,$1012; + mov bx,21; { 21 = light pink (why?) */ + /* mov cx,1; + mov dx,seg @flesh; + mov es,dx; + mov dx,offset @flesh; + int $10; + + mov dx,seg @darkflesh; + mov es,dx; + mov dx,offset @darkflesh; + mov bx,5; { 5 = dark pink. */ + /*int $10; + + jmp @TheEnd; + + @flesh: + db 56,35,35; + + @darkflesh: + db 43,22,22; + + @TheEnd: */ + } + +void setup() +{ + integer gd,gm; + file<fonttype> ff; + + if (paramstr(1)!="jsb") exit(255); + checkbreak=false; + val(paramstr(2),storage_seg,gd); + val(paramstr(3),storage_ofs,gd); + + assign(ff,"avalot.fnt"); + reset(ff); ff >> font; close(ff); + + gd=3; gm=1; initgraph(gd,gm,""); + setvisualpage(1); + + icons(); +} + +void big(word x,word y, string z, boolean notted); +static word start,image; + + +static void generate(byte from, boolean& notted) +{ + byte fv; + + image=0; + for( fv=0; fv <= 7; fv ++) + image += (from & (1 << fv)) << fv; + + image += image << 1; + image=hi(image)+lo(image)*256; + if (notted) image=~ image; +} + +void big(word x,word y, string z, boolean notted) +{ + byte fv,ff;byte bit; + + start=x+y*80; + + for( fv=1; fv <= length(z); fv ++) + { + for( ff=1; ff <= 12; ff ++) + { + generate(font[z[fv]][ff+1], notted); + for( bit=0; bit <= 2; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + memw[0xa000*start+ ff*160]=image; + memw[0xa000*start+80+ff*160]=image; + } + } + start += 2; + } + bit=getpixel(0,0); +} + +void centre(integer y, string z) +{ + big(40-(length(z)),y,z,false); +} + +void option(byte which, string what) +{ + big(16,41+which*33,string((char)(which+48))+')',true); + big(24,41+which*33,what,true); +} + +void invert(integer x1,integer y1,integer x2,integer y2) +{ + word s; pointer p; + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + putimage(x1,y1,p,4); + sound(y1); delay(30); + sound(600-y2); delay(20); + nosound; delay(200); + putimage(x1,y1,p,0); + delay(250); +} + +void wait() +{ + word x; char r; boolean pressed; + + x=0; pressed=false; + do { + setfillstyle(6,15); bar(x ,330,x-1,337); + setfillstyle(1, 0); bar(x-2,330,x-3,337); + delay(40); x += 1; + + if (keypressed()) + { + r=readkey(); + if (r=='\0') + { + r=readkey(); /* and...? */ + } else + { /* Not an extended keystroke. */ + if (set::of(range('1','6'),cspace,cescape,creturn, eos).has(r)) pressed=true; + } + } + + } while (!((x==640) || pressed)); + + if ((r==cspace) || (r==creturn)) r='1'; + if (r==cescape) r='6'; + if (pressed) + { + result=ord(r)-48; + invert(48,37+result*33,114,69+result*33); + } else result=177; +} + +void show_up() +{ + setvisualpage(0); +} + +void loadmenu() +{ + untyped_file f; byte bit; + + assign(f,"mainmenu.avd"); + reset(f,1); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,mem[0xa000*0],59*80); + } + close(f); + bit=getpixel(0,0); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + setup(); + loadmenu(); + load_regi_info(); + option(1,"Play the game."); + option(2,"Read the background."); + option(3,"Preview... perhaps..."); + option(4,"View the documentation."); + option(5,"Registration info."); + option(6,"Exit back to DOS."); + centre(275,registrant); + centre(303,"Make your choice, or wait for the demo."); + + show_up(); + wait(); + mem[storage_seg*storage_ofs]=result; + closegraph(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/avvyans.cpp b/engines/avalanche/avvyans.cpp new file mode 100644 index 0000000000..68756874a8 --- /dev/null +++ b/engines/avalanche/avvyans.cpp @@ -0,0 +1,84 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +integer gd,gm; +untyped_file f; +array<1,16000,byte> aa; +matrix<0,27,0,35,byte> cols; +text t; +string x; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + fillchar(cols,sizeof(cols),'\0'); + assign(f,"v:avvypic.ptx"); + reset(f,1); + blockread(f,aa,filesize(f)); + close(f); + putimage(0,0,aa,0); + for( gd=0; gd <= 27; gd ++) + for( gm=0; gm <= 34; gm ++) + cols[gd][gm+1]=getpixel(gd,gm); + + restorecrtmode(); +/* + asm + mov ax,$1003 + mov bl,0 + int $10 + end; +*/ + for( gm=0; gm <= 17; gm ++) + for( gd=0; gd <= 27; gd ++) + {; + gotoxy(gd+1,gm+1); + if (cols[gd][2*gm]==cols[gd][2*gm+1]) + {; + textattr=cols[gd][2*gm]; output << 'Û'; + } else + if ((cols[gd][2*gm]>7) && (cols[gd][2*gm+1]<8)) + {; + textattr=cols[gd][2*gm]+cols[gd][2*gm+1]*16; + output << 'ß'; + } else + {; + textattr=cols[gd][2*gm]*16+cols[gd][2*gm+1]; + if (textattr>blink) textattr -= blink; + output << 'Ü'; + } + } + gotoxy(23,5); textattr=red; output << 'ß'; + + assign(t,"v:avalot.txt"); reset(t); + textattr=9; gm=2; + do { + gm += 1; + t >> x >> NL; + gotoxy(30,gm); + output << x << NL; + } while (!(eof(t))); + + textattr=7; gotoxy(35,2); output << "Back in good old A.D. "; + textattr=15; output << "1176"; textattr=7; output << "..."; + textattr=9; gotoxy(40,4); output << "Lord"; + gotoxy(67,9); output << "d'Argent"; + textattr=yellow; + gotoxy(37,12); output << "He's back..."; + gotoxy(47,14); output << "And this time,"; + gotoxy(52,15); output << "he's wearing tights..."; + textattr=4; + gotoxy(36,17); output << "A Thorsoft of Letchworth game. * Requires EGA"; + gotoxy(38,18); output << "and HD. * By Mike, Mark and Thomas Thurman."; + gotoxy(40,19); output << "Sfx archive- "; + textattr=9; output << "Download "; + textattr=14; output << "AVLT10.EXE"; + textattr=9; output << " now!"; + gotoxy(1,1); + input >> NL; +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/avvyans2.cpp b/engines/avalanche/avvyans2.cpp new file mode 100644 index 0000000000..915a33d372 --- /dev/null +++ b/engines/avalanche/avvyans2.cpp @@ -0,0 +1,185 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Ansi.h"*/ + +integer gd,gm; +untyped_file f; +array<1,16000,byte> aa; +matrix<0,27,0,35,byte> cols; +text t; +string x; +byte n; +byte spaces; +byte cfg,cbg; /* Current foreground & background. */ +byte ofg,obg; /* Old fg & bg. */ + +void do_spaces() +{; + if (spaces==0) return; + along(spaces); + spaces=0; +} + +void finishline(); +static byte wx,wy; + +static void jumpto(byte xx) +{; + along(xx-wx); +} + +void finishline() +{; + wx=29-spaces; wy=gm+1; + switch (wy) { + case 1: {; + sgr(7); jumpto(35); output << "Back in good old A.D. "; + sgr(15); output << "1189"; sgr(7); output << "..." << NL; cfg=7; + } + break; + case RANGE_5(3,7): {; + t >> x >> NL; + while (x[length(x)]=='\40') x[0] -= 1; + if (x!="") + {; + jumpto(30); + sgr(9); + spaces=0; + while (x!="") + {; + if (x[1]==' ') + spaces += 1; + else + {; + do_spaces(); + output << x[1]; + } + Delete(x,1,1); + } + if (wy==7) close(t); + output << NL; + } + } + break; + case 8: {; + jumpto(67); sgr(9); output << "d'Argent" << NL; cfg=9; + } + break; + case 11: {; + jumpto(37); sgr(14); output << "He's back..." << NL; + } + break; + case 13: {; + jumpto(47); sgr(14); output << "And this time," << NL; + } + break; + case 14: {; + jumpto(52); sgr(14); output << "he's wearing tights..." << NL; + } + break; + case 16: {; + jumpto(35); sgr(4); + output << "A Thorsoft of Letchworth game. * Requires EGA" << NL; + } + break; + case 17: {; + jumpto(37); sgr(4); + output << "and HD. * By Mike, Mark and Thomas Thurman." << NL; + } + break; + case 18: {; + jumpto(39); + sgr( 4); output << "Sfx archive- "; + sgr( 9); output << "Download "; + sgr(14); output << "AVLT10.EXE"; + sgr( 9); output << " now!"; + } + break; + default: output << NL; + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + fillchar(cols,sizeof(cols),'\0'); + assign(f,"v:avvypic.ptx"); + reset(f,1); + blockread(f,aa,filesize(f)); + close(f); + putimage(0,0,aa,0); + for( gd=0; gd <= 27; gd ++) + for( gm=0; gm <= 34; gm ++) + cols[gd][gm+1]=getpixel(gd,gm); + + restorecrtmode(); + + assign(output,"v:avalot.ans"); rewrite(output); normal; ed; +/* assign(output,''); rewrite(output); normal; ed;*/ + assign(t,"v:avalot.txt"); reset(t); + + for( gm=0; gm <= 17; gm ++) + {; + spaces=0; + for( gd=0; gd <= 27; gd ++) + {; + if ((gd==22) && (gm==4)) + {; + do_spaces(); + sgr(red); output << 'ß'; + } else + {; + if (cols[gd][2*gm]==cols[gd][2*gm+1]) + {; + if (cols[gd][2*gm]==0) + spaces += 1; /* a blank space */ + else {; + do_spaces(); + + if (cfg==cols[gd][2*gm]) output << 'Û'; else + if (cbg==cols[gd][2*gm]) output << ' '; else + {; + sgr((cols[gd][2*gm])+(cbg*16)); + cfg=cols[gd][2*gm]; + output << 'Û'; + } + } + } else + if ((cols[gd][2*gm]>7) && (cols[gd][2*gm+1]<8)) + {; + do_spaces(); + sgr(cols[gd][2*gm]+cols[gd][2*gm+1]*16); + cfg=cols[gd][2*gm]; cbg=cols[gd][2*gm+1]*16; + output << 'ß'; + } else + {; + do_spaces(); + + ofg=cfg; obg=cbg; + cbg=cols[gd][2*gm]; cfg=cols[gd][2*gm+1]; + + if ((cbg==ofg) && (cfg==obg)) + {; + n=cfg*16+cbg; + if (n>128) n -= 128; + output << 'ß'; + } else + {; + n=cbg*16+cfg; + if (n>128) n -= 128; + if ((cfg!=ofg) || (cbg!=obg)) sgr(n); + output << 'Ü'; + } + + } + } + } finishline(); + } + output << NL; + normal; +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/avvymonk.cpp b/engines/avalanche/avvymonk.cpp new file mode 100644 index 0000000000..5a4b70c818 --- /dev/null +++ b/engines/avalanche/avvymonk.cpp @@ -0,0 +1,72 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; +byte z; +array<1,4,pointer> a; +untyped_file f; word s; +string check; +integer x,y; +void savesc() +{ + varying_string<40> adf; untyped_file f; byte z; array<1,2,pointer> c; word s; +varying_string<14> nam; varying_string<30> screenname; +; + nam="v:avvymonk.avd"; + adf=string("aved as a stuff file, so there! TJAT.")+'\15'+'\12'+'\32'; + adf[0]='S'; + screenname="Avalot in a monk's costume"; + assign(f,nam); /* not scrambled */ + rewrite(f,1); + blockwrite(f,adf,41); + blockwrite(f,nam,13); + blockwrite(f,screenname,31); + s=imagesize(0,0,getmaxx(),75); + for( z=1; z <= 2; z ++) + {; + getmem(c[z],s); + getimage(0,15+(z-1)*75,getmaxx(),15+(z)*75,c[z]); + blockwrite(f,c[z],s); + freemem(c[z],s); + } +} +void loadscreen(string nam) +{; + assign(f,nam); + reset(f,1); + blockread(f,check,41); + blockread(f,check,13); + blockread(f,check,31); + s=imagesize(0,0,getmaxx(),75); + for( z=1; z <= 2; z ++) + {; + getmem(a[z],s); + blockread(f,a[z],s); + setactivepage(0); + putimage(0,15+(z-1)*75,a[z],0); + freemem(a[z],s); + } + close(f); +} +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; + x=0; y=0; + initgraph(gd,gm,"o:"); + loadscreen("v:legion.avd"); + while (y<100) + {; + switch (getpixel(x,y)) { + case 7: putpixel(x,y,0); break; + case 8: putpixel(x,y,0); break; + case 9: putpixel(x,y,15); break; + } + x += 1; + if (x>640) {; y += 1; x=0; } + } + savesc(); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/bakchunk.cpp b/engines/avalanche/bakchunk.cpp new file mode 100644 index 0000000000..5cea62db12 --- /dev/null +++ b/engines/avalanche/bakchunk.cpp @@ -0,0 +1,28 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Celer.h"*/ +/*#include "Lucerna.h"*/ + +integer gd,gm; +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + gd=3; gm=0; initgraph(gd,gm,""); + setvisualpage(3); + load_chunks('1'); + + for( gd=0; gd <= num_chunks; gd ++) + show_one_at(gd,0,gd*40); + + mblit(0,0,79,200,3,0); + + gd=getpixel(0,0); + setvisualpage(0); setactivepage(0); + + settextstyle(0,0,4); setcolor(15); + outtextxy(100,50,"Chunk1"); + input >> NL; + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/basher.cpp b/engines/avalanche/basher.cpp new file mode 100644 index 0000000000..56cfcca023 --- /dev/null +++ b/engines/avalanche/basher.cpp @@ -0,0 +1,385 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + BASHER Handles the keyboard. */ + +#define __basher_implementation__ + + + /* Note: this unit can record keystrokes, for the demo. If you want it + to do this, define the o.c.c. RECORD. Setting gyro.demo to True will + cause them to be played back. */ + +#include "basher.h" + + +#include "enhanced.h" +#include "lucerna.h" +#include "Graph.h" +#include "scrolls.h" +#include "acci.h" +#include "trip5.h" +#include "pingo.h" +#include "dropdown.h" +#include "logger.h" +#include "Sticks.h" +#include "enid.h" + + +boolean entering_filename; +byte left_margin; + +void plottext() +{ + const array<0,2,byte> p = {{0,1,3}}; + byte x,y,n; + + x=0; if (mouse_near_text()) super_off(); + cursor_off(); + for( n=0; n <= 2; n ++) + for( y=0; y <= 7; y ++) + { + for( x=1; x <= length(current); x ++) + mem[0xa000*p[n]*pagetop+12882+y*80+x]=little[current[x]][y]; + fillchar(mem[0xa000*p[n]*pagetop+12883+y*80+x],77-x,'\0'); + } + cursor_on(); + super_on(); +} + +void wipetext() +{ + const array<0,2,byte> n = {{0,1,3}}; + byte y,p; + + if (mouse_near_text()) super_off(); + cursor_off(); + for( y=0; y <= 7; y ++) + for( p=0; p <= 2; p ++) + fillchar(mem[0xa000*n[p]*pagetop+12883+y*80],77,'\0'); + quote=true; curpos=1; cursor_on(); + super_on(); +} + +/*procedure cursor; +begin + if curflash=0 then + begin + if mouse_near_text then Super_Off; + cursoron:=not cursoron; + mem[$A000*13442+curpos]:=not mem[$A000*13442+curpos]; + mem[$A000*pagetop+13442+curpos]:=not mem[$A000*pagetop+13442+curpos]; + curflash:=17; + Super_On; + end else dec(curflash); +end;*/ + +void do_cursor() +{ + bytefield bf; + byte fv; + + mem[0xac00*13442+curpos]=~ mem[0xac00*13442+curpos]; + { + bf.x1=curpos+1; bf.x2=curpos+2; bf.y1=168; bf.y2=168; + } + for( fv=0; fv <= 1; fv ++) getset[fv].remember(bf); +} + +void cursor_on() +{ + if (cursoron) return; + do_cursor(); cursoron=true; +} + +void cursor_off() +{ + if (! cursoron) return; + do_cursor(); cursoron=false; +} + + +void get_demorec() +{ + demofile >> demo_rec; + inchar=demo_rec.key; + extd=demo_rec.extd; + demo_rec.delay -= 1; +} + +#ifdef RECORD + void record_one() + { + demo_rec.delay=count; + demo_rec.key=inchar; + demo_rec.extd=extd; + + demofile << demo_rec; + count=0; + } +#endif +/* +procedure storeline(whatwhat:string); +var + fv:byte; + what:string[77]; + ok:boolean; + + function upline(x:string):string; + var fv:byte; n:string[77]; + begin + for fv:=1 to length(x) do n[fv]:=upcase(x[fv]); + n[0]:=x[0]; upline:=n; + end; +begin + + what:=upline(whatwhat); ok:=false; + for fv:=1 to 20 do + if what=upline(previous^[fv]) then + begin { it already exists, in string "fv" } + move(previous^[fv+1],previous^[fv],(20-fv)*78); + previous^[20]:=whatwhat; ok:=true; + end; + if ok then exit; + { it's not on the list, so add it } + move(previous^[2],previous^[1],1482); { shove up } + previous^[20]:=whatwhat; +end; +*/ +void typein(); + +static char firstchar(string x) { char firstchar_result; + firstchar_result=x[1]; return firstchar_result; + } + + +static void try_dd() /* This asks the Parsekey proc in Dropdown if it knows it. */ +{ + parsekey(inchar,extd); +} + +void typein() +{ + byte w; + + inkey(); + #ifdef RECORD record_one(); #endif + + switch (inchar) { + case RANGE_15('\40','\56'):case '\60' ... '\337':case '\341' ... '\377': if (ddm_o.menunow) + { + parsekey(inchar,extd); + } else + { + if (length(current)<76) + { + if ((inchar=='"') || (inchar=='`')) + { + if (quote) inchar='`'; else inchar='"'; + quote=! quote; /* Quote- Unquote... */ + } + insert(inchar,current,curpos); + curpos += 1; + plottext(); + } else blip(); + } + break; + case '\10': if (! ddm_o.menunow) + { + if (curpos>left_margin) + { + curpos -= 1; + if (set::of('"','`', eos).has(current[curpos])) quote=! quote; + Delete(current,curpos,1); + plottext(); + } else blip(); + } + break; + case '\0':case '\340': { + switch (extd) { + /* Function keys: */ + case cf1: callverb(vb_help); break; /* f1 - help (obviously) */ + case cf2: fxtoggle(); break; /* f2 - sound */ + case ccf2:case cf11: { clearwords(); callverb(vb_save); } break; /* ^f2 - save */ + case cf3: if (length(current)<length(/*previous^[20]*/last)) /* f3 - rec last */ + { + current=current+copy( /*previous^[20]*/last,length(current)+1,255); + curpos=length(current)+1; + plottext(); + } + break; + case ccf3:case cf12: { clearwords(); callverb(vb_load); } break; /* ^f3 - load */ + case cf4: callverb(vb_restart); break; /* f4 - restart game */ + case cf5: { + person=pardon; thing=pardon; + callverb(firstchar(f5_does())); /* f5 - get up/ whatever */ + } + break; + case cf6: callverb(vb_pause); break; /* f6 - pause */ + case cf7: callverb(vb_open); break; /* f7 - open door */ + case cf8: callverb(vb_look); break; /* f8 - look */ + case cf9: callverb(vb_score); break; /* f9 - score */ + case ccf7: major_redraw(); break; /* ^f7 - open door */ + case cf10:case c_ax:case caf4: { + #ifdef RECORD + display("Hi. You have just finished recording. GIED."); + close(demofile); exit(0); + #endif + callverb(vb_quit); /* f10, alt-X, alt-f4 - quit */ + } + break; + case ccf5: back_to_bootstrap(2); break; /* ^f5 - Dos shell. */ + case csf10: callverb(vb_info); break; /* sf10 - version */ + + case c_ab: callverb(vb_boss); break; /* alt-B */ + case c_ad: display("Wrong game!"); break; /* alt-D */ + case ccleft: if (curpos>left_margin) + { cursor_off(); curpos -= 1; cursor_on(); } + break; /* ^left */ + case ccright: if (curpos<=length(current)) /* ^right */ + { cursor_off(); curpos += 1; cursor_on(); } + break; + case cchome: { cursor_off(); curpos=1; cursor_on(); } break; /* ^home */ + case ccend: { cursor_off(); curpos=length(current)+1; cursor_on(); } break; /* ^end */ + case c_ar: oh=177; break; /* alt-R = repeater (re-chime) */ + case cup:case cdown:case cleft:case cright:case cpgup:case cpgdn:case chome:case cend: if (ddm_o.menunow) try_dd(); + else tripkey(extd); + break; /* Up/Down/Left/Right/PgUp/PgDn */ + case cnum5: tripkey(extd); break; /* Numeric 5 */ + case cdel: if (! ddm_o.menunow) + { + if (curpos<=length(current)) + { + if (set::of('"','`', eos).has(current[curpos])) quote=! quote; + Delete(current,curpos,1); + plottext(); + } else blip(); + } + break; + default: try_dd(); + } + } + break; + case cescape:case '/': if (ddm_o.menunow) /* Escape */ + { ddm_o.wipe(); } else + if (entering_filename) + { normal_edit(); wipetext(); } else + ddm_m.getcertain(ddm_o.menunum); + break; + case creturn: if (ddm_o.menunow) try_dd(); /* Return */ + else { + log_command(current); + if (entering_filename) + { + edna_save(copy(current,24,255)); + normal_edit(); wipetext(); + } else + { + if (current!="") last=current; + parse(); do_that(); + if (! entering_filename) + { + current=""; + wipetext(); + } + } + } + break; + case '\11': callverb(vb_inv); break; /* Ctrl-I= inventory */ + case '\7': errorled(); break; + case '\25': { + current=""; + wipetext(); + } + break; + + case '\27': { tr[1].xs=walk; newspeed(); } break; + case '\22': { tr[1].xs=run; newspeed(); } break; + + case '\2': bosskey(); break; + case '\12': ctrl=cjoy; break; /* Joystick */ + case '\13': ctrl=ckey; break; /* Keyboard */ + case '\3': callverb(vb_quit); break; /* Ctrl-C= request to quit */ + + } + showrw(); + + if (demo) get_demorec(); +} + +/* 'x'..'z': begin setvisualpage(ord(extd)-63); write(#7); inkey; end; + '': begin setvisualpage(0); write(#7); inkey; end;*/ + +void keyboard_link() +{ + state(defaultled); /* if defaultled=1 then on; { For the menus }*/ + joykeys(); /* Test joystick buttons- I know that's not keyboard. */ + + if (demo) + { + if (keypressede()) exit(0); + if (demo_rec.delay>0) + demo_rec.delay -= 1; + else typein(); + return; + } + + #ifdef RECORD count += 1; #endif + + if (! keypressede()) return; + if (keyboardclick) click(); + typein(); +} + +boolean demo_ready() +{ + boolean demo_ready_result; + if (demo_rec.delay>0) + { + slowdown(); + demo_rec.delay -= 1; + } + demo_ready_result=demo_rec.delay==0; + return demo_ready_result; +} + +void filename_edit() +{ + entering_filename=true; + current="Filename\? (Esc=cancel):"; + left_margin=24; curpos=24; + plottext(); +} + +void normal_edit() +{ + entering_filename=false; + current=""; + left_margin=1; curpos=1; +} + +class unit_basher_initialize { + public: unit_basher_initialize(); +}; +static unit_basher_initialize basher_constructor; + +unit_basher_initialize::unit_basher_initialize() { +/* new(previous);*/ last=""; normal_edit(); + + if (demo) + { + assign(demofile,"demo.avd"); + reset(demofile); + } + + #ifdef RECORD + count=0; + assign(demofile,"demo.avd"); + rewrite(demofile); + #endif + +} diff --git a/engines/avalanche/basher.h b/engines/avalanche/basher.h new file mode 100644 index 0000000000..1afecae441 --- /dev/null +++ b/engines/avalanche/basher.h @@ -0,0 +1,40 @@ +#ifndef __basher_h__ +#define __basher_h__ + + +#include "gyro.h" +/*#include "Tommys.h"*/ + + +#ifdef RECORD + +#ifdef __basher_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN word count; +#undef EXTERN +#define EXTERN extern + +#endif + + void plottext(); + + void keyboard_link(); + + void cursor_on(); + + void get_demorec(); + + boolean demo_ready(); + + void cursor_off(); + + void filename_edit(); + void normal_edit(); +#ifdef RECORD + void record_one(); +#endif + +#endif diff --git a/engines/avalanche/bootstrp.cpp b/engines/avalanche/bootstrp.cpp new file mode 100644 index 0000000000..a903679a90 --- /dev/null +++ b/engines/avalanche/bootstrp.cpp @@ -0,0 +1,349 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ + + +/*$M 8192,0,$6000, S-*/ + +enum elm {normal, musical, elmpoyten, regi, last_elm}; + +const integer run_shootemup = 1; +const integer run_dosshell = 2; +const integer run_ghostroom = 3; +const integer run_golden = 4; + +const array<false,true,varying_string<2> > runcodes = {{"et","Go"}}; + +const integer reset_ = 0; + +const boolean jsb = true; const boolean no_jsb = false; +const boolean bflight = true; const boolean no_bflight = false; + + +struct { + byte operation; + word skellern; + array<1,10000,byte> contents; +} storage; + +string arguments,demo_args,args_with_no_filename; + +boolean first_time; + +byte original_mode; +pointer old_1c; + +string segofs; + +boolean zoomy; + +longint soundcard,speed,baseaddr,irq,dma; + +void cursor_off() /*assembler; */ +{; +/* asm + mov ah,01; { Change cursor size. */ +/* mov cx,8224; { CH & CL are now 32. */ +/* int $10; { Call the Bios */ + +} /* That's all. */ + +void cursor_on() /*assembler; */ +{; +/* +asm + mov ah,01; { Change cursor size. */ +/* mov ch,5; { Top line is 5. */ +/* mov cl,7; { Bottom line is 7. */ +/* int $10; { Call the Bios. */ + +} + +void quit() +{ + cursor_on(); + exit(0); +} + +string strf(longint x) +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +string command_com() +{ + string temp; + + string command_com_result; + temp=getenv("comspec"); + if (temp=="") + output << "avvy_bootstrap: COMSPEC not defined, => cannot run Dos shell." << NL; + command_com_result=temp; + return command_com_result; +} + +void explain(byte error) +{ + output << " ("; + switch (error) { + case 2: output << "it's not there"; break; + case 8: output << "out of memory"; break; + default: output << "error " << error; + } + output << ")." << NL; +} + +/*$F+*/ + +void b_flight() /*interrupt;*/ +{ + storage.skellern += 1; +} + +/*$F-*/ + +void bflight_on() +{ + storage.skellern=reset_; + setintvec(0x1c,&b_flight); +} + +void bflight_off() +{ + setintvec(0x1c,old_1c); +} + +void run(string what, boolean with_jsb,boolean with_bflight, elm how); + + +static string elm2str(elm how) +{ + string elm2str_result; + switch (how) { + case normal: case musical: elm2str_result="jsb"; break; + case regi: elm2str_result="REGI"; break; + case elmpoyten: elm2str_result="ELMPOYTEN"; break; + } + return elm2str_result; +} + +void run(string what, boolean with_jsb,boolean with_bflight, elm how) +{ + string which_dir,args; + integer error; + + + if (what=="") return; + + getdir(0,which_dir); + + if (with_jsb) + { + if (how==musical) + args=elm2str(how)+' '+args_with_no_filename; /* FN is NOT given if musical*/ + else + args=elm2str(how)+' '+arguments; + } else args=""; + + if (how==musical) args=args+strf(soundcard)+' '+strf(speed)+' '+ + strf(baseaddr)+' '+strf(dma)+' '+strf(irq); + if (with_bflight) bflight_on(); + + swapvectors; + exec(what,args); + swapvectors; + cursor_off(); + + error=doserror; + + if (with_bflight) bflight_off(); + + chdir(which_dir); + + if (error!=0) + { + output << "avvy_bootstrap: cannot execute " << what << '!'; + explain(error); + output << "Press Enter:"; input >> NL; quit(); + } +} + +void run_avalot() +{ + integer error; + + + bflight_on(); + + swapvectors; + exec("avalot.avx",runcodes[first_time]+arguments); + swapvectors; + + error=doserror; + + bflight_off(); + + if (error!=0) + { + output << "avvy_bootstrap: error in loading AVALOT.AVX!"; + explain(error); + quit(); + } + + first_time=false; +} + +void run_the_demo() +{ + string args; + + args=arguments; + arguments=demo_args; /* Force the demo. */ + + run_avalot(); + + arguments=args; /* Put all back to normal again. */ + first_time=true; +} + +void get_arguments() +{ + byte fv; + + arguments=""; + + for( fv=1; fv <= paramcount; fv ++) + arguments=arguments+paramstr(fv)+' '; + + arguments[0] -= 1; /* Get rid of the trailing space. */ + + segofs=string(' ')+strf(seg(storage))+' '+strf(ofs(storage)); + + arguments=segofs+' '+arguments; +} + +void dos_shell() +{ + registers r; + + r.ax=original_mode; intr(0x10,r); + output << NL; + output << "The Avalot Dos Shell." << NL; + output << "---------------------" << NL; + output << NL; + output << "Type EXIT to return to Avalot." << NL; + output << NL; + + cursor_on(); + run(command_com(),no_jsb,no_bflight,normal); + cursor_off(); + + output << "Please wait, restoring your game..." << NL; +} + +boolean keypressed1() { + registers r; + + boolean keypressed1_result; + r.ah=0xb; + msdos(r); + keypressed1_result=r.al==0xff; + return keypressed1_result; + } + +void flush_buffer() { + registers r; r.ah=7; + while (keypressed1()) msdos(r); } + +void demo() +{ + run_the_demo(); if (keypressed1()) return; + run("intro.avx",jsb,bflight,musical); if (keypressed1()) return; + run("stars.avx",jsb,no_bflight,musical); if (keypressed1()) return; + + flush_buffer(); +} + +void call_menu() +{ + run("stars.avx",jsb,no_bflight,musical); + flush_buffer(); + do { + run("avmenu.avx",jsb,no_bflight,normal); + + switch (storage.operation) { + case 1: return; break; /* Play the game. */ + case 2: run("intro.avx",jsb,bflight,musical); break; + case 3: run("preview1.avd",jsb,no_bflight,normal); break; + case 4: run("viewdocs.avx",jsb,bflight,elmpoyten); break; + case 5: run("viewdocs.avx",jsb,bflight,regi); break; + case 6: quit(); break; + case 177: demo(); break; + } + + flush_buffer(); + } while (!false); +} + +void get_slope() +{ + run("slope.avx",jsb,no_bflight,normal); + if (dosexitcode!=0) + { + cursor_on(); + exit(0); + } + + move(storage.contents,arguments,sizeof(arguments)); + move(storage.contents[4998],soundcard,4); + move(storage.contents[5002],baseaddr,4); + move(storage.contents[5006],irq,4); + move(storage.contents[5010],dma,4); + move(storage.contents[5014],speed,4); + + zoomy=(arguments[8]=='y') || (arguments[2]=='y'); + demo_args=arguments; demo_args[7]='y'; + arguments=segofs+' '+arguments; + demo_args=segofs+' '+demo_args; + + args_with_no_filename=arguments; + if (arguments[length(arguments)]!=' ') + { /* Filename was given */ + args_with_no_filename=arguments; + while ((args_with_no_filename!="") + && (args_with_no_filename[length(args_with_no_filename)]!=' ')) + args_with_no_filename[0] -= 1; /* Strip off the filename. */ + } +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + original_mode=mem[seg0040*0x49]; getintvec(0x1c,old_1c); + first_time=true; cursor_off(); + + get_arguments(); + get_slope(); + + if (! zoomy) call_menu(); /* Not run when zoomy. */ + + do { + run_avalot(); + + if (dosexitcode!=77) quit(); /* Didn't stop for us. */ + + switch (storage.operation) { + case run_shootemup: run("seu.avx",jsb,bflight,normal); break; + case run_dosshell: dos_shell(); break; + case run_ghostroom: run("g-room.avx",jsb,no_bflight,normal); break; + case run_golden: run("golden.avx",jsb,bflight,musical); break; + } + + } while (!false); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/cadburys.cpp b/engines/avalanche/cadburys.cpp new file mode 100644 index 0000000000..b891123af5 --- /dev/null +++ b/engines/avalanche/cadburys.cpp @@ -0,0 +1,109 @@ +#include "ptoc.h" + +#define __cadburys_implementation__ + + +#include "cadburys.h" + + +#include "graph.h" + + + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=((realx-ch.x*8)+(x2-x1)+7) / 8; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + + diff --git a/engines/avalanche/cadburys.h b/engines/avalanche/cadburys.h new file mode 100644 index 0000000000..65e7bd7c8b --- /dev/null +++ b/engines/avalanche/cadburys.h @@ -0,0 +1,41 @@ +#ifndef __cadburys_h__ +#define __cadburys_h__ + + +const integer arraysize = 12000; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + + +#ifdef __cadburys_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN array<0,arraysize,byte> aa; +EXTERN byte num_chunks,this_chunk; +EXTERN integer gd,gm; +EXTERN array<1,30,longint> offsets; +EXTERN untyped_file f; +#undef EXTERN +#define EXTERN extern + + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat); + +#endif diff --git a/engines/avalanche/celer.cpp b/engines/avalanche/celer.cpp new file mode 100644 index 0000000000..61357f567b --- /dev/null +++ b/engines/avalanche/celer.cpp @@ -0,0 +1,472 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + CELER The unit for updating the screen pics. */ + +#define __celer_implementation__ + + +#include "celer.h" + + +#include "Graph.h" +#include "trip5.h" +#include "lucerna.h" +/*#include "Crt.h"*/ + + +untyped_file f; /* Private variable- not accessible from elsewhere. */ + +const integer on_disk = -1; /* Value of memos[fv].x when it's not in memory. */ + +void pics_link() +{ + byte xx; + + if (ddmnow) return; /* No animation when the menus are up. */ + + { dnatype& with = dna; + switch (with.room) { + + case r__outsideargentpub: { + if ((roomtime % longint(12))==0) + show_one(longint(1)+(roomtime / longint(12)) % longint(4)); + } + break; + + case r__brummieroad: if ((roomtime % longint(2))==0) + show_one(longint(1)+(roomtime / longint(2)) % longint(4)); + break; + + case r__bridge: if ((roomtime % longint(2))==0) + show_one(longint(4)+(roomtime / longint(2)) % longint(4)); + break; + + case r__yours: if ((! with.avvy_is_awake) && ((roomtime % longint(4))==0)) + show_one(longint(1)+(roomtime / longint(12)) % longint(2)); + break; + + case r__argentpub: { + if (((roomtime % longint(7))==1) && (dna.malagauche!=177)) + { /* Malagauche cycle */ + dna.malagauche += 1; + switch (dna.malagauche) { + case 1:case 11:case 21: show_one(12); break; /* Looks forwards. */ + case 8:case 18:case 28:case 32: show_one(11); break; /* Looks at you. */ + case 30: show_one(13); break; /* Winks. */ + case 33: dna.malagauche=0; break; + } + } + + switch (roomtime % longint(200)) { + case 179:case 197: show_one(5); break; /* Dogfood's drinking cycle */ + case 182:case 194: show_one(6); break; + case 185: show_one(7); break; + case 199: dna.dogfoodpos=177; break; /* Impossible value for this. */ + case 0 ... 178: { /* Normally. */ + switch (bearing(2)) {/* Bearing of Avvy from Dogfood. */ + case 1 ... 90:case RANGE_3(358,360): xx=3; break; + case 293 ... 357: xx=2; break; + case 271 ... 292: xx=4; break; + } + if (xx!=dna.dogfoodpos) /* Only if it's changed.*/ + { + show_one(xx); + dna.dogfoodpos=xx; + } + } + break; + } + } + break; + + case r__westhall: if ((roomtime % longint(3))==0) + switch ((roomtime / longint(3)) % longint(6)) { + case 4: show_one(1); break; + case 1:case 3:case 5: show_one(2); break; + case 0:case 2: show_one(3); break; + } + break; + case r__lustiesroom: if (! (dna.lustie_is_asleep)) { + if ((roomtime % longint(45))>42) xx=4; /* du Lustie blinks */ + else + switch (bearing(2)) {/* Bearing of Avvy from du Lustie. */ + case 0 ... 45:case 315 ... 360: xx=1; break; /* Middle. */ + case 45 ... 180: xx=2; break; /* Left. */ + case 181 ... 314: xx=3; break; /* Right. */ + } + if (xx!=dna.dogfoodpos) /* Only if it's changed.*/ + { + show_one(xx); + dna.dogfoodpos=xx; /* We use DogfoodPos here too- why not? */ + } + } + break; + + case r__aylesoffice: if ((! dna.ayles_is_awake) && (roomtime % longint(14)==0)) + { + switch ((roomtime / longint(14)) % longint(2)) { + case 0: show_one(1); break; /* Frame 2: EGA. */ + case 1: show_one(3); break; /* Frame 1: Natural. */ + } + } + break; + + case r__robins: if (dna.tied_up) + switch (roomtime % longint(54)) { + case 20: show_one(4); break; /* Frame 4: Avalot blinks. */ + case 23: show_one(2); break; /* Frame 1: Back to normal. */ + } + break; + + case r__nottspub: { + switch (bearing(5)) { /* Bearing of Avvy from Port. */ + case 0 ... 45:case 315 ... 360: xx=2; break; /* Middle. */ + case 45 ... 180: xx=6; break; /* Left. */ + case 181 ... 314: xx=8; break; /* Right. */ + } + + if ((roomtime % longint(60))>57) xx -= 1; /* Blinks */ + + if (xx!=dna.dogfoodpos) /* Only if it's changed.*/ + { + show_one(xx); + dna.dogfoodpos=xx; /* We use DogfoodPos here too- why not? */ + } + + switch (roomtime % longint(50)) { + case 45 : show_one(9); break; /* Spurge blinks */ + case 49 : show_one(10); break; + } + } + break; + + case r__ducks: { + if ((roomtime % longint(3))==0) /* The fire flickers */ + show_one(longint(1)+(roomtime / longint(3)) % longint(3)); + + switch (bearing(2)) {/* Bearing of Avvy from Duck. */ + case 0 ... 45:case 315 ... 360: xx=4; break; /* Middle. */ + case 45 ... 180: xx=6; break; /* Left. */ + case 181 ... 314: xx=8; break; /* Right. */ + } + + if ((roomtime % longint(45))>42) xx += 1; /* Duck blinks */ + + if (xx!=dna.dogfoodpos) /* Only if it's changed.*/ + { + show_one(xx); + dna.dogfoodpos=xx; /* We use DogfoodPos here too- why not? */ + } + } + break; + + }} + + if ((dna.ringing_bells) && (flagset('B'))) + /* They're ringing the bells. */ + switch (roomtime % longint(4)) { + case 1: { + dnatype& with = dna; + + if (with.nextbell<5) with.nextbell=12; + with.nextbell -= 1; + note(notes[with.nextbell]); + } + break; + case 2: nosound; break; + } + +} + +void load_chunks(string xx) +{ + chunkblocktype ch; + byte fv; + + /*$I-*/ + assign(f,string("chunk")+xx+".avd"); /* strf is done for us by Lucerna. */ + reset(f,1); + if (ioresult!=0) return; /* no Chunk file. */ + seek(f,44); + blockread(f,num_chunks,1); + blockread(f,offsets,num_chunks*4); + + for( fv=1; fv <= num_chunks; fv ++) + { + seek(f,offsets[fv]); + blockread(f,ch,sizeof(ch)); + { + if (ch.memorise) + { + + { + memotype& with1 = memos[fv]; + + with1.x=ch.x; with1.xl=ch.xl; + with1.y=ch.y; with1.yl=ch.yl; + with1.flavour=ch.flavour; + with1.size=ch.size; + } + + getmem(memory[fv],ch.size); + + if (ch.natural) + { + getimage(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl,memory[fv]); + } else + blockread(f,memory[fv],ch.size); + } else memos[fv].x=on_disk; + } + } + + close(f); + /*$I+*/ +} + +void forget_chunks() +{ + byte fv; + + for( fv=1; fv <= num_chunks; fv ++) + if (memos[fv].x>on_disk) + freemem(memory[fv],memos[fv].size); + fillchar(memos,sizeof(memos),'\377'); /* x=-1, => on disk. */ +} + +void mdrop(integer x,integer y,integer xl,integer yl, pointer p) /* assembler; +asm + push ds; { Strictly speaking, we shouldn't modify DS, so we'll save it.} + push bp; { Nor BP! } + + + { DI holds the offset on this page. It starts at the top left-hand corner. } + { (It should equal ch.y*80+ch.x. } + + mov ax,y; + mov dl,80; + mul dl; { Line offset now calculated. } + mov di,ax; { Move it into DI. } + mov ax,x; + add di,ax; { Full offset now calculated. } + + mov bx,yl; { No. of times to repeat lineloop. } + inc bx; { "loop" doesn't execute the zeroth time. } + mov bh,bl; { Put it into BH. } + + { BP holds the length of the string to copy. It's equal to ch.xl.} + + mov ax,word(p); { Data is held at DS:SI. } + mov si,ax; + mov ax,word(p+2); { This will be moved over into ds in just a tick... } + + mov bp,xl; + + mov ds,ax; + + + cld; { We're allowed to hack around with the flags! } + + mov ax,$AC00; { Top of the first EGA page. } + mov es,ax; { Offset on this page is calculated below... } + + +{ port[$3c4]:=2; port[$3ce]:=4; } + + mov dx,$3c4; + mov al,2; + out dx,al; + mov dx,$3ce; + mov al,4; + out dx,al; + + mov cx,4; { This loop executes for 3, 2, 1, and 0. } + mov bl,0; + + + @mainloop: + + push di; + push cx; + +{ port[$3C5]:=1 shl bit; } + mov dx,$3C5; + mov al,1; + mov cl,bl; { BL = bit. } + shl al,cl; + out dx,al; +{ port[$3CF]:=bit; } + mov dx,$3CF; + mov al,bl; { BL = bit. } + out dx,al; + + xor ch,ch; + mov cl,bh; { BH = ch.yl. } + + @lineloop: + + push cx; + + mov cx,bp; + + repz movsb; { Copy the data. } + + sub di,bp; + add di,80; + + pop cx; + + loop @lineloop; + + inc bl; { One more on BL. } + + pop cx; + pop di; + + loop @mainloop; + + pop bp; + pop ds; { Get DS back again. } +*/ +{; +} + +void show_one(byte which); + +static bytefield r; + +static void display_it(integer x,integer y,integer xl,integer yl, flavourtype flavour, pointer p) +{ + { + switch (flavour) { + case ch_bgi : { + putimage(x*8,y,p,0); + r.x1=x; r.y1=y; + r.x2=x+xl+1; r.y2=y+yl; + } + break; + case ch_ega : { + mdrop(x,y,xl,yl,p); blitfix(); + r.x1=x; r.y1=y; r.x2=x+xl; r.y2=y+yl; + } + break; + } +} +} + +void show_one(byte which) +{ + chunkblocktype ch; + pointer p; + byte fv; + + + setactivepage(3); + + { + memotype& with = memos[which]; + + if (with.x>on_disk) + { + display_it(with.x,with.y,with.xl,with.yl,with.flavour,memory[which]); + } else + { + reset(f,1); + seek(f,offsets[which]); + blockread(f,ch,sizeof(ch)); + + { + getmem(p,ch.size); + blockread(f,p,ch.size); + + display_it(ch.x,ch.y,ch.xl,ch.yl,ch.flavour,p); + freemem(p,ch.size); + + close(f); + } + + } + + setactivepage(1-cp); + + for( fv=0; fv <= 1; fv ++) + getset[fv].remember(r); + } + +} + +void show_one_at(byte which, integer xxx,integer yyy); + +static bytefield r1; + +static void display_it1(integer xl,integer yl, flavourtype flavour, pointer p, integer& xxx, integer& yyy) +{ + { + switch (flavour) { + case ch_bgi : { + putimage(xxx,yyy,p,0); + r1.x1=xxx; r1.y1=yyy; + r1.x2=xxx+xl+1; r1.y2=yyy+yl; + } + break; + case ch_ega : { + mdrop(xxx / 8,yyy,xl,yl,p); blitfix(); + r1.x1=xxx / 8; r1.y1=yyy; r1.x2=(xxx / 8)+xl; r1.y2=yyy+yl; + } + break; + } +} +} + +void show_one_at(byte which, integer xxx,integer yyy) +{ + chunkblocktype ch; + pointer p; + byte fv; + + + setactivepage(3); + + { + memotype& with = memos[which]; + + if (with.x>on_disk) + { + display_it1(with.xl,with.yl,with.flavour,memory[which], xxx, yyy); + } else + { + reset(f,1); + seek(f,offsets[which]); + blockread(f,ch,sizeof(ch)); + + { + getmem(p,ch.size); + blockread(f,p,ch.size); + + display_it1(ch.xl,ch.yl,ch.flavour,p, xxx, yyy); + freemem(p,ch.size); + + close(f); + } + + } + + setactivepage(1-cp); + + for( fv=0; fv <= 1; fv ++) + getset[fv].remember(r1); + } +} + +class unit_celer_initialize { + public: unit_celer_initialize(); +}; +static unit_celer_initialize celer_constructor; + +unit_celer_initialize::unit_celer_initialize() { + num_chunks=0; +} diff --git a/engines/avalanche/celer.h b/engines/avalanche/celer.h new file mode 100644 index 0000000000..f6ad52ffb1 --- /dev/null +++ b/engines/avalanche/celer.h @@ -0,0 +1,53 @@ +#ifndef __celer_h__ +#define __celer_h__ + + +#include "closing.h" +#include "incline.h" +#include "gyro.h" + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +struct memotype { + integer x,y; + integer xl,yl; + flavourtype flavour; + word size; +}; + + +#ifdef __celer_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN array<1,40,longint> offsets; +EXTERN byte num_chunks; +EXTERN array<1,40,memotype> memos; +EXTERN array<1,40,pointer> memory; +#undef EXTERN +#define EXTERN extern + + + void pics_link(); + + void load_chunks(string xx); + + void forget_chunks(); + + void show_one(byte which); + + void show_one_at(byte which, integer xxx,integer yyy); + +#endif diff --git a/engines/avalanche/ch_egats.cpp b/engines/avalanche/ch_egats.cpp new file mode 100644 index 0000000000..a27c2612c1 --- /dev/null +++ b/engines/avalanche/ch_egats.cpp @@ -0,0 +1,155 @@ +#include "ptoc.h" + + +#include "graph.h" + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +untyped_file f; +longint offset; +chunkblocktype ch; +integer gd,gm; +byte bit; +pointer p; + +void mdrop(integer x,integer y,integer xl,integer yl, pointer p) /* assembler; +asm + push ds; { Strictly speaking, we shouldn't modify DS, so we'll save it.} + push bp; { Nor BP! } + + + { DI holds the offset on this page. It starts at the top left-hand corner. } + { (It should equal ch.y*80+ch.x. } + + mov ax,y; + mov dl,80; + mul dl; { Line offset now calculated. } + mov di,ax; { Move it into DI. } + mov ax,x; + add di,ax; { Full offset now calculated. } + + mov bx,yl; { No. of times to repeat lineloop. } + inc bx; { "loop" doesn't execute the zeroth time. } + mov bh,bl; { Put it into BH. } + + { BP holds the length of the string to copy. It's equal to ch.xl.} + + mov ax,word(p); { Data is held at DS:SI. } + mov si,ax; + mov ax,word(p+2); { This will be moved over into ds in just a tick... } + + mov bp,xl; + + mov ds,ax; + + + cld; { We're allowed to hack around with the flags! } + + mov ax,$A000; { Top of the first EGA page. } + mov es,ax; { Offset on this page is calculated below... } + + +{ port[$3c4]:=2; port[$3ce]:=4; } + + mov dx,$3c4; + mov al,2; + out dx,al; + mov dx,$3ce; + mov al,4; + out dx,al; + + mov cx,4; { This loop executes for 3, 2, 1, and 0. } + mov bl,0; + + + @mainloop: + + push di; + push cx; + +{ port[$3C5]:=1 shl bit; } + mov dx,$3C5; + mov al,1; + mov cl,bl; { BL = bit. } + shl al,cl; + out dx,al; +{ port[$3CF]:=bit; } + mov dx,$3CF; + mov al,bl; { BL = bit. } + out dx,al; + + xor ch,ch; + mov cl,bh; { BH = ch.yl. } + + @lineloop: + + push cx; + + mov cx,bp; + + repz movsb; { Copy the data. } + + sub di,bp; + add di,80; + + pop cx; + + loop @lineloop; + + inc bl; { One more on BL. } + + pop cx; + pop di; + + loop @mainloop; + + pop bp; + pop ds; { Get DS back again. } +*/ +{; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + assign(f,"chunk21.avd"); + reset(f,1); + + seek(f,49); + blockread(f,offset,4); + + seek(f,offset); + + blockread(f,ch,sizeof(ch)); + + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + + getmem(p,ch.size); + blockread(f,p,ch.size); +/* putimage(0,0,p^,0);*/ + + +/* with ch do + for bit:=0 to 3 do + begin; + port[$3c4]:=2; port[$3ce]:=4; port[$3C5]:=1 shl bit; port[$3CF]:=bit; + for gm:=0 to yl do + blockread(f,mem[$A000*gm*80],(ch.xl+7) div 8); + end;*/ + + mdrop(ch.x,ch.y,ch.xl,ch.yl,p); + + close(f); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/charmap.cpp b/engines/avalanche/charmap.cpp new file mode 100644 index 0000000000..8b38f8ad62 --- /dev/null +++ b/engines/avalanche/charmap.cpp @@ -0,0 +1,30 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ + +struct infotype { + matrix<128,255,1,8,byte> chars; + string data; +}; +infotype table; +pointer where; +byte w,fv,ff,num; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + getintvec(0x1f,where); move(where,table,1024); + for( w=128; w <= 255; w ++) + {; output << w << NL; + for( fv=1; fv <= 8; fv ++) + {; + num=table.chars[w][fv]; + for( ff=1; ff <= 8; ff ++) + {; + if ((num & 128)==0) output << " "; else output << "ÛÛ"; + num=num << 1; + } + output << NL; + } } +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/chunker.cpp b/engines/avalanche/chunker.cpp new file mode 100644 index 0000000000..6d48054a2e --- /dev/null +++ b/engines/avalanche/chunker.cpp @@ -0,0 +1,86 @@ +#include "ptoc.h" + + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +untyped_file f; +string fn; +byte num_chunks,fv; +longint offset; +chunkblocktype ch; + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + output << NL; + output << "CHUNKER 12/3/1995 TT" << NL; + output << NL; + + if (paramcount!=1) + { + output << "which chunk file?" << NL; + exit(0); + } + + fn=paramstr(1); + assign(f,fn); + reset(f,1); + output << "----- In chunk file " << fn << ", there are: -----" << NL; + + seek(f,44); + blockread(f,num_chunks,1); + output << format(num_chunks,4) << " chunks:" << NL; + + output << " No Hdr Offset Flvr Mem Nat X Y Width Height Size of image" << NL; + + for( fv=1; fv <= num_chunks; fv ++) + { + + output << "Ch" << format(fv,2) << ':'; + + seek(f,41+fv*4); + + output << format(41+fv*4,4); + blockread(f,offset,4); + output << format(offset,10); + + seek(f,offset); + blockread(f,ch,sizeof(ch)); + { + if (ch.flavour==ch_bgi) + output << " ch_BGI"; + else + output << " ch_EGA"; + + if (ch.memorise) + output << " yes"; + else + output << " no "; + + if (ch.natural) + output << " yes"; + else + output << " no "; + + output << format(ch.x,7) << format(ch.y,7) << format(ch.xl,7) << format(ch.yl,7) << format(ch.size,10); + } + + output << NL; + } + + output << "---ENDS---" << NL; + + close(f); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/chunkxf1.cpp b/engines/avalanche/chunkxf1.cpp new file mode 100644 index 0000000000..dce3722837 --- /dev/null +++ b/engines/avalanche/chunkxf1.cpp @@ -0,0 +1,259 @@ +#include "ptoc.h" + + +#include "graph.h" +#include "cadburys.h" + + +/*type + flavourtype = (ch_EGA,ch_BGI); + + chunkblocktype = record + flavour:flavourtype; + x,y:integer; + xl,yl:integer; + size:longint; + natural:boolean; + + memorise:boolean; { Hold it in memory? } + end;*/ + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +/* arraysize = 12000;*/ + +/* offsets:array[1..30] of longint;*/ +byte num_chunks/*,this_chunk*/; +integer gd,gm; +/* f:file;*/ +/* aa:array[0..arraysize] of byte;*/ + +void load() +{ + byte a0 /*absolute $A000:800*/; + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + assign(f,"chunkbit.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + assign(f,"place21.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); +} + +void open_chunk() +{; + assign(f,"chunk21.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} +/* +procedure mgrab(x1,y1,x2,y2:integer; size:word); +var yy:integer; aapos:word; length,bit:byte; +begin; + if size>arraysize then + begin; + writeln('*** SORRY! *** Increase the arraysize constant to be greater'); + writeln(' than ',size,'.'); + halt; + end; + + aapos:=0; + + length:=x2-x1; + + for bit:=0 to 3 do + begin; + port[$3c4]:=2; port[$3ce]:=4; port[$3C5]:=1 shl bit; port[$3CF]:=bit; + for yy:=y1 to y2 do + begin; + move(mem[$A400*yy*80+x1],aa[aapos],length); + move(aa[aapos],mem[$A400*yy*80],length); +(* fillchar(mem[$A400:yy*80+x1],length,#177);*) + inc(aapos,length); + end; + end; + bit:=getpixel(0,0); + +end; +*/ +/*procedure grab(x1,y1,x2,y2,realx,realy:integer; flav:flavourtype; + mem,nat:boolean); + { yes, I *do* know how to spell "really"! } +var + s:word; + p:pointer; + ch:chunkblocktype; +begin; + inc(this_chunk); + offsets[this_chunk]:=filepos(f); + + + s:=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p^); + + with ch do + begin; + flavour:=flav; + x:=realx; y:=realy; + + xl:=x2-x1; + yl:=y2-y1; + size:=s; + memorise:=mem; + natural:=nat; + end; + + setvisualpage(1); + setactivepage(1); + readln; + putimage(ch.x,ch.y,p^,0); + + if flav=ch_EGA then + begin; + freemem(p,s); + s:=4*((x2-x1+7) div 8)*(y2-y1+1); + with ch do + begin; + size:=s; + x:=x div 8; + xl:=(xl+7) div 8; + mgrab(x,y,x+xl,y+yl,s); + end; + end; + + readln; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + case flav of + ch_EGA : if not nat then blockwrite(f,aa,s); + ch_BGI : begin; + if not nat then blockwrite(f,p^,s); + freemem(p,s); + end; + end; +{ rectangle(x1,y1,x2,y2);} +end;*/ + +/*procedure grab(x1,y1,x2,y2,realx,realy:integer; flav:flavourtype; + mem,nat:boolean);*/ + /* yes, I *do* know how to spell "really"! */ +/*var + s:word; + p:pointer; + ch:chunkblocktype; +begin; +(* rectangle(x1,y1,x2,y2); exit;*) + inc(this_chunk); + offsets[this_chunk]:=filepos(f); + + + s:=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p^); + + with ch do + begin; + flavour:=flav; + x:=realx; y:=realy; + + xl:=x2-x1; + yl:=y2-y1; + size:=s; + memorise:=mem; + natural:=nat; + end; + + setvisualpage(1); + setactivepage(1); + readln; + putimage(ch.x,ch.y,p^,0); + + if flav=ch_EGA then + begin; + freemem(p,s); + s:=4*(((x2 div 8)-(x1 div 8))+2)*(y2-y1+1); + with ch do + begin; + size:=s; + x:=x div 8; + xl:=(xl div 8)+2; + mgrab(x,y,x+xl,y+yl,s); + end; + end else + with ch do { For BGI pictures. *//* + begin; + x:=x div 8; + xl:=(xl+7) div 8; + size:=imagesize(x*8,y,(x+xl)*8,y+yl); + end; + + readln; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + case flav of + ch_EGA : if not nat then blockwrite(f,aa,s); + ch_BGI : begin; + if not nat then blockwrite(f,p^,s); + freemem(p,s); + end; + end; +(* rectangle(x1,y1,x2,y2);*) +end;*/ + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + setwritemode(xorput); + + num_chunks=7; + + open_chunk(); + + grab( 98,10,181,41,247,82,ch_ega,false,false); /* Drawbridge... */ + grab(223,10,320,41,233,82,ch_ega,false,false); + grab(361,10,458,64,233,82,ch_ega,false,false); + + grab( 11,10, 39,22,172,17,ch_bgi,true,true); + grab( 11,38, 39,50,172,17,ch_ega,true,false); /* Flag. */ + grab( 11,24, 39,36,172,17,ch_ega,true,false); + grab( 11,10, 39,22,172,17,ch_ega,true,false); + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxf2.cpp b/engines/avalanche/chunkxf2.cpp new file mode 100644 index 0000000000..5d77d298d2 --- /dev/null +++ b/engines/avalanche/chunkxf2.cpp @@ -0,0 +1,192 @@ +#include "ptoc.h" + + +#include "graph.h" + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 32000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void load() +{ + byte a0 /*absolute $A000:800*/; + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place9.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); +} + +void load_temp(string which) +{ + byte a0 /*absolute $A000:800*/; + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + assign(f,which); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + bit=getpixel(0,0); +} + +void open_chunk() +{; + assign(f,"chunk9.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); +} + +void grab(integer x1,integer y1,integer x2,integer y2, integer realx, integer realy, boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + if (nat) + ch.flavour=ch_bgi; + else ch.flavour=ch_ega; /* At the moment, Celer can't handle natural ch_EGAs. */ + ch.x=realx; + ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + freemem(p,s); + {; + if (ch.flavour==ch_bgi) s=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + else s=4*((x2-x1+7) / 8)*(y2-y1+1); + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + if (! nat) blockwrite(f,aa,s); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + load_temp("d:chunkbit.avd"); + setwritemode(xorput); + + num_chunks=7; + + open_chunk(); + + grab( 78, 78,232,102,212, 10,true,false); /* 154 across */ + grab(235, 78,389,102,212, 10,true,false); + grab(392, 78,546,102,212, 10,true,false); + grab(392, 78,546,102,212, 10,true,true); + + load_temp("d:chunkbi3.avd"); + + grab(437, 51,475, 78,147,120,false,false); /* 5 = door half-open. */ + grab(397, 51,435, 78,147,120,false,false); /* 6 = door open. */ + grab(397, 51,435, 78,147,120,true,true); /* 7 = door shut. */ + + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxf3.cpp b/engines/avalanche/chunkxf3.cpp new file mode 100644 index 0000000000..220d07b563 --- /dev/null +++ b/engines/avalanche/chunkxf3.cpp @@ -0,0 +1,250 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ +#include "cadburys.h" + + +/*type + flavourtype = (ch_EGA,ch_BGI); + + chunkblocktype = record + flavour:flavourtype; + x,y:integer; + xl,yl:integer; + size:longint; + natural:boolean; + + memorise:boolean; { Hold it in memory? } + end; + +const + chunkheader : array[1..44] of char = + 'Chunk-type AVD file, for an Avvy game.'+#26+#177+#$30+#$01+#$75+#177; + + arraysize = 12000; + +var + offsets:array[1..30] of longint; + num_chunks,this_chunk:byte; + gd,gm:integer; + f:file; + aa:array[0..arraysize] of byte;*/ + +string strf(longint x) +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void loadtemp(string n) +{ + byte a0 /*absolute $A000:800*/; + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + assign(f,n); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + bit=getpixel(0,0); + finder(); +} + +void load() +{ + byte a0 /*absolute $A000:800*/; + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + assign(f,"place22.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setactivepage(1); setvisualpage(1); finder(); + setactivepage(0); setvisualpage(0); +} + +void open_chunk() +{; + assign(f,"chunk22.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +/*procedure mgrab(x1,y1,x2,y2:integer; size:word); +var yy:integer; aapos:word; length,bit:byte; +begin; + if size>arraysize then + begin; + writeln('*** SORRY! *** Increase the arraysize constant to be greater'); + writeln(' than ',size,'.'); + halt; + end; + + aapos:=0; + + length:=x2-x1; + + for bit:=0 to 3 do + begin; + port[$3c4]:=2; port[$3ce]:=4; port[$3C5]:=1 shl bit; port[$3CF]:=bit; + for yy:=y1 to y2 do + begin; + move(mem[$A400*yy*80+x1],aa[aapos],length); + inc(aapos,length); + end; + end; + bit:=getpixel(0,0); + +end; + +procedure grab(x1,y1,x2,y2,realx,realy:integer; flav:flavourtype; + mem,nat:boolean); + { yes, I *do* know how to spell "really"! } +var + s:word; + p:pointer; + ch:chunkblocktype; +begin; + inc(this_chunk); + offsets[this_chunk]:=filepos(f); + + + s:=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p^); + + with ch do + begin; + flavour:=flav; + x:=realx; y:=realy; + + xl:=x2-x1; + yl:=y2-y1; + size:=s; + memorise:=mem; + natural:=nat; + end; + + setvisualpage(1); + setactivepage(1); + readln; + putimage(ch.x,ch.y,p^,0); + + if flav=ch_EGA then + begin; + freemem(p,s); + s:=4*((x2-x1+7) div 8)*(y2-y1+1); + with ch do + begin; + size:=s; + x:=x div 8; + xl:=(xl+7) div 8; + mgrab(x,y,x+xl,y+yl,s); + end; + end; + + readln; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + case flav of + ch_EGA : if not nat then blockwrite(f,aa,s); + ch_BGI : begin; + if not nat then blockwrite(f,p^,s); + freemem(p,s); + end; + end; +{ rectangle(x1,y1,x2,y2);} +end;*/ + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + loadtemp("chunkbit.avd"); load(); + setwritemode(xorput); + + num_chunks=9; + + open_chunk(); + + grab( 0,103,169,159, 72,86,ch_ega,false,false); /* Stairs... */ + grab(172,103,341,159, 72,86,ch_ega,false,false); + + loadtemp("chunkbi3.avd"); + + grab( 0,130, 79,157,341,94,ch_bgi,true ,true ); + grab( 0,130, 79,157,341,94,ch_ega,false,false); + grab( 0,102, 79,129,341,94,ch_ega,false,false); + grab( 0, 74, 79,101,341,94,ch_ega,false,false); /* Far door. */ + + loadtemp("chunkbi2.avd"); + + grab(393, 92,451,137,512,98,ch_bgi,true ,true ); /* Right-hand door. */ + grab(393, 92,451,137,512,98,ch_ega,false,false); + grab(453, 92,511,137,512,98,ch_ega,false,false); + + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxf4.cpp b/engines/avalanche/chunkxf4.cpp new file mode 100644 index 0000000000..2dfa34dc27 --- /dev/null +++ b/engines/avalanche/chunkxf4.cpp @@ -0,0 +1,285 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +enum kind {walled,unwalled, last_kind}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +const kind w = walled; const kind uw = unwalled; + +array<1,50,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void rdln() +{ + char r; + return; + do { r=readkey(); } while (!(! keypressed())); +} + +void load(kind k) +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; + + + if (k==unwalled) assign(f,"place29.avd"); + else assign(f,"walled.avd"); + + reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); +} + +void finder() +{ + char r; integer x,y; + return; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void loadtemp(string which) +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; + + + assign(f,string("corr")+which+"tmp.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{ + assign(f,"chunk29.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{ + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; + + if (size>arraysize) + { + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + { + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat, kind k) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; + +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + { + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + load(k); + + setvisualpage(1); + setactivepage(1); + rdln(); + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + { + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + { + ch.size=s; + ch.x=ch.x / 8; + ch.xl=((realx-ch.x*8)+(x2-x1)+7) / 8; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + { + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + rdln(); + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : { + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + setwritemode(xorput); + + loadtemp("2"); + + num_chunks=32; + + open_chunk(); + + grab( 0, 11,100,104,260,41,ch_ega,false,false,uw); /*1 Geida's door. */ + grab(103, 12,203, 55,207,61,ch_ega,false,false,uw); /*2 "Ite mingite" sign. */ + grab(123, 59,185,103,254,90,ch_ega,false,false,uw); /*3 Normal N door (rt handle)*/ + grab(227, 10,289, 56,254,88,ch_ega,false,false,uw); /*4 Normal N door (lt handle)*/ + grab(207, 63,294,105, 9,47,ch_ega,false,false, w); /*5 Window in left wall. */ + grab(312, 10,416, 56,233,88,ch_ega,false,false,uw); /*6 North archway */ + grab(331, 78,384,101, 32,64,ch_ega,false,false, w); /*7 2 torches, L wall. */ + grab(607,142,621,157,233,88,ch_ega,false,false,uw); /*8 1 torch, N wall. */ + grab(417, 11,577, 59,311,61,ch_ega,false,false,uw); /*9 "The Wrong Way!" sign. */ + + loadtemp("3"); + + grab( 0, 11, 62, 63,557,108,ch_ega,false,false, w); /*10 Near right candle */ + grab( 64, 11,120, 63, 18,108,ch_ega,false,false, w); /*11 Near left candle */ + grab(122, 11,169, 55, 93,100,ch_ega,false,false, w); /*12 Far left candle */ + grab(171, 11,222, 52,500,100,ch_ega,false,false, w); /*13 Far right candle */ + grab( 32, 68, 84,104,285, 70,ch_ega,false,false,uw); /*14 Far window */ + grab(138, 65,190, 92,233, 88,ch_ega,false,false,uw); /*15 Baron du Lustie pic 1 */ + grab(244, 65,296, 92,103, 51,ch_ega,false,false,uw); /*16 Baron du Lustie pic 2 */ + grab(172, 54,280, 63,233, 88,ch_ega,false,false,uw); /*17 "Art Gallery" sign */ + grab(341, 18,402, 47,563, 48,ch_ega,false,false, w); /*18 Right wall torches */ + grab(528, 10,639,160,528, 10,ch_ega,false,false,uw); /*19 Right wall */ + grab(430, 50,526, 88,543, 50,ch_ega,false,false, w); /*20 Window in right wall */ + grab(451, 91,494,152,566, 91,ch_ega,false,false, w); /*21 Door in right wall */ + grab(238, 10,307, 14,484,156,ch_ega,false,false, w); /*22 Near wall door: right */ + grab(239, 16,300, 20,300,156,ch_ega,false,false, w); /*23 Near wall door: middle */ + grab(234, 22,306, 26,100,156,ch_ega,false,false, w); /*24 Near wall door: left */ + grab( 25,113, 87,156,254, 90,ch_ega,false,false, w); /*25 Far door opening stage 1 */ + grab(131,113,193,156,254, 90,ch_ega,false,false, w); /*26 Far door opening stage 2 */ + grab(237,113,299,156,254, 90,ch_ega,false,false, w); /*27 Far door opening stage 3 */ + + loadtemp("4"); + + grab( 0, 11,112,160, 0, 11,ch_ega,false,false,uw); /*28 Left wall */ + grab(144, 44,197, 76, 30, 44,ch_ega,false,false, w); /*29 Shield on L wall. */ + grab(149, 90,192,152, 35, 90,ch_ega,false,false, w); /*30 Door in L wall. */ + grab(463, 28,527, 43,252,100,ch_ega,false,false, w); /*31 Archway x 2 */ + grab(463, 79,527, 94,252,100,ch_ega,false,false, w); /*32 Archway x 3 */ + + close_chunk(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxf5.cpp b/engines/avalanche/chunkxf5.cpp new file mode 100644 index 0000000000..c9766830ae --- /dev/null +++ b/engines/avalanche/chunkxf5.cpp @@ -0,0 +1,244 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"v:place1.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + + setvisualpage(1); setactivepage(1); + finder(); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"chunkbi9.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + setvisualpage(0); setactivepage(0); + finder(); +} + +void open_chunk() +{; + assign(f,"chunk1.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + if (! nat) putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2+7) / 8)-(x1 / 8))*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=9; + + open_chunk(); + + grab( 48, 42, 94, 66,400,105,ch_ega, true,false); /*1 Avvy asleep. */ + grab(100, 42,146, 66,400,105,ch_ega, true,false); /*2 Avvy asleep again. */ + grab(152, 42,198, 66,400,105,ch_ega,false,false); /*3 Avvy awake in bed. */ + grab(106,113,152,137,400,105,ch_bgi,true ,true ); /*4 No Avvy in bed. */ + + grab(206, 42,279, 75,150, 91,ch_ega,false,false); /*5 Open trunk. */ + grab(206, 42,287, 75,150, 91,ch_bgi,true, true); /*6 Shut trunk. */ + + grab( 69, 70,102, 88,431,100,ch_ega,false,false); /*7 Arkata 1. */ + grab(118, 70,151, 88,431,100,ch_ega,false,false); /*8 Arkata 2. */ + grab(167, 70,200, 88,431,100,ch_ega,false,false); /*9 Arkata 3. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxf6.cpp b/engines/avalanche/chunkxf6.cpp new file mode 100644 index 0000000000..665222252a --- /dev/null +++ b/engines/avalanche/chunkxf6.cpp @@ -0,0 +1,251 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +const integer x_ofs = 165; +const integer y_ofs = 58; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"v:place19.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"d:temp1.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + +/* finder;*/ +} + +void open_chunk() +{; + assign(f,"chunk19.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; + x1 -= x_ofs; x2 -= x_ofs; + y1 -= y_ofs; y2 -= y_ofs; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); +/* readln;*/ + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + +/* readln;*/ + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=13; + + open_chunk(); + + grab(165, 68,207, 87,127,105,ch_ega,false,false); /*1 The settle with no lute*/ + grab(209, 68,255, 96,159, 84,ch_bgi, true, true); /*2 Dogfood looks right. */ + grab(209, 68,255, 96,159, 84,ch_ega, true,false); /*3 Dogfood- straight ahead. */ + grab(257, 68,303, 96,159, 84,ch_ega, true,false); /*4 Dogfood- left. */ + grab(305, 68,351, 96,159, 84,ch_ega, true,false); /*5 DF drinks: stage 1. */ + grab(353, 68,399, 96,159, 84,ch_ega, true,false); /*6 DF drinks: stage 2. */ + grab(401, 68,447, 96,159, 84,ch_ega, true,false); /*7 DF drinks: stage 3. */ + grab(449, 84,465, 94,392, 87,ch_ega, true,false); /*8 Ibythneth smiles. */ + grab(449, 75,488, 82,341,123,ch_ega, true,false); /*9 No habit under the settle. */ + grab(508, 68,580,106,485,105,ch_ega, true,false); /*10 M gets your drink. */ + grab(508, 68,580,106,485,105,ch_bgi, true, true); /*11 M gets up again. */ + grab(470, 84,486, 91,510,108,ch_ega, true,false); /*12 M looks right. */ + grab(488, 84,504, 91,510,108,ch_ega, true,false); /*13 M winks. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxf7.cpp b/engines/avalanche/chunkxf7.cpp new file mode 100644 index 0000000000..97bacb5967 --- /dev/null +++ b/engines/avalanche/chunkxf7.cpp @@ -0,0 +1,236 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place25.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"chunkbi3.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk25.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=3; + + open_chunk(); + + grab( 16, 24,101, 45,448,116,ch_ega, true,false); /*2 The fire again. */ + grab(118, 20,203, 45,448,112,ch_bgi, true, true); /*1 The natural fire. */ + grab(118, 20,203, 45,448,112,ch_ega, true,false); /*3 Third stage of the fire. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxf8.cpp b/engines/avalanche/chunkxf8.cpp new file mode 100644 index 0000000000..4435ee48bd --- /dev/null +++ b/engines/avalanche/chunkxf8.cpp @@ -0,0 +1,243 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place23.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp(string x) +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,x); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk23.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp("chunkbi3.avd"); + setwritemode(xorput); + + num_chunks=6; + + open_chunk(); + + grab(226, 21,242, 29,348, 96,ch_bgi, true,true ); /*1 Looking forwards. */ + grab(226, 21,242, 29,348, 96,ch_ega, true,false); /*2 Looking left. */ + grab(253, 21,269, 29,348, 96,ch_ega, true,false); /*3 Looking right. */ + grab(240, 11,256, 19,348, 96,ch_ega, true,false); /*4 Blinking. */ + + loadtemp("chunkbi4.avd"); + + grab( 48, 83,110,126,324, 96,ch_ega,false,false); /*5 Eyes shut... */ + grab(112, 83,173,126,325, 96,ch_ega,false,false); /*6 Asleep. */ + + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxf9.cpp b/engines/avalanche/chunkxf9.cpp new file mode 100644 index 0000000000..96241d1487 --- /dev/null +++ b/engines/avalanche/chunkxf9.cpp @@ -0,0 +1,237 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place42.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"a:chunkbi3.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk42.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=4; + + open_chunk(); + + grab(276, 36,329, 73, 94, 97,ch_bgi, true,true ); /*1 Not tied to the tree.*/ + grab(276, 36,329, 73, 94, 97,ch_ega,false,false); /*2 Tied to the tree. */ + grab(182, 80,226, 88,311,132,ch_ega,false,false); /*3 Mushrooms have gone! */ + grab(253, 75,267, 82,114, 98,ch_ega,false,false); /*4 Avalot blinks. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfa.cpp b/engines/avalanche/chunkxfa.cpp new file mode 100644 index 0000000000..6493e5241f --- /dev/null +++ b/engines/avalanche/chunkxfa.cpp @@ -0,0 +1,240 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place7.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); +/* finder;*/ + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"chunkbi3.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + +/* finder;*/ +} + +void open_chunk() +{; + assign(f,"chunk7.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=7; + + open_chunk(); + + grab(220, 32,269, 62,370,115,ch_ega,false,false); /*1 Jacques awake... */ + grab(400, 12,450, 48,369,112,ch_ega,false,false); /*2 Jacques gone! */ + grab(116, 47,176, 98,393, 87,ch_ega,false,false); /*3 Jacques going... */ + grab(333, 31,393, 82,393, 87,ch_ega,false,false); /*4 The open door. */ + grab(396, 80,452,135, 39, 91,ch_ega,false,false); /*5 The left door opening. */ + grab(455, 80,510,135, 39, 91,ch_ega,false,false); /*6 The left door open. */ + grab(455, 80,510,135, 39, 91,ch_bgi,true ,true ); /*7 The left door shut. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfb.cpp b/engines/avalanche/chunkxfb.cpp new file mode 100644 index 0000000000..7fda96c375 --- /dev/null +++ b/engines/avalanche/chunkxfb.cpp @@ -0,0 +1,238 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place71.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"d:chunkbi2.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk71.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=5; + + open_chunk(); + + grab( 54, 57,124,116,188, 94,ch_ega,false,false); /*1 Door half-shut. */ + grab(144, 57,203,116,188, 94,ch_ega,false,false); /*2 Door shut. */ + grab(513, 92,572,151,188, 94,ch_ega,false,false); /*3 Door with arrow. */ + grab(610, 94,627,106,367,122,ch_ega,false,false); /*4 Holder with no pen. */ + grab( 54, 57,124,116,188, 94,ch_bgi,true ,true ); /*5 Door wide open. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfc.cpp b/engines/avalanche/chunkxfc.cpp new file mode 100644 index 0000000000..aefb15f8a2 --- /dev/null +++ b/engines/avalanche/chunkxfc.cpp @@ -0,0 +1,236 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place2.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"d:chunkbi2.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk2.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=3; + + open_chunk(); + + grab( 59, 15,166, 55,226, 86,ch_ega,false,false); /*1 Door half-shut. */ + grab(171, 15,278, 55,226, 86,ch_ega,false,false); /*2 Door half-open. */ + grab(283, 15,390, 55,226, 86,ch_ega,false,false); /*3 Door open. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfd.cpp b/engines/avalanche/chunkxfd.cpp new file mode 100644 index 0000000000..e87fbbabb1 --- /dev/null +++ b/engines/avalanche/chunkxfd.cpp @@ -0,0 +1,236 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place15.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"d:chunkbi3.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk15.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=3; + + open_chunk(); + + grab(535, 11,633, 74, 46, 97,ch_ega,false,false); /*1 Door half-open. */ + grab(539, 76,637,139, 46, 97,ch_ega,false,false); /*2 Door open. */ + grab(539, 76,637,139, 46, 97,ch_bgi,true ,true ); /*3 Door shut. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfe.cpp b/engines/avalanche/chunkxfe.cpp new file mode 100644 index 0000000000..adb7f8628e --- /dev/null +++ b/engines/avalanche/chunkxfe.cpp @@ -0,0 +1,236 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place5.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"chunkbi2.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk5.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=3; + + open_chunk(); + + grab(252, 57,375,132,501, 85,ch_ega,false,false); /*1 Door half-open. */ + grab(418, 15,553, 90,504, 85,ch_ega,false,false); /*2 Door open. */ + grab(252, 57,375,132,504, 85,ch_bgi,true ,true ); /*3 Door shut. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxff.cpp b/engines/avalanche/chunkxff.cpp new file mode 100644 index 0000000000..9fb2a2ed59 --- /dev/null +++ b/engines/avalanche/chunkxff.cpp @@ -0,0 +1,236 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place13.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"chunkbi3.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk13.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=3; + + open_chunk(); + + grab(323, 84,393,123,266, 72,ch_ega,false,false); /*1 Door half-open. */ + grab(251, 84,321,123,266, 72,ch_ega,false,false); /*2 Door open. */ + grab(251, 84,321,123,266, 72,ch_bgi,true ,true ); /*3 Door shut. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfg.cpp b/engines/avalanche/chunkxfg.cpp new file mode 100644 index 0000000000..077a330afe --- /dev/null +++ b/engines/avalanche/chunkxfg.cpp @@ -0,0 +1,236 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place16.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"chunkbi3.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk16.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=3; + + open_chunk(); + + grab(336, 12,365, 28,187, 89,ch_ega,false,false); /*1 Ayles asleep frame 2. */ + grab(368, 12,397, 28,187, 89,ch_ega,false,false); /*2 Ayles awake. */ + grab(336, 12,365, 28,187, 89,ch_bgi,true ,true ); /*3 Ayles asleep frame 1. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfh.cpp b/engines/avalanche/chunkxfh.cpp new file mode 100644 index 0000000000..163ae51219 --- /dev/null +++ b/engines/avalanche/chunkxfh.cpp @@ -0,0 +1,237 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place46.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"d:chunkbi4.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk46.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=4; + + open_chunk(); + + grab(136, 11,216, 49,288,104,ch_ega,false,false); /*1 Door opening, frame 1.*/ + grab( 45, 11,124, 49,289,104,ch_ega,false,false); /*2 Door opening, frame 2.*/ + grab(227, 11,306, 49,289,104,ch_ega,false,false); /*3 Door opening, frame 3.*/ + grab(227, 11,306, 49,289,104,ch_bgi,true ,true ); /*4 Natural frame. */ + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfi.cpp b/engines/avalanche/chunkxfi.cpp new file mode 100644 index 0000000000..84157a84c5 --- /dev/null +++ b/engines/avalanche/chunkxfi.cpp @@ -0,0 +1,246 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; +; + + assign(f,"place47.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; +; + + assign(f,"chunkbi9.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{; + assign(f,"chunk47.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{; + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; +; + if (size>arraysize) + {; + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + {; + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; +; +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + {; + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + {; + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + {; + ch.size=s; + ch.x=ch.x / 8; + ch.xl=(ch.xl / 8)+2; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + {; + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : {; + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=10; + + open_chunk(); + + grab(323, 35,340, 43,337, 93,ch_ega,true ,false); /*1 Port blinks */ + grab(323, 35,340, 43,337, 93,ch_bgi,true ,true ); /*2 Port normally */ + grab(421, 22,511, 71,474,101,ch_ega,false,false); /*3 Avalot & Spurge */ + grab(421, 22,511, 71,474,101,ch_bgi,true ,true ); /*4 Just Spurge. */ + + grab(524, 40,540, 47,337, 93,ch_ega,true ,false); /*5 Port L blinks */ + grab(524, 22,540, 29,337, 93,ch_ega,true ,false); /*6 Port L */ + grab(563, 40,579, 47,337, 93,ch_ega,true ,false); /*7 Port R blinks */ + grab(563, 22,579, 29,337, 93,ch_ega,true ,false); /*8 Port R */ + + grab(307, 38,310, 38,493,104,ch_ega,true ,false); /*9 Spurge blinks */ + grab(307, 38,310, 38,493,104,ch_bgi,true ,true ); /*10 Spurge doesn't blink */ + + close_chunk(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfj.cpp b/engines/avalanche/chunkxfj.cpp new file mode 100644 index 0000000000..34a7109acc --- /dev/null +++ b/engines/avalanche/chunkxfj.cpp @@ -0,0 +1,237 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; + + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; + + + assign(f,"place20.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; + + + assign(f,"chunkbit.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{ + assign(f,"chunk20.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{ + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; + + if (size>arraysize) + { + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + { + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; + +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + { + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + { + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + { + ch.size=s; + ch.x=ch.x / 8; + ch.xl=((realx-ch.x*8)+(x2-x1)+7) / 8; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + { + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : { + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=4; + + open_chunk(); + + grab( 57, 11, 72, 18,399, 13,ch_ega,true ,false); /* 1 - all numbers are */ + grab( 57, 21, 72, 28,399, 13,ch_ega,true ,false); /* 2 flags. */ + grab( 56, 31, 71, 38,399, 13,ch_ega,true ,false); /* 3 */ + grab( 56, 31, 71, 38,399, 13,ch_bgi,true ,true ); /* 4, the natural one. */ + close_chunk(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfk.cpp b/engines/avalanche/chunkxfk.cpp new file mode 100644 index 0000000000..70748b9a5f --- /dev/null +++ b/engines/avalanche/chunkxfk.cpp @@ -0,0 +1,237 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + + +enum flavourtype {ch_ega,ch_bgi, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; + boolean natural; + + boolean memorise; /* Hold it in memory? */ +}; + +const array<1,44,char> chunkheader = +string("Chunk-type AVD file, for an Avvy game.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer arraysize = 12000; + +array<1,30,longint> offsets; +byte num_chunks,this_chunk; +integer gd,gm; +untyped_file f; +array<0,arraysize,byte> aa; + +void finder() +{ + char r; integer x,y; + + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; + + + assign(f,"place50.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; + + + assign(f,"chunkbi4.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{ + assign(f,"chunk50.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{ + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +void mgrab(integer x1,integer y1,integer x2,integer y2, word size) +{ + integer yy; word aapos; byte length,bit; + + if (size>arraysize) + { + restorecrtmode(); + output << "*** SORRY! *** Increase the arraysize constant to be greater" << NL; + output << " than " << size << '.' << NL; + exit(0); + } + + aapos=0; + + length=x2-x1; + + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( yy=y1; yy <= y2; yy ++) + { + move(mem[0xa400*yy*80+x1],aa[aapos],length); + aapos += length; + } + } + bit=getpixel(0,0); + +} + +void grab(integer x1,integer y1,integer x2,integer y2,integer realx,integer realy, flavourtype flav, + boolean mem,boolean nat) + /* yes, I *do* know how to spell "really"! */ +{ + word s; + pointer p; + chunkblocktype ch; + +/* rectangle(x1,y1,x2,y2); exit;*/ + this_chunk += 1; + offsets[this_chunk]=filepos(f); + + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + + { + ch.flavour=flav; + ch.x=realx; ch.y=realy; + + ch.xl=x2-x1; + ch.yl=y2-y1; + ch.size=s; + ch.memorise=mem; + ch.natural=nat; + } + + setvisualpage(1); + setactivepage(1); + input >> NL; + putimage(ch.x,ch.y,p,0); + + if (flav==ch_ega) + { + freemem(p,s); + s=4*(((x2 / 8)-(x1 / 8))+2)*(y2-y1+1); + { + ch.size=s; + ch.x=ch.x / 8; + ch.xl=((realx-ch.x*8)+(x2-x1)+7) / 8; + mgrab(ch.x,ch.y,ch.x+ch.xl,ch.y+ch.yl,s); + } + } else + /* For BGI pictures. */ + { + ch.x=ch.x / 8; + ch.xl=(ch.xl+7) / 8; + ch.size=imagesize(ch.x*8,ch.y,(ch.x+ch.xl)*8,ch.y+ch.yl); + } + + input >> NL; + setvisualpage(0); + setactivepage(0); + + blockwrite(f,ch,sizeof(ch)); + + switch (flav) { + case ch_ega : if (! nat) blockwrite(f,aa,s); break; + case ch_bgi : { + if (! nat) blockwrite(f,p,s); + freemem(p,s); + } + break; + } +/* rectangle(x1,y1,x2,y2);*/ +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=4; + + open_chunk(); + + grab( 46, 53,107, 81,246, 88,ch_ega,false,false); /*1 - all numbers are */ + grab(115, 53,175, 81,248, 88,ch_ega,false,false); /*2 door stages. */ + grab(180, 53,241, 81,246, 88,ch_ega,false,false); /*3 */ + grab(180, 53,246, 84,246, 88,ch_bgi,true ,true ); /*4 */ + close_chunk(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/chunkxfl.cpp b/engines/avalanche/chunkxfl.cpp new file mode 100644 index 0000000000..01a05509b6 --- /dev/null +++ b/engines/avalanche/chunkxfl.cpp @@ -0,0 +1,127 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ +#include "cadburys.h" + + +void finder() +{ + char r; integer x,y; + + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +void load() +{ + byte a1 /*absolute $A400:800*/; + byte bit; + untyped_file f; + + + assign(f,"place51.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a1,12080); + } + + close(f); + bit=getpixel(0,0); + setvisualpage(1); setactivepage(1); + finder(); + setvisualpage(0); setactivepage(0); +} + +void loadtemp() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; + + + assign(f,"chunkbi4.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + + bit=getpixel(0,0); + + finder(); +} + +void open_chunk() +{ + assign(f,"chunk51.avd"); + rewrite(f,1); + blockwrite(f,chunkheader,sizeof(chunkheader)); + blockwrite(f,num_chunks,1); + blockwrite(f,offsets,num_chunks*4); + + this_chunk=0; +} + +void close_chunk() +{ + seek(f,45); + blockwrite(f,offsets,num_chunks*4); /* make sure they're right! */ + close(f); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); + loadtemp(); + setwritemode(xorput); + + num_chunks=9; + + open_chunk(); + + grab(346,119,404,154,539,116,ch_ega,true ,false); /*1 fire */ + grab(435,119,490,154,541,116,ch_ega,true ,false); /*2 fire */ + grab(435,119,490,154,541,116,ch_bgi,true ,true ); /*3 natural fire */ + + grab(300, 58,315, 68,258, 95,ch_ega,true ,false); /*6 Duck's head 2 */ + grab(246, 52,259, 62,258, 95,ch_ega,true ,false); /*5 Duck blinks 1 */ + + grab(300, 58,315, 68,258, 95,ch_bgi,true ,true ); /*4 Duck's head 1 */ + grab(262, 52,278, 62,257, 95,ch_ega,true ,false); /*7 Duck blinks 2 */ + + grab(333, 58,347, 68,258, 95,ch_ega,true ,false); /*8 Duck's head 3 */ + grab(250, 63,265, 73,258, 95,ch_ega,true ,false); /*9 Duck blinks 3 */ + + close_chunk(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/clock.cpp b/engines/avalanche/clock.cpp new file mode 100644 index 0000000000..16ec6f552b --- /dev/null +++ b/engines/avalanche/clock.cpp @@ -0,0 +1,60 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ +#include "graph.h" +/*#include "Crt.h"*/ + +const integer xm = 511; const integer ym = 184; +integer gd,gm; +word oh,om,/*os,*/h,m,s,s1; char r; + +void hand(word ang,word length, byte colour) +{ + arccoordstype a; +; + if (ang>900) return; + setcolor(colour); + arc(xm,ym,449-ang,450-ang,length); + getarccoords(a); + line(xm,ym,a.xend,a.yend); /* "With a do-line???!", Liz said */ +} + +void chime() +{ + integer gd,gm,fv; +; + if (oh>177) return; /* too high- must be first time around */ + fv=h / 30; if (fv==0) fv=12; + for( gd=1; gd <= fv; gd ++) + {; + for( gm=1; gm <= 3; gm ++) + {; + sound(140-gm*30); delay(50-gm*3); + } + nosound; if ((cardinal)gd!=oh) delay(100); + } +} + +void plothands() +{; + hand(oh,17,brown); + hand(h,17,yellow); + hand(om*6,20,brown); + hand(m*6,20,yellow); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + setfillstyle(1,6); bar(0,0,640,200); oh=17717; om=17717; + do { + gettime(h,m,s,s1); + h=(h % 12)*30+m / 2; + if (oh!=h) {; plothands(); chime(); } + if (om!=m) plothands(); + oh=h; om=m; + } while (!false); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/closing.cpp b/engines/avalanche/closing.cpp new file mode 100644 index 0000000000..b2af98740f --- /dev/null +++ b/engines/avalanche/closing.cpp @@ -0,0 +1,119 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + CLOSING The closing screen and error handler. */ + +#define __closing_implementation__ + + +#include "closing.h" + + +#include "gyro.h" +#include "Graph.h" +/*#include "Crt.h"*/ +#include "lucerna.h" + + +typedef array<1,3840,char> scrtype; + +scrtype q /*absolute $B8FA:0*/; /* Nobody's using the graphics memory now. */ +file<scrtype> f; +pointer exitsave; + +void get_screen(byte which) +{; + closegraph(); + textattr=0; clrscr; + assign(f,string("text")+strf(which)+".scr"); reset(f); f >> q; close(f); +} + +void show_screen() +{ + byte fv,ff,fq, tl,bl; + scrtype a /*absolute $B800:0*/; +; + for( fv=1; fv <= 40; fv ++) + {; + if (fv>36) {; tl=1; bl=24; } + else {; tl=12-fv / 3; bl=12+fv / 3; } + for( fq=tl; fq <= bl; fq ++) + for( ff=80-fv*2; ff <= 80+fv*2; ff ++) + a[fq*160-ff]=q[fq*160-ff]; + delay(5); + } + gotoxy(1,25); textattr=31; clreol; gotoxy(1,24); +} + +void quit_with(byte which,byte errorlev) +{; + dusk(); + get_screen(which); + show_screen(); /* No changes. */ + exit(errorlev); +} + +void put_in(string x, word where) +{ + word fv; +; + for( fv=1; fv <= length(x); fv ++) + q[1+(where+fv)*2]=x[fv]; +} + +void end_of_program() + +{ + const array<0,11,varying_string<11> > nouns = + {{"sackbut","harpsichord","camel","conscience","ice-cream","serf", + "abacus","castle","carrots","megaphone","manticore","drawbridge"}}; + + const array<0,11,varying_string<9> > verbs = + {{"haunt","daunt","tickle","gobble","erase","provoke","surprise", + "ignore","stare at","shriek at","frighten","quieten"}}; + + string result; +; + nosound; + get_screen(scr_nagscreen); + result=nouns[Random(12)]+" will "+verbs[Random(12)]+" you"; + put_in(result,1628); + show_screen(); /* No halt- it's already set up. */ +} + +/*$F+*/ + +void bug_handler() +{; + exitproc=exitsave; + + if (erroraddr!=nil) + {; /* An error occurred! */ + if (exitcode==203) + get_screen(scr_ramcram); + else + {; + get_screen(scr_bugalert); + put_in(strf(exitcode),678); /* 678 = [38,8]. */ + put_in(strf(seg(erroraddr))+':'+strf(ofs(erroraddr)),758); /* 758 = [38,9]. */ + } + show_screen(); + erroraddr=nil; + } +} + +/*$F-*/ + +class unit_closing_initialize { + public: unit_closing_initialize(); +}; +static unit_closing_initialize closing_constructor; + +unit_closing_initialize::unit_closing_initialize() {; + exitsave=exitproc; + exitproc=&bug_handler; +} diff --git a/engines/avalanche/closing.h b/engines/avalanche/closing.h new file mode 100644 index 0000000000..97dd37e0c3 --- /dev/null +++ b/engines/avalanche/closing.h @@ -0,0 +1,15 @@ +#ifndef __closing_h__ +#define __closing_h__ + + +const integer scr_bugalert = 1; +const integer scr_ramcram = 2; +const integer scr_nagscreen = 3; +const integer scr_twocopies = 5; + + +void quit_with(byte which,byte errorlev); + +void end_of_program(); + +#endif diff --git a/engines/avalanche/convert.cpp b/engines/avalanche/convert.cpp new file mode 100644 index 0000000000..08639eecd7 --- /dev/null +++ b/engines/avalanche/convert.cpp @@ -0,0 +1,79 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; +string fn1,fn2; +varying_string<30> desc; + +void loadscreen(string nam) +{ + byte z; + array<1,4,pointer> a; + untyped_file f; word s; + string check; +; + assign(f,nam); + reset(f,1); + blockread(f,check,41); + blockread(f,check,13); + blockread(f,check,31); + s=imagesize(0,0,getmaxx(),75); + for( z=1; z <= 2; z ++) + {; + getmem(a[z],s); + blockread(f,a[z],s); + setactivepage(0); + putimage(0,15+(z-1)*75,a[z],0); + freemem(a[z],s); + } + close(f); +} + +void load2(string name) +{ + byte a /*absolute $A000:1200*/; + byte bit; + untyped_file f; +; + assign(f,name); reset(f,1); seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a,12080); + } + close(f); +} + +void save2(string name) +{ + const string header = + string("This is a file from an Avvy game, and its contents are subject to ")+ + "copyright."+'\15'+'\12'+'\15'+'\12'+"Have fun!"+'\32'; + byte a /*absolute $A000:1200*/; + byte bit; + untyped_file f; +; + assign(f,name); rewrite(f,1); blockwrite(f,header[1],146); /* really 90 */ + blockwrite(f,desc,31); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,a,12080); + } + close(f); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + output << "Filename?"; input >> fn1 >> NL; + output << "New name?"; input >> fn2 >> NL; + output << "Describe?"; input >> desc >> NL; + gd=3; gm=0; initgraph(gd,gm,""); + loadscreen(fn1); + save2(fn2); + closegraph(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/convmous.cpp b/engines/avalanche/convmous.cpp new file mode 100644 index 0000000000..c607b11e22 --- /dev/null +++ b/engines/avalanche/convmous.cpp @@ -0,0 +1,80 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Binu.h"*/ +/*#include "Crt.h"*/ + + + /* ...gogogoch */struct cursor { + matrix<0,1,0,15,word> mask; + integer horzhotspot,verthotspot; + }; +typedef /* ha ha */matrix<0,1,0,15,varying_string<16> > precursor; + +const array<0,3,byte> colours = {{darkgray,blue,white,green}}; + +cursor c_current; +boolean usepointer; +precursor cpc; +byte hhs,vhs; +string fn,desc; +integer gd,gm; + +void recalc() +{ + byte a,b; +; + {; + for( a=0; a <= 1; a ++) + for( b=0; b <= 15; b ++) + c_current.mask[a][b]=bintoword(cpc[a][b]); + c_current.horzhotspot=hhs; c_current.verthotspot=vhs; + } +} + +void load() +{ + text t; string x; byte a,b; +; + assign(t,fn); + reset(t); + do { t >> x >> NL; } while (!(x=='|')); /* bypass junk */ + t >> desc >> NL; + for( a=0; a <= 1; a ++) + for( b=0; b <= 15; b ++) + t >> cpc[a][b] >> NL; + t >> hhs >> NL; t >> vhs >> NL; + close(t); recalc(); +} + +void display() +{ + const integer o0 = ord('0'); const integer o1 = ord('1'); + byte x,y,p1,p2; +; + for( y=0; y <= 15; y ++) + {; + for( x=1; x <= 16; x ++) + {; + switch (ord(cpc[0][y][x])*2+ord(cpc[1][y][x])) { + case o0*2+o0: {; p1= 0; p2= 0; } break; /* p1= silhouette, p2= real */ + case o0*2+o1: {; p1= 0; p2=15; } break; + case o1*2+o0: {; p1=15; p2= 0; } break; + case o1*2+o1: {; p1= 9; p2= 9; } break; /* invalid- can't use this */ + } + putpixel(x-1,y,p1); putpixel(x+99,y,p2); + } + output << NL; + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=1; initgraph(gd,gm,""); + fn="d:screwdri.inc"; + load(); + display(); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/credits.cpp b/engines/avalanche/credits.cpp new file mode 100644 index 0000000000..7669c85eaa --- /dev/null +++ b/engines/avalanche/credits.cpp @@ -0,0 +1,88 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +/*$R+*/ + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +integer gd,gm; +text t; +array<1,2,fonttype> f; +file<fonttype> ff; +array<1,80,byte> l; +varying_string<80> x; + +void do_one(byte z) +{ + byte a /*absolute $A000:0*/; + byte aa /*absolute $A000:80*/; + byte az /*absolute $A000:27921*/; +; + a=getpixel(0,0); + move(l,az,z); + + port[0x3c5]=8; port[0x3cf]=0; + move(aa,a,27920); +} + +void background() +{ + byte y; +; + for( y=1; y <= 15; y ++) + {; + setcolor(y); + outtextxy(17,y*12,"Jesus is Lord!"); + } +} + +void scroll(string z) +{ + byte x,y,lz; char c; +; + fillchar(l,80,'\0'); + if (z=="") + for( y=1; y <= 12; y ++) do_one(0); + c=z[1]; Delete(z,1,1); + lz=length(z); + switch (c) { + case '*': for( y=0; y <= 15; y ++) + {; + for( x=1; x <= lz; x ++) + l[x]=f[2][z[x]][y]; + do_one(lz); + } + break; + case '>': {; + lz += 7; + for( y=0; y <= 13; y ++) + {; + for( x=1; x <= lz; x ++) + l[x+7]=f[1][z[x]][y]; + do_one(lz); do_one(lz); /* double-height characters */ + } + } + break; + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=1; initgraph(gd,gm,""); + port[0x3c4]=2; port[0x3cf]=4; + assign(ff,"avalot.fnt"); reset(ff); ff >> f[1]; close(ff); + assign(ff,"avitalic.fnt"); reset(ff); ff >> f[2]; close(ff); + assign(t,"credits.txt"); reset(t); + background(); + for( gd=8; gd <= 15; gd ++) setpalette(gd,62); + do { + t >> x >> NL; + scroll(x); + } while (!(eof(t) || keypressed())); + close(t); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/displtxt.cpp b/engines/avalanche/displtxt.cpp new file mode 100644 index 0000000000..3c706dc14d --- /dev/null +++ b/engines/avalanche/displtxt.cpp @@ -0,0 +1,34 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + + +const char fn[] = "text3.scr"; + +typedef array<1,3840,char> atype; + +file<atype> f; +word fv,ff,fq,st; +char r; +byte tl,bl; +atype q; +atype a /*absolute $B800:0*/; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + textattr=0; clrscr; + assign(f,fn); reset(f); f >> q; close(f); + for( fv=1; fv <= 40; fv ++) + {; + if (fv>36) {; tl=1; bl=24; } + else {; tl=12-fv / 3; bl=12+fv / 3; } + for( fq=tl; fq <= bl; fq ++) + for( ff=80-fv*2; ff <= 80+fv*2; ff ++) + a[fq*160-ff]=q[fq*160-ff]; + delay(5); + } + gotoxy(1,25); textattr=31; clreol; gotoxy(1,24); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/dropdown.cpp b/engines/avalanche/dropdown.cpp new file mode 100644 index 0000000000..6c03a4724d --- /dev/null +++ b/engines/avalanche/dropdown.cpp @@ -0,0 +1,802 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + DROPDOWN A customised version of Oopmenu (qv). */ + +#define __dropdown_implementation__ + + +#include "dropdown.h" + + +/*#include "Crt.h"*/ +#include "graph.h" +/*#include "Dos.h"*/ +#include "lucerna.h" +#include "Gyro.h" +#include "acci.h" +#include "trip5.h" +#include "enid.h" +#include "basher.h" + +/*$V-*/ +const integer indent = 5; +const integer spacing = 10; + +/* menu_b = blue; { Morpheus } + menu_f = yellow; + menu_border = black; + highlight_b = lightblue; + highlight_f = yellow; + disabled = lightgray; */ + +const integer menu_b = lightgray; /* Windowsy */ +const integer menu_f = black; +const integer menu_border = black; +const integer highlight_b = black; +const integer highlight_f = white; +const integer disabled = darkgray; + +char r; +byte fv; + +void find_what_you_can_do_with_it() +{; + switch (thinks) { + case wine:case ink: verbstr=string(vb_exam)+vb_drink; break; + case bell: verbstr=string(vb_exam)+vb_ring; break; + case potion:case wine: verbstr=string(vb_exam)+vb_drink; break; + case chastity: verbstr=string(vb_exam)+vb_wear; break; + case lute: verbstr=string(vb_exam)+vb_play; break; + case mushroom:case onion: verbstr=string(vb_exam)+vb_eat; break; + case clothes: verbstr=string(vb_exam)+vb_wear; break; + default: verbstr=vb_exam; /* anything else */ + } +} + +void chalk(integer x,integer y, char t, string z, boolean valid) +{ + byte fv,ff,p,bit; + word pageseg; + byte ander; +; + + pageseg=0xa000+cp*0x400; + + if (valid) ander=255; else ander=170; + + for( fv=1; fv <= length(z); fv ++) + for( ff=0; ff <= 7; ff ++) + for( bit=0; bit <= 2; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + mem[pageseg*x+fv-1+(y+ff)*80]=~ (little[z[fv]][ff] & ander); + } + + for( ff=0; ff <= 8; ff ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << 3; port[0x3cf]=3; + fillchar(mem[pageseg*x+(y+ff)*80],length(z),'\0'); /* blank it out. */ + } + + p=pos(t,z); if (p==0) return; p -= 1; + + for( bit=0; bit <= 2; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + mem[pageseg*x+p+(y+8)*80]=~ ander; + } + + blitfix(); +} + +void hlchalk(integer x,integer y, char t, string z, boolean valid) + /* Highlighted. */ +{ + byte fv,ff,p; + word pageseg; + byte ander; +; + + pageseg=0xa000+cp*0x400; + + if (valid) ander=255; else ander=170; + + for( fv=1; fv <= length(z); fv ++) + for( ff=0; ff <= 7; ff ++) + mem[pageseg*x+fv-1+(y+ff)*80]=little[z[fv]][ff] & ander; + + p=pos(t,z); if (p==0) return; p -= 1; + + mem[pageseg*x+p+(y+8)*80]=ander; + blitfix(); +} + +/*procedure say(x,y:integer; t:char; z:string; f,b:byte); +begin; + settextjustify(0,2); setfillstyle(1,b); setcolor(f); + bar(x-3,y-1,x+textwidth(z)+3,y+textheight(z)); + chalk(x,y,t,z); +end;*/ + +void bleep() +{; + sound(177); delay(7); nosound; +} + +void onemenu::start_afresh() +{; + number=0; width=0; firstlix=false; oldy=0; highlightnum=0; +} + +onemenu* onemenu::init() +{; + menunow=false; ddmnow=false; menunum=1; + return this; +} + +void onemenu::opt(string n, char tr, string key, boolean val) +{ + integer l; +; + number += 1; + l=length(n+key)+3; if (width<l) width=l; + { + optiontype& with = oo[number]; + ; + with.title=n; + with.trigger=tr; + with.shortcut=key; + with.valid=val; + } +} + +void onemenu::displayopt(byte y, boolean highlit) +{ + string data; +; + { + optiontype& with = oo[y]; + ; + + if (highlit) + setfillstyle(1,0); + else + setfillstyle(1,7); + bar((flx1+1)*8,3+y*10,(flx2+1)*8,12+y*10); + +/* settextjustify(2,2); + if shortcut>'' then outtextxy(flx2,4+y*10,shortcut);*/ + + data=with.title; + + while (length(data+with.shortcut)<width) + data=data+' '; /* Pad with spaces. */ + + data=data+with.shortcut; + + if (highlit) + hlchalk(left,4+y*10,with.trigger,data,with.valid); + else + chalk(left,4+y*10,with.trigger,data,with.valid); + + } +} + +void onemenu::display() +{ + byte y; +; + off(); + setactivepage(cp); setvisualpage(cp); + setfillstyle(1,menu_b); setcolor(menu_border); + firstlix=true; + flx1=left-2; flx2=left+width; fly=14+number*10; + menunow=true; ddmnow=true; + + bar((flx1+1)*8,12,(flx2+1)*8,fly); + rectangle((flx1+1)*8-1,11,(flx2+1)*8+1,fly+1); + + displayopt(1,true); + for( y=2; y <= number; y ++) + { optiontype& with = oo[y]; displayopt(y,false);} + defaultled=1; cmp=177; mousepage(cp); on(); /* 4= fletch */ +} + +void onemenu::wipe() +{ + bytefield r; +; + setactivepage(cp); + off(); + { headtype& with = ddm_m.ddms[ddm_o.menunum]; + chalk(with.xpos,1,with.trigger,with.title,true);} +/* mblit((flx1-3) div 8,11,((flx2+1) div 8)+1,fly+1,3,cp);*/ + +/* with r do + begin; + x1:=flx1; + y1:=11; + x2:=flx2+1; + y2:=fly+1; + end; + getset[cp].remember(r);*/ + + mblit(flx1,11,flx2+1,fly+1,3,cp); blitfix(); + menunow=false; ddmnow=false; firstlix=false; defaultled=2; + on_virtual(); +} + +void onemenu::movehighlight(shortint add) +{ + shortint hn; +; + if (add!=0) + {; + hn=highlightnum+add; + if ((hn<0) || (hn>=(unsigned char)number)) return; + highlightnum=hn; + } + setactivepage(cp); off(); + displayopt(oldy+1,false); + displayopt(highlightnum+1,true); + setactivepage(1-cp); + oldy=highlightnum; on(); +} + +void onemenu::lightup() /* This makes the menu highlight follow the mouse.*/ +{; + if ((mx<(cardinal)flx1*8) || (mx>(cardinal)flx2*8) || (my<=12) || (my>(cardinal)fly-3)) return; + highlightnum=(my-13) / 10; + if (highlightnum==oldy) return; + movehighlight(0); +} + +void onemenu::select(byte n) /* Choose which one you want. */ +{; + if (! oo[n+1].valid) return; + choicenum=n; wipe(); + + if (choicenum==number) choicenum -= 1; /* Off the bottom. */ + if (choicenum>number) choicenum=0; /* Off the top, I suppose. */ + + ddm_m.ddms[menunum].do_choose(); +} + +void onemenu::keystroke(char c) +{ + byte fv; boolean found; +; + c=upcase(c); found=false; + for( fv=1; fv <= number; fv ++) + { optiontype& with = oo[fv]; + if ((upcase(with.trigger)==c) && with.valid) + {; + select(fv-1); + found=true; + }} + if (! found) blip(); +} + + headtype* headtype::init + (char trig,char alttrig, string name, byte p, proc dw,proc dc) + {; + trigger=trig; alttrigger=alttrig; title=name; + position=p; xpos=(position-1)*spacing+indent; + xright=position*spacing+indent; + do_setup=dw; do_choose=dc; + return this; + } + + void headtype::display() + {; + off(); /*MT*/ + chalk(xpos,1,trigger,title,true); + on(); /*MT*/ + } + + void headtype::highlight() + {; + off(); off_virtual(); nosound; + setactivepage(cp); + hlchalk(xpos,1,trigger,title,true); + {; + ddm_o.left=xpos; + ddm_o.menunow=true; ddmnow=true; ddm_o.menunum=position; + } + cmp=177; /* Force redraw of cursor. */ + } + + boolean headtype::extdparse(char c) + {boolean extdparse_result; + ; + if (c!=alttrigger) {; extdparse_result=true; return extdparse_result; } + extdparse_result=false; + return extdparse_result; + } + + menuset* menuset::init() + {; + howmany=0; + return this; + } + + void menuset::create(char t, string n, char alttrig, proc dw,proc dc) + {; + howmany += 1; + ddms[howmany].init(t,alttrig,n,howmany,dw,dc); + } + + void menuset::update() + { + const bytefield menuspace = {0, 0, 80, 9}; + byte fv,page_,savecp; + ; + setactivepage(3); + setfillstyle(1,menu_b); bar(0, 0,640, 9); + savecp=cp; cp=3; + + for( fv=1; fv <= howmany; fv ++) + ddms[fv].display(); + + for( page_=0; page_ <= 1; page_ ++) + getset[page_].remember(menuspace); + + cp=savecp; + } + + void menuset::extd(char c) + { + byte fv; + ; + fv=1; + while ((fv<=howmany) && (ddms[fv].extdparse(c))) fv += 1; + if (fv>howmany) return; getcertain(fv); + } + + void menuset::getcertain(byte fv) + {; + { headtype& with = ddms[fv]; + {; + if (ddm_o.menunow) + {; + wipe(); /* get rid of menu */ + if (ddm_o.menunum==with.position) return; /* clicked on own highlight */ + } + highlight(); do_setup(); + }} + } + + void menuset::getmenu(integer x) + { + byte fv; + ; + fv=0; + do { + fv += 1; + if ((x>ddms[fv].xpos*8) && (x<ddms[fv].xright*8)) + {; + getcertain(fv); + return; + } + } while (!(fv>howmany)); + } + +void parsekey(char r,char re) +{; + switch (r) { + case '\0':case '\340': {; + switch (re) { + case 'K': if (ddm_o.menunum>1) {; + wipe(); + ddm_m.getcertain(ddm_o.menunum-1); + } else + {; /* Get menu on the left-hand side */ + wipe(); + ddm_m.getmenu((ddm_m.howmany-1)*spacing+indent); + } + break; + case 'M': if (ddm_o.menunum<ddm_m.howmany) {; + wipe(); + ddm_m.getcertain(ddm_o.menunum+1); + } else + {; /* Get menu on the far right-hand side */ + wipe(); + ddm_m.getmenu(indent); + } + break; + case 'H': movehighlight(-1); break; + case 'P': movehighlight(1); break; + default: ddm_m.extd(re); + } + } + break; + case '\15': select(ddm_o.highlightnum); break; + default: + {; + if (ddm_o.menunow) keystroke(r); + } + } +} + +/*$F+ *** Here follow all the ddm__ and do__ procedures for the DDM system. */ + +void ddm__game() +{; + {; + start_afresh(); + opt("Help...",'H',"f1",true); + opt("Boss Key",'B',"alt-B",true); + opt("Untrash screen",'U',"ctrl-f7",true); + opt("Score and rank",'S',"f9",true); + opt("About Avvy...",'A',"shift-f10",true); + display(); + } +} + +void ddm__file() +{; + {; + start_afresh(); + opt("New game",'N',"f4",true); + opt("Load...",'L',"^f3",true); + opt("Save",'S',"^f2",alive); + opt("Save As...",'v',"",alive); + opt("DOS Shell",'D',atkey+'1',true); + opt("Quit",'Q',"alt-X",true); + display(); + } +} + +void ddm__action() +{ + string n; +; + n=copy(f5_does(),2,255); + + {; + start_afresh(); + if (n=="") + opt("Do something",'D',"f5",false); + else + opt(copy(n,2,255),n[1],"f5",true); + opt("Pause game",'P',"f6",true); + if (dna.room==99) + opt("Journey thither",'J',"f7",neardoor()); + else + opt("Open the door",'O',"f7",neardoor()); + opt("Look around",'L',"f8",true); + opt("Inventory",'I',"Tab",true); + if (tr[1].xs==walk) + opt("Run fast",'R',"^R",true); + else + opt("Walk slowly",'W',"^W",true); + display(); + } +} + +void ddm__people() +{ + byte here; char fv; +; + + people=""; + here=dna.room; + + {; + start_afresh(); + for( fv='\226'; fv <= '\262'; fv ++) + if (whereis[fv]==here) + {; + opt(getname(fv),getnamechar(fv),"",true); + people=people+fv; + } + display(); + } +} + +void ddm__objects() +{ + char fv; +; + {; + start_afresh(); + for( fv='\1'; fv <= numobjs; fv ++) + if (dna.obj[fv]) + opt(get_thing(fv),get_thingchar(fv),"",true); + display(); + } +} + +string himher(char x) /* Returns "im" for boys, and "er" for girls.*/ +{string himher_result; +; + if (x<'\257') himher_result="im"; else himher_result="er"; +return himher_result; +} + +void ddm__with() +{ + byte fv; varying_string<7> verb; char vbchar; boolean n; +; + {; + start_afresh(); + + if (thinkthing) + {; + + find_what_you_can_do_with_it(); + + for( fv=1; fv <= length(verbstr); fv ++) + {; + verbopt(verbstr[fv],verb,vbchar); + opt(verb,vbchar,"",true); + } + + /* We disable the "give" option if: (a), you haven't selected anybody, + (b), the person you've selected isn't in the room, + or (c), the person you've selected is YOU! */ + + if ((set::of(nowt,pavalot, eos).has(last_person)) || + (whereis[last_person]!=dna.room)) + opt("Give to...",'G',"",false); /* Not here. */ else + {; + opt(string("Give to ")+getname(last_person),'G',"",true); + verbstr=verbstr+vb_give; + } + + } else + {; + opt("Examine",'x',"",true); + opt(string("Talk to h")+himher(thinks),'T',"",true); + verbstr=string(vb_exam)+vb_talk; + switch (thinks) { + + case pgeida:case parkata: + {; + opt("Kiss her",'K',"",true); + verbstr=verbstr+vb_kiss; + } + break; + + case pdogfood: + {; + opt("Play his game",'P',"",! dna.wonnim); /* True if you HAVEN'T won. */ + verbstr=verbstr+vb_play; + } + break; + + case pmalagauche: + {; + n=! dna.teetotal; + opt("Buy some wine",'w',"",! dna.obj[wine]); + opt("Buy some beer",'b',"",n); + opt("Buy some whisky",'h',"",n); opt("Buy some cider",'c',"",n); + opt("Buy some mead",'m',"",n); + verbstr=verbstr+'\145'+'\144'+'\146'+'\147'+'\150'; + } + break; + + case ptrader: + {; + opt("Buy an onion",'o',"",! dna.obj[onion]); + verbstr=verbstr+'\151'; + } + break; + + } + } + display(); + } +} + +/*procedure ddm__map; +begin; + with ddm_o do + begin; + start_afresh; + opt('Cancel map','G','f5',true); + opt('Pause game','P','f6',true); + opt('Journey thither','J','f7',neardoor); + opt('Explanation','L','f8',true); + display; + end; +end; + +procedure ddm__town; +begin; + with ddm_o do + begin; + start_afresh; + opt('Argent','A','',true); + opt('Birmingham','B','',true); + opt('Nottingham','N','',true); + opt('Cardiff','C','',true); + display; + end; +end;*/ + +void do__game() +{; + switch (ddm_o.choicenum) { + /* Help, boss, untrash screen. */ + case 0: callverb(vb_help); break; + case 1: callverb(vb_boss); break; + case 2: major_redraw(); break; + case 3: callverb(vb_score); break; + case 4: callverb(vb_info); break; + } +} + +void do__file() +{; + switch (ddm_o.choicenum) { + /* New game, load, save, save as, DOS shell, about, quit. */ + case 0: callverb(vb_restart); break; + case 1: {; realwords[2]=""; callverb(vb_load); } break; + case 2: {; realwords[2]=""; callverb(vb_save); } break; + case 3: filename_edit(); break; + case 4: back_to_bootstrap(2); break; + case 5: callverb(vb_quit); break; + } +} + +void do__action() +{ + string n; +; + switch (ddm_o.choicenum) { + /* Get up/pause game/open door/look/inv/walk-run */ + case 0: { + person=pardon; thing=pardon; + n=f5_does(); callverb(n[1]); + } + break; + case 1: callverb(vb_pause); break; + case 2: callverb(vb_open); break; + case 3: callverb(vb_look); break; + case 4: callverb(vb_inv); break; + case 5: { + if (tr[1].xs==walk) tr[1].xs=run; + else tr[1].xs=walk; + newspeed(); + } + break; + } +} + +void do__objects() +{; + thinkabout(objlist[ddm_o.choicenum+1],a_thing); +} + +void do__people() +{; + thinkabout(people[ddm_o.choicenum+1],a_person); + last_person=people[ddm_o.choicenum+1]; +} + +void do__with() +{; + thing=thinks; + + if (thinkthing) + {; + + thing += 49; + + if (verbstr[ddm_o.choicenum+1]==vb_give) + person=last_person; + else + person='\376'; + + } else + {; + switch (verbstr[ddm_o.choicenum+1]) { + case '\144': {; thing='\144'; callverb(vb_buy); return; } break; /* Beer */ + case '\145': {; thing= '\62'; callverb(vb_buy); return; } break; /* Wine */ + case '\146': {; thing='\146'; callverb(vb_buy); return; } break; /* Whisky */ + case '\147': {; thing='\147'; callverb(vb_buy); return; } break; /* Cider */ + case '\150': {; thing='\153'; callverb(vb_buy); return; } break; /* Mead */ + case '\151': {; thing= '\103'; callverb(vb_buy); return; } break; /* Onion (trader) */ + default: + {; + person=thing; + thing='\376'; + } + } + } + callverb(verbstr[ddm_o.choicenum+1]); +} + +/*$F- That's all. Now for the ...bar procs. */ + +void standard_bar() /* Standard menu bar */ +{; + ddm_m.init(); ddm_o.init(); + {; /* Set up menus */ + create('F',"File",'!',ddm__file,do__file); /* same ones in map_bar, below, */ + create('G',"Game",'\42',ddm__game,do__game); /* Don't forget to change the */ + create('A',"Action",'\36',ddm__action,do__action); /* if you change them */ + create('O',"Objects",'\30',ddm__objects,do__objects); /* here... */ + create('P',"People",'\31',ddm__people,do__people); + create('W',"With",'\21',ddm__with,do__with); + update(); + } +} + +/*procedure map_bar; { Special menu bar for the map (screen 99) } +begin; + ddm_m.init; ddm_o.init; + with ddm_m do + begin; { Set up menus } + create('G','Game','#',ddm__game,do__game); + create('F','File','!',ddm__file,do__test); + create('M','Map','2',ddm__map,do__test); + create('T','Town',#20,ddm__town,do__test); + update; + end; +end;*/ + +void checkclick() /* only for when the menu's displayed */ +{; + if (mpress>0) + {; + if (mpy>10) + {; + if (! ((ddm_o.firstlix) && + ((mpx>=(cardinal)ddm_o.flx1*8) && (mpx<=(cardinal)ddm_o.flx2*8) && + (mpy>=12) && (mpy<=(cardinal)ddm_o.fly)))) + {; /* Clicked OUTSIDE the menu. */ + if (ddm_o.menunow) wipe(); + } /* No "else"- clicking on menu has no effect (only releasing) */ + } else + {; /* Clicked on menu bar */ + ddm_m.getmenu(mpx); + } + } else + {; /* NOT clicked button... */ + if (mrelease>0) + {; + if ((ddm_o.firstlix) && + ((mrx>=(cardinal)ddm_o.flx1*8) && (mrx<=(cardinal)ddm_o.flx2*8) && + (mry>=12) && (mry<=(cardinal)ddm_o.fly))) + select((mry-13) / 10); + } + } +} + +void menu_link() +{; + {; + if (! ddm_o.menunow) return; + + check(); /* find mouse coords & click information */ + checkclick(); /* work out click codes */ + + /* Change arrow... */ + + switch (my) { + case RANGE_11(0, 10): newpointer(1); + break; /* up-arrow */ + case 11 ... 169: {; + if ((mx>=(cardinal)ddm_o.flx1*8) && (mx<=(cardinal)ddm_o.flx2*8) && (my>10) && (my<=(cardinal)ddm_o.fly)) + newpointer(3); /* right-arrow */ + else newpointer(4); /* fletch */ + } + break; + case RANGE_32(169,200): newpointer(2); + break; /* screwdriver */ + } + + if (! ddm_o.menunow) return; + + lightup(); + } +} + + diff --git a/engines/avalanche/dropdown.h b/engines/avalanche/dropdown.h new file mode 100644 index 0000000000..9d32fb9705 --- /dev/null +++ b/engines/avalanche/dropdown.h @@ -0,0 +1,94 @@ +#ifndef __dropdown_h__ +#define __dropdown_h__ + + +typedef void(*proc)(); + +class headtype { +public: + varying_string<8> title; + char trigger,alttrigger; + byte position; + integer xpos,xright; + proc do_setup,do_choose; + + headtype* init + (char trig,char alttrig, string name, byte p, proc dw,proc dc); + void display(); + void highlight(); + boolean extdparse(char c); +}; + +struct optiontype { + string title; + char trigger; + varying_string<9> shortcut; + boolean valid; +}; + +class onemenu { +public: + array<1,12,optiontype> oo; + byte number; + integer width,left; + boolean firstlix; + integer flx1,flx2,fly; + byte oldy; /* used by Lightup */ + boolean menunow; /* Is there a menu now? */ + byte menunum; /* And if so, which is it? */ + byte choicenum; /* Your choice? */ + byte highlightnum; + + void start_afresh(); + void opt(string n, char tr, string key, boolean val); + void display(); + void wipe(); + void lightup(); + void displayopt(byte y, boolean highlit); + void movehighlight(shortint add); + void select(byte n); + void keystroke(char c); + onemenu* init(); +}; + +class menuset { +public: + array<1,8,headtype> ddms; + byte howmany; + + menuset* init(); + void create(char t, string n, char alttrig, proc dw,proc dc); + void update(); + void extd(char c); + void getcertain(byte fv); + void getmenu(integer x); +}; + + + +#ifdef __dropdown_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN onemenu ddm_o; +EXTERN menuset ddm_m; + +EXTERN varying_string<5> people; +#undef EXTERN +#define EXTERN extern + + + + void find_what_you_can_do_with_it(); + + void parsekey(char r,char re); + + void menu_link(); + + /* DDM menu-bar procs */ + + void standard_bar(); + /*procedure map_bar;*/ + +#endif diff --git a/engines/avalanche/dwidth.cpp b/engines/avalanche/dwidth.cpp new file mode 100644 index 0000000000..f66a417610 --- /dev/null +++ b/engines/avalanche/dwidth.cpp @@ -0,0 +1,20 @@ +#include "ptoc.h" + + +#include "graph.h" + + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +integer gd,gm; +fonttype f; +file<fonttype> ff; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + assign(ff,"v:avalot.fnt"); reset(ff); ff >> f; close(ff); + gd=3; gm=0; initgraph(gd,gm,""); + for( gd=0; gd <= 15; gd ++) mem[0xa000*gd*80]=f['A'][gd]; +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/edhead.cpp b/engines/avalanche/edhead.cpp new file mode 100644 index 0000000000..9fcb68583b --- /dev/null +++ b/engines/avalanche/edhead.cpp @@ -0,0 +1,86 @@ +#include "ptoc.h" + + + +const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; +const string ednaid = string("TT")+'\261'+'\36'+'\1'+'\113'+'\261'+'\231'+'\261'; + +struct edhead { /* Edna header */ + /* This header starts at byte offset 177 in the .ASG file. */ + array<1,9,char> id; /* signature */ + word revision; /* EDNA revision, here 2 (1=dna256) */ + varying_string<50> game; /* Long name, eg Lord Avalot D'Argent */ + varying_string<15> shortname; /* Short name, eg Avalot */ + word number; /* Game's code number, here 2 */ + word ver; /* Version number as integer (eg 1.00 = 100) */ + varying_string<5> verstr; /* Vernum as string (eg 1.00 = "1.00" */ + varying_string<12> filename; /* Filename, eg AVALOT.EXE */ + byte os; /* Saving OS (here 1=DOS. See below for others.) */ + + /* Info on this particular game */ + + varying_string<8> fn; /* Filename (not extension ('cos that's .ASG)) */ + byte d,m; /* D, M, Y are the Day, Month & Year this game was... */ + word y; /* ...saved on. */ + varying_string<40> desc; /* Description of game (same as in Avaricius!) */ + word len; /* Length of DNA (it's not going to be above 65535!) */ + + /* Quick reference & miscellaneous */ + + word saves; /* no. of times this game has been saved */ + integer cash; /* contents of your wallet in numerical form */ + varying_string<20> money; /* ditto in string form (eg 5/-, or 1 denarius)*/ + word points; /* your score */ + + /* DNA values follow, then footer (which is ignored) */ +}; + /* Possible values of edhead.os: + 1 = DOS 4 = Mac + 2 = Windows 5 = Amiga + 3 = OS/2 6 = ST */ + +untyped_file f; +byte fv; +array<1,255,word> dna256; +boolean ok; +edhead e; + +void info(string x) /* info on .ASG files */ +{ + varying_string<40> describe; +; + assign(f,x); + /*$I-*/ reset(f,1); + seek(f,47); + blockread(f,describe,40); + blockread(f,dna256,sizeof(dna256)); + close(f); /*$I+*/ + e.revision=1; + game="Denarius Avaricius Sextus"; + shortname="Avaricius"; + number=1; + verstr="[?]"; + filename="AVVY.EXE"; + os=1; + fn=x; + d=dna256[7]; m=dna256[8]; y=dna256[9]; + desc=describe; + len=512; + saves=dna256[6]; + /*money:string[20]; { ditto in string form (eg 5/-, or 1 denarius)*/ + /*points:word; { your score */ +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + info("tt.asg"); + + output << "Filename: " << x << NL; + output << "Description: " << desc << NL; + output << "Cash: " << dna256[30] << NL; + output << "Score: " << dna256[36] << NL; + output << "Date: " << dna256[7] << ' ' << copy(months,dna256[8]*3-2,3) << ' ' << dna256[9] << NL; + output << "Number of saves: " << dna256[6] << NL; +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/edna.cpp b/engines/avalanche/edna.cpp new file mode 100644 index 0000000000..74352fe9f7 --- /dev/null +++ b/engines/avalanche/edna.cpp @@ -0,0 +1,337 @@ +#include "ptoc.h" + +/*$M 10000,0,1000*/ /*$V-*/ + +/*#include "Dos.h"*/ +/*#include "Tommys.h"*/ + + +struct ednahead { /* Edna header */ + /* This header starts at byte offset 177 in the .ASG file. */ + array<1,9,char> id; /* signature */ + word revision; /* EDNA revision, here 2 (1=dna256) */ + varying_string<50> game; /* Long name, eg Lord Avalot D'Argent */ + varying_string<15> shortname; /* Short name, eg Avalot */ + word number; /* Game's code number, here 2 */ + word ver; /* Version number as integer (eg 1.00 = 100) */ + varying_string<5> verstr; /* Vernum as string (eg 1.00 = "1.00" */ + varying_string<12> filename; /* Filename, eg AVALOT.EXE */ + byte osbyte; /* Saving OS (here 1=DOS. See below for others.*/ + varying_string<5> os; /* Saving OS in text format. */ + + /* Info on this particular game */ + + varying_string<8> fn; /* Filename (not extension ('cos that's .ASG)) */ + byte d,m; /* D, M, Y are the Day, Month & Year this game was... */ + word y; /* ...saved on. */ + varying_string<40> desc; /* Description of game (same as in Avaricius!) */ + word len; /* Length of DNA (it's not going to be above 65535!) */ + + /* Quick reference & miscellaneous */ + + word saves; /* no. of times this game has been saved */ + integer cash; /* contents of your wallet in numerical form */ + varying_string<20> money; /* ditto in string form (eg 5/-, or 1 denarius)*/ + word points; /* your score */ + + /* DNA values follow, then footer (which is ignored) */ +}; + +/* Possible values of edhead.os: + 1 = DOS 4 = Mac + 2 = Windows 5 = Amiga + 3 = OS/2 6 = ST + 7 = Archimedes */ + +typedef array<1,4,char> fourtype; + +struct avaricius_dna { + varying_string<39> desc; + array<1,256,integer> dna; +}; + +const string ednaid = string("TT")+'\261'+'\60'+'\1'+'\165'+'\261'+'\231'+'\261'; +const fourtype avaricius_file = "Avvy"; + +string filename; +boolean quiet,info; +ednahead eh; + +boolean avaricius; +fourtype id4; +avaricius_dna av_eh; +varying_string<4> av_ver; + +boolean ok; + +string first_dir; + +void explain() +{ + output << "EDNA Bucket v1.0 (c) 1993 Thomas Thurman." << NL; + output << " To load Avvy files." << NL; + output << NL; + output << "Associate .ASG files with EDNA.EXE to load them directly." << NL; + output << NL; + output << "Switches:" << NL; + output << " /q (quiet) will stop EDNA from printing text to the screen." << NL; + output << " /i (info) will print info about the file, but won't load it." << NL; + output << NL; + exit(1); +} + +void fix_filename() +{ + string p,n,groi; + + fsplit(filename,p,n,groi); + filename=p+n+".ASG"; +} + +void error(string x) +{ + output << "EDNA : " << x << NL; + exit(255); +} + +void paramparse() +{ + byte fv; + string x; + + if (paramcount==0) explain(); + + filename=""; + quiet=false; info=false; + + for( fv=1; fv <= paramcount; fv ++) + { + x=paramstr(fv); + + if ((x[1]=='/') || (x[1]=='-')) + switch (upcase(x[2])) { /* Parse switches */ + case 'Q': quiet=! quiet; break; + case 'I': info=! info; break; + default: error(string("Unknown switch! (")+x[2]+')'); + } + else + if (filename=="") filename=x; + else error("Please, only one filename at a time!"); + } + + if (quiet && info) error("How can you give info quietly??"); + + if (filename=="") error("No filename given! Use EDNA alone for help."); + + fix_filename(); +} + +void getfile() +{ + untyped_file f; + + assign(f,filename); + /*$I-*/ + reset(f,1); + /*$I+*/ + if (ioresult!=0) error(string("Can't read file \"")+filename+"\"."); + + seek(f,11); blockread(f,id4,4); + avaricius=id4==avaricius_file; + + if (avaricius) + { + seek(f,47); + blockread(f,av_eh,sizeof(av_eh)); + av_ver[0]='\4'; seek(f,31); blockread(f,av_ver[1],4); + } else + { + seek(f,177); + blockread(f,eh,sizeof(eh)); + } + + close(f); +} + +string plural(byte x) +{ + string plural_result; + if (x==1) plural_result=""; else plural_result='s'; + return plural_result; +} + +void show_info() +{ + string _game,_shortname,_verstr,_filename,_os,_fn,_desc,_money; + integer _revision,_number,_d,_m,_y,_saves,_points; + boolean readable,understandable; + + output << "Info on file " << filename << ':' << NL; + output << NL; + if (avaricius) + { /* DNA-256 file. */ + _verstr=av_ver; + _game="Denarius Avaricius Sextus"; _shortname="Avaricius"; + _filename="AVVY.EXE"; _os="DOS"; _desc=av_eh.desc; + _revision=1; _number=1; _fn="(as above)"; + + _money=strf(av_eh.dna[30])+" denari"; + if (av_eh.dna[30]==1) _money=_money+"us"; else _money=_money+'i'; + _d=av_eh.dna[7]; _m=av_eh.dna[8]; _y=av_eh.dna[9]; + _saves=av_eh.dna[6]; _points=av_eh.dna[36]; + + readable=true; understandable=true; + } else + { + if (eh.id==ednaid) + { /* EDNA file. */ + _game=eh.game; + _shortname=eh.shortname; + _verstr=eh.verstr; + _filename=eh.filename; + _os=eh.os; _fn=eh.fn; _desc=eh.desc; + _money=eh.money; _revision=eh.revision; + _number=eh.number; _d=eh.d; _m=eh.m; _y=eh.y; + _saves=eh.saves; _points=eh.points; + + readable=true; understandable=eh.revision==2; + } else + { + output << "Unknown format." << NL; + readable=false; + } + } + + if (_desc=="") _desc="<none>"; + + if (readable) + { + output << "Signature is valid." << NL; + output << "Revision of .ASG format: " << _revision << NL; + output << NL; + if (understandable) + { + output << "The file was saved by " << _game << '.' << NL; + output << "Game number " << _number << " (" << _shortname << "), version " << + _verstr << ", filename " << _filename << '.' << NL; + output << "Saved under " << _os << '.' << NL; + output << NL; + output << "This is " << _fn << ".ASG, saved on " << _d << '/' << _m << '/' << _y << " (d/m/y)." << NL; + output << "Description: " << _desc << NL; + output << "It has been saved " << _saves << " time" << plural(_saves) << + ". You have " << _points << " point" << plural(_points) << ',' << NL; + output << "and " << _money << " in cash." << NL; + } else output << "Nothing else can be discovered." << NL; + } + + exit(2); +} + +void load_file() +{ + string progname,gamename,shortname,listname,exname,prog_dir; + + string localdir,groi; + + string x,y; + + text t; + + integer i,ii; + + gamename=fexpand(filename); + fsplit(fexpand(paramstr(0)),localdir,groi,groi); + listname=localdir+"EDNA.DAT"; + + if (avaricius) + { shortname="Avaricius"; exname="AVVY"; } + else { shortname=eh.shortname; fsplit(eh.filename,groi,exname,groi); } + + assign(t,listname); + /*$I-*/ + reset(t); + /*$I+*/ + progname=""; + if (ioresult==0) + { + do { + t >> x >> NL; t >> y >> NL; + if (x==shortname) + { + progname=y; + flush(); + } + } while (!(eof(t))); + } + + if (progname=="") + { /* No entry in EDNA.DAT */ + output << "This file was saved by " << shortname << '.' << NL; + output << "However, no entry was found in EDNA.DAT for that game." << NL; + output << NL; + output << "Please give the full path to that game, or press Enter to cancel." << NL; + output << string("(Example: C:\\")+exname+'\\'+exname+".EXE)" << NL; + output << NL; + input >> progname >> NL; + if (progname=="") exit(254); /* Quick exit! */ + + /*$I-*/ + append(t); + if (ioresult!=0) rewrite(t); + + t << shortname << NL; + t << progname << NL; + + if (ioresult!=0) + { + output << "Strange... could not write to EDNA.DAT. (Disk read-only or full?)" << NL; + output << "The path will be used this time only." << NL; + output << "Press Enter..."; input >> NL; + } + close(t); + /*$I+*/ + } + + if (! quiet) output << "Running " << shortname << ": " << progname << "..." << NL; + + fsplit(fexpand(progname),prog_dir,groi,groi); + if (prog_dir[length(prog_dir)]=='\\') prog_dir[0] -= 1; + + /*$I-*/ + chdir(prog_dir); i=ioresult; + swapvectors; + exec(progname,gamename); ii=ioresult; + swapvectors; + chdir(first_dir); + /*$I+*/ + + if ((i!=0) || (ii!=0)) + { + output << "WARNING: DOS reported an error. This probably means that the entry" << NL; + output << "for this game in " << listname << " is wrong." << NL; + output << NL; + output << "Please edit this file, using" << NL; + output << NL; + if (lo(dosversion)<0x5) + output << " edlin " << listname << " (or similar)" << NL; + else + output << " edit " << listname << NL; + output << NL; + output << "and change the line after \"" << shortname << "\" to show the correct path." << NL; + output << NL; + output << "More info is in the Avvy documentation. Good luck!" << NL; + output << NL; + output << "Press Enter..."; input >> NL; + } +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + getdir(0,first_dir); + paramparse(); + getfile(); + if (info) show_info(); + load_file(); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/enhanced.cpp b/engines/avalanche/enhanced.cpp new file mode 100644 index 0000000000..299aec2914 --- /dev/null +++ b/engines/avalanche/enhanced.cpp @@ -0,0 +1,86 @@ +#include "ptoc.h" + +#define __enhanced_implementation__ + + +/* This is the unit set up by Thomas with help from all the people on + CIS:BPROGA to read the *enhanced* keyboard codes (as opposed to the + readkey-type ones.) */ + +#include "enhanced.h" + + +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ + + +boolean isenh() +{ + byte statefrom16; + registers r; + + boolean isenh_result; + isenh_result = false; + {; + ah=0x12; + intr(0x16,r); + statefrom16=al; + } + if (statefrom16 != shiftstate) return isenh_result; + shiftstate = shiftstate ^ 0x20; + {; + ah=0x12; + intr(0x16,r); + statefrom16=al; + } + isenh_result = statefrom16 == shiftstate; + shiftstate = shiftstate ^ 0x20; + return isenh_result; +} + +void readkeye() +/* function fancystuff:word; + inline( $B4/ $10/ { MOV AH,10 } + $CD/ $16); { INT 16 } + function notfancystuff:word; + inline( $B4/ $00/ { MOV AH,0 } + $CD/ $16); { INT 16 } +*/ +{ + registers r; word fs; +; + if (atbios) + fs=fancystuff; /* We're using an AT */ + else fs=notfancystuff; /* ditto, an XT */ + inchar=chr(lo(fs)); + extd=chr(hi(fs)); +} + +boolean keypressede() +/* + function fancystuff:boolean; + inline( $B4/ $11/ { MOV AH,11 } + $CD/ $16/ { INT 16 } + $B8/ $00/ $00/ { MOV AX, 0000 } + $74/ $01/ { JZ 0112 (or wherever- the next byte after $40, anyway) } + $40); { INC AX } +*/ +{ + registers r; +boolean keypressede_result; +; + if (atbios) + keypressede_result=fancystuff; /* ATs get the fancy stuff */ + else keypressede_result=keypressed(); /* XTs get the usual primitive... */ +return keypressede_result; +} + +class unit_enhanced_initialize { + public: unit_enhanced_initialize(); +}; +static unit_enhanced_initialize enhanced_constructor; + +unit_enhanced_initialize::unit_enhanced_initialize() {; + /* determine bios type */ + atbios=isenh(); +} diff --git a/engines/avalanche/enhanced.h b/engines/avalanche/enhanced.h new file mode 100644 index 0000000000..a028648ced --- /dev/null +++ b/engines/avalanche/enhanced.h @@ -0,0 +1,22 @@ +#ifndef __enhanced_h__ +#define __enhanced_h__ + + + +#ifdef __enhanced_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN byte shiftstate;/*ABSOLUTE $40:$17;*/ +EXTERN boolean atbios; +EXTERN char inchar,extd; +#undef EXTERN +#define EXTERN extern + + +void readkeye(); + +boolean keypressede(); + +#endif diff --git a/engines/avalanche/enid.cpp b/engines/avalanche/enid.cpp new file mode 100644 index 0000000000..89e1327191 --- /dev/null +++ b/engines/avalanche/enid.cpp @@ -0,0 +1,581 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + ENID Edna's manager. */ + +#define __enid_implementation__ + /* Loads/ saves files. */ + +/*$V-*/ + +#include "enid.h" + + +/*#include "Dos.h"*/ +#include "scrolls.h" +#include "lucerna.h" +#include "trip5.h" +#include "timeout.h" +#include "Celer.h" +#include "sequence.h" +#include "fileunit.h" +#include "basher.h" + + +const string crlf = string('\15')+'\12'; +const char tab = '\11'; +const char eof_ = '\32'; + +const array<1,177,char> ednafirst = + string("This is an EDNA-based file, saved by a Thorsoft game. Good luck!")+ /*64*/ + crlf+eof_+crlf+crlf+ /*7*/ + tab+"Glory to God in the highest,"+crlf+ /*31*/ + tab+"and on earth peace, goodwill toward men."+ /*42*/ + crlf+tab+tab+tab+tab+ /*6*/ + "Luke 2:14."+ /*10*/ + crlf+crlf+crlf+ /* 6 */ + "1234567890"+crlf; /*11*/ + +const string ednaid = string("TT")+'\261'+'\60'+'\1'+'\165'+'\261'+'\231'+'\261'; + +const integer ttage = 18; +const array<1,16,char> ttwashere = "Thomas was here "; + +boolean bug; + +string expanddate(byte d,byte m, word y); + +const array<1,12,varying_string<7> > months = +{{"Jan#","Febr#","March","April","May","June","July","August", +"Septem*","Octo*","Novem*","Decem*"}}; + + +static varying_string<10> month; + + +static void addon(string x) { month[0] -= 1; month=month+x; } + +string expanddate(byte d,byte m, word y) +{ + varying_string<4> day; + + + string expanddate_result; + month=months[m]; + switch (month[length(month)]) { + case '#': addon("uary"); break; + case '*': addon("ber"); break; + } + + day=strf(d); + + if (set::of(range(1,9),range(21,31), eos).has(d)) + switch (d % 10) { + case 1: day=day+"st"; break; + case 2: day=day+"nd"; break; + case 3: day=day+"rd"; break; + default: day=day+"th"; + } + + expanddate_result=day+' '+month+' '+strf(y); + return expanddate_result; +} + +void edna_save(string name); + + +static void show_bug(char icon, string strn) +{ display(string("\7\6\23")+icon+"\26\r"+strn+'\15'); } + + + +static boolean test_bug(byte what) +{ + boolean test_bug_result; + if (what==0) { test_bug_result=false; return test_bug_result; } + switch (what) { + case 2: show_bug('7',"Error in filename!"); break; + case 101: show_bug('6',"Disk full!"); break; + case 150: show_bug('4',"Disk is write-protected!"); break; + default: show_bug('B',"Saving error!"); + } + test_bug_result=true; + return test_bug_result; +} + +void edna_save(string name) +{ + untyped_file f; + ednahead eh; + word groi; + string groi2,path; + word tempd,tempm; + + if (name=="") + { /* We were given no name. Do we have a default? */ + if (enid_filename=="") + { /* No */ + filename_edit(); /* Request one. */ + return; + } else /* Yes */ + name=enid_filename; + } + + wait(); /* Put up hourglass pointer */ + + fillchar(eh,sizeof(eh),'\261'); /* Fill up the edhead */ + + dna.saves += 1; /* It's been saved one more time... */ + + { + + /* Info about this program */ + + eh.id=ednaid; /* Edna's signature */ + eh.revision=thisgamecode; /* 2- second revision of .ASG format */ + eh.game="Lord Avalot d'Argent"; /* Title of game */ + eh.shortname="Avalot"; + eh.number=2; /* Second Avvy game */ + eh.ver=thisvercode; /* Version 1.00 */ + eh.verstr=vernum; /* ditto */ + eh.filename="AVALOT.EXE"; /* program's filename */ + eh.osbyte=1; /* Saved under DOS */ + eh.os="DOS"; + + /* Info on this particular game */ + + fsplit(name,path,eh.fn,groi2); /* fn = filename of this game */ + getdate(eh.y,tempm,tempd,groi); /* Day, month & year when the game was saved */ + eh.d=tempd; eh.m=tempm; + eh.desc=roomname; /* Description of game (same as in Avaricius!) */ + eh.len=sizeof(dna); /* Length of DNA. */ + + /* Quick reference & miscellaneous */ + + eh.saves=dna.saves; /* no. of times this game has been saved */ + eh.cash=dna.pence; /* contents of your wallet in numerical form */ + eh.money=lsd(); /* ditto in string form (eg 5/-, or 1 denarius)*/ + eh.points=dna.score; /* your score */ + + name=path+eh.fn+".ASG"; + } + + assign(f,name); + /*$I-*/ + rewrite(f,1); + if (test_bug(ioresult)) return; + + blockwrite(f,ednafirst,177); if (test_bug(ioresult)) return; + blockwrite(f,eh,sizeof(eh)); if (test_bug(ioresult)) return; + blockwrite(f,dna,sizeof(dna)); if (test_bug(ioresult)) return; + + for( groi=1; groi <= numtr; groi ++) + { triptype& with = tr[groi]; + if (with.quick) + { + blockwrite(f,groi,1); if (test_bug(ioresult)) return; + savedata(f); if (test_bug(ioresult)) return; + }} + + groi=177; blockwrite(f,groi,1); + + blockwrite(f,times,sizeof(times)); /* Timeout.times: Timers. */ + + if (test_bug(ioresult)) return; + + blockwrite(f,seq,sizeof(seq)); /* Sequencer information. */ + + if (test_bug(ioresult)) return; + + for( groi=1; groi <= ttage; groi ++) + blockwrite(f,ttwashere[1-1],16); + + if (test_bug(ioresult)) return; + + close(f); + if (test_bug(ioresult)) return; + /*$I+*/ + + display(string('\6')+"Saved: "+'\22'+name+'.'); + enid_filename=name; +} + +void loaderror(string x, char icon) +{ + if (holdthedawn) + { + holdthedawn=false; + dawn(); + } + display(string('\7')+'\6'+'\23'+icon+'\26'+"Loading error: "+"\r\r\22"+x); + bug=true; +} + + + +typedef array<1,4,char> fourtype; + + + +const fourtype avaricius_file = "Avvy"; + +void edna_load(string name) + +{ + untyped_file f; + ednahead eh; + byte fv; + byte io; + string path,fn,groi; + fourtype id4; + + word len2load; + + + + if (name=="") + { /* No filename specified, so let's call the filer. */ + name=do_filer(); + if (name=="") return; /* STILL no filename, so they must have cancelled. */ + } + + bug=false; + + wait(); /* Put up hourglass pointer */ + + fsplit(name,path,fn,groi); + name=path+fn+".ASG"; + + /* Load the file into memory */ + + /*$I-*/ + assign(f,name); + reset(f,1); + + io=ioresult; + if (io!=0) + switch (io) { + case 2: loaderror("File not found!",'8'); break; + case 3: loaderror("Directory not found!",'3'); break; + default: loaderror(string("Error no.")+strf(io),'1'); + } + + if (bug) return; + + seek(f,11); blockread(f,id4,4); + if (id4==avaricius_file) + { + loaderror("That's an Avaricius file!",'1'); + close(f); + return; + } + + seek(f,177); /* bypass ednafirst */ + + blockread(f,eh,sizeof(eh)); /* load ednahead */ + + /* Check ednahead for errors */ + + { + if ((eh.id!=ednaid) || (eh.revision!=2)) loaderror("Not an EDNA file!",'7'); else + if (eh.number!=2) loaderror(string("That file was saved by ")+eh.shortname+'!','1'); + } + + if (bug) + { + close(f); + return; + } + + len2load=eh.len; + + if (eh.len!=(cardinal)sizeof(dna)) + { + if (holdthedawn) + { + holdthedawn=false; + dawn(); + } + display("\233\26Warning: \3\rEDNA size doesn't match.\f"); + if (eh.len>(cardinal)sizeof(dna)) + len2load=sizeof(dna); /* BIGGER than ours */ + else fillchar(dna,sizeof(dna),'\0'); /* Otherwise, smaller. */ + } + + blockread(f,dna,len2load); + + for( fv=1; fv <= numtr; fv ++) + { triptype& with = tr[fv]; + if (with.quick) done();} /* Deallocate sprite */ + + do { + blockread(f,fv,1); + if (fv!=177) tr[fv].loaddata(f); + } while (!(fv==177)); + + blockread(f,times,sizeof(times)); /* Timeout.times: Timers. */ + + blockread(f,seq,sizeof(seq)); /* Sequencer information. */ + + close(f); + + seescroll=true; /* This prevents display of the new sprites before the + new picture is loaded. */ + + if (holdthedawn) + { + holdthedawn=false; + dawn(); + } + + display(string('\6')+"Loaded: "+'\22'+name+'\3'+"\r\r"+eh.desc+"\r\r"+"saved on "+ + expanddate(eh.d,eh.m,eh.y)+'.'); + + forget_chunks(); + + minor_redraw(); + + whereis[pavalot]=dna.room; +/* showscore;*/ + alive=true; + + objectlist(); +/*$I+*/ + + enid_filename=name; +} + +void dir(string where); + +static string path,groi; + + +static void showheader() +{ + display(string("Dir: ")+path+"\r\r\4"); +} + +void dir(string where) + /* OK, it worked in Avaricius, let's do it in Avalot! */ +{ + searchrec s; + byte count; + + if ((where!="") && (!(set::of('\\',':', eos).has(where[length(where)])))) + where=where+'\\'; + fsplit(where,path,groi,groi); + path=path+"*.asg"; + count=0; + + findfirst(path,anyfile,s); + showheader(); + + while (doserror==0) + { + count += 1; + if (count==11) + { + display("\r\nPress Enter..."); + showheader(); + count=1; + } + + display(s.name+"\r\4"); + + findnext(s); + } + + if (count==0) + display("No files found!"); + else display("\nThat's all!"); + +} + +void avvy_background() /* Not really a filing procedure, + but it's only called just before edna_load, so I thought I'd put it + in Enid instead of, say, Lucerna. */ +{ +/* port[$3c4]:=2; port[$3ce]:=4; port[$3C5]:=1; port[$3CF]:=1; { Blue. }*/ +/* + asm + mov dx,$3c4; mov al,2; out dx,al; { Set up the VGA to use the "blue" } + mov dx,$3ce; mov al,4; out dx,al; { register. } + mov dx,$3c5; mov al,1; out dx,al; + mov dx,$3cf; out dx,al; + + mov bx,$A000; call far ptr @drawup; + mov bx,$A400; call far ptr @drawup; + + jmp @the_end; + + @drawup: + + mov es,bx; { The segment to copy it to... } + mov di,$370; { The offset (10 pixels down, plus 1 offset.) } + + mov cx,10; + mov ax,$AA4A; call far ptr @sameline; { Print "AVVY" } + mov ax,$AEAA; call far ptr @sameline; + mov ax,$A4EA; call far ptr @sameline; + mov ax,$44A4; call far ptr @sameline; + + mov cx,9; + mov ax,$AAA4; call far ptr @sameline; { Print "YAVV" } + mov ax,$AAEA; call far ptr @sameline; + mov ax,$AA4E; call far ptr @sameline; + mov ax,$444A; call far ptr @sameline; + + mov ax,$4AAA; call far ptr @sameline; { Print "VYAV" } + mov ax,$AAAE; call far ptr @sameline; + mov ax,$EAA4; call far ptr @sameline; + mov ax,$A444; call far ptr @sameline; + + mov ax,$A4AA; call far ptr @sameline; { Print "VVYA" } + mov ax,$EAAA; call far ptr @sameline; + mov ax,$4EAA; call far ptr @sameline; + mov ax,$4A44; call far ptr @sameline; + + ret; + + + { Replicate the same line many times. } + + @sameline: + { Requires: + what to copy in AX, + how many lines in CX, and + original offset in DI. } + push cx; + push di; + + @samelineloop: + + push cx; + mov cx,40; { No. of times to repeat it on one line. } + + repz stosw; { Fast word-copying } + + pop cx; + + add di,1200; { The next one will be 16 lines down. } + + loop @samelineloop; + pop di; + add di,80; + pop cx; + + ret; + + @the_end: + end; +*/ +blitfix(); +} + +void to_sundry(sundry& sund) +{ + { + sund.qenid_filename=enid_filename; + sund.qsoundfx=soundfx; + sund.qthinks=thinks; + sund.qthinkthing=thinkthing; + } +} + +void from_sundry(sundry sund) +{ + { + enid_filename=sund.qenid_filename; + soundfx=sund.qsoundfx; + thinks=sund.qthinks; + thinkthing=sund.qthinkthing; + } +} + +void restore_dna() +{ + word here,fv; + sundry sund; + + move(mem[storage_seg*storage_ofs+3],dna,sizeof(dna)); + move(mem[storage_seg*storage_ofs+3+sizeof(dna)],times,sizeof(times)); + move(mem[storage_seg*storage_ofs+3+sizeof(dna)+sizeof(times)], + seq,sizeof(seq)); + move(mem[storage_seg*storage_ofs+3+sizeof(dna)+sizeof(times)+sizeof(seq)], + sund,sizeof(sund)); + from_sundry(sund); + + here=storage_ofs+3+sizeof(dna)+sizeof(times)+sizeof(seq)+sizeof(sund); + do { + fv=mem[storage_seg*here]; here += 1; + if (fv!=177) tr[fv].load_data_from_mem(here); + } while (!(fv==177)); +} + +void edna_reload() +{ + + restore_dna(); + + seescroll=true; /* This prevents display of the new sprites before the + new picture is loaded. */ + + major_redraw(); + + whereis[pavalot]=dna.room; + + alive=true; + + objectlist(); + + if (holdthedawn) + { + holdthedawn=false; + dawn(); + } +} + +void back_to_bootstrap(byte what) +{ + byte fv; + word here; + sundry sund; + + mem[storage_seg*storage_ofs]=what; /* Save the operation code. */ + to_sundry(sund); /* Save the sundry information. */ + + /* Save the DNA, times and sequencer info: */ + move(dna,mem[storage_seg*storage_ofs+3],sizeof(dna)); + move(times,mem[storage_seg*storage_ofs+3+sizeof(dna)],sizeof(times)); + move(seq,mem[storage_seg*storage_ofs+3+sizeof(dna)+sizeof(times)], + sizeof(seq)); + move(sund, + mem[storage_seg*storage_ofs+3+sizeof(dna)+sizeof(times)+sizeof(seq)], + sizeof(sund)); + + here=storage_ofs+3+sizeof(dna)+sizeof(times)+sizeof(seq)+sizeof(sund); + + for( fv=1; fv <= numtr; fv ++) + { triptype& with = tr[fv]; + if (with.quick) + { + mem[storage_seg*here]=fv; here += 1; + save_data_to_mem(here); + }} + mem[storage_seg*here]=177; + + exit(77); /* Code to return to the Bootstrap. */ +} + +boolean there_was_a_problem() +{ + boolean there_was_a_problem_result; + there_was_a_problem_result=bug; + return there_was_a_problem_result; +} + + diff --git a/engines/avalanche/enid.h b/engines/avalanche/enid.h new file mode 100644 index 0000000000..abf20a27dc --- /dev/null +++ b/engines/avalanche/enid.h @@ -0,0 +1,22 @@ +#ifndef __enid_h__ +#define __enid_h__ + + +#include "gyro.h" + + +void edna_save(string name); + +void edna_load(string name); + +void edna_reload(); /* From Bootstrap's storage. */ + +void dir(string where); + +void avvy_background(); + +void back_to_bootstrap(byte what); + +boolean there_was_a_problem(); + +#endif diff --git a/engines/avalanche/filer.cpp b/engines/avalanche/filer.cpp new file mode 100644 index 0000000000..036aa945af --- /dev/null +++ b/engines/avalanche/filer.cpp @@ -0,0 +1,791 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ +/*#include "Tommys.h"*/ +#include "lucerna.h" + +/*$V-*/ + +struct windowtype { + integer x1,y1,x2,y2; + varying_string<20> title; +}; + + struct ednahead { /* Edna header */ + /* This header starts at byte offset 177 in the .ASG file. */ + array<1,9,char> id; /* signature */ + word revision; /* EDNA revision, here 2 (1=dna256) */ + varying_string<50> game; /* Long name, eg Lord Avalot D'Argent */ + varying_string<15> shortname; /* Short name, eg Avalot */ + word number; /* Game's code number, here 2 */ + word ver; /* Version number as integer (eg 1.00 = 100) */ + varying_string<5> verstr; /* Vernum as string (eg 1.00 = "1.00" */ + varying_string<12> filename; /* Filename, eg AVALOT.EXE */ + byte osbyte; /* Saving OS (here 1=DOS. See below for others.*/ + varying_string<5> os; /* Saving OS (here 1=DOS. See below for others.*/ + + /* Info on this particular game */ + + varying_string<8> fn; /* Filename (not extension ('cos that's .ASG)) */ + byte d,m; /* D, M, Y are the Day, Month & Year this game was... */ + word y; /* ...saved on. */ + varying_string<40> desc; /* Description of game (same as in Avaricius!) */ + word len; /* Length of DNA (it's not going to be above 65535!) */ + + /* Quick reference & miscellaneous */ + + word saves; /* no. of times this game has been saved */ + integer cash; /* contents of your wallet in numerical form */ + varying_string<20> money; /* ditto in string form (eg 5/-, or 1 denarius)*/ + word points; /* your score */ + + /* DNA values follow, then footer (which is ignored) */ + }; + +const integer border = 1; /* size of border on shadowboxes */ + +const array<1,4,varying_string<7> > buttons = {{"Okay","Wipe","Cancel","Info..."}}; + +const integer files = 3; +const integer dirs = 4; + +const integer drlen = 15; /* no. of drives on one line */ + +const array<1,4,windowtype> threewins = + {{{155, 12, 630, 22, "Name"}, + {15, 25, 410, 70, "Drives"}, + {15, 83, 480, 179, "Files (*.ASG)"}, + {490, 83, 630, 179, "Subdirectories"}}}; + +const integer name_win = 1; +const integer drive_win = 2; +const integer file_win = 3; +const integer subdir_win = 4; + +matrix<3,4,1,77,varying_string<12> > lists; +array<1,77,varying_string<40> > descs; +array<3,4,byte> nums,where,top; +searchrec s; +boolean loading; +varying_string<26> drives; +pathstr current; +byte nowwin; +varying_string<17> doing; + +pathstr filename; +boolean filefound; + +void shadow(integer x1,integer y1,integer x2,integer y2, byte hc,byte sc) +{ + byte fv; +; + for( fv=0; fv <= border; fv ++) + {; + setfillstyle(1,hc); + bar(x1+fv,y1+fv,x1+fv,y2-fv); + bar(x1+fv,y1+fv,x2-fv,y1+fv); + + setfillstyle(1,sc); + bar(x2-fv,y1+fv,x2-fv,y2-fv); + bar(x1+fv,y2-fv,x2-fv,y2-fv); + } +} + +void shbox(integer x1,integer y1,integer x2,integer y2, string t) +{ + const integer fc = 7; +; + shadow(x1,y1,x2,y2,15,8); + setfillstyle(1,fc); + bar(x1+border+1,y1+border+1,x2-border-1,y2-border-1); + setcolor(1); x1=(x2-x1) / 2+x1; y1=(y2-y1) / 2+y1; + outtextxy(x1,y1,t); + if (length(t)>1) + {; + fillchar(t[2],length(t)-1,'\40'); t[1]='_'; + outtextxy(x1-1,y1+1,t); + } +} + +void show_drives() +{ + byte fv; +; + settextjustify(1,1); + for( fv=0; fv <= length(drives)-1; fv ++) + shbox((fv % drlen)*25+25,(fv / drlen)*19+31, + (fv % drlen)*25+40,45+(fv / drlen)*19,drives[fv+1]); + setcolor(11); + settextjustify(0,2); +} + +void box(integer x1,integer y1,integer x2,integer y2, string z) +{; + rectangle(x1,y1,x2,y2); + outtextxy(x1+1,y1-10,z+':'); + outtextxy(x1,y1-9,"_"); +} + +string lowstr(string x) +{ + byte fv; +string lowstr_result; +; + for( fv=1; fv <= length(x); fv ++) + if (set::of(range('A','Z'), eos).has(x[fv])) x[fv] += 32; + lowstr_result=x; +return lowstr_result; +} + +char lowchar(char x) +{ + char lowchar_result; + if (set::of(range('A','Z'), eos).has(x)) x -= 32; + lowchar_result=x; + return lowchar_result; +} + +void getcurrent() +{; + current=lowstr(fexpand("*.asg")); +} + +void setup() +{ + integer gd,gm; + registers r; + byte floppies; +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + dusk(); + setfillstyle(1,1); bar(2,2,637,197); shadow(0,0,639,199,15,7); + + if (loading) doing="LOAD"; else doing="SAV"; + doing=doing+"ING a file..."; + + /* Now... find all drives that exist. */ + drives=""; + intr(0x11,r); floppies=(((cardinal)r.ax >> 6) & 0x3)+1; /* useful bit of code! */ + for( gm=1; gm <= floppies; gm ++) drives=drives+chr(64+gm); + /* Winchesters, etc., can be found the easy way... */ + for( gd=3; gd <= 26; gd ++) /* C: to Z: */ + if (disksize(gd)>-1) drives=drives+chr(64+gd); + + fillchar(where,sizeof(where),'\1'); + fillchar(top,sizeof(top),'\1'); + + settextstyle(0,0,0); + settextjustify(1,1); + for( gd=1; gd <= 2; gd ++) + for( gm=0; gm <= 1; gm ++) + shbox(420+gm*110,gd*25,520+gm*110,gd*25+20,buttons[gm*2+gd]); + shbox(15,182,350,196,"Help... (press f1)"); + settextjustify(0,2); setcolor(11); + setcolor(15); outtextxy(15,5,"The Avvy Filer..."); + setcolor(11); outtextxy(317,3,string('(')+doing+')'); + outtextxy(357,185,"Copyright (c) 1993, Thomas Thurman."); + + /* Draw the boxes and names */ + setcolor(3); + for( gm=1; gm <= 4; gm ++) + { windowtype& with = threewins[gm]; + box(with.x1,with.y1,with.x2,with.y2,with.title);} + nowwin=1; getcurrent(); +} + +void quicksort(byte whichlist, integer lo, integer hi); + + +static void sort(integer l, integer r, byte& whichlist) +{ + integer i, j; + varying_string<12> x, y; + + i = l; j = r; x = lists[whichlist][(l+r) / 2]; + do { + while (lists[whichlist][i] < x) i = i + 1; + while (x < lists[whichlist][j]) j = j - 1; + if (i <= j) + { + y = lists[whichlist][i]; + lists[whichlist][i] = lists[whichlist][j]; + lists[whichlist][j] = y; + i = i + 1; j = j - 1; + } + } while (!(i > j)); + if (l < j) sort(l, j, whichlist); + if (i < r) sort(i, r, whichlist); +} + +void quicksort(byte whichlist, integer lo, integer hi) + +{ /*QuickSort*/; + sort(lo,hi, whichlist); +} + +void scandir() +{ + pathstr nix; + namestr name; + untyped_file f; + ednahead eh; + array<1,4,char> dna_type; + +; + nums[files]=0; + findfirst("*.asg",archive+hidden+readonly,s); + + while (doserror==0) + {; + fsplit(s.name,nix,name,nix); + nums[files] += 1; + lists[files][nums[files]]=lowstr(name); + + assign(f,s.name); + reset(f,1); + seek(f,11); + blockread(f,dna_type,4); + + if (dna_type=="Avvy") + {; /* A DNA256 file. */ + descs[nums[files]]="* Saved by Avaricius!"; + } else + {; /* EDNA-based files. */ + if (dna_type=="EDNA") + {; + seek(f,177); + blockread(f,eh,sizeof(eh)); + + if (eh.revision!=2) + descs[nums[files]]="* Unknown EDNA type!"; + else + {; + + if (eh.number!=2) + descs[nums[files]]=string("* Saved by ")+eh.shortname+'!'; + else + {; /* Well... everything seems to have gone OK! */ + descs[nums[files]]=eh.desc; + } + } + } else + descs[nums[files]]="* Not an Avvy saved game!"; + } + close(f); + findnext(s); + } + nums[dirs]=0; findfirst("*.*",directory,s); + while (doserror==0) + {; + if (((s.attr & directory)>0) && ((length(s.name))>1)) + {; + nums[dirs] += 1; + lists[dirs][nums[dirs]]=lowstr(s.name); + } + findnext(s); + } + + /* Now sort 'em! */ + + quicksort ( dirs,1,nums[ dirs]); + quicksort (files,1,nums[files]); + + where[dirs]=1; where[files]=1; + top[dirs]=1; top[files]=1; +} + +void show_file(integer x,integer y, byte which) +{ + varying_string<58> z; +; + fillchar(z[1],13,'\40'); + z=lists[files][which]+".asg"; + z[0]='\15'; z=z+descs[which]; + + if (descs[which][1]=='*') /* Can't load these! */ + setcolor(red); + else + setcolor(lightcyan); + + outtextxy(x,y,z); +} + +void showfiles() +{ + byte fv; +; + if (loading) setcolor(11); else setcolor(3); + if (nums[3]==0) + {; + outtextxy(22,86,"(None here!)"); + return; + } + for( fv=0; fv <= 8; fv ++) + if (where[3]+fv<=nums[3]) + show_file(19,87+fv*10,where[3]+fv); +} + +void showdirs() +{ + byte fv; +; + setcolor(11); + for( fv=0; fv <= 8; fv ++) + if (where[4]+fv<=nums[4]) + outtextxy(497,87+fv*10,string('[')+lists[dirs][fv+where[4]]+']'); +} + +void show() +{ + byte fv; + dirstr d; namestr n; extstr e; +; + setfillstyle(1,1); + for( fv=1; fv <= 4; fv ++) + if (fv!=2) + { windowtype& with = threewins[fv]; + bar(with.x1+1,with.y1+1,with.x2-1,with.y2-1);} + showfiles(); + showdirs(); + setcolor(7); outtextxy(159,14,current); +} + +void blip() +{; + sound(177); delay(77); nosound; +} + +void invert(integer x1,integer y1,integer x2,integer y2) +{ + pointer p,restore; word s; +; + s=imagesize(x1,y1,x2,y2); + mark(restore); getmem(p,s); + getimage(x1,y1,x2,y2,p); + putimage(x1,y1,p,notput); + release(restore); +} + +void changedrive(char drive) +{ + byte fv; +; + fv=pos(drive,drives); + if (fv==0) {; blip(); return; } + fv -= 1; + shadow((fv % drlen)*25+25,(fv / drlen)*19+31, + (fv % drlen)*25+40,45+(fv / drlen)*19,8,7); + chdir(string(drive)+':'); + getcurrent(); scandir(); show(); + shadow((fv % drlen)*25+25,(fv / drlen)*19+31, + (fv % drlen)*25+40,45+(fv / drlen)*19,15,8); +} + +void highlight(byte win,byte line) +{; + switch (win) { + case 3: invert(16,75+line*10,479,85+line*10); break; + case 4: invert(491,75+line*10,619,85+line*10); break; + } +} + +void repaint(byte whichwindow) +{ + setfillstyle(1,1); + { windowtype& with = threewins[whichwindow]; + bar(with.x1+1,with.y1+1,with.x2-1,with.y2-1);} + switch (whichwindow) { + case file_win: showfiles(); break; + case subdir_win: showdirs(); break; + } + highlight(whichwindow,1); + top[whichwindow]=where[whichwindow]; +} + +void fileblit(word xpos,word xlen,word y1,word y2, shortint dir, word ylen) +{ + word fv; byte bit; +; + for( bit=0; bit <= 3; bit ++) + {; + fv=0; + while (fv<ylen) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(mem[0xa000*(y1+fv*dir)*80+xpos],mem[0xa000*(y2+fv*dir)*80+xpos],xlen); + fv += 1; + } + } + bit=getpixel(0,0); +} + +void seekthrough(byte whichlist, byte& wherenow, char whatfor) +{ + byte startedat; + + startedat=wherenow; + do { + wherenow += 1; + if (wherenow>nums[whichlist]) wherenow=1; + } while (!((startedat==wherenow) || (lists[whichlist][wherenow][1]==whatfor))); + repaint(whichlist); +} + +void gotohome(byte whichlist) +{ + where[whichlist]=1; + repaint(whichlist); +} + +void gotoend(byte whichlist) +{ + where[whichlist]=nums[whichlist]; + repaint(whichlist); +} + +void pageup(byte whichlist) +{ + if (where[whichlist]>9) + { + where[whichlist] -= 9; + repaint(whichlist); + } +} + +void pagedown(byte whichlist) +{ + if (where[whichlist]<nums[whichlist]-9) + { + where[whichlist] += 9; + repaint(whichlist); + } +} + +void subdirparse(string r); + +static void movehl(byte which, shortint howmuch) +{; + highlight(4,where[4]-top[4]+1); + if (((where[which]+howmuch)>0) && ((where[which]+howmuch)<=(unsigned char)nums[4])) + where[which]=where[which]+howmuch; + highlight(4,where[4]-top[4]+1); +} + + + +static void change_dir() +{; + dusk(); + /*$I-*/ chdir(lists[4][where[4]]); + /*$I+*/ + if (ioresult!=0) {; dawn(); blip(); return; } + where[4]=1; top[4]=1; + getcurrent(); scandir(); show(); + highlight(4,1); + dawn(); +} + +void subdirparse(string r) + +{; + switch (r[1]) { + case creturn: change_dir(); break; + + case '\0': switch (r[2]) { + case cup: if (where[4]-top[4]>0) /* Up */ + movehl(4,-1); /* Within range */ + else if (top[4]>1) + {; /* Outside range- must scroll */ + highlight(4,1); + top[4] -= 1; where[4] -= 1; + fileblit(61,18,166,176,-1,80); + setfillstyle(1,1); bar(490,85,630,95); setcolor(11); + outtextxy(497,87,string('[')+lists[dirs][where[4]]+']'); + highlight(4,1); + } + break; + case cdown: + if (where[4]-top[4]<8) /* Down */ + movehl(4,1); + else if (top[4]+8<nums[4]) + {; + highlight(4,9); + top[4] += 1; where[4] += 1; + fileblit(60,18,97,87,1,80); + setfillstyle(1,1); bar(490,165,630,175); setcolor(11); + outtextxy(497,167,string('[')+lists[dirs][where[4]]+']'); + highlight(4,9); + } + break; + case chome: gotohome(4); break; + case cend: gotoend(4); break; + case cpgup: pageup(4); break; + case cpgdn: pagedown(4); break; + case c_ao: change_dir(); break; + } + break; + default: seekthrough(4,where[4],lowchar(r[1])); + } +} + +void fileinfo(byte which); + + +static void display(integer y, string left,string right) +{; + y=17+y*12; + settextjustify(2,1); setcolor(11); outtextxy(315,y,left); + settextjustify(0,1); setcolor(15); outtextxy(325,y,right); +} + +void fileinfo(byte which) + /* This gives information on the file whose name is in lists[files,which]. */ +{ + ednahead eh; + untyped_file f; + varying_string<4> os; + char r; + +; + + /* Firstly, we must check whether or not it's an Avalot file. This is easily + done, since the descriptions of all others always begin with a star. */ + + if ((descs[which][1]=='*') || (descs[which][1]=='(')) + {; /* it is. */ + blip(); /* Naaaarghh! */ + return; + } + + /* Anyway... it wasn't. */ + + assign(f,lists[files][which]+".asg"); + reset(f,1); + seek(f,177); + blockread(f,eh,sizeof(eh)); + close(f); + + /* We now hold its EDNA record. */ + + setfillstyle(1,1); bar(2,2,637,197); /* Interesting information coming up! */ + + {; + display(2,"Saved by:", eh.game); + display(3,"version:", eh.verstr); + +/* display(4,'under', os);*/ + + display(6,"Saved on ",strf(eh.d)+'-'+strf(eh.m)+'-'+strf(eh.y)); + + display(9,"No. of times saved:",strf(eh.saves)); + + display(11,"Money:",eh.money); + display(12,"Score:",strf(eh.points)); + } + + shbox(500,177,650,200,"Press any key..."); + r=readkey(); + + setfillstyle(1,1); bar(2,2,637,197); +} + +void filer_help() + /* This gives general help. */ +{ + char r; +; + outtextxy(100,100,"Just general help here."); + shbox(500,177,650,200,"Press any key..."); + r=readkey(); + + setfillstyle(1,1); bar(2,2,637,197); +} + +void wipe() + /* This allows you to delete files. */ +{ + char r; +; + outtextxy(100,100,"Are you sure you want to delete \"foo.bar\"?"); + shbox(500,177,650,200,"[Y/N]"); + r=readkey(); + + setfillstyle(1,1); bar(2,2,637,197); +} + +void filesparse(string r); + +static void movehl1(byte which, shortint howmuch) +{; + highlight(3,where[3]-top[3]+1); + if (((where[which]+howmuch)>0) && ((where[which]+howmuch)<=(unsigned char)nums[3])) + where[which]=where[which]+howmuch; + highlight(3,where[3]-top[3]+1); +} + + + +static boolean selected_file() +{boolean selected_file_result; +; + if (descs[where[file_win]][1]=='*') + { + blip(); + selected_file_result=false; + } else + { + filename=lists[file_win][where[file_win]]; + filefound=true; + selected_file_result=true; + } +return selected_file_result; +} + +void filesparse(string r) + +{; + switch (r[1]) { + case creturn: if (selected_file()) return; break; + case '\0': switch (r[2]) { + case cup: if (where[3]-top[3]>0) /* Up */ + movehl1(3,-1); /* Within range */ + else if (top[3]>1) + {; /* Outside range- must scroll */ + highlight(3,1); + top[3] -= 1; where[3] -= 1; + fileblit(1,59,166,176,-1,80); + setfillstyle(1,1); bar( 15,85,480,95); + show_file( 19,87,where[3]); + highlight(3,1); + } + break; + case cdown: if (where[3]-top[3]<8) /* Down */ + movehl1(3,1); + else if (top[3]+8<nums[3]) + {; + highlight(3,9); + top[3] += 1; where[3] += 1; + fileblit(1,59,97,87,1,80); + setfillstyle(1,1); bar( 15,165,480,175); + show_file( 19,167,where[3]); + highlight(3,9); + } + break; + case c_ai: fileinfo(where[3]); break; /* alt-I: information. */ + case c_ah:case c_f1: filer_help(); break; /* alt-I: information. */ + case chome: gotohome(3); break; + case cend: gotoend(3); break; + case cpgup: pageup(3); break; + case cpgdn: pagedown(3); break; + case c_ao: if (selected_file()) return; break; + } + break; + default: seekthrough(3,where[3],lowchar(r[1])); + } +} + +string playaround(); + +static void changewin(byte i) +{; + switch (nowwin) { + case 3:case 4: highlight(nowwin,where[nowwin]-top[nowwin]+1); break; + } + setcolor(3); { windowtype& with = threewins[nowwin]; box(with.x1,with.y1,with.x2,with.y2,with.title);} + nowwin=i; + if (nowwin<1) nowwin=4; if (nowwin>4) nowwin=1; + switch (nowwin) { + case 3:case 4: highlight(nowwin,where[nowwin]-top[nowwin]+1); break; + } +} + +string playaround() +{ + char r,r2; +string playaround_result; +; + filefound=false; dawn(); + + do { + setcolor(14); { windowtype& with = threewins[nowwin]; box(with.x1,with.y1,with.x2,with.y2,with.title);} + r=readkey(); + switch (r) { + case ctab: changewin(nowwin+1); break; + case cescape: {; + playaround_result=""; + return playaround_result; + } + break; + case '\0': {; /* parse extd keystroke */ + r2=readkey(); + switch (r2) { + case cs_tab: changewin(nowwin-1); break; + case c_an: changewin(1); break; + case c_ad: changewin(2); break; + case c_af: changewin(3); break; + case c_as: changewin(4); break; + case c_ac: {; + playaround_result=""; + return playaround_result; + } + break; + default: + switch (nowwin) { + case 3: filesparse(string('\0')+r2); break; + case 4: subdirparse(string('\0')+r2); break; + } + } + } + break; + default: + {; /* Pass keystroke to current window */ + switch (nowwin) { + case 2: changedrive(upcase(r)); break; + case 4: subdirparse(r); break; + case 3: filesparse(r); break; + default: blip(); + } + } + + } + + if (filefound) + {; + dusk(); + playaround_result=filename; + return playaround_result; + } + } while (!false); +return playaround_result; +} + +void do_filer() +{ + pathstr p; +void do_filer_result; +; + loading=true; + setup(); + scandir(); + show(); show_drives(); + p=playaround(); + if (p!="") p=fexpand(p+".ASG"); + do_filer_result=p; +return do_filer_result; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + filename=do_filer(); + closegraph(); + if (filename=="") + output << "*** CANCELLED! ***" << NL; + else + output << "Selected: " << filename << NL; + input >> NL; +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/fileunit.cpp b/engines/avalanche/fileunit.cpp new file mode 100644 index 0000000000..a944fbc0a0 --- /dev/null +++ b/engines/avalanche/fileunit.cpp @@ -0,0 +1,1118 @@ +#include "ptoc.h" + +#define __fileunit_implementation__ + /* v:filer.pas - "avvyfiler" - in unit form. */ + +#include "fileunit.h" + + +#include "graph.h" +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ +/*#include "Tommys.h"*/ +#include "lucerna.h" +#include "pingo.h" +#include "Gyro.h" + +/*$V-*/ + +struct windowtype { + integer x1,y1,x2,y2; + varying_string<20> title; +}; + +const integer border = 1; /* size of border on shadowboxes */ + +const array<1,4,string> buttons = {{"Okay","Wipe","Cancel","Info..."}}; + +const integer files = 3; +const integer dirs = 4; + +const integer drlen = 15; /* no. of drives on one line */ + +const array<1,4,windowtype> threewins = + {{{155, 12, 630, 22, "Name"}, + {15, 25, 410, 70, "Drives"}, + {15, 83, 480, 179, "Files (*.ASG)"}, + {490, 83, 630, 179, "Subdirectories"}}}; + +const integer name_win = 1; +const integer drive_win = 2; +const integer file_win = 3; +const integer subdir_win = 4; + +const integer filer_page = 3; + +matrix<3,4,1,77,varying_string<12> > lists; +array<1,77,varying_string<40> > descs; +array<3,4,byte> nums,where,top,thumb_pos,thumb_len; +searchrec s; +boolean loading; +varying_string<26> drives; +pathstr current; +byte nowwin; + +pathstr filename; +boolean filefound; + +boolean cancelled; + +void shadow(integer x1,integer y1,integer x2,integer y2, byte hc,byte sc) +{ + byte fv; + + for( fv=0; fv <= border; fv ++) + { + setfillstyle(1,hc); + bar(x1+fv,y1+fv,x1+fv,y2-fv); + bar(x1+fv,y1+fv,x2-fv,y1+fv); + + setfillstyle(1,sc); + bar(x2-fv,y1+fv,x2-fv,y2-fv); + bar(x1+fv,y2-fv,x2-fv,y2-fv); + } +} + +void shbox(integer x1,integer y1,integer x2,integer y2, string t) +{ + const integer fc = 7; + + shadow(x1,y1,x2,y2,15,8); + setfillstyle(1,fc); + bar(x1+border+1,y1+border+1,x2-border-1,y2-border-1); + setcolor(1); x1=(x2-x1) / 2+x1; y1=(y2-y1) / 2+y1; + outtextxy(x1,y1,t); + if ((t[1]!='[') && (length(t)>1)) + { + fillchar(t[2],length(t)-1,'\40'); t[1]='_'; + outtextxy(x1-1,y1+1,t); + } +} + +void show_drives() +{ + byte fv; + + settextjustify(1,1); + for( fv=0; fv <= length(drives)-1; fv ++) + shbox((fv % drlen)*25+25,(fv / drlen)*19+31, + (fv % drlen)*25+40,45+(fv / drlen)*19,drives[fv+1]); + setcolor(11); + settextjustify(0,2); +} + +char which_drive(integer x,integer y) +{ + char which_drive_result; + x=(x-25) / 25; y=(y-32) / 19; + + which_drive_result= drives[1+x+y*drlen]; + return which_drive_result; +} + +void box(integer x1,integer y1,integer x2,integer y2, string z) +{ + rectangle(x1,y1,x2,y2); + outtextxy(x1+1,y1-10,z+':'); + outtextxy(x1,y1-9,"_"); +} + +string lowstr(string x) +{ + byte fv; + + string lowstr_result; + for( fv=1; fv <= length(x); fv ++) + if (set::of(range('A','Z'), eos).has(x[fv])) x[fv] += 32; + lowstr_result=x; + return lowstr_result; +} + +char lowchar(char x) +{ + char lowchar_result; + if (set::of(range('A','Z'), eos).has(x)) x -= 32; + lowchar_result=x; + return lowchar_result; +} + +void getcurrent() +{ + current=lowstr(fexpand("*.asg")); +} + +void firstsetup() +{ + integer gd,gm; + registers r; + byte floppies; + + /* Now... find all drives that exist. */ + drives=""; + intr(0x11,r); floppies=(((cardinal)r.ax >> 6) & 0x3)+1; /* useful bit of code! */ + for( gm=1; gm <= floppies; gm ++) drives=drives+chr(64+gm); + /* Winchesters, etc., can be found the easy way... */ + for( gd=3; gd <= 26; gd ++) /* C: to Z: */ + if (disksize(gd)>-1) drives=drives+chr(64+gd); + + fillchar(where,sizeof(where),'\1'); + fillchar(top,sizeof(top),'\1'); + + /* Set up mouse. */ + off_virtual(); + oncandopageswap=false; + newpointer(2); +} + +void draw_scroll_bar(byte which) +{ + setcolor(1); + { + windowtype& with = threewins[which]; + + setfillstyle(1,7); + bar(with.x2-7,with.y1+10,with.x2-1,with.y2-10); + setfillstyle(1,3); + bar(with.x2-7,with.y1+ 1,with.x2-1,with.y1+9); + bar(with.x2-7,with.y2- 9,with.x2-1,with.y2-1); + outtextxy(with.x2-7,with.y1+2,"\30"); + outtextxy(with.x2-7,with.y2-8,"\31"); + } +} + +void setup() +{ + integer gd,gm; + registers r; + byte floppies; + + setactivepage(filer_page); setvisualpage(filer_page); + setfillstyle(1,1); bar(2,2,637,197); shadow(0,0,639,199,15,7); + + settextstyle(0,0,0); + settextjustify(1,1); + for( gd=1; gd <= 2; gd ++) + for( gm=0; gm <= 1; gm ++) + shbox(420+gm*110,gd*25,520+gm*110,gd*25+20,buttons[gm*2+gd]); + shbox(15,182,350,196,"Help... (press f1)"); + settextjustify(0,2); setcolor(11); + setcolor(15); outtextxy(15,5,"The Avvy Filer..."); + setcolor(11); outtextxy(317,3,"Select a file to load."); + outtextxy(357,185,"Copyright (c) 1993, Thomas Thurman."); + + /* Draw the boxes and names */ + setcolor(3); + for( gm=1; gm <= 4; gm ++) + { windowtype& with = threewins[gm]; + box(with.x1,with.y1,with.x2,with.y2,with.title);} + + /* Draw the scroll bars. */ + + for( gm=3; gm <= 4; gm ++) draw_scroll_bar(gm); +} + +void thumb(byte whichwin) +{ + word length,the_top; + + if (nums[whichwin]<9) + { + length=76; + the_top=0; + } else + { + length=trunc(76*((real)(8)/nums[whichwin])); + the_top=trunc(((real)(where[whichwin])/nums[whichwin])*(76-length)); + } + + the_top += 93; /* Top of both the scrollbars. */ + + setfillstyle(1,7); + { windowtype& with = threewins[whichwin]; + bar(with.x2-6,thumb_pos[whichwin],with.x2-3,thumb_pos[whichwin]+length);} + setfillstyle(1,1); + { windowtype& with = threewins[whichwin]; + bar(with.x2-6,the_top,with.x2-3,the_top+length);} + + thumb_pos[whichwin]=the_top; + thumb_len[whichwin]=length; +} + +void quicksort(byte whichlist, integer lo, integer hi); + + +static void sort(integer l, integer r, byte& whichlist) +{ + integer i, j; + varying_string<12> x, y; + varying_string<40> d; + + i = l; j = r; x = lists[whichlist][(l+r) / 2]; + do { + while (lists[whichlist][i] < x) i = i + 1; + while (x < lists[whichlist][j]) j = j - 1; + if (i <= j) + { + y = lists[whichlist][i]; + lists[whichlist][i] = lists[whichlist][j]; + lists[whichlist][j] = y; + + d = descs[i]; + descs[i] = descs[j]; + descs[j] = d; + + i = i + 1; j = j - 1; + } + } while (!(i > j)); + +/* if j<1 then j:=1; + if r<1 then r:=1;*/ + + if (l < j) sort(l, j, whichlist); + if (i < r) sort(i, r, whichlist); +} + +void quicksort(byte whichlist, integer lo, integer hi) + +{ /*QuickSort*/; + sort(lo,hi, whichlist); +} + +void scandir() +{ + pathstr nix; + namestr name; + untyped_file f; + ednahead eh; + array<1,4,char> dna_type; + + + nums[files]=0; + findfirst("*.asg",archive+hidden+readonly,s); + + while ((doserror==0) && (nums[files]<77)) + { + fsplit(s.name,nix,name,nix); + nums[files] += 1; + lists[files][nums[files]]=lowstr(name); + + assign(f,s.name); + reset(f,1); + seek(f,11); + blockread(f,dna_type,4); + + if (dna_type=="Avvy") + { /* A DNA256 file. */ + descs[nums[files]]="* Saved by Avaricius!"; + } else + { /* EDNA-based files. */ + if (dna_type=="EDNA") + { + seek(f,177); + blockread(f,eh,sizeof(eh)); + + if (eh.revision!=2) + descs[nums[files]]="* Unknown EDNA type!"; + else + { + + if (eh.number!=2) + descs[nums[files]]=string("% Saved by ")+eh.shortname+'!'; + else + { /* Well... everything seems to have gone OK! */ + descs[nums[files]]=eh.desc; + } + } + } else + descs[nums[files]]="* Not an Avvy saved game!"; + } + close(f); + findnext(s); + } + nums[dirs]=0; findfirst("*.*",directory,s); + while ((doserror==0) && (nums[dirs]<77)) + { + if (((s.attr & directory)>0) && ((length(s.name))>1)) + { + nums[dirs] += 1; + lists[dirs][nums[dirs]]=lowstr(s.name); + } + findnext(s); + } + + /* Now sort 'em! */ + + if (nums[dirs ]!=0) quicksort ( dirs,1,nums[ dirs]); + if (nums[files]!=0) quicksort (files,1,nums[files]); + + where[dirs]=1; where[files]=1; + top[dirs]=1; top[files]=1; + + thumb_pos[3]=93; thumb_pos[4]=93; +} + +void show_file(integer x,integer y, byte which) +{ + varying_string<58> z; + + fillchar(z[1],13,'\40'); + z=lists[files][which]+".asg"; + z[0]='\15'; z=z+descs[which]; + + if (set::of('*','%', eos).has(descs[which][1])) /* Can't load these! */ + setcolor(red); + else + setcolor(lightcyan); + + outtextxy(x,y,z); +} + +void showfiles() +{ + byte fv; + + if (loading) setcolor(11); else setcolor(3); + if (nums[3]==0) + { + outtextxy(22,86,"(None here!)"); + return; + } + for( fv=0; fv <= 8; fv ++) + if (top[3]+fv<=nums[3]) + show_file(19,87+fv*10,top[3]+fv); + + draw_scroll_bar(files); +} + +void showdirs() +{ + byte fv; + + setcolor(11); + for( fv=0; fv <= 8; fv ++) + if (top[4]+fv<=nums[4]) + outtextxy(497,87+fv*10,string('[')+lists[dirs][fv+top[4]]+']'); + draw_scroll_bar(dirs); +} + +void show() +{ + byte fv; + dirstr d; namestr n; extstr e; + + setfillstyle(1,1); + for( fv=1; fv <= 4; fv ++) + if (fv!=2) + { windowtype& with = threewins[fv]; + bar(with.x1+1,with.y1+1,with.x2-8,with.y2-1);} + showfiles(); + showdirs(); + setcolor(7); outtextxy(159,14,current); + for( fv=3; fv <= 4; fv ++) thumb(fv); +} + +void blip() +{ + sound(177); delay(77); nosound; +} + +void invert(integer x1,integer y1,integer x2,integer y2) +{ + pointer p,restore; word s; + + s=imagesize(x1,y1,x2,y2); + mark(restore); getmem(p,s); + getimage(x1,y1,x2,y2,p); + putimage(x1,y1,p,notput); + release(restore); +} + +void changedrive(char drive) +{ + byte fv; + + fv=pos(drive,drives); + if (fv==0) { blip(); return; } + off(); + fv -= 1; + shadow((fv % drlen)*25+25,(fv / drlen)*19+31, + (fv % drlen)*25+40,45+(fv / drlen)*19,8,7); + chdir(string(drive)+':'); + getcurrent(); scandir(); show(); + shadow((fv % drlen)*25+25,(fv / drlen)*19+31, + (fv % drlen)*25+40,45+(fv / drlen)*19,15,8); + on(); +} + +void highlight(byte win,byte line) +{ + switch (win) { + case 3: invert(16,75+line*10,470,85+line*10); break; + case 4: invert(491,75+line*10,620,85+line*10); break; + } + thumb(win); +} + +void repaint(byte whichwindow) +{ + setfillstyle(1,1); + { windowtype& with = threewins[whichwindow]; + bar(with.x1+1,with.y1+1,with.x2-8,with.y2-1);} + top[whichwindow]=where[whichwindow]; + switch (whichwindow) { + case file_win: showfiles(); break; + case subdir_win: showdirs(); break; + } + thumb(whichwindow); +} + +void fileblit(word xpos,word xlen,word y1,word y2, shortint dir, word ylen) +{ + word fv; byte bit; + + for( bit=0; bit <= 3; bit ++) + { + fv=0; + while (fv<ylen) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(mem[0xac00*(y1+fv*dir)*80+xpos],mem[0xac00*(y2+fv*dir)*80+xpos],xlen); + fv += 1; + } + } + bit=getpixel(0,0); +} + +void seekthrough(byte whichlist, byte& wherenow, char whatfor) +{ + byte startedat; + + startedat=wherenow; + do { + wherenow += 1; + if (wherenow>nums[whichlist]) wherenow=1; + } while (!((startedat==wherenow) || (lists[whichlist][wherenow][1]==whatfor))); + off(); + repaint(whichlist); + on(); +} + +void gotohome(byte whichlist) +{ + off(); + where[whichlist]=1; + repaint(whichlist); + highlight(whichlist,1); + on(); +} + +void gotoend(byte whichlist) +{ + off(); + where[whichlist]=nums[whichlist]; + repaint(whichlist); + highlight(whichlist,1); + on(); +} + +void pageup(byte whichlist) +{ + off(); + if (where[whichlist]>9) + { + where[whichlist] -= 9; + repaint(whichlist); + highlight(whichlist,1); + } else gotohome(whichlist); + on(); +} + +void pagedown(byte whichlist) +{ + off(); + if (where[whichlist]<nums[whichlist]-9) + { + where[whichlist] += 9; + repaint(whichlist); + highlight(whichlist,1); + } else gotoend(whichlist); + on(); +} + +void subdirparse(string r); + +static void movehl(byte which, shortint howmuch) +{ + off(); + highlight(4,where[4]-top[4]+1); + if (((where[which]+howmuch)>0) && ((where[which]+howmuch)<=(unsigned char)nums[4])) + where[which]=where[which]+howmuch; + highlight(4,where[4]-top[4]+1); + on(); +} + + + +static void change_dir() +{ + off(); dusk(); + /*$I-*/ chdir(lists[4][where[4]]); + /*$I+*/ + if (ioresult!=0) { dawn(); blip(); return; } + where[4]=1; top[4]=1; + getcurrent(); scandir(); show(); + highlight(4,1); + dawn(); on(); +} + +void subdirparse(string r) + +{ + switch (r[1]) { + case creturn: change_dir(); break; + + case '\0': switch (r[2]) { + case cup: if (where[4]-top[4]>0) /* Up */ + movehl(4,-1); /* Within range */ + else if (top[4]>1) + { /* Outside range- must scroll */ + off(); + highlight(4,1); + top[4] -= 1; where[4] -= 1; + fileblit(61,17,166,176,-1,80); + setfillstyle(1,1); bar(490,85,622,95); setcolor(11); + outtextxy(497,87,string('[')+lists[dirs][where[4]]+']'); + highlight(4,1); + on(); + } + break; + case cdown: + if (where[4]-top[4]<8) /* Down */ + movehl(4,1); + else if (top[4]+8<nums[4]) + { + off(); + highlight(4,9); + top[4] += 1; where[4] += 1; + fileblit(60,17,97,87,1,80); + setfillstyle(1,1); bar(490,165,622,175); setcolor(11); + outtextxy(497,167,string('[')+lists[dirs][where[4]]+']'); + highlight(4,9); + on(); + } + break; + case chome: gotohome(4); break; + case cend: gotoend(4); break; + case cpgup: pageup(4); break; + case cpgdn: pagedown(4); break; + case c_ao: change_dir(); break; + } + break; + default: { + off(); + seekthrough(4,where[4],lowchar(r[1])); + highlight(4,1); + on(); + } + } +} + +void fileinfo(byte which); +void filer_help(); +void wipe(byte which); + +void in_name_box(string x) +{ + off(); + setfillstyle(1,1); bar(156,13,629,21); + setcolor(7); outtextxy(159,14,x); + on(); +} + +void filesparse(string r); + +static void movehl1(byte which, shortint howmuch) +{ + off(); + highlight(3,where[3]-top[3]+1); + if (((where[which]+howmuch)>0) && ((where[which]+howmuch)<=(unsigned char)nums[3])) + where[which]=where[which]+howmuch; + highlight(3,where[3]-top[3]+1); + on(); +} + + + +static boolean selected_file() +{ + boolean selected_file_result; + if ((set::of('*','%', eos).has(descs[where[file_win]][1])) || (nums[3]==0)) + { + blip(); + selected_file_result=false; + } else + { + filename=lists[file_win][where[file_win]]; + filefound=true; + selected_file_result=true; + } + return selected_file_result; +} + +void filesparse(string r) + +{ + switch (r[1]) { + case creturn: if (selected_file()) return; break; + case '\0': switch (r[2]) { + case cup: if (where[3]-top[3]>0) /* Up */ + movehl1(3,-1); /* Within range */ + else if (top[3]>1) + { /* Outside range- must scroll */ + off(); + highlight(3,1); + top[3] -= 1; where[3] -= 1; + fileblit(1,58,166,176,-1,80); + setfillstyle(1,1); bar( 15,85,472,95); + show_file( 19,87,where[3]); + highlight(3,1); + on(); + } + break; + case cdown: if (where[3]-top[3]<8) /* Down */ + movehl1(3,1); + else if (top[3]+8<nums[3]) + { + off(); + highlight(3,9); + top[3] += 1; where[3] += 1; + fileblit(1,58,97,87,1,80); + setfillstyle(1,1); bar( 15,165,472,175); + show_file( 19,167,where[3]); + highlight(3,9); + on(); + } + break; + case c_ai: fileinfo(where[3]); break; /* alt-I: information. */ + case c_aw: wipe(where[3]); break; /* alt-W: wipe. */ + case chome: gotohome(3); break; + case cend: gotoend(3); break; + case cpgup: pageup(3); break; + case cpgdn: pagedown(3); break; + case c_ao: if (selected_file()) return; break; + } + break; + default: { + off(); + seekthrough(3,where[3],lowchar(r[1])); + highlight(3,1); + on(); + } + } + in_name_box(lists[files][where[3]]+".asg"); +} + +void entername(char r) +{ + switch (r) { + case '\10': if (filename[0]!='\0') filename[0] -= 1; break; + case '\15': filefound=true; break; + case '\40':; break; /* ignore spaces. */ + default: + { + if (length(filename)<55) filename=filename+r; + + if (length(filename)==1) + { + where[3]=1; + seekthrough(3,where[3],filename[1]); + } + } + } + + in_name_box(filename+".asg"); + +} + +void changewin(byte i) +{ + off(); + switch (nowwin) { + case 3:case 4: highlight(nowwin,where[nowwin]-top[nowwin]+1); break; + } + setcolor(3); { windowtype& with = threewins[nowwin]; box(with.x1,with.y1,with.x2,with.y2,with.title);} + nowwin=i; + if (nowwin<1) nowwin=4; if (nowwin>4) nowwin=1; + switch (nowwin) { + case 3:case 4: highlight(nowwin,where[nowwin]-top[nowwin]+1); break; + } + on(); +} + +void checkmouse(); + +static void relevant(string x) +{ + setcolor(14); off(); { windowtype& with = threewins[nowwin]; box(with.x1,with.y1,with.x2,with.y2,with.title);} + on(); if (nowwin==3) filesparse(x); else subdirparse(x); +} + +void checkmouse() +{ + byte fv,new,waswin; + + check(); + if (mrelease>0) + { /* Where did they click? */ + for( fv=1; fv <= 4; fv ++) + { windowtype& with = threewins[fv]; + if (((cardinal)with.x1<=mx) && ((cardinal)with.x2>=mx) && ((cardinal)with.y1<=my) && ((cardinal)with.y2>=my)) + { + waswin=nowwin; + + if (nowwin!=fv) + { + changewin(fv); + off(); + setcolor(14); { windowtype& with1 = threewins[nowwin]; box(with1.x1,with1.y1,with1.x2,with1.y2,with1.title);} + on(); + } + /* Now... individual windows should do their own checkclicking. */ + + switch (fv) { + /* 1: no effect. */ + case 2: changedrive(which_drive(mx,my)); break; /* Change drive w/mouse. */ + case 3:case 4: if (my<175) { /* Click on highlight users. */ + if (mx>(cardinal)threewins[nowwin].x2-9) + { /* Scroll bar. */ + if (my<(cardinal)threewins[nowwin].y1+10) + relevant(null+cup); /* scroll up */ + else if (my>(cardinal)threewins[nowwin].y2-10) + relevant(null+cdown); /* scroll down. */ + else if (my<(unsigned char)thumb_pos[nowwin]) + relevant(null+cpgup); /* above thumb-- page up. */ + else if (my>(unsigned char)thumb_pos[nowwin]+thumb_len[nowwin]) + relevant(null+cpgdn); /* above thumb-- page up. */ + else { /* On the thumb. */ + blip(); + } + } else + { + new=top[fv]+(my-75) / 10-1; + + if ((new==where[fv]) && (nowwin==waswin)) + { /* Double-clicked, --> "OK" */ + /* filefound:=true; + filename:=lists[fv,new];*/ + if (fv==3) filesparse("\15"); else subdirparse("\15"); + } else + { /* Single-clicked, --> move highlight */ + off(); + highlight(fv,where[fv]-top[fv]+1); + if ((new>0) && (new<=nums[fv])) + where[fv]=new; + highlight(fv,where[fv]-top[fv]+1); + on(); + } + } + } + break; + } + + return; /* Since they've clicked in a window... */ + }} + + /* Righto, they must have clicked on a button. Which? */ + + switch (my) { + case 25 ... 45: /* Top row: Okay, Cancel. */ + switch (mx) { + case 420 ... 520: switch (nowwin) { + case 1: entername('\15'); break; + case 3: filesparse("\15"); break; + case 4: subdirparse("\15"); break; + default: blip(); + } + break; + case 530 ... 630: cancelled=true; break; + } + break; + case 50 ... 95: /* Bottom row: Wipe, Info. */ + switch (mx) { + case 420 ... 520: if (nowwin==3) wipe(where[3]); else blip(); break; + case 530 ... 630: if (nowwin==3) fileinfo(where[3]); else blip(); break; + } + break; + case 180 ... 200: filer_help(); break; /* The "help" button. */ + } + } +} + +string playaround() +{ + char r,r2; + + string playaround_result; + filefound=false; dawn(); + + do { + setcolor(14); off(); { windowtype& with = threewins[nowwin]; box(with.x1,with.y1,with.x2,with.y2,with.title);} on(); + do { checkmouse(); } while (!(keypressed() || filefound || cancelled)); + if (! (filefound || cancelled)) + { + r=readkey(); + switch (r) { + case ctab: changewin(nowwin+1); break; + case cescape: { + playaround_result=""; + return playaround_result; + } + break; + case '\0': { /* parse extd keystroke */ + r2=readkey(); + switch (r2) { + case cs_tab: changewin(nowwin-1); break; + case c_an: changewin(1); break; + case c_ad: changewin(2); break; + case c_af: changewin(3); break; + case c_as: changewin(4); break; + case c_ac: cancelled=false; break; + case c_ah:case cf1: filer_help(); break; /* alt-H: help. */ + default: + switch (nowwin) { + case 3: filesparse(string('\0')+r2); break; + case 4: subdirparse(string('\0')+r2); break; + } + } + } + break; + default: + { /* Pass keystroke to current window */ + switch (nowwin) { + case 1: entername(r); break; + case 2: changedrive(upcase(r)); break; + case 4: subdirparse(r); break; + case 3: filesparse(r); break; + default: blip(); + } + } + } + + } + + if (filefound) + { + dusk(); + playaround_result=filename; + return playaround_result; + } + + if (cancelled) + { + dusk(); + playaround_result=""; + return playaround_result; + } + } while (!false); + return playaround_result; +} + +void drawup() +{ + off(); + loading=true; + setup(); + show(); show_drives(); + on(); +} + +void little_cls() +{ + setfillstyle(1,1); bar(2,2,637,197); /* Interesting information coming up! */ +} + +void wait_for_keypress_or_mouse_click() +{ + char r; + + do { check(); } while (!((mrelease>0) || keypressed())); + while (keypressed()) r=readkey(); +} + +void fileinfo(byte which); + + +static void display(integer y, string left,string right) +{ + y=17+y*12; + settextjustify(2,1); setcolor(11); outtextxy(315,y,left); + settextjustify(0,1); setcolor(15); outtextxy(325,y,right); +} + +void fileinfo(byte which) + /* This gives information on the file whose name is in lists[files,which]. */ +{ + ednahead eh; + untyped_file f; + varying_string<4> os; + + + + /* Firstly, we must check whether or not it's an Avalot file. This is easily + done, since the descriptions of all others always begin with a star. */ + + if ((descs[which][1]=='*') || (nums[3]==0)) + { /* it is. */ + blip(); /* Naaaarghh! */ + return; + } + + /* Anyway... it wasn't. */ + + assign(f,lists[files][which]+".asg"); + reset(f,1); + seek(f,177); + blockread(f,eh,sizeof(eh)); + close(f); + + /* We now hold its EDNA record. */ + + off(); + little_cls(); /* Interesting information coming up! */ + + { + display(0,"File:",eh.fn); + display(1,"Description:",eh.desc); + display(2,"Saved by:", eh.game); + display(3,"version:", eh.verstr); + + display(4,"under", eh.os); + + display(6,"Saved on:",strf(eh.d)+'-'+strf(eh.m)+'-'+strf(eh.y)); + + display(9,"No. of times saved:",strf(eh.saves)); + + display(11,"Money:",eh.money); + display(12,"Score:",strf(eh.points)); + } + + settextjustify(1,1); + shbox(400,177,600,195,"[Press any key...]"); + settextjustify(0,2); on(); + wait_for_keypress_or_mouse_click(); + + off(); setfillstyle(1,1); bar(2,2,637,197); + drawup(); + off(); highlight(3,where[3]-top[3]+1); on(); +} + +void filer_help() + /* Just some general help... */ + +{ + off(); little_cls(); + + setcolor(15); + outtextxy(10, 10,"To change to a particular pane:"); + outtextxy(10, 50,"To choose a file:"); + outtextxy(10,100,"To change drives:"); + outtextxy(10,140,"Finally..."); + + setcolor(14); + outtextxy(20, 20,"Press Alt and the initial letter simultaneously."); + outtextxy(20, 30,"(e.g. to change to the Name pane, press Alt-N.)"); + outtextxy(20, 60,"Either type its name in the Name pane or choose it"); + outtextxy(20, 70,"from the list in the Files pane. You may either use"); + outtextxy(20, 80,"a mouse or the keyboard to do this."); + outtextxy(20,110,"Move into the Drives pane and press the letter of the"); + outtextxy(20,120,"drive you want."); + outtextxy(20,150,"Either select OK to load the file, or Cancel to back out."); + + settextjustify(1,1); + shbox(400,177,600,195,"[Press any key...]"); + settextjustify(0,2); on(); + wait_for_keypress_or_mouse_click(); + + off(); setfillstyle(1,1); bar(2,2,637,197); + drawup(); off(); + if (set::of(3,4, eos).has(nowwin)) highlight(nowwin,where[nowwin]-top[nowwin]+1); + on(); +} + +void wipe(byte which) + /* This wipes the file whose name is in lists[files,which]. */ +{ + char r; + untyped_file f; + + + off(); little_cls(); + + settextjustify(1,1); + outtextxy(320,100,string("Are you sure you want to delete \"")+ + lists[files][which]+".asg\"?"); + shbox(400,177,600,195,"[Y/N]"); + + do { + r=upcase(readkey()); + if (r=='Y') + { + assign(f,lists[files][which]+".asg"); /*$I-*/ erase(f); /*$I+*/ + + setcolor(14); + if (ioresult==0) + { + scandir(); + outtextxy(100,140,"Deleted."); + } else + outtextxy(100,140,"Not deleted (some problem...)"); + + shbox(400,177,600,195,"[Press any key...]"); + on(); + wait_for_keypress_or_mouse_click(); off(); + } + } while (!(set::of('Y','N', eos).has(r))); + + settextjustify(0,2); setcolor(14); + setfillstyle(1,1); bar(2,2,637,197); + drawup(); + off(); highlight(3,where[3]-top[3]+1); on(); +} + +string do_filer() +{ + pathstr p; byte groi; dirstr original_directory; + + string do_filer_result; + getdir(0,original_directory); + dusk(); + oncandopageswap=false; cancelled=false; + copypage(3,1-cp); /* Store old screen. */ groi=getpixel(0,0); + off(); + + firstsetup(); + scandir(); + nowwin=1; getcurrent(); + firstsetup(); drawup(); + on(); + mousepage(filer_page); + + p=playaround(); + if (p!="") p=fexpand(p+".ASG"); + do_filer_result=p; + filename=""; + + mousepage(cp); + dusk(); off(); + oncandopageswap=true; + copypage(1-cp,3); /* Restore old screen. */ groi=getpixel(0,0); + on_virtual(); dawn(); fix_flashers(); + + setvisualpage(cp); + setactivepage(1-cp); + chdir(original_directory); + + return do_filer_result; +} + + diff --git a/engines/avalanche/fileunit.h b/engines/avalanche/fileunit.h new file mode 100644 index 0000000000..08f9262653 --- /dev/null +++ b/engines/avalanche/fileunit.h @@ -0,0 +1,7 @@ +#ifndef __fileunit_h__ +#define __fileunit_h__ + + +string do_filer(); /* Result is filename, or "" if cancelled. */ + +#endif diff --git a/engines/avalanche/filing.cpp b/engines/avalanche/filing.cpp new file mode 100644 index 0000000000..f990f8c338 --- /dev/null +++ b/engines/avalanche/filing.cpp @@ -0,0 +1,144 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + FILING The saving and loading handler. */ + + +/*$R+*/ + +/*interface*/ + +/*#include "Gyro.h"*/ + + +const array<1,12,varying_string<6> > months = + {{"Jan*","Feb*","March","April","May","June","July","August", + "Sept&","Oct&","Nov&","Dec&"}}; +const string ednaid = string("TT")+'\261'+'\36'+'\1'+'\113'+'\261'+'\231'+'\261'; +const array<1,6,varying_string<7> > systems = + {{"DOS","Windows","OS/2","Mac","Amiga","ST"}}; + +struct edhead { /* Edna header */ + /* This header starts at byte offset 177 in the .ASG file. */ + array<1,9,char> id; /* signature */ + word revision; /* EDNA revision, here 2 (1=dna256) */ + varying_string<50> game; /* Long name, eg Lord Avalot D'Argent */ + varying_string<15> shortname; /* Short name, eg Avalot */ + word number; /* Game's code number, here 2 */ + word ver; /* Version number as integer (eg 1.00 = 100) */ + varying_string<5> verstr; /* Vernum as string (eg 1.00 = "1.00" */ + varying_string<12> filename; /* Filename, eg AVALOT.EXE */ + byte os; /* Saving OS (here 1=DOS). See below for others.*/ + + /* Info on this particular game */ + + varying_string<8> fn; /* Filename (not extension ('cos that's .ASG)) */ + byte d,m; /* D, M, Y are the Day, Month & Year this game was... */ + word y; /* ...saved on. */ + varying_string<40> desc; /* Description of game (same as in Avaricius!) */ + word len; /* Length of DNA (it's not going to be above 65535!) */ + + /* Quick reference & miscellaneous */ + + word saves; /* no. of times this game has been saved */ + integer cash; /* contents of your wallet in numerical form */ + varying_string<20> money; /* ditto in string form (eg 5/-, or 1 denarius)*/ + word points; /* your score */ + + /* DNA values follow, then footer (which is ignored) */ +}; + /* Possible values of edhead.os: + 1 = DOS 4 = Mac + 2 = Windows 5 = Amiga + 3 = OS/2 6 = ST */ + +/*implementation*/ + +untyped_file f; +byte fv; +array<1,255,word> dna256; +boolean ok; +edhead e; + +void info256(string x) /* info on dna256 *.ASG files */ +{ + varying_string<40> describe; +; + assign(f,x); + /*$I-*/ reset(f,1); + seek(f,47); + blockread(f,describe,40); + blockread(f,dna256,sizeof(dna256)); + close(f); /*$I+*/ + {; + e.revision=1; + e.game="Denarius Avaricius Sextus"; + e.shortname="Avaricius"; + e.number=1; + e.verstr="[?]"; + e.filename="AVVY.EXE"; + e.os=1; /* Dos */ + e.fn=x; + e.d=dna256[7]; e.m=dna256[8]; e.y=dna256[9]; + e.desc=describe; + e.len=512; + e.saves=dna256[6]; + e.cash=dna256[30]; + e.money=strf(e.cash)+" denari"; + if (e.cash==1) e.money=e.money+"us"; else e.money=e.money+'i'; + e.points=dna256[36]; + } +} + +string enlarge(string x) +{string enlarge_result; +; + switch (x[length(x)]) { + case '*': {; x[0] -= 1; x=x+"uary"; } break; + case '&': {; x[0] -= 1; x=x+"ember"; } break; + } + enlarge_result=x; +return enlarge_result; +} + +string th(byte x) +{ + varying_string<4> n; +string th_result; +; + n=strf(x); + switch (x) { + case 1:case 21:case 31: n=n+"st"; break; + case 2:case 22: n=n+"nd"; break; + case 3:case 23: n=n+"rd"; break; + default: n=n+"th"; + } + th_result=n; +return th_result; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + info256("t:justb4.asg"); + + {; + output << "DNA coding: "; + switch (e.revision) { + case 1: output << "dna256" << NL; break; + case 2: output << "E.D.N.A." << NL; break; + default: output << "Unknown!" << NL; + } + output << "Filename: " << e.game << " (version " << e.verstr << ')' << NL; + output << "Description: " << e.desc << NL; + output << "Cash: " << e.money << NL; + output << "Score: " << e.points << NL; + output << "Date: " << th(e.d) << ' ' << enlarge(months[e.m]) << ' ' << e.y << NL; + output << "Number of saves: " << e.saves << NL; + } +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/folktemp.cpp b/engines/avalanche/folktemp.cpp new file mode 100644 index 0000000000..c715aa9936 --- /dev/null +++ b/engines/avalanche/folktemp.cpp @@ -0,0 +1,79 @@ +#include "ptoc.h" + + /* Get 'em back! */ +#include "graph.h" + + +const integer picsize = 966; +const integer number_of_objects = 19; + +const array<1,65,char> thinks_header = + string("This is an Avalot file, which is subject to copyright. Have fun.")+'\32'; + +const array<0,19,byte> order = + {{ 4, 19, 1, 18, 15, 9, 12, 13, 17, 10, 2, 6, 3, 5, 7, 14, + 16, + + 0, 11, 8}}; + +/* + pAvalot=#150; pSpludwick=#151; pCrapulus=#152; pDrDuck=#153; + pMalagauche=#154; pFriarTuck=#155; pRobinHood=#156; pCwytalot=#157; + pduLustie=#158; pDuke=#159; pDogfood=#160; pTrader=#161; + pIbythneth=#162; pAyles=#163; pPort=#164; pSpurge=#165; + pJacques=#166; + + pArkata=#175; pGeida=#176; pWiseWoman=#178; +*/ + +integer gd,gm; +untyped_file f; +pointer p; +byte noo; + +void load() +{ + byte a0 /*absolute $A000:1200*/; + byte bit; + untyped_file f; +; + assign(f,"d:folk.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); bit=getpixel(0,0); +} + +void get_one() +{; + + gd=((order[noo] % 9)*70+10); + gm=((order[noo] / 9)*40+20); + + getimage(gd,gm,gd+59,gm+29,p); + putimage(gd,gm,p,notput); + blockwrite(f,p,picsize); + +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + + load(); noo=0; + + assign(f,"folk.avd"); + getmem(p,picsize); + rewrite(f,1); + blockwrite(f,thinks_header,65); + + for( noo=0; noo <= number_of_objects; noo ++) + get_one(); + + close(f); freemem(p,picsize); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/fontslid.cpp b/engines/avalanche/fontslid.cpp new file mode 100644 index 0000000000..4a2ceb21c6 --- /dev/null +++ b/engines/avalanche/fontslid.cpp @@ -0,0 +1,25 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +fonttype font1; +byte fv; +char r; +file<fonttype> f; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + assign(f,"v:avalot.fnt"); reset(f); f >> font1; close(f); + for( r='\0'; r <= '\377'; r ++) + {; + for( fv= 0; fv <= 3; fv ++) font1[r][fv]=(cardinal)font1[r][fv] >> 1; + for( fv= 7; fv <= 8; fv ++) font1[r][fv]=font1[r][fv] << 1; + for( fv= 9; fv <= 14; fv ++) font1[r][fv]=font1[r][fv] << 2; + } + assign(f,"v:avitalic.fnt"); rewrite(f); f << font1; close(f); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/frere.cpp b/engines/avalanche/frere.cpp new file mode 100644 index 0000000000..b3118ddd1d --- /dev/null +++ b/engines/avalanche/frere.cpp @@ -0,0 +1,102 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + + +typedef array<1,31,byte> tunetype; + +const integer lower = 0; + const integer same = 1; +const integer higher = 2; + +const array<1,12,char> keys = "QWERTYUIOP[]"; +const array<1,12,word> notes = +{{196,220,247,262,294,330,350,392,440,494,523,587}}; + +const tunetype tune = +{{higher,higher,lower,same,higher,higher,lower,higher,higher,higher, + lower,higher,higher, + same,higher,lower,lower,lower,lower,higher,higher,lower,lower,lower, + lower,same,lower,higher,same,lower,higher}}; + +byte this_one,last_one; + +char pressed; + +byte value; + +tunetype played; + +void store_(byte what) +{; + + move(played[2],played[1],sizeof(played)-1); + + played[31]=what; + +} + +boolean they_match() +{ + byte fv; +boolean they_match_result; +; + + for( fv=1; fv <= sizeof(played); fv ++) + if (played[fv]!=tune[fv]) + {; + they_match_result=false; + return they_match_result; + } + + they_match_result=true; + +return they_match_result; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + + textattr=30; clrscr; output << NL; + + do { + + pressed=upcase(readkey()); + + value=pos(pressed,keys); + + if (value>0) + {; + + last_one=this_one; + this_one=value; + + sound(notes[this_one]); + delay(100); + nosound; + + if (this_one<last_one) + store_(lower); else + + if (this_one==last_one) + store_(same); else + + store_(higher); + + if (they_match()) + {; + textattr=94; clrscr; output << NL; + output << string('\7')+"It matches!" << NL; + input >> NL; + exit(0); + } + + } + + } while (!(pressed=='\33')); + + output << "*** PROGRAM STOPPED! ***" << NL; +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/g-room.cpp b/engines/avalanche/g-room.cpp new file mode 100644 index 0000000000..fc8f47ec51 --- /dev/null +++ b/engines/avalanche/g-room.cpp @@ -0,0 +1,413 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +/*$R+*/ + +const array<1,5,shortint> adjustment = {{7,0,7,7,7}}; + +const array<0,3,byte> plane_to_use = {{2,2,2,3}}; + +const array<1,5,byte> waveorder = {{5,1,2,3,4}}; + +const array<1,26,byte> glerkfade = + {{1,1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,4,4,3,3,3,2,2,1}}; + +const array<1,18,byte> greldetfade = {{1,2,3,4,5,6,6,6,5,5,4,4,3,3,2,2,1,1}}; + +enum flavourtype {ch_ega,ch_bgi,ch_natural,ch_two,ch_one, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; +}; + +typedef array<1,6,0,3,0,34,1,9,byte> glerktype; + + +untyped_file f; +chunkblocktype cb; +array<1,5,2,3,0,65,0,25,byte> ghost; +byte fv; +pointer memlevel; +byte y,yy,bit,xofs; + +array<0,1,pointer> eyes; +pointer exclamation; +array<1,6,pointer> aargh; +array<1,3,pointer> bat; +glerktype* glerk; +array<1,5,pointer> green_eyes; +matrix<1,6,false,true,pointer> greldet; + +array<1,6,pointtype> aargh_where; + +integer gd,gm; boolean gb; + +byte glerkstage; + +integer bat_x,bat_y; word bat_count; shortint aargh_count; + +integer greldet_x,greldet_y; byte greldet_count; boolean red_greldet; + +void plain_grab() + /* Just grabs the next one and puts it where it's told to. */ +{ + integer xx,yy,xofs; +; + blockread(f,cb,sizeof(cb)); + + switch (cb.flavour) { + case ch_one: {; + xofs=cb.x / 8; + bit=3; + for( yy=0; yy <= cb.yl; yy ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + + blockread(f,mem[0xa000*(yy+cb.y)*80+xofs],cb.xl / 8); + } + } + break; + case ch_ega: {; + xofs=cb.x / 8; + bit=3; + for( bit=0; bit <= 3; bit ++) + for( yy=0; yy <= cb.yl; yy ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + + blockread(f,mem[0xa000*(yy+cb.y)*80+xofs],cb.xl / 8); + } + } + break; + } +} + +void get_me(pointer& p) +{; + blockread(f,cb,sizeof(cb)); + /* Take it for granted that cb.flavour = ch_BGI! */ + + {; + getmem(p,cb.size); + blockread(f,p,cb.size); + } +} + +void get_me_aargh(byte which) +{; + blockread(f,cb,sizeof(cb)); + /* Take it for granted that cb.flavour = ch_BGI! */ + + {; + getmem(aargh[which],cb.size); + blockread(f,aargh[which],cb.size); + } + + { + pointtype& with = aargh_where[which]; + + with.x=cb.x; + with.y=cb.y; + } +} + +void wait(word how_long) +{ + word i; char r; + + for( i=1; i <= how_long; i ++) + if (keypressed()) + { + sound(6177); + while (keypressed()) r=readkey(); + delay(1); + nosound; + } else + delay(1); +} + +void do_bat(); +static byte batimage; +static pointtype batsize; + +static void super_blank() +{ + pointtype oldsize; + + move(bat[batimage-1],oldsize,4); + bar(bat_x+batsize.x,bat_y,bat_x+oldsize.x,bat_y+oldsize.y); +} + +void do_bat() +{ + shortint dx,iy; + + bat_count += 1; + + if (odd(bat_count)) + { + switch (bat_count) { + case 1 ... 90: { dx=2; iy=1; batimage=1; } break; + case 91 ... 240: { dx=1; iy=1; batimage=2; } break; + case 241 ... 260: { dx=1; iy=4; batimage=3; } break; + } + + move(bat[batimage],batsize,4); + + if ((bat_count==91) || (bat_count==241)) + super_blank(); /* When the bat changes, blank out the old one. */ + + bar(bat_x,bat_y,bat_x+batsize.x,bat_y+iy); + bar(bat_x+batsize.x,bat_y,bat_x+batsize.x-dx,bat_y+batsize.y); + + bat_x -= dx; bat_y += 1; + putimage(bat_x,bat_y,bat[batimage],0); + } +} + +void big_green_eyes(byte how) +{ + putimage(330,103,green_eyes[how],0); + putimage(376,103,green_eyes[how],0); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + if (paramstr(1)!="jsb") exit(255); + gd=3; gm=0; initgraph(gd,gm,""); + fillchar(ghost,sizeof(ghost),'\0'); + + assign(f,"spooky.avd"); + reset(f,1); + seek(f,44); + + mark(memlevel); + + for( fv=1; fv <= 5; fv ++) + {; + blockread(f,cb,sizeof(cb)); + for( bit=2; bit <= 3; bit ++) + for( y=0; y <= cb.yl; y ++) + blockread(f,ghost[fv][bit][y],cb.xl / 8); + } + + get_me(eyes[0]); /* Get BGI-based ones */ + get_me(eyes[1]); + get_me(exclamation); + + plain_grab(); /* Grabs to screen (cobweb) */ + plain_grab(); /* Grabs to screen (Mark's signature) */ + plain_grab(); /* Grabs to screen (open door) */ + + for( fv=1; fv <= 3; fv ++) + get_me(bat[fv]); + +/* new(glerk); + for fv:=1 to 5 do { Grab the Glerk. } + begin; + blockread(f,cb,sizeof(cb)); + for bit:=0 to 3 do + for y:=0 to 34 do + blockread(f,glerk^[fv,bit,y],cb.xl div 8); + inc(gd,gm); + end; +*/ + + glerk = new glerktype; + + for( fv=1; fv <= 6; fv ++) + {; + blockread(f,cb,sizeof(cb)); + bit=3; + for( bit=0; bit <= 3; bit ++) + for( yy=0; yy <= cb.yl; yy ++) +/* begin; + port[$3c4]:=2; port[$3ce]:=4; + port[$3C5]:=1 shl bit; port[$3CF]:=bit;*/ + + blockread(f,(*glerk)[fv][bit][yy],cb.xl / 8); +/* move(glerk^[fv,bit,yy],mem[$A000:yy*80+177],xl div 8);*/ +/* blockread(f,mem[$A000:yy*80+177],xl div 8);*/ + +/* end;*/ + } + + for( fv=1; fv <= 6; fv ++) get_me_aargh(fv); + for( fv=1; fv <= 5; fv ++) get_me(green_eyes[fv]); + for( gb=false; gb <= true; gb ++) + for( fv=1; fv <= 6; fv ++) get_me(greldet[fv][gb]); + + close(f); + + /* Avvy walks over... */ + + setfillstyle(1,0); + glerkstage=0; bat_x=277; bat_y=40; bat_count=0; + + for( gd=500; gd >= 217; gd --) + {; + if (set::of(range(22,27), eos).has((gd % 30))) + {; + if ((gd % 30)==27) bar(gd,135,gd+16,136); + putimage(gd,136,eyes[0],0); + putpixel(gd+16,137,0); + } else + {; + if (gd % 30==21) bar(gd,137,gd+17,138); + + putimage(gd,135,eyes[0],0); + putpixel(gd+16,136,0); /* eyes would leave a trail 1 pixel high behind them */ + } + + /* Plot the Glerk: */ + if (gd % 10==0) + {; + glerkstage += 1; + if (glerkstage>26) flush(); + + for( gm=0; gm <= 34; gm ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + + move((*glerk)[glerkfade[glerkstage]][bit][gm], + mem[0xa000*1177+gm*80],9); + } + bit=getpixel(0,0); + } + + do_bat(); + + wait(15); + } + + setfillstyle(1,0); + bar(456,14,530,50); + + /* It descends... */ + + for( gm=-64; gm <= 103; gm ++) + {; + bit=getpixel(0,0); + + if (gm>0) + fillchar(mem[0xa000*(gm-1)*80],26,'\0'); + + for( y=0; y <= 65; y ++) + if ((y+gm)>=0) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + + move(ghost[2+(abs(gm / 7) % 2)*3][plane_to_use[bit]][y], + mem[0xa000*(y+gm)*80],26); + } + + wait(27); + } + + /* And waves... */ + + aargh_count=-14; + + for( gd=1; gd <= 4; gd ++) + for( fv=1; fv <= 5; fv ++) + {; + + y=getpixel(0,0); + + for( y=0; y <= 7; y ++) + fillchar(mem[0xa000*7760+y*80],26,'\0'); + + for( y=0; y <= 65; y ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(ghost[waveorder[fv]][plane_to_use[bit]][y], + mem[0xa000*7760+(y+adjustment[fv])*80],26); + } + + aargh_count += 1; + + if (aargh_count>0) + { pointtype& with = aargh_where[aargh_count]; + putimage(with.x,with.y,aargh[aargh_count],0);} + + wait(177); + } + + /* ! appears */ + + gd=getpixel(0,0); + putimage(246,127,exclamation,0); + wait(777); + bar(172, 78,347,111); /* erase "aargh" */ + + for( gm=5; gm >= 1; gm --) + { + wait(377); + big_green_eyes(gm); + } + bar(246,127,251,133); /* erase the "!" */ + + /* He hurries back. */ + + glerkstage=1; greldet_count=18; red_greldet=false; + + for( gd=217; gd <= 479; gd ++) + {; + if (set::of(range(22,27), eos).has((gd % 30))) + {; + if ((gd % 30)==22) + bar(gd+22,134,gd+38,137); + putimage(gd+23,136,eyes[1],0); + putpixel(gd+22,137,0); + } else + {; + if (gd % 30==28) + bar(gd+22,135,gd+38,138); + + putimage(gd+23,135,eyes[1],0); + putpixel(gd+22,136,0); /* eyes would leave a trail 1 pixel high behind them */ + } + + /* Plot the Green Eyes: */ + if (gd % 53==5) + {; + big_green_eyes(glerkstage); + glerkstage += 1; + } + + /* Plot the Greldet: */ + + if (greldet_count==18) + { /* A new greldet. */ + greldet_x=Random(600); + greldet_y=Random(80); + greldet_count=0; + red_greldet=! red_greldet; + } + + greldet_count += 1; + putimage + (greldet_x,greldet_y,greldet[greldetfade[greldet_count]][red_greldet],0); + + wait(10); + } + + release(memlevel); + closegraph(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/golden.cpp b/engines/avalanche/golden.cpp new file mode 100644 index 0000000000..009a828e0a --- /dev/null +++ b/engines/avalanche/golden.cpp @@ -0,0 +1,437 @@ +#include "ptoc.h" + + +/*$I c:\sleep5\DSMI.INC*/ #include "graph.h" +/*#include "Crt.h"*/ + + +const varying_string<255> song = +string("Golden slumbers kiss your eyes/Smiles awake you when you rise/")+ +"Sleep, pretty Baron, do not cry/And I will sing a lullaby.%Care you "+ +"know not, therefore sleep/While I o'er you watch do keep;/Sleep now, "+ +"du Lustie, do not cry/And I will leave the castle.*Bye!"; + +const integer scardcount = 13; + +const array<0,scardcount-1,integer> soundcards = + {{1,2,6,3,4,5,8,9,10,7,7,7,7}}; + +const array<1,5,byte> holding = +{{ 24, /* 0 : 24 */ +64, /* 1 : 00 */ +128, /* 2 : 00 */ +152, /* 2 : 24 */ +170}}; /* 2 : 42 */ + +integer gd,gm; +byte fv; +word* skellern; +word s,o; +boolean firstverse; +word nexthangon; + +boolean nomusic; + +integer getsoundhardware(psoundcard scard) +{ + integer sc,i,autosel,select; + char ch; + integer e; + + + +integer getsoundhardware_result; +Lagain: + sc=detectgus(scard); + if (sc!=0) sc=detectpas(scard); + if (sc!=0) sc=detectaria(scard); + if (sc!=0) sc=detectsb(scard); + + /* if no sound card found, zero scard */ + if (sc!=0) fillchar(scard,sizeof(tsoundcard),0); + + autosel=-1; +/* if sc=0 then + for i:=0 to scardcount-1 do + if scard^.ID=soundcards[i].ID then begin + { Set auto selection mark } + autosel:=i+1; + break; + end;*/ + + /* Print the list of sound cards */ + + val(paramstr(13),select,e); + + /* Default entry? */ + if (select==0) select=autosel; + if (select!=autosel) { + /* clear all assumptions */ + sc=-1; + fillchar(scard,sizeof(tsoundcard),0); + scard->id=soundcards[select-1]; /* set correct ID */ + } + + /* Query I/O address */ + if (scard->id==id_dac) scard->ioport=0x378; + + /* Read user input */ + val(paramstr(15),i,e); + + if (i!=0) scard->ioport=i; + if (sc!=1) /* Not autodetected */ + switch (scard->id) { + case id_sb16: + case id_pas16: + case id_wss: + case id_aria: + case id_gus : scard->samplesize=2; + break; /* 16-bit card */ + case id_sbpro: + case id_pas: + case id_pasplus: scard->stereo=true; + break; /* enable stereo */ + default: { + scard->samplesize=1; + scard->stereo=false; + } + } + + if (scard->id!=id_dac) { + val(paramstr(17),i,e); + + if (i!=0) scard->dmairq=i; + + val(paramstr(16),i,e); + + if (i!=0) scard->dmachannel=i; + } else { + /* Select correct DAC */ + scard->maxrate=44100; + if (select==11) { + scard->stereo=true; + scard->dmachannel=1; /* Special 'mark' */ + scard->maxrate=60000; + } else + if (select==12) { + scard->stereo=true; + scard->dmachannel=2; + scard->maxrate=60000; + if (scard->ioport==0) scard->ioport=0x378; + } else + if (select==13) { + scard->dmachannel=0; + scard->ioport=0x42; /* Special 'mark' */ + scard->maxrate=44100; + } + } + +/* writeln('Your selection: ',select,' at ',scard^.ioPort, + ' using IRQ ',scard^.dmaIRQ,' and DMA channel ',scard^.dmaChannel); + readln;*/ + + getsoundhardware_result=0; +return getsoundhardware_result; +} + +byte here() +{ + byte here_result; + here_result=(ampgetpattern % 3)*64+ampgetrow; + return here_result; +} + +void hold(word amount) +{ + *skellern=0; + do {; } while (!(*skellern>=amount)); +} + +void hangon(word forwhat) +{ + if (nomusic) + hold(40); + else + do { + if (keypressed()) exit(0); + } while (!(here()>=holding[forwhat])); +} + +tsoundcard scard; +tmcpstruct mcpstrc; +tdds dds; +pmodule module; +tsdi_init sdi; +integer e, +bufsize; +char ch; +boolean v86, +vdsok; +longint a,rate, +tempseg; +string answer; +pointer temp; +word flags; +word curch; +byte modulevolume; +array<0,4,tsampleinfo> sample; +array<0,31,word> voltable; + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + for( e=1; e <= paramcount; e ++) answer=paramstr(e); + + nomusic=paramstr(13)=='0'; + + if (! nomusic) + { + /* Read sound card information */ + if (getsoundhardware(&scard)==-1) exit(1); + + + /* Initialize Timer Service */ + tsinit; + atexit(&tsclose); + if (scard.id==id_gus) { + /* Initialize GUS player */ + #ifndef DPMI + scard.extrafield[2]=1; /* GUS DMA transfer does not work in V86 */ + #endif + gusinit(&scard); + atexit(&gusclose); + + /* Initialize GUS heap manager */ + gushminit; + + /* Init CDI */ + cdiinit; + + /* Register GUS into CDI */ + cdiregister(&cdi_gus,0,31); + + /* Add GUS event player engine into Timer Service */ + tsaddroutine(&gusinterrupt,gus_timer); + } else { + /* Initialize Virtual DMA Specification */ + #ifndef DPMI + vdsok=vdsinit==0; + #else + vdsok=false; + #endif + + fillchar(mcpstrc,sizeof(tmcpstruct),0); + + /* Query for sampling rate */ + val(paramstr(14),a,e); + if (a>4000) rate=a; else rate=21000; + + /* Query for quality */ + mcpstrc.options=mcp_quality; + + switch (scard.id) { + case id_sb : { + sdi=sdi_sb; + scard.maxrate=22000; + } + break; + case id_sbpro : { + sdi=sdi_sbpro; + scard.maxrate=22000; + } + break; + case id_pas: + case id_pasplus: + case id_pas16 : { + sdi=sdi_pas; + scard.maxrate=44100; + } + break; + case id_sb16 : { + sdi=sdi_sb16; + scard.maxrate=44100; + } + break; + case id_aria : { + sdi=sdi_aria; + scard.maxrate=44100; + } + break; + case id_wss : { + sdi=sdi_wss; + scard.maxrate=48000; + } + break; + #ifndef DPMI + case id_dac : sdi=sdi_dac; break; /* Only available in real mode */ + #endif + } + + mcpinitsounddevice(sdi,&scard); + a=mcp_tablesize; + mcpstrc.reqsize=0; + + /* Calculate mixing buffer size */ + bufsize=(longint)(2800*(integer)(scard.samplesize) << (byte)(scard.stereo))* + (longint)(rate) / (longint)(22000); + mcpstrc.reqsize=0; + if ((mcpstrc.options & mcp_quality)>0) + if (scard.samplesize==1) a += mcp_qualitysize; else + a=mcp_tablesize16+mcp_qualitysize16; + if ((longint)(bufsize)+(longint)(a)>65500) bufsize=longint(65500)-a; + + #ifdef DPMI + dpmiversion((byte)(e),(byte)(e),(byte)(e),flags); + v86=(flags & 2)==0; + #endif + + /* Allocate volume table + mixing buffer */ + #ifdef DPMI + + /* In the V86 mode, the buffer must be allocated below 1M */ + if (v86) { + tempseg=0; + dpmiallocdos((a+longint(bufsize)) / longint(16)+longint(1),flags,(word)(tempseg)); + } else { + #endif + getmem(temp,a+longint(bufsize)); + if (temp==nil) exit(2); + #ifdef DPMI + tempseg=seg(temp); + } + #else + tempseg=seg(temp)+ofs(temp) / 16+1; + #endif + mcpstrc.bufferseg=tempseg; + mcpstrc.bufferphysical=-1; + + if (vdsok && (scard.id!=id_dac)) { + dds.size=bufsize; + dds.segment=tempseg; + dds.offset=0; + + /* Lock DMA buffer if VDS present */ + if (vdslockdma(&dds)==0) mcpstrc.bufferphysical=dds.address; + } + if (mcpstrc.bufferphysical==-1) + #ifdef DPMI + mcpstrc.bufferphysical=dpmigetlinearaddr(tempseg); + #else + mcpstrc.bufferphysical=(longint)(tempseg) << 4; + #endif + + mcpstrc.buffersize=bufsize; + mcpstrc.samplingrate=rate; + /* Initialize Multi Channel Player */ + if (mcpinit(&mcpstrc)!=0) exit(3); + atexit(&mcpclose); + + /* Initialize Channel Distributor */ + cdiinit; + + /* Register MCP into CDI*/ + cdiregister(&cdi_mcp,0,31); + } + + /* Try to initialize AMP */ + if (ampinit(0)!=0) exit(3); + atexit(&close); + + /* Hook AMP player routine into Timer Service */ + tsaddroutine(&interrupt,amp_timer); + + #ifndef DPMI + /* If using DAC, then adjust DAC timer */ + if (scard.id==id_dac) setdactimer(tsgettimerrate); + #endif + + if (scard.id!=id_gus) mcpstartvoice; else gusstartvoice; + + /* Load an example AMF */ + module=amploadmod("golden.mod",0); + if (module==nil) exit(4); + + /* Is it MCP, Quality mode and 16-bit card? */ + if ((scard.id!=id_gus) && ((mcpstrc.options & mcp_quality)>0) + && (scard.samplesize==2)) { + /* Open module+2 channels with amplified volumetable (4.7 gain) */ + for( a=1; a <= 32; a ++) voltable[a-longint(1)]=a*longint(150) / longint(32); + cdisetupchannels(0,module->channelcount+2,&voltable); + } else { + /* Open module+2 channels with regular volumetable */ + cdisetupchannels(0,module->channelcount+2,nil); + } + + curch=module->channelcount; + modulevolume=64; + + /***/ ampplaymodule(module,0); + } + + val(paramstr(2),s,e); if (e!=0) exit(0); + val(paramstr(3),o,e); if (e!=0) exit(0); + skellern=ptr(s,o+1); + + gd=3; gm=0; initgraph(gd,gm,""); + + if (! nomusic) do {; } while (!(ampgetrow>=10)); + + setcolor(9); + for( gd=0; gd <= 320; gd ++) + { + rectangle(320-gd,100-gd / 2,320+gd,100+gd / 2); + } + + + gd=50; gm=20; + firstverse=true; + + hangon(1); nexthangon=2; + for( fv=1; fv <= 255; fv ++) + { + switch (song[fv]) { + case '/': { + gd=50; + gm += 15; + hangon(nexthangon); + nexthangon += 1; + } + break; + + case '%': { + gd=50; + gm += 35; + if (nomusic) + hold(15); + else + do {; } while (!(ampgetpattern>2)); + nexthangon=2; + hangon(1); + } + break; + + case '*': { + gd += 24; + hangon(5); + } + break; + + default: { + setcolor(1); outtextxy(gd+1,gm+1,song[fv]); + setcolor(0); outtextxy( gd , gm ,song[fv]); + gd += 12; + } + } + if (song[fv]==' ') hold(1); + if (keypressed()) exit(0); + } + + if (nomusic) + hold(25); + else + do {; } while (!(ampgetmodulestatus!=md_playing)); + + setcolor(0); + for( gd=320; gd >= 0; gd --) rectangle(320-gd,100-gd / 2,320+gd,100+gd / 2); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/gyro.cpp b/engines/avalanche/gyro.cpp new file mode 100644 index 0000000000..b530e45b08 --- /dev/null +++ b/engines/avalanche/gyro.cpp @@ -0,0 +1,532 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + GYRO It all revolves around this bit! */ + +#define __gyro_implementation__ + + +#include "gyro.h" + + +#include "pingo.h" +#include "scrolls.h" +#include "lucerna.h" +#include "visa.h" +#include "acci.h" +#include "trip5.h" +#include "dropdown.h" +#include "basher.h" + + +const array<'\1',numobjs,varying_string<15> > things = + {{"Wine","Money-bag","Bodkin","Potion","Chastity belt", + "Crossbow bolt","Crossbow","Lute","Pilgrim's badge","Mushroom","Key", + "Bell","Scroll","Pen","Ink","Clothes","Habit","Onion"}}; + +const array<'\1',numobjs,char> thingchar = "WMBParCLguKeSnIohn"; /* V=Vinegar */ + +const array<'\1',numobjs,varying_string<17> > better = + {{"some wine","your money-bag","your bodkin","a potion","a chastity belt", + "a crossbow bolt","a crossbow","a lute","a pilgrim's badge","a mushroom", + "a key","a bell","a scroll","a pen","some ink","your clothes","a habit", + "an onion"}}; + +const array<'\1',numobjs,char> betterchar = "WMBParCLguKeSnIohn"; + +void newpointer(byte m) +{ + if (m==cmp) return; cmp=m; + { + ax=9; bx=(word)(mps[m].horzhotspot); cx=(word)(mps[m].verthotspot); + es=seg(mps[m].mask); dx=ofs(mps[m].mask); + } + intr(0x33,r); + load_a_mouse(m); +} + +void wait() /* makes hourglass */ +{ + newpointer(5); +} + +void on() +{ + if (set_of_enum(<null>)::of(m_yes,m_virtual, eos).has(visible)) return; + + r.ax=1; intr(0x33,r); visible=m_yes; + if (oncandopageswap) + { + r.ax=29; r.bx=cp; intr(0x33,r); /* show mouse on current page */ + } +} + +void on_virtual() +{ + switch (visible) { + case m_virtual: return; break; + case m_yes: off(); break; + } + + visible=m_virtual; +} + +void off() +{ + switch (visible) { + case m_no:case m_virtual : return; break; + case m_yes : { r.ax=2; intr(0x33,r); } break; + } + visible=m_no; +} + +void off_virtual() +{ + byte fv; + + if (visible!=m_virtual) return; + + for( fv=0; fv <= 1; fv ++) + { + setactivepage(fv); + wipe_vmc(1-fv); + } + setactivepage(1-cp); visible=m_no; +} + +void xycheck() /* only updates mx & my, not all other mouse vars */ +{ + r.ax=3; intr(0x33,r); /* getbuttonstatus */ + { + keystatus=bx; + mx=cx; my=dx; + } +} + +void hopto(integer x,integer y) /* Moves mouse pointer to x,y */ +{ + { + ax=4; + cx=x; + dx=y; + } + intr(0x33,r); +} + +void check() +{ + { ax=6; bx=0; } intr(0x33,r); /* getbuttonreleaseinfo */ + { + mrelease=bx; + mrx=cx; mry=dx; + } + { ax=5; bx=0; } intr(0x33,r); /* getbuttonpressinfo */ + { + mpress=bx; + mpx=cx; mpy=dx; + } + xycheck(); /* just to complete the job. */ +} + +void note(word hertz) +{ + if (soundfx) sound(hertz); +} + +void blip() +{ + byte fv; + + for( fv=1; fv <= 7; fv ++) { sound(177+(fv*200) % 177); delay(1); } + nosound; +} + +string strf(longint x) +{ + string q; + + string strf_result; + str(x,q); strf_result=q; + return strf_result; +} + +void shadow(integer x1,integer y1,integer x2,integer y2, byte hc,byte sc) +{ + byte fv; + + for( fv=0; fv <= border; fv ++) + { + setfillstyle(1,hc); + bar(x1+fv,y1+fv,x1+fv,y2-fv); + bar(x1+fv,y1+fv,x2-fv,y1+fv); + + setfillstyle(1,sc); + bar(x2-fv,y1+fv,x2-fv,y2-fv); + bar(x1+fv,y2-fv,x2-fv,y2-fv); + } +} + +void shbox(integer x1,integer y1,integer x2,integer y2, string t) +{ + const integer fc = 7; + + off(); + shadow(x1,y1,x2,y2,15,8); setfillstyle(1,fc); + bar(x1+border+1,y1+border+1,x2-border-1,y2-border-1); + setcolor(1); x1=(x2-x1) / 2+x1; y1=(y2-y1) / 2+y1; + outtextxy(x1,y1,t); + if (length(t)>1) + { + fillchar(t[2],length(t)-1,'\40'); t[1]='_'; + outtextxy(x1-1,y1+1,t); + } + on(); +} + +void newgame() /* This sets up the DNA for a completely new game. */ +{ + byte gd,gm; + + for( gm=1; gm <= numtr; gm ++) + { triptype& with = tr[gm]; + if (with.quick) done();} /* Deallocate sprite. Sorry, beta testers! */ + + tr[1].init(0,true); + alive=true; + + score=0; /*for gd:=0 to 5 do which[gd]:=1;*/ + fillchar(dna,sizeof(dna),'\0'); natural(); + normal_edit(); mousepage(0); + dna.spare_evening="answer a questionnaire"; + dna.like2drink="beer"; + + { + dna.pence=30; /* 2/6 */ dna.rw=stopped; dna.wearing=clothes; + dna.obj[money]=true; dna.obj[bodkin]=true; dna.obj[bell]=true; dna.obj[clothes]=true; + } + + thinks='\2'; objectlist(); + ontoolbar=false; seescroll=false; + + ppos[0][1]=-177; /*tr[1].appear(300,117,right);*/ gd=0; + for( gd=0; gd <= 30; gd ++) for( gm=0; gm <= 1; gm ++) also[gd][gm]=nil; +/* fillchar(previous^,sizeof(previous^),#0); { blank out array } */ + him='\376'; her='\376'; it='\376'; last_person='\376'; /* = Pardon? */ + dna.pass_num=Random(30)+1; after_the_scroll=false; + dna.user_moves_avvy=false; doing_sprite_run=false; + dna.avvy_in_bed=true; enid_filename=""; + + for( gd=0; gd <= 1; gd ++) { cp=1-cp; getback(); } + + enterroom(1,1); new_game_for_trippancy(); + showscore(); + + standard_bar(); clock(); + sprite_run(); +} + +void click() /* "Audio keyboard feedback" */ +{ + sound(7177); delay(1); nosound; +} + +void slowdown() +{ +/* repeat until TSkellern>=howlong; TSkellern:=0;*/ + do {; } while (!(memw[storage_seg*skellern]>=howlong)); + memw[storage_seg*skellern]=0; +} + +boolean flagset(char x) +{ + boolean flagset_result; + flagset_result=pos(x,flags)>0; + return flagset_result; +} + +void force_numlock() +{ + if ((locks & num)>0) locks -= num; +} + +boolean pennycheck(word howmuchby) +{ + boolean pennycheck_result; + dna.pence -= howmuchby; + if (dna.pence<0) + { + dixi('Q',2); /* "you are now denariusless!" */ + pennycheck_result=false; + gameover(); + } else + pennycheck_result=true; + return pennycheck_result; +} + +string getname(char whose) +{ + string getname_result; + if (whose<'\257') getname_result=lads[whose]; else getname_result=lasses[whose]; + return getname_result; +} + +char getnamechar(char whose) +{ + char getnamechar_result; + if (whose<'\257') getnamechar_result=ladchar[whose-1]; + else getnamechar_result=lasschar[whose-1]; + return getnamechar_result; +} + +string get_thing(char which) +{ + string get_thing_result; + switch (which) { + case wine: switch (dna.winestate) { + case 1:case 4: get_thing_result=things[which]; break; + case 3: get_thing_result="Vinegar"; break; + } + break; + case onion: if (dna.rotten_onion) + get_thing_result="rotten onion"; + else get_thing_result=things[which]; + break; + default: get_thing_result=things[which]; + } + return get_thing_result; +} + +char get_thingchar(char which) +{ + char get_thingchar_result; + switch (which) { + case wine: if (dna.winestate==3) get_thingchar_result='V'; /* Vinegar */ + else get_thingchar_result=thingchar[which-1]; + break; + default: get_thingchar_result=thingchar[which-1]; + } + return get_thingchar_result; +} + +string get_better(char which) +{ + string get_better_result; + if (which>'\226') which -= 149; + switch (which) { + case wine: switch (dna.winestate) { + case 0:case 1:case 4: get_better_result=better[which]; break; + case 3: get_better_result="some vinegar"; break; + } + break; + case onion: if (dna.rotten_onion) + get_better_result="a rotten onion"; + else if (dna.onion_in_vinegar) + get_better_result="a pickled onion (in the vinegar)"; + else get_better_result=better[which]; + break; + default: + if ((which<numobjs) && (which>'\0')) + get_better_result=better[which]; else + get_better_result=""; + } + return get_better_result; +} + +string f5_does() + /* This procedure determines what f5 does. */ +{ + string f5_does_result; + switch (dna.room) { + case r__yours: + { + if (! dna.avvy_is_awake) + { /* He's asleep, =>= wake up. */ + f5_does_result=string(vb_wake)+"WWake up"; + return f5_does_result; + } + + if (dna.avvy_in_bed) + { /* In bed. => = get up. */ + f5_does_result=string(vb_stand)+"GGet up"; + return f5_does_result; + } + + } + break; + + case r__insidecardiffcastle: + { + if (dna.standing_on_dais) + f5_does_result=string(vb_climb)+"CClimb down"; + else + f5_does_result=string(vb_climb)+"CClimb up"; + return f5_does_result; + } + break; + + case r__nottspub: + { + if (dna.sitting_in_pub) + f5_does_result=string(vb_stand)+"SStand up"; + else + f5_does_result=string(vb_sit)+"SSit down"; + return f5_does_result; + } + break; + + case r__musicroom: + if (infield(7)) + { + f5_does_result=string(vb_play)+"PPlay the harp"; + return f5_does_result; + } + break; + } + + f5_does_result=pardon; /* If all else fails... */ + return f5_does_result; +} + +void plot_vmc(integer xx,integer yy, byte page_) +{ + if (visible!=m_virtual) return; + { + xx=xx+vmc.ofsx; if (xx<0) xx=0; + yy=yy+vmc.ofsy; if (yy<0) yy=0; + + setactivepage(1-cp); + getimage(xx,yy,xx+15,yy+15,vmc.backpic[page_]); + putimage(xx,yy,vmc.andpic,andput); + putimage(xx,yy,vmc.xorpic,xorput); + +/* setcolor( 0); outtextxy(xx+8,yy+16,'Û'); outtextxy(xx,yy+16,'Û'); + setcolor(11+page); + outtextxy(xx+8,yy+16,chr(48+roomtime mod 10)); + outtextxy(xx ,yy+16,chr(48+(roomtime div 10) mod 10));*/ + + { + pointtype& with1 = vmc.wherewas[page_]; + + with1.x=xx; + with1.y=yy; + } + } +} + +void wipe_vmc(byte page_) +{ + if (visible!=m_virtual) return; + { pointtype& with1 = vmc.wherewas[page_]; + if (with1.x!=maxint) + putimage(with1.x,with1.y,vmc.backpic[page_],0);} +} + +void setup_vmc() +{ + byte fv; + + { + getmem(vmc.andpic,mouse_size); + getmem(vmc.xorpic,mouse_size); + + for( fv=0; fv <= 1; fv ++) + { + getmem(vmc.backpic[fv],mouse_size); + vmc.wherewas[fv].x=maxint; + } + } +} + +void clear_vmc() +{ + byte fv; + + for( fv=0; fv <= 1; fv ++) vmc.wherewas[fv].x=maxint; +} + +void setminmaxhorzcurspos(word min,word max) /* phew */ +{ + { + ax=7; + cx=min; + dx=max; + } + intr(0x33,r); +} + +void setminmaxvertcurspos(word min,word max) +{ + { + ax=8; /* A guess. In the book, 7 */ + cx=min; + dx=max; + } + intr(0x33,r); +} + +void load_a_mouse(byte which) +{ + untyped_file f; + + assign(f,"mice.avd"); + reset(f,1); + seek(f,mouse_size*2*(which-1)+134); + + { + blockread(f,vmc.andpic,mouse_size); + blockread(f,vmc.xorpic,mouse_size); + close(f); + { + mp& with1 = mps[which]; + + vmc.ofsx=-with1.horzhotspot; + vmc.ofsy=-with1.verthotspot; + + setminmaxhorzcurspos(with1.horzhotspot+3,624+with1.horzhotspot); + setminmaxvertcurspos(with1.verthotspot,199); + } + } +} + +void background(byte x) { setbkcolor(x); } + +void hang_around_for_a_while() +{ + byte fv; + + for( fv=1; fv <= 28; fv ++) slowdown(); +} + +boolean mouse_near_text() +{ + boolean mouse_near_text_result; + mouse_near_text_result=(my>144) && (my<188); + return mouse_near_text_result; +} + +/* Super_Off and Super_On are two very useful procedures. Super_Off switches + the mouse cursor off, WHATEVER it's like. Super_On restores it again + afterwards. */ + +void super_off() +{ + super_was_off=visible==m_no; + if (super_was_off) return; + + super_was_virtual=visible==m_virtual; + + if (visible==m_virtual) off_virtual(); else off(); +} + +void super_on() +{ + if ((visible!=m_no) || (super_was_off)) return; + + if (super_was_virtual) on_virtual(); else on(); +} + + diff --git a/engines/avalanche/gyro.h b/engines/avalanche/gyro.h new file mode 100644 index 0000000000..8a1fdb5c0a --- /dev/null +++ b/engines/avalanche/gyro.h @@ -0,0 +1,702 @@ +#ifndef __gyro_h__ +#define __gyro_h__ + + +#include "graph.h" +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ + + +const char numobjs = '\22'; /* always preface with a # */ +const integer maxobjs = 12; /* carry limit */ +const byte howlong = 1/*8*/; /* 18 ticks. */ + +const boolean oncandopageswap = true; /* Variable constant for overriding the + ability of On to switch pages. You may know better than On which page + to switch to. */ + +const integer num = 32; /* Code for Num Lock */ + +const integer mouse_size = 134; + +typedef void(*proc)(); + +struct postype { + word x,y,datapos; byte length; +}; + +struct mp { /* mouse-pointer */ + matrix<0,1,0,15,word> mask; + integer horzhotspot,verthotspot; +}; + +struct dnatype { /* here goes... */ /* Ux, uy, & ww now all belong to Trip5 */ + byte rw; /* Realway- just for convenience! */ + byte carrying; /* how many objects you're carrying... */ + array<'\1',numobjs,boolean> obj; /* ...and which ones they are. */ + integer score; /* your score, of course */ + longint pence; /* your current amount of dosh */ + byte room; /* your current room */ + char wearing; /* what you're wearing */ + byte swore; /* number of times you've sworn */ + byte saves; /* number of times this game has been saved */ + array<1,100,byte> rooms; /* Add one to each every time + you enter a room */ + byte alcohol; /* Your blood alcohol level. */ + byte playednim; /* How many times you've played Nim. */ + boolean wonnim; /* Have you *won* Nim? (That's harder.) */ + byte winestate; /* 0=good (Notts), 1=passable(Argent) ... 3=vinegar.*/ + boolean cwytalot_gone; /* Has Cwytalot rushed off to Jerusalem yet?*/ + + byte pass_num; /* Number of the password for this game. */ + boolean ayles_is_awake; /* pretty obvious! */ + byte drawbridge_open; /* Between 0 (shut) and 4 (open). */ + byte avaricius_talk; /* How much Avaricius has said to you. */ + boolean bought_onion; /* Have you bought an onion yet? */ + boolean rotten_onion; /* And has it rotted? */ + boolean onion_in_vinegar; /* Is the onion in the vinegar? */ + + byte given2spludwick; /* 0 = nothing given, 1 = onion... */ + byte brummie_stairs; /* Progression through the stairs trick. */ + byte cardiff_things; /* Things you get asked in Cardiff. */ + + boolean cwytalot_in_herts; /* Have you passed Cwytalot in Herts?*/ + + boolean avvy_is_awake; /* Well? Is Avvy awake? (Screen 1 only.) */ + boolean avvy_in_bed; /* True if Avvy's in bed, but awake. */ + + boolean user_moves_avvy; /* If this is false, the user has no + control over Avvy's movements. */ + + byte dogfoodpos; /* Which way Dogfood's looking in the pub. */ + + boolean givenbadgetoiby; /* Have you given the badge to Iby yet? */ + + boolean friar_will_tie_you_up; /* If you're going to get tied up. */ + boolean tied_up; /* You ARE tied up! */ + + char box_contents; /* 0 = money (sixpence), 254 = empty, any + other number implies the contents of the box. */ + + boolean talked_to_crapulus; /* Pretty self-explanatory. */ + + byte jacques_awake; /* 0=asleep, 1=awake, 2=gets up, 3=gone. */ + + boolean ringing_bells; /* Is Jacques ringing the bells? */ + + boolean standing_on_dais; /* In room 71, inside Cardiff Castle. */ + boolean taken_pen; /* Have you taken the pen (in Cardiff?) */ + boolean arrow_triggered; /* And has the arrow been triggered? */ + boolean arrow_in_the_door; /* Did the arrow hit the wall? */ + + varying_string<77> like2drink, + favourite_song, + worst_place_on_earth, + spare_evening; /* Personalisation str's */ + + longint total_time; /* Your total time playing this game, in ticks.*/ + + byte jumpstatus; /* Fixes how high you're jumping. */ + + boolean mushroom_growing; /* Is the mushroom growing in 42? */ + + boolean spludwicks_here; /* Is Spludwick at home? */ + + byte last_room; + byte last_room_not_map; + + boolean crapulus_will_tell; /* Will Crapulus tell you about + Spludwick being away? */ + + boolean enter_catacombs_from_lusties_room; + boolean teetotal; /* Are we touching any more drinks? */ + byte malagauche; /* Position of Malagauche. See Celer for more info. */ + char drinking; /* What's he getting you? */ + + boolean entered_lusties_room_as_monk; + + byte cat_x, cat_y; /* XY coords in the catacombs. */ + + boolean avvys_in_the_cupboard; /* On screen 22. */ + + boolean geida_follows; /* Is Geida following you? */ + + byte geida_spin,geida_time; /* For the making "Geida dizzy" joke. */ + + byte nextbell; /* For the ringing. */ + + boolean geida_given_potion; /* Does Geida have the potion? */ + boolean lustie_is_asleep; /* Is BDL asleep? */ + + byte flip_to_where, flip_to_ped; /* For the sequencer. */ + + boolean been_tied_up; /* In r__Robins. */ + + boolean sitting_in_pub; /* Are you sitting down in the pub? */ + byte spurge_talk; /* Count for talking to Spurge. */ + + boolean met_avaroid; + + boolean taken_mushroom, + given_pen_to_ayles, + asked_dogfood_about_nim; +}; + +struct pedtype { + integer x,y; byte dir; +}; + +struct magictype { + byte op; /* one of the operations */ + word data; /* data for them */ +}; + +class fieldtype { +public: + integer x1,y1,x2,y2; +}; + +struct bytefield { + byte x1,y1,x2,y2; +}; + +class linetype : public fieldtype { +public: + byte col; +}; + +struct adxtype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +typedef matrix<'\0','\377',0,15,byte> raw; /* raw_font_type */ + +enum controllers {cjoy,ckey, last_controllers}; + +typedef array<1,20,varying_string<77> > previoustype; + +struct corridor_type { /* Decarations for the corridors. */ + word doors; /* Door styles are calc'ed from this word. + Assign a different number to each one! */ +}; + +struct demo_type { + word delay; + char key,extd; +}; + +struct quasiped_type { + byte whichped,fgc,room,bgc; char who; +}; +/* A quasiped defines how people who aren't sprites talk. For example, + quasiped "A" is Dogfood. The rooms aren't stored because I'm leaving + that to context. */ + +typedef array<1,31,byte> tunetype; + +struct vmctype { /* Virtual Mouse Cursor */ + pointer andpic,xorpic; + array<0,1,pointer> backpic; + array<0,1,pointtype> wherewas; + byte picnumber; + shortint ofsx,ofsy; +}; + +struct sundry { /* Things which must be saved over a backtobootstrap, + outside DNA. */ + pathstr qenid_filename; + boolean qsoundfx; + char qthinks; + boolean qthinkthing; +}; + +struct joysetup { + word xmid,ymid,xmin,ymin,xmax,ymax; + byte centre; /* Size of centre in tenths */ +}; + +struct ednahead { /* Edna header */ + /* This header starts at byte offset 177 in the .ASG file. */ + array<1,9,char> id; /* signature */ + word revision; /* EDNA revision, here 2 (1=dna256) */ + varying_string<50> game; /* Long name, eg Lord Avalot D'Argent */ + varying_string<15> shortname; /* Short name, eg Avalot */ + word number; /* Game's code number, here 2 */ + word ver; /* Version number as integer (eg 1.00 = 100) */ + varying_string<5> verstr; /* Vernum as string (eg 1.00 = "1.00" */ + varying_string<12> filename; /* Filename, eg AVALOT.EXE */ + byte osbyte; /* Saving OS (here 1=DOS. See below for others.*/ + varying_string<5> os; /* Saving OS in text format. */ + + /* Info on this particular game */ + + varying_string<8> fn; /* Filename (not extension ('cos that's .ASG)) */ + byte d,m; /* D, M, Y are the Day, Month & Year this game was... */ + word y; /* ...saved on. */ + varying_string<40> desc; /* Description of game (same as in Avaricius!) */ + word len; /* Length of DNA (it's not going to be above 65535!) */ + + /* Quick reference & miscellaneous */ + + word saves; /* no. of times this game has been saved */ + integer cash; /* contents of your wallet in numerical form */ + varying_string<20> money; /* ditto in string form (eg 5/-, or 1 denarius)*/ + word points; /* your score */ + + /* DNA values follow, then footer (which is ignored) */ +}; + + /* Possible values of edhead.os: + 1 = DOS 4 = Mac + 2 = Windows 5 = Amiga + 3 = OS/2 6 = ST + 7 = Archimedes */ + +const char vernum[] = "1.30"; +const char copyright[] = "1995"; +const integer thisvercode = 130; + /* as "vernum", but numerically & without the ".". */ +const integer thisgamecode = 2; /* Avalot's code number */ + +/* Objects you can hold: */ + const char wine = '\1'; const char money = '\2'; const char bodkin = '\3'; const char potion = '\4'; const char chastity = '\5'; const char bolt = '\6'; + const char crossbow = '\7'; const char lute = '\10'; const char badge = '\11'; const char mushroom = '\12'; const char key = '\13'; const char bell = '\14'; + const char prescription = '\15'; const char pen = '\16'; const char ink = '\17'; const char clothes = '\20'; const char habit = '\21'; const char onion = '\22'; + +/* People who hang around this game. */ + +/* Boys: */ +const char pavalot = '\226'; const char pspludwick = '\227'; const char pcrapulus = '\230'; const char pdrduck = '\231'; +const char pmalagauche = '\232'; const char pfriartuck = '\233'; const char probinhood = '\234'; const char pcwytalot = '\235'; +const char pdulustie = '\236'; const char pduke = '\237'; const char pdogfood = '\240'; const char ptrader = '\241'; +const char pibythneth = '\242'; const char payles = '\243'; const char pport = '\244'; const char pspurge = '\245'; const char pjacques = '\246'; + +/* Girls: */ +const char parkata = '\257'; const char pgeida = '\260'; const char pwisewoman = '\262'; + +const integer xw = 30; +const integer yw = 36; /* x width & y whatsit */ + +const integer margin = 5; + +const array<1,9,mp> mps = +{{{ /* 1 - up-arrow */ + {{{{65151,64575,64575,63519,63519,61455,61455,57351,57351,49155,49155,64575,64575,64575,64575,64575}}, + {{0,384,384,960,960,2016,2016,4080,4080,8184,384,384,384,384,384,0}}}}, + 8, + 0}, + +{ /* 2 - screwdriver */ + {{{{8191,4095,2047,34815,50175,61951,63743,64543,65039,65031,65027,65281,65408,65472,65505,65523}}, + {{0,24576,28672,12288,2048,1024,512,256,224,176,216,96,38,10,12,0}}}}, + 0, + 0}, + +{ /* 3 - right-arrow */ + {{{{65535,65535,64639,64543,7,1,0,1,7,64543,64639,65535,65535,65535,65535,65535}}, + {{0,0,0,384,480,32760,32766,32760,480,384,0,0,0,0,0,0}}}}, + 15, + 6}, + +{ /* 4 - fletch */ + {{{{255,511,1023,2047,1023,4607,14591,31871,65031,65283,65281,65280,65280,65409,65473,65511}}, + {{0,10240,20480,24576,26624,17408,512,256,128,88,32,86,72,20,16,0}}}}, + 0, + 0}, + +{ /* 5 - hourglass */ + {{{{0,0,0,34785,50115,61455,61455,63519,63519,61839,61455,49155,32769,0,0,0}}, + {{0,32766,16386,12300,2064,1440,1440,576,576,1056,1440,3024,14316,16386,32766,0}}}}, + 8, + 7}, + +{ /* 6 - TTHand */ + {{{{62463,57855,57855,57855,57471,49167,32769,0,0,0,0,32768,49152,57344,61441,61443}}, + {{3072,4608,4608,4608,4992,12912,21070,36937,36873,36865,32769,16385,8193,4097,2050,4092}}}}, + 4, + 0}, + +{ /* 7- Mark's crosshairs */ + {{{{65535,65151,65151,65151,65151,0,65151,65151,65151,65151,65535,65535,65535,65535,65535,65535}}, + {{0,384,384,384,384,65535,384,384,384,384,0,0,0,0,0,0}}}}, + 8, + 5}, + +{ /* 8- I-beam. */ + {{{{65535,65535,63631,63503,63503,65087,65087,65087,65087,65087,63503,63503,63631,65535,65535,65535}}, + {{0,0,0,864,128,128,128,128,128,128,128,864,0,0,0,0}}}}, + 8, + 7}, + +{ /* 9- Question mark. */ + {{{{511,1023,2047,31,15,8199,32647,65415,63503,61471,61503,61695,63999,63999,61695,61695}}, + {{65024,33792,34816,34784,40976,57224,32840,72,1936,2080,2496,2304,1536,1536,2304,3840}}}}, + 0, + 0}}}; + +const array<'\226','\246',varying_string<19> > lads = + {{"Avalot","Spludwick","Crapulus","Dr. Duck","Malagauche","Friar Tuck", + "Robin Hood","Cwytalot","du Lustie","the Duke of Cardiff","Dogfood", + "A trader","Ibythneth","Ayles","Port","Spurge","Jacques"}}; + +const array<'\257','\262',varying_string<14> > lasses = + {{"Arkata","Geida",'±',"the Wise Woman"}}; + + const array<'\226','\245',char> ladchar = "ASCDMTRwLfgeIyPu"; + +const array<'\257','\262',char> lasschar = "kG±o"; + +const integer numtr = 2; /* current max no. of sprites */ + +const boolean a_thing = true; const boolean a_person = false; /* for Thinkabout */ + +/* Magic/portal commands are */ + +/*N*/ const integer nix = 0; /* ignore it if this line is touched */ +/*B*/ const integer bounces = 1; /* bounce off this line. Not valid for portals. */ +/*E*/ const integer exclaim = 2; /* put up a chain of scrolls */ +/*T*/ const integer transport = 3; /* enter new room */ +/*U*/ const integer unfinished = 4; /* unfinished connection */ +/*S*/ const integer special = 5; /* special function. */ +/*O*/ const integer mopendoor = 6; /* opening door. */ + +/* These following constants should be included in CFG when it's written. */ + + const boolean slow_computer = false; /* stops walking when mouse touches toolbar */ + +/* --- */ + +const integer border = 1; /* size of border on shadowboxes */ + +const integer pagetop = 81920; + + const integer up = 0; +const integer right = 1; + const integer down = 2; + const integer left = 3; +const integer ur = 4; const integer dr = 5; const integer dl = 6; const integer ul = 7; + const integer stopped = 8; + +const integer walk = 3; +const integer run = 5; + +/*$I ROOMNUMS.INC - Room number constants (r__xxx) */ + +const array<'\226','\262',byte> whereis = + /* The Lads */ + {{r__yours, /* Avvy */ + r__spludwicks, /* Spludwick */ + r__outsideyours, /* Crapulus */ + r__ducks, /* Duck - r__DucksRoom's not defined yet. */ + r__argentpub, /* Malagauche */ + r__robins, /* Friar Tuck. */ + 177, /* Robin Hood - can't meet him at the start. */ + r__brummieroad, /* Cwytalot */ + r__lustiesroom, /* Baron du Lustie. */ + r__outsidecardiffcastle, /* The Duke of Cardiff. */ + r__argentpub, /* Dogfood */ + r__outsideducks, /* Trader */ + r__argentpub, /* Ibythneth */ + r__aylesoffice, /* Ayles */ + r__nottspub, /* Port */ + r__nottspub, /* Spurge */ + r__musicroom, /* Jacques */ + 0,0,0,0,0,0,0,0, + /* The Lasses */ + r__yours, /* Arkata */ + r__geidas, /* Geida */ + 177, /* nobody allocated here! */ + r__wisewomans}}; /* The Wise Woman. */ + +/* Art gallery at 2,1; notice about this at 2,2. */ + +const matrix<1,8,1,8,longint> catamap = + /* Geida's room */ + /* 1 2 3 | 4 5 6 7 8*/ +{{{{0x204,0x200,0xd0f0,0xf0ff,0xff,0xd20f,0xd200,0x200}}, + {{0x50f1,0x20ff,0x2ff,0xff,0xe0ff,0x20ff,0x200f,0x7210}}, + {{0xe3f0,0xe10f,0x72f0,0xff,0xe0ff,0xff,0xff,0x800f}}, + {{0x2201,0x2030,0x800f,0x220,0x20f,0x30,0xff,0x23f}}, /* >> Oubliette */ + {{0x5024,0xf3,0xff,0x200f,0x22f0,0x20f,0x200,0x7260}}, + {{0xf0,0x2ff,0xe2ff,0xff,0x200f,0x50f0,0x72ff,0x201f}}, + {{0xf6,0x220f,0x22f0,0x30f,0xf0,0x20f,0x8200,0x2f0}}, /* <<< In here */ + {{0x34,0x200f,0x51f0,0x201f,0xf1,0x50ff,0x902f,0x2062}}}}; + /* vv Stairs trap. */ + +/* Explanation: $NSEW. + Nibble N: North. + 0 = no connection, + 2 = (left,) middle(, right) door with left-hand handle, + 5 = (left,) middle(, right) door with right-hand handle, + 7 = arch, + 8 = arch and 1 north of it, + 9 = arch and 2 north of it, + D = no connection + WINDOW, + E = no connection + TORCH, + F = recessed door (to Geida's room.) + + Nibble S: South. + 0 = no connection, + 1,2,3 = left, middle, right door. + + Nibble E: East. + 0 = no connection (wall), + 1 = no connection (wall + window), + 2 = wall with door, + 3 = wall with door and window, + 6 = wall with candles, + 7 = wall with door and candles, + F = straight-through corridor. + + Nibble W: West. + 0 = no connection (wall), + 1 = no connection (wall + shield), + 2 = wall with door, + 3 = wall with door and shield, + 4 = no connection (window), + 5 = wall with door and window, + 6 = wall with candles, + 7 = wall with door and candles, + F = straight-through corridor. */ + +const byte interrogation = 0; + /* If this is greater than zero, the next line you type is stored in + the DNA in a position dictated by the value. If a scroll comes up, + or you leave the room, it's automatically set to zero. */ + +const boolean demo = false; /* If this is true, we're in a demo of the game. */ + +const array<0,2,char> spludwick_order = {{onion,ink,mushroom}}; + +const array<10,25,quasiped_type> quasipeds = +{{{2,lightgray, 19,brown,pdogfood}, /* A: Dogfood (screen 19). */ +{3,green, 19,white,pibythneth}, /* B: Ibythneth (screen 19). */ +{3,white, 1,magenta,parkata}, /* C: Arkata (screen 1). */ +{3,black, 23,red,'\261'}, /* D: Hawk (screen 23). */ +{3,lightgreen,50,brown,ptrader}, /* E: Trader (screen 50). */ +{6,yellow, 42,red,pavalot}, /* F: Avvy, tied up (scr.42) */ +{2,blue, 16,white,payles}, /* G: Ayles (screen 16). */ +{2,brown, 7,white,pjacques}, /* H: Jacques (screen 7). */ +{2,lightgreen,47,green,pspurge}, /* I: Spurge (screen 47). */ +{3,yellow, 47,red,pavalot}, /* J: Avalot (screen 47). */ +{2,lightgray, 23,black,pdulustie}, /* K: du Lustie (screen 23). */ +{2,yellow, 27,red,pavalot}, /* L: Avalot (screen 27). */ +{3,white, 27,red,'\261'}, /* M: Avaroid (screen 27). */ +{4,lightgray, 19,darkgray,pmalagauche}, /*N: Malagauche (screen 19). */ +{5,lightmagenta,47,red,pport}, /* O: Port (screen 47). */ +{2,lightgreen, 51,darkgray,pdrduck}}}; /*P: Duck (screen 51). */ + + const integer lower = 0; + const integer same = 1; +const integer higher = 2; + +const array<1,12,char> keys = "QWERTYUIOP[]"; +const array<1,12,word> notes = + {{196,220,247,262,294,330,350,392,440,494,523,587}}; + +const tunetype tune = + {{higher,higher,lower,same,higher,higher,lower,higher,higher,higher, + lower,higher,higher, + same,higher,lower,lower,lower,lower,higher,higher,lower,lower,lower, + lower,same,lower,higher,same,lower,higher}}; + +/* special run-time errors */ + +const integer runerr_getset_overflow = 50; + + +#ifdef __gyro_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN varying_string<77> current; EXTERN byte curpos; EXTERN boolean cursoron; +/* previous:^previoustype;*/ +EXTERN varying_string<77> last; +EXTERN dnatype dna; +EXTERN array<1,50,linetype> lines; /* For Also. */ +EXTERN integer c; +EXTERN registers r; +EXTERN enum { m_no , m_yes , m_virtual } visible; +EXTERN boolean dropsok,screturn,soundfx,cheat; +EXTERN word mx,my; /* mouse x & y now */ +EXTERN word mpx,mpy; /* mouse x & y when pressed */ +EXTERN word mrx,mry; /* mouse x & y when released */ +EXTERN byte mpress,mrelease; /* times left mouse button has been pressed/released */ +EXTERN byte keystatus; /* Mouse key status */ +EXTERN array<1,10,varying_string<20> > un; +EXTERN byte unn; EXTERN string mousetext; +/* which:array[0..5] of byte;*/ +EXTERN pointer p; EXTERN boolean weirdword; +EXTERN byte to_do; EXTERN boolean lmo,mousemade; +EXTERN array<1,15,varying_string<50> > scroll; +EXTERN byte scrolln,score,whichwas; EXTERN char thinks; EXTERN boolean thinkthing; + +/* pp:array[1..1000] of postype; + bb:array[1..9000] of byte;*/ +EXTERN word pptr,bptr; +EXTERN matrix<0,0,0,1,integer> ppos; +EXTERN array<1,24,word> pozzes; +EXTERN byte anim; EXTERN pointer copier; +EXTERN integer talkx,talky; EXTERN byte talkb,talkf; +EXTERN byte scrollbells; /* no. of times to ring the bell */ +EXTERN boolean ontoolbar,seescroll; + +EXTERN array<1,10,char> objlist; +EXTERN array<'0','9',pointer> digit; +EXTERN array<0,8,pointer> rwlite; EXTERN byte oldrw; +EXTERN varying_string<3> lastscore; EXTERN byte cmp; /* current mouse-pointer */ +EXTERN varying_string<10> verbstr; /* what you can do with your object. :-) */ + +EXTERN matrix<0,30,0,1,string*> also; +EXTERN array<1,15,pedtype> peds; +EXTERN array<1,15,magictype> magics; +EXTERN array<9,15,magictype> portals; +EXTERN array<1,30,fieldtype> fields; EXTERN byte numfields; +EXTERN varying_string<26> flags; EXTERN string listen; + +EXTERN word oh,onh,om,h,m,s,s1; + +EXTERN varying_string<4> atkey; /* For XTs, set to "alt-". For ATs, set to "f1". */ + +EXTERN byte cp,ledstatus,defaultled; +EXTERN raw little; EXTERN boolean quote; /* 66 or 99 next? */ +EXTERN boolean alive; +EXTERN array<1,2000,char> buffer; EXTERN word bufsize; + +EXTERN byte oldjw; /* Old joystick-way */ +EXTERN controllers ctrl; + +EXTERN integer underscroll; /* Y-coord of just under the scroll text. */ + +/* TSkellern is only temporary, and I'll replace it + with a local version when it's all fixed up. */ + +/* tskellern:longint absolute $0:244; { Over int $61 }*/ + +EXTERN boolean ddmnow; /* Kludge so we don't have to keep referring to Dropdown */ +EXTERN varying_string<40> roomname; /* Name of this room */ + +EXTERN text logfile; EXTERN boolean logging,log_epson; + +EXTERN boolean cl_override; + +EXTERN byte locks; /*ABSOLUTE $40:$17;*/ + +EXTERN varying_string<20> subject; /* What you're talking to them about. */ +EXTERN byte subjnumber; /* The same thing. */ + +EXTERN boolean keyboardclick; /* Is a keyboard click noise wanted? */ + +EXTERN char him,her,it; +EXTERN longint roomtime; /* Set to 0 when you enter a room, added to in every loop.*/ + +EXTERN boolean after_the_scroll; + + /* For the demo: */ +EXTERN demo_type demo_rec; +EXTERN file<demo_type> demofile; + +EXTERN char last_person; /* Last person to have been selected using the People + menu. */ + +EXTERN boolean doing_sprite_run; /* Only set to True if we're doing a sprite_run + at this moment. This stops the trippancy system from moving any of the + sprites. */ + +EXTERN vmctype vmc; +EXTERN string filetoload; + +EXTERN boolean holdthedawn; /* If this is true, calling Dawn will do nothing. + It's used, for example, at the start, to stop Load from dawning. */ + +EXTERN word storage_seg,storage_ofs; /* Seg and ofs of the Storage area. */ +EXTERN word skellern; /* Offset of the timer variable - 1 more than storage_OFS */ +EXTERN boolean reloaded; /* Is this NOT the primary loading? */ + +EXTERN boolean super_was_virtual,super_was_off; /* Used by Super_Off and Super_On */ + +EXTERN pathstr enid_filename; + +EXTERN joysetup js; +EXTERN word cxmin,cxmax,cymin,cymax; EXTERN boolean use_joy_a; +#undef EXTERN +#define EXTERN extern + + + void newpointer(byte m); + + void wait(); /* makes hourglass */ + + void on(); + + void off(); + + void on_virtual(); + + void off_virtual(); + + void xycheck(); + + void hopto(integer x,integer y); /* Moves mouse pointer to x,y */ + + void check(); + + void note(word hertz); + + void blip(); + + string strf(longint x); + + void shbox(integer x1,integer y1,integer x2,integer y2, string t); + + void newgame(); + + void click(); + + void slowdown(); + + boolean flagset(char x); + + void force_numlock(); + + boolean pennycheck(word howmuchby); + + string getname(char whose); + + char getnamechar(char whose); + + string get_thing(char which); + + char get_thingchar(char which); + + string get_better(char which); + + string f5_does(); + + void plot_vmc(integer xx,integer yy, byte page_); + + void wipe_vmc(byte page_); + + void setup_vmc(); + + void clear_vmc(); + + void load_a_mouse(byte which); + + void background(byte x); + + void hang_around_for_a_while(); + + void super_off(); + + void super_on(); + + boolean mouse_near_text(); + +#endif diff --git a/engines/avalanche/help.cpp b/engines/avalanche/help.cpp new file mode 100644 index 0000000000..d155263306 --- /dev/null +++ b/engines/avalanche/help.cpp @@ -0,0 +1,225 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Rodent.h"*/ +/*#include "Crt.h"*/ + +typedef graphcursmasktype cursor; +const char vernum[] = "v1ù00"; +const char copyright[] = "1992"; +const cursor questionmark = +{ + ((511,1023,2047,31,15,8199,32647,65415,63503,61471,61503,61695,63999,63999,61695,61695), + (65024,33792,34816,34784,40976,57224,32840,72,1936,2080,2496,2304,1536,1536,2304,3840)), + 0, + 0}; + +const array<1,7,varying_string<12> > topics = + {{"Front page","Background","Toolbar","Menus", + "Keyboard","Shareware","Exit Help"}}; + +const array<1,6,char> keys = "FBTMKS"; + +byte page_; +palettetype dp,dark; +char r; +boolean lmo; + +void hilight(integer x,integer y, byte c1,byte c2, string z) +{ + string w; +; + w=z; w[1]='\40'; setcolor(c1); outtextxy(x,y,w); + w=z; fillchar(w[2],length(z)-1,'\40'); setcolor(c2); + outtextxy(x,y,w); outtextxy(x-1,y,w); +} + +void showpage(byte x) +{; + if (x==page_) return; /* twit */ + if (x==7) {; lmo=true; return; } + setallpalette(dark); hidemousecursor; settextjustify(1,1); + if (page_!=177) + {; + setfillstyle(1,1); bar(507,page_*25+2,607,page_*25+22); + setfillstyle(1,9); bar(500,page_*25,600,page_*25+20); +/* setcolor(11); outtextxy(550,page*25+10,topics[page]);*/ + hilight(550,page_*25+10,11,14,topics[page_]); + } + page_=x; + setfillstyle(1,4); bar(507,page_*25+2,607,page_*25+22); + setfillstyle(1,12); bar(500,page_*25,600,page_*25+20); +/* setcolor(14); outtextxy(550,page*25+10,topics[page]); */ + hilight(550,page_*25+10,14,15,topics[page_]); + setfillstyle(1,7); bar(0,27,470,189); settextjustify(0,2); setcolor(1); + switch (page_) { + case 1: {; /* Front page */ + setcolor(black); + outtextxy( 10, 40,"Thorsoft of Letchworth presents"); + outtextxy(300, 80,vernum); + outtextxy( 10, 90,string("(c) ")+copyright+", Mike, Mark and Thomas Thurman."); + setcolor(red); + outtextxy(100,129,"Finding your way around it..."); + setcolor(blue); + outtextxy( 10,120,"You are now using the Help System."); + outtextxy( 10,138,"Press the first letter of the topic that you want to"); + outtextxy( 10,147,"read (eg T for (T)oolbar), or click on its button (on"); + outtextxy( 10,156,"the right) using the mouse. Use \"Exit Help\" to quit."); + outtextxy( 10,174,"(Fastest exit- just hit Esc!)"); + } + break; + case 2: {; /* Background */ + setcolor(red); + outtextxy(300, 30,"Remember this chap?"); + setcolor(blue); + outtextxy( 10, 55,"Back in good old A.D. 79, there lived a Roman"); + outtextxy( 10, 64,"whose name was Denarius Avaricius Sextus, known"); + outtextxy( 10, 73,"to his friends as Avvy. His wife was called Arkata,"); + outtextxy( 10, 82,"and he had a slave named Crapulus. His grandson"); + outtextxy( 10, 91,"joined the army, was posted to Gaul, and liked it"); + outtextxy( 10,100,"so much that he stayed there, telling everyone the"); + outtextxy( 10,109,"one about the centurion and the Turkish bath. His"); + outtextxy( 10,118,"thirty-sixth male-line descendant accidentally"); + outtextxy( 10,127,"poisoned an old enemy of William of Normandy, and"); + outtextxy( 10,136,"to his great surprise came so much into Bill's favour"); + outtextxy( 10,145,"that, after the Battle of Hastings a few years"); + outtextxy( 10,154,"later, he was made the lord of a small town in"); + outtextxy( 10,163,"Hertfordshire called Argent. It is his great-grandson"); + outtextxy( 10,172,"who stars in this game, back in good old A.D. 1189."); + } + break; + case 3: {; /* ? */ + outtextxy( 15, 30,"The Toolbar is there so that (along with the menus)"); + outtextxy( 15, 39,"you can perform a lot of the functions contained in"); + outtextxy( 15, 48,"the game, using the mouse."); + setcolor(red); + outtextxy( 15, 66,"COMPASS:"); + setcolor(blue); + outtextxy( 90, 66,"Used to point Avvy in the right direction."); + setcolor(red); + outtextxy( 15, 75,"THINKS:"); + setcolor(blue); + outtextxy( 90, 75,"Shows the person/object you're thinking of."); + setcolor(red); + outtextxy( 15, 84,"SCORE:"); + setcolor(blue); + outtextxy( 90, 84,"Shows how many points you've got."); + setcolor(red); + outtextxy( 15, 93,"SPEED:"); + setcolor(blue); + outtextxy( 90, 93,"Adjusts the speed of the game."); + setcolor(red); + outtextxy( 15,102,"L.E.D.s:"); + setcolor(blue); + outtextxy( 90,102,"Shows whether sound is on (toggle with <F2>),"); + outtextxy( 90,111,"the computer is ready, or there is an error."); + setcolor(red); + outtextxy( 15,120,"CLOCK:"); + setcolor(blue); + outtextxy( 90,120,"Shows the time."); + setcolor(red); + outtextxy( 15,129,"'OK' box:"); + setcolor(blue); + outtextxy( 90,129,"Works the same as pressing <ENTER>."); + setcolor(0); + outtextxy( 15,147,"N.B. The game action is suspended while you are"); + outtextxy( 15,156,"using the toolbar."); + } + break; + case 4: {; /* menus */ + outtextxy( 15, 60,"To use the drop-down menus, either click on the bar"); + outtextxy( 15, 69,"at the top with the mouse, or press Alt and the first"); + outtextxy( 15, 78,string("letter of the menu's name (eg alt-A = (A)ction.) The ")+'\3'); + outtextxy( 15, 87,"menu is alt-H, for (H)eart."); + outtextxy( 15,105,"When you have a menu, either click on the option you"); + outtextxy( 15,114,"want, or press its initial letter (eg O for \"OS Shell\")."); + outtextxy( 15,132,"To do something to, or with, an object or person, first"); + outtextxy( 15,141,"select them (or it) from the People or Things menu. Then"); + outtextxy( 15,150,"select whatever you wanted to do from the Use menu."); + setcolor(red); + outtextxy(15,177,"(OK, so it sounds complicated, but then it's intuitive!)"); + } + break; + case 5: {; /* Keyboard */ + outtextxy(15, 60,"The keyboard interface is even simpler than the mouse"); + outtextxy(15, 70,"interface! Just type what you want Avvy to do."); + outtextxy(15, 80,"For example, to open a door, type in:"); + setcolor(red); outtextxy(100,95,"open door"); setcolor(blue); + outtextxy(15,110,"And to look at Crapulus, type:"); + setcolor(red); outtextxy(100,125,"look at Crapulus"); + setcolor(blue); outtextxy(15,140,"(Don't forget to press Enter after each command!)"); + outtextxy(15,160,"This is a traditional command-line parser interface,"); + outtextxy(15,170,"similar to the one in \"Avaricius\", only more advanced."); + } + break; + case 6: {; /* ? */ + outtextxy(15, 30,"This game is Shareware. Most programs are sold through"); + outtextxy(15, 40,"shops, and the authors prevent you from copying them."); + outtextxy(15, 50,"Shareware is different. You may copy it and give it to"); + outtextxy(15, 60,"ANYBODY at all. You may post it on any BBS, give it to"); + outtextxy(15, 70,"friends, etc. If you like it, we ask you to pay us for"); + outtextxy(15, 80,"the software directly through the post. We're relying"); + outtextxy(15, 90,"on you to register!"); + outtextxy(99,177,"{ ETC }"); + } + break; + } + setallpalette(dp); showmousecursor; +} + +void helpsetup() +{ + integer gd,gm; +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); settextstyle(1,0,0); setcolor(11); + getpalette(dp); dark.size=dp.size; fillchar(dark.colors,dark.size,'\0'); + setallpalette(dark); setusercharsize(3,1,8,10); + for( gm=1; gm <= 3; gm ++) outtextxy(gm,0,"Avalot- HELP!"); + resetmouse; setgraphicscursor(questionmark); showmousecursor; + settextstyle(0,0,1); settextjustify(1,1); + for( gd=2; gd <= 7; gd ++) + {; + setfillstyle(1,1); bar(507,gd*25+2,607,gd*25+22); + setfillstyle(1,9); bar(500,gd*25,600,gd*25+20); +/* setcolor(11); outtextxy(550,gd*25+10,topics[gd]); */ + hilight(550,gd*25+10,11,14,topics[gd]); + } + showmousecursor; + page_=177; showpage(1); lmo=false; setfillstyle(1,7); + for( gd=1; gd <= 3; gd ++) + {; + bar( 10-gd*3,200-gd*3,490-gd*6,200-gd*3); + bar(490-gd*6, 37-gd*3,491-gd*6,200-gd*3); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + helpsetup(); + do { + do { getbuttonstatus; } while (!((mkey==left) || keypressed())); + if (keypressed()) + {; /* keyboard choice */ + r=upcase(readkey()); + if (pos(r,keys)>0) showpage(pos(r,keys)); else + if (r=='\0') + switch (readkey()) { /* grab extd keystroke */ + case 'H': if (page_>1) showpage(page_-1); break; + case 'P': if (page_<6) showpage(page_+1); break; + case 'G':case 'I': showpage(1); break; + case 'O':case 'Q': showpage(6); break; + } else + if (set::of('\33','Q','X','E','H', eos).has(r)) lmo=true; /* quit */ + } + else + {; /* mouse choice */ + if ((mousex>400) && (mousey>25)) + {; + showpage(mousey / 25); + } + } + } while (!lmo); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/help2.cpp b/engines/avalanche/help2.cpp new file mode 100644 index 0000000000..b062015aec --- /dev/null +++ b/engines/avalanche/help2.cpp @@ -0,0 +1,244 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +struct hypertype { + char trigger; + byte line; + byte start,finish; + word ref; +}; + +integer gd,gm; +array<1,2,fonttype> font; +matrix<0,7,1,80,byte> current; +array<1,250,varying_string<79> > data; +integer fv,position,size; +varying_string<79> title; +array<1,20,hypertype> link; +byte numlinks; +char r; +array<0,9,byte> reverse; +array<0,9,byte> revpos; + +void loadfont() +{ + file<fonttype> fontfile; +; + assign(fontfile,"c:\\thomas\\ttsmall.fnt"); reset(fontfile); + fontfile >> font[1]; close(fontfile); +/* assign(fontfile,'c:\avalot\avalot.fnt'); reset(fontfile); + read(fontfile,font[2]); close(fontfile);*/ + /* NB: We'll put BOTH of these fonts one after the other, in the same + file, in the final compilation. */ +} + +void scribe(byte which,byte what); + +static void underline(byte& x) {; x=x | 177; } + +void scribe(byte which,byte what) +{ + byte fv,ff; string x; +; + x=data[what]; + fillchar(current,sizeof(current),'\0'); + for( ff=1; ff <= length(x); ff ++) + for( fv=0; fv <= 7; fv ++) + {; + current[fv][ff]=font[which][x[ff]][fv]; + } + + for( fv=1; fv <= numlinks; fv ++) + { hypertype& with = link[fv]; + if (with.line==what) + for( ff=with.start; ff <= with.finish; ff ++) + underline(current[7][ff]);} + +} + +void display(word y) +{; + for( fv=0; fv <= 7; fv ++) + move(current[fv],mem[0xa000*(y+fv)*80],79); +} + +void update_link(char which, byte whence,byte whither) +{ + byte fv; +; + for( fv=1; fv <= numlinks; fv ++) + { hypertype& with = link[fv]; + if (with.trigger==which) + {; + with.line=size; + with.start=whence; + with.finish=whither; + }} +} + +void getlinks(string& x) +{ + byte p,q; +; + do { + p=pos("[",x); + if (p==0) return; /* lousy, huh? */ + q=pos("]",x); + update_link(x[p+1],p,q-3); + Delete(x,q,1); Delete(x,p,2); + } while (!false); +} + +void loaddata(byte which) +{ + text t; + string x; + integer e; +; + revpos[9]=position; + fillchar(data,sizeof(data),'\0'); + move(reverse[1],reverse[0],9); + move(revpos[1],revpos[0],9); + reverse[9]=which; revpos[9]=1; + + str(which,x); + assign(t,string('h')+x+".raw"); + reset(t); + t >> title >> NL; + size=0; numlinks=0; + while (! eof(t)) + {; + t >> x >> NL; + if (x[1]==':') + {; + numlinks += 1; + { + hypertype& with = link[numlinks]; + ; + with.trigger=x[2]; + Delete(x,1,3); + Delete(x,pos(" ",x),255); + val(x,with.ref,e); + } + } else {; + size += 1; + getlinks(x); + data[size]=x; + } + } + position=1; size -= 15; + close(t); +} + +void screen() +{; + setbkcolor(1); + setfillstyle(1,1); bar(0,0,640,38); + setfillstyle(1,14); bar(0,39,640,39); +} + +void showscreen() +{ + byte fv; +; + if (position<1) position=1; + for( fv=0; fv <= 15; fv ++) + {; + scribe(1,fv+position); + display(41+fv*10); + } +} + +void up() +{ + byte fv; +; + position -= 1; + scribe(1,position); + for( fv=0; fv <= 9; fv ++) + {; + move(mem[0xa000*3200],mem[0xa000*3280],12720); + if (set::of(0,9, eos).has(fv)) fillchar(mem[0xa000*3200],79,'\0'); else + move(current[8-fv],mem[0xa000*3200],80); + } +} + +void down() +{ + byte fv; +; + position += 1; + scribe(1,position+15); + for( fv=0; fv <= 9; fv ++) + {; + move(mem[0xa000*3280],mem[0xa000*3200],12720); + if (set::of(0,9, eos).has(fv)) fillchar(mem[0xa000*15920],79,'\0'); else + move(current[fv-1],mem[0xa000*15920],80); + } +} + +void newpage(char c) +{ + byte fv; +; + for( fv=1; fv <= numlinks; fv ++) + { hypertype& with = link[fv]; + if (with.trigger==c) + {; + loaddata(with.ref); + showscreen(); + }} +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + loadfont(); + screen(); + loaddata(0); + showscreen(); + fillchar(reverse,sizeof(reverse),'\0'); + fillchar(revpos,sizeof(revpos),'\1'); + do { + r=upcase(readkey()); + switch (r) { + case '\0': switch (readkey()) { + case 'H': if (position>1) up(); break; + case 'P': if (position<size) down(); break; + case 'I': {; position -= 16; showscreen(); } break; + case 'Q': {; position += 16; showscreen(); } break; + case 'G': {; position=1; showscreen(); } break; + case 'O': {; position=size; showscreen(); } break; + } + break; + case 'B': {; /* go Back */ + gd=reverse[8]; + gm=revpos[8]; + move(reverse[0],reverse[2],8); + move(revpos[0],revpos[2],8); + loaddata(gd); position=gm; + showscreen(); + } + break; + case 'C': {; /* Contents */ + loaddata(0); + showscreen(); + } + break; + case 'H': {; + loaddata(7); /* help on help */ + showscreen(); + } + break; + case '\33': exit(0); break; + default: newpage(r); + } + } while (!false); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/helpbak.cpp b/engines/avalanche/helpbak.cpp new file mode 100644 index 0000000000..91825236fa --- /dev/null +++ b/engines/avalanche/helpbak.cpp @@ -0,0 +1,161 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + HELPER The help system unit. */ + +#define __helper_implementation__ + + +#include "helpbak.h" + + +/*#include "Crt.h"*/ +/*#include "Lucerna.h"*/ + + +struct buttontype { + char trigger; + byte whither; +}; + +const integer buttonsize = 930; + +const integer toolbar = 0; const integer nim = 1; const integer kbd = 2; const integer credits = 3; const integer joystick = 4; const integer troubleshooting = 5; const integer story = 6; +const integer mainscreen = 7; const integer registering = 8; const integer sound = 9; const integer mouse = 10; const integer filer = 11; const integer back2game = 12; +const integer helponhelp = 13; const integer pgdn = 14; const integer pgup = 15; + +array<1,10,buttontype> buttons; + +void plot_button(integer y, byte which) +{ + untyped_file f; + pointer p; + + getmem(p,buttonsize); + assign(f,"buttons.avd"); + reset(f,1); + seek(f,which*buttonsize); + blockread(f,p,buttonsize); + putimage(470,y,p,0); + close(f); + freemem(p,buttonsize); +} + +void getme(byte which); + + +static void chalk(byte y, string z) +{ + outtextxy(16,41+y*10,z); +} + +void getme(byte which) /* Help icons are 80x20 */ +{ + string x; + text t; + byte y,fv; + + + str(which,x); + assign(t,string('h')+x+".raw"); + y=0; + reset(t); + + t >> x >> NL; + setfillstyle(1,1); bar(0,0,640,200); + setfillstyle(1,15); bar(8,40,450,200); + settextjustify(1,1); setcolor(14); + outtextxy(320,15,x); + settextjustify(0,2); + setcolor(3); settextstyle(0,0,2); + outtextxy(550,0,"help!"); + /***/ setcolor(0); settextstyle(0,0,1); + + do { + t >> x >> NL; + if (x=='!') flush(); /* End of the help text is signalled with a !. */ + chalk(y,x); + y += 1; + } while (!false); + + /* We are now at the end of the text. Next we must read the icons. */ + + y=0; settextjustify(1,1); setcolor(3); + while (! eof(t)) + { + y += 1; + t >> x >> NL; /* Get the name of this button, and... */ + if (x!='-') /* (hyphen signals an empty button.) */ + { + t >> buttons[y].trigger >> NL; + t >> fv >> NL; plot_button(13+y*27,fv); + t >> buttons[y].whither >> NL; /* this is the position to jump to */ + + switch (buttons[y].trigger) { + case 'þ' : outtextxy(580,25+y*27,"Esc"); break; + case 'Ö' : outtextxy(580,25+y*27,"\30"); break; + case 'Ø' : outtextxy(580,25+y*27,"\31"); break; + default: + outtextxy(580,25+y*27,buttons[y].trigger); + } + + } else buttons[y].trigger='\0'; + } + + settextjustify(0,2); + close(t); +} + +void continue_help() +{ + char r; + byte fv; + + do { + r=upcase(readkey()); + switch (r) { + case '\33' : return; break; + case '\0' : switch (readkey()) { + case '\110':case '\111': r='Ö'; break; + case '\120':case '\121': r='Ø'; break; + case '\73': r='H'; break; /* Help on help */ + } + break; + } + + for( fv=1; fv <= 10; fv ++) + { buttontype& with = buttons[fv]; + if (with.trigger==r) + { + dusk; + getme(with.whither); + dawn; + flush(); + }} + + } while (!false); +} + +void boot_help() +{ + setactivepage(2); + + getme(0); + + dusk; + setvisualpage(2); + dawn; + + continue_help(); + + dusk; + setvisualpage(cp); + draw_also_lines; + setactivepage(1-cp); + dawn; +} + diff --git a/engines/avalanche/helpbak.h b/engines/avalanche/helpbak.h new file mode 100644 index 0000000000..12a7869092 --- /dev/null +++ b/engines/avalanche/helpbak.h @@ -0,0 +1,11 @@ +#ifndef __helpbak_h__ +#define __helpbak_h__ + + +#include "graph.h" +/*#include "Gyro.h"*/ + + +void boot_help(); + +#endif diff --git a/engines/avalanche/helper.cpp b/engines/avalanche/helper.cpp new file mode 100644 index 0000000000..50e6a074d8 --- /dev/null +++ b/engines/avalanche/helper.cpp @@ -0,0 +1,282 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + HELPER The help system unit. */ + +#define __helper_implementation__ + + +#include "helper.h" + + +/*#include "Crt.h"*/ +/*#include "Lucerna.h"*/ +/*#include "Pingo.h"*/ + + +struct buttontype { + char trigger; + byte whither; +}; + +const integer buttonsize = 930; + +const integer toolbar = 0; const integer nim = 1; const integer kbd = 2; const integer credits = 3; const integer joystick = 4; const integer troubleshooting = 5; const integer story = 6; +const integer mainscreen = 7; const integer registering = 8; const integer sound = 9; const integer mouse = 10; const integer filer = 11; const integer back2game = 12; +const integer helponhelp = 13; const integer pgdn = 14; const integer pgup = 15; + +array<1,10,buttontype> buttons; +byte highlight_was; + +void plot_button(integer y, byte which) +{ + untyped_file f; + pointer p; + + if (y>200) + { background(2); delay(10); background(0); return; } /* Silly buttons. */ + getmem(p,buttonsize); + assign(f,"buttons.avd"); + reset(f,1); + seek(f,which*buttonsize); + blockread(f,p,buttonsize); + + if (y==-177) + putimage(229,5,p,0); + else + putimage(470,y,p,0); + close(f); + freemem(p,buttonsize); +} + +void getme(byte which); + +static untyped_file f; + + +static void chalk(byte y, string z) +{ + outtextxy(16,41+y*10,z); +} + + + +static void getline(string& x) +{ + byte fz; + + blockread(f,x[0],1); + blockread(f,x[1],(byte)(x[0])); + for( fz=1; fz <= length(x); fz ++) + x[fz]=chr(ord(x[fz]) ^ 177); +} + +void getme(byte which) /* Help icons are 80x20 */ +{ + string x; + byte y,fv; + word offset; + + + off; + assign(f,"help.avd"); + y=0; + highlight_was=177; /* Forget where the highlight was. */ + reset(f,1); + seek(f,which*2); + blockread(f,offset,2); + seek(f,offset); + + getline(x); + setfillstyle(1,1); bar(0,0,640,200); + setfillstyle(1,15); bar(8,40,450,200); + settextjustify(2,2); + blockread(f,fv,1); + plot_button(-177,fv); + + setcolor(0); outtextxy(629,26,x); /* Plot the title. */ + setcolor(3); outtextxy(630,25,x); + + settextjustify(0,2); settextstyle(0,0,2); + setcolor(0); outtextxy(549,1,"help!"); + setcolor(3); outtextxy(550,0,"help!"); + /***/ settextstyle(0,0,1); + + do { + getline(x); + if (x=='!') flush(); /* End of the help text is signalled with a !. */ + if (x[1]=='\\') + { + setcolor(4); + chalk(y,copy(x,2,255)); + } else + { + setcolor(0); + chalk(y,x); + } + y += 1; + } while (!false); + + /* We are now at the end of the text. Next we must read the icons. */ + + y=0; settextjustify(1,1); settextstyle(0,0,2); + while (! eof(f)) + { + y += 1; + blockread(f,buttons[y].trigger,1); + if (buttons[y].trigger=='\261') flush(); + blockread(f,fv,1); + if (buttons[y].trigger!='\0') plot_button(13+y*27,fv); + blockread(f,buttons[y].whither,1); /* this is the position to jump to */ + + + switch (buttons[y].trigger) { + case 'þ' : x="Esc"; break; + case 'Ö' : x='\30'; break; + case 'Ø' : x='\31'; break; + default: + x=buttons[y].trigger; + } + setcolor(0); outtextxy(589,26+y*27,x); + setcolor(3); outtextxy(590,25+y*27,x); + + } + + settextjustify(0,2); settextstyle(0,0,1); + close(f); on; +} + + +byte check_mouse(); + /* Returns clicked-on button, or 0 if none. */ +static void light(byte which,byte colour) +{ + if (which==177) return; /* Dummy value for "no button at all". */ + setcolor(colour); which=which & 31; + rectangle(466,11+which*27,555,35+which*27); +} + +byte check_mouse() +{ + byte h_is; + + byte check_mouse_result; + check; + + if (mrelease!=0) + { /* Clicked *somewhere*... */ + if ((mx<470) || (mx>550) || (((my-13) % 27)>20)) + check_mouse_result=0; else + /* Clicked on a button. */ + check_mouse_result=((my-13) / 27); + } else + { + if ((mx>470) && (mx<=550) && (((my-13) % 27)<=20)) + { /* No click, so highlight. */ + h_is=(my-13) / 27; + if ((h_is<1) || (h_is>6)) h_is=177; /* In case of silly values. */ + } else h_is=177; + + if ((h_is!=177) && ((keystatus & 1)>0)) h_is += 32; + + if (h_is!=highlight_was) + { + off; + light(highlight_was,1); + highlight_was=h_is; + if (buttons[h_is & 31].trigger!='\0') + { + if (h_is>31) light(h_is,11); else light(h_is,9); + } + on; + } + + check_mouse_result=0; + } + return check_mouse_result; +} + +void continue_help() +{ + char r; + byte fv; + + do { + while (! keypressed()) + { + fv=check_mouse(); + + if (fv>0) + switch (buttons[fv].trigger) { + case '\0':/*null*/; break; + case '\376': return; break; + default: { + dusk; + getme(buttons[fv].whither); + dawn; + continue_; + } + } + + } + r=upcase(readkey()); + switch (r) { + case '\33' : return; break; + case '\0' : switch (readkey()) { + case '\110':case '\111': r='Ö'; break; + case '\120':case '\121': r='Ø'; break; + case '\73': r='H'; break; /* Help on help */ + default: continue_; + } + break; + } + + for( fv=1; fv <= 10; fv ++) + { buttontype& with = buttons[fv]; + if (with.trigger==r) + { + dusk; + getme(with.whither); + dawn; + flush(); + }} + + } while (!false); +} + +void boot_help() +{ + byte groi; + + dusk; + off; + oncandopageswap=false; highlight_was=177; + copypage(3,1-cp); /* Store old screen. */ groi=getpixel(0,0); + + /* Set up mouse. */ + off_virtual; + newpointer(2); + setactivepage(3); setvisualpage(3); + + getme(0); + dawn; + + newpointer(9); on; + mousepage(3); + + continue_help(); + + mousepage(cp); + dusk; off; + oncandopageswap=true; + copypage(1-cp,3); /* Restore old screen. */ groi=getpixel(0,0); + on_virtual; dawn; fix_flashers; + + setvisualpage(cp); + setactivepage(1-cp); +} + diff --git a/engines/avalanche/helper.h b/engines/avalanche/helper.h new file mode 100644 index 0000000000..9c1c43ca42 --- /dev/null +++ b/engines/avalanche/helper.h @@ -0,0 +1,11 @@ +#ifndef __helper_h__ +#define __helper_h__ + + +#include "graph.h" +/*#include "Gyro.h"*/ + + +void boot_help(); + +#endif diff --git a/engines/avalanche/hibits.cpp b/engines/avalanche/hibits.cpp new file mode 100644 index 0000000000..8dba55c3c3 --- /dev/null +++ b/engines/avalanche/hibits.cpp @@ -0,0 +1,27 @@ +#include "ptoc.h" + + +file<char> inf,outf; +char x; +string q; +byte fv; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + assign(inf,"v:thank.you"); + assign(outf,"d:hibits.out"); + reset(inf); rewrite(outf); + + q=string('\40')+"(Seven is a bit of a lucky number.)"+'\40'+'\215'+'\212'+'\212'; + + for( fv=1; fv <= length(q); fv ++) outf << q[fv]; + + while (! eof(inf)) + {; + inf >> x; + if (x<'\200') x += 128; + outf << x; + } + close(inf); close(outf); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/highs.cpp b/engines/avalanche/highs.cpp new file mode 100644 index 0000000000..2ffd27198b --- /dev/null +++ b/engines/avalanche/highs.cpp @@ -0,0 +1,116 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + HIGHS This handles the high-scores. */ + +#define __highs_implementation__ + + +#include "highs.h" + + +/*#include "Gyro.h"*/ +/*#include "Scrolls.h"*/ + + +typedef array<1,12,struct A1 { + varying_string<30> name; + word score; + varying_string<12> rank; + }> highscoretype; + +highscoretype h; + +void get_new_highs() +{ + byte fv; +; + for( fv=1; fv <= 12; fv ++) + { + A1& with = h[fv]; + ; + with.score=32-fv*2; + with.rank="..."; + } + h[1].name="Mike"; h[2].name="Liz"; h[3].name="Thomas"; h[4].name="Mark"; + h[5].name="Mandy"; h[6].name="Andrew"; h[7].name="Lucy Tryphena"; + h[8].name="Tammy the dog"; + h[9].name="Avaricius"; h[10].name="Spellchick"; h[11].name="Caddelli"; + h[12].name="Spludwick"; +} + +void show_highs() + /* This procedure shows the high-scores. */ +{ + byte fv; + varying_string<40> x; + varying_string<5> y; +; + display("HIGH SCORERS\3\r Name\n\nScore Rank\r \"\"\"\"\n\n\"\"\"\"\" \"\"\"\"\f\4"); + for( fv=1; fv <= 12; fv ++) + { + A1& with = h[fv]; + ; + display(string('\15')+with.name+'\4'); + fillchar(x,sizeof(x),'\40'); + y=strf(with.score); + x[0]=chr(29-(length(with.name+y))); + display(x+y+' '+with.rank+'\4'); + } + + display(""); +} + +void store_high(string who) + /* This procedure shows the high-scores. */ +{ + byte fv,ff; +; + + for( fv=1; fv <= 12; fv ++) + if (h[fv].score<dna.score) flush(); + + /* Shift all the lower scores down a space. */ + for( ff=fv; ff <= 11; ff ++) + h[ff+1]=h[ff]; + + { + A1& with = h[fv]; + ; + with.name=who; + with.score=dna.score; + } + +} + +void get_highs() +{ + file<highscoretype> f; +; + /*$I-*/ + assign(f,"scores.avd"); + reset(f); + /* Did we get it? */ + + if (ioresult!=0) + {; /* No. */ + get_new_highs(); /* Invent one. */ + } else + {; /* Yes. */ + f >> h; + close(f); + } +} + +class unit_highs_initialize { + public: unit_highs_initialize(); +}; +static unit_highs_initialize highs_constructor; + +unit_highs_initialize::unit_highs_initialize() {; + get_highs(); +}
\ No newline at end of file diff --git a/engines/avalanche/highs.h b/engines/avalanche/highs.h new file mode 100644 index 0000000000..3d6eb65807 --- /dev/null +++ b/engines/avalanche/highs.h @@ -0,0 +1,9 @@ +#ifndef __highs_h__ +#define __highs_h__ + + + void show_highs(); + + void store_high(string who); + +#endif diff --git a/engines/avalanche/hiz.cpp b/engines/avalanche/hiz.cpp new file mode 100644 index 0000000000..bcff8ab2bd --- /dev/null +++ b/engines/avalanche/hiz.cpp @@ -0,0 +1,287 @@ +#include "ptoc.h" + + +/*$M 6000,600,600*/ +/*$V-,I-,R-,F+*/ /* Do not change these directives. */ +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Dos.h"*/ +/*#include "Tsru.h"*/ + + + /* program's signature */ +const varying_string<20> tsr_tmark = "FISH FISH FISH!!!"; + +integer gd,gm; +byte a /*absolute $A000:0*/; +matrix<1,800,0,3,byte> sv; +byte bit; string nam; +byte tsr_int; word tsr_ax; + +void grab() +{; + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(a,sv[1][bit],800); + } +} + +void drop() +{; + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(sv[1][bit],a,800); + } +} + +void say(string x) +{; + grab(); output << string('\15')+x; +} + +void pak(string x) +{ + char r; +; + say(x+" (press any key...)"); r=readkey(); drop(); +} + +string typein() +{ + char r; string x; +string typein_result; +; + x=""; + do { + r=readkey(); + switch (r) { + case '\10': if (x[0]>'\0') {; output << string('\10')+'\40'+'\10'; x[0] -= 1; } break; + case '\15': {; typein_result=x; return typein_result; } break; + case '\33': {; typein_result=""; return typein_result; } break; + default: if (x[0]<'\62') {; x=x+r; output << r; } + } + } while (!false); +return typein_result; +} + +void load() +{ + byte a /*absolute $A000:1200*/; untyped_file f; +; + say("LOAD: filename?"); nam=typein(); drop(); + if (nam=="") return; + assign(f,nam); reset(f,1); + if (ioresult!=0) + {; + pak("LOAD: file not found."); return; + } + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a,12080); + if (ioresult!=0) + {; + pak("LOAD: error whilst loading."); close(f); return; + } + } + close(f); +} + +void save() +{ + const string header = + string("This is a file from an Avvy game, and its contents are subject to ")+ + "copyright."+'\15'+'\12'+'\15'+'\12'+"Have fun!"+'\32'; + untyped_file f; varying_string<30> screenname; searchrec s; char r; +byte a /*absolute $A000:1200*/; +; + say("SAVE: filename?"); nam=typein(); drop(); + if (nam=="") return; + findfirst(nam,anyfile,s); if (doserror==0) + {; + say("SAVE: That exists, are you sure\? (Y/N)"); + do { r=upcase(readkey()); } while (!(set::of('Y','N', eos).has(r))); drop(); + if (r=='N') return; + } + screenname="Saved with HIZ."; + assign(f,nam); rewrite(f,1); blockwrite(f,header[1],146); + blockwrite(f,screenname,31); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,a,12080); + if (ioresult!=0) + {; + pak("SAVE: error whilst saving."); close(f); return; + } + } +} + +void hedges() +{; + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + fillchar(mem[0xa000*14*80],80,'\377'); + fillchar(mem[0xa000*166*80],80,'\377'); + } +} + +void reset_() +{ + registers regs; +; + regs.ax=14; + intr(0x10,regs); + directvideo=false; +} + +void do_pop() +{ + char r; +; + do { + say("HIZ: Load Save Hedges Reset eXit?"); r=upcase(readkey()); drop(); + switch (r) { + case 'L': load(); break; + case 'S': save(); break; + case 'H': hedges(); break; + case 'R': reset_(); break; + case 'X': return; break; + } + } while (!false); +} + +/* Now for the TSR stuff */ + +void mypoprtn() +{ + registers r; +; + beginpop; + do_pop(); + endpop; +} +/**********************/ +void stop_tsr() +{; + if (tsrexit) + output << "HIZ stopped" << NL; + else + output << "Unable to stop HIZ - other TSR has been installed." << NL; +} +/**********************/ +/* This interrupt is called at program start-up. Its purpose is to provide + a way to communicate with an installed copy of the TSR through cmdline + params. The installation of the intrpt serves to prevent any attempt to + install a 2nd copy of the TSR */ +void tsr_intrtn(word flags,word cs,word ip,word ax,word bx,word cx,word dx,word si,word di,word ds,word es,word bp) +/*interrupt;*/ +{; + tsr_ax=ax; + cli; + beginint; + sti; + + switch (tsr_ax) { + case 1: {; + stop_tsr(); /* Terminate TSR, if poss.*/ + } + break; + case 2: {; + tsroff= true; /* Suspend TSR */ + output << "HIZ suspended." << NL; + } + break; + case 3: {; + tsroff=false; + output << "HIZ restarted" << NL; + } + break; + } + cli; + endint; + sti; +} +/*******************/ +byte i; +registers r; +string st; +boolean b; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + + /********************************************/ + /* Check to see if TSR is already installed */ + /********************************************/ + + tsr_int=dupcheck(tsr_tmark,&tsr_intrtn); + + /*****************************************/ + /* If it IS already installed, check for */ + /* parameter. */ + /*****************************************/ + + if (tsr_int > 0) + { + if (paramcount>0) + { + st=paramstr(1); + for( i=1; i <= length(st); i ++) + st[i]=upcase(st[i]); + if (st=="STOP") + r.ax=1; + else if (st=="HOLD") r.ax=2; + else if (st=="RSTR") r.ax=3; + else r.ax=4; + + if (r.ax<4) + {; + intr(tsr_int,r); + return 0; + } + else + {; + output << "HIZ: invalid parameter " << paramstr(1) << NL; + output << "Syntax: HIZ stop/hold/rstr" << NL; + return 0; + } + } + else + {; + output << "HIZ already installed." << NL; + output << "(If you're sure it isn't, try running BLANKINT /I." << NL; + output << "It's in the TURBO directory.)" << NL; + } + return 0; + } + + output << string("Wait...")+'\15'; /* tell 'em to wait...! */ + + /* Call PopSetUp to point to PopUp routine. Include the + scancode and the keymask to activate the program. In + this example, the scancode is $23 (H) and the + keymask is 08h (Alt.) */ + + popsetup(&mypoprtn,0x23,0x8); + + directvideo=false; + output << "Û Û ßÛß ßßÛ v1.0, (c) 1992, Thomas Thurman." << NL; + output << "ÛßÛ Û Üß" << NL; + output << "ß ß ßßß ßßß The AVD saving/loading/hedging program." << NL; + output << " Use with Dr. Genius. The Hot Key is Ctrl-Alt-H." << NL; + + output << NL; + output << " Enter \"HIZ stop\" to remove Hiz from memory" << NL; + output << " \"HIZ hold\" to temporarily halt Hiz" << NL; + output << " \"HIZ rstr\" to restart Hiz" << NL; + stacksw=-1; + install_int; + keep(0); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/incline.cpp b/engines/avalanche/incline.cpp new file mode 100644 index 0000000000..4103089cf5 --- /dev/null +++ b/engines/avalanche/incline.cpp @@ -0,0 +1,172 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + INCLINE The command-line parser. */ + +#define __incline_implementation__ + + +#include "incline.h" + +#include "gyro.h" +#include "logger.h" + + +byte fv; +char t; +string bugline; +boolean zoomy,numlockhold; + +boolean filename_specified; + +void syntax() +{ + assign(output,""); rewrite(output); + output << NL; + output << string("Lord Avalot d'Argent\n\n(c) ")+copyright+" Mark, Mike and Thomas Thurman." << NL; + output << string("~~~~~~~~~~~~~~~~~~~~~\n\n")+vernum << NL; + output << NL; + output << "Syntax:" << NL; + output << "\n/?\ndisplays this screen," << NL; + output << "\n/O\noverrides EGA check," << NL; + output << "\n/L<f>\nlogs progress to <f>, default AVVY.LOG," << NL; + output << "\n/P<x>\nlogs with Epson codes to <x>, default PRN," << NL; + output << "\n/Q\ncancels sound effects," << NL; + output << "\n/Z\ngoes straight into the game." << NL; + output << NL; + output << "\n\n\n\n\n\n\n... Have fun!" << NL; + exit(177); +} + +void not_through_bootstrap() +{ + output << "Avalot must be loaded through the bootstrap." << NL; + exit(0); +} + +void get_storage_addr() +{ + integer e; + + val(paramstr(2),storage_seg,e); if (e!=0) not_through_bootstrap(); + val(paramstr(3),storage_ofs,e); if (e!=0) not_through_bootstrap(); + skellern=storage_ofs+1; +} + +longint value(string x) +{ + longint q; integer e; + + longint value_result; + val(x,q,e); value_result=q; + return value_result; +} + +void undo_js() +{ + { + joysetup& with = js; + + cxmin=with.xmid-(((with.xmid-with.xmin) / 10)*with.centre); + cxmax=with.xmid+(((with.xmax-with.xmid) / 10)*with.centre); + cymin=with.ymid-(((with.ymid-with.ymin) / 10)*with.centre); + cymax=with.ymid+(((with.ymax-with.ymid) / 10)*with.centre); + +/* writeln(lst,'MID ',xmid,'x',ymid); + writeln(lst,'MAX ',xmax,'x',ymax); + writeln(lst,'MIN ',xmin,'x',ymin); + writeln(lst,'CENTRE ',xmid); + writeln(lst,cxmin); + writeln(lst,cxmax); + writeln(lst,cymin); + writeln(lst,cymax);*/ + } +} + +void check_slope_line(); +static string slope; + +static boolean yn1(byte where) { boolean yn1_result; + yn1_result=slope[where]=='y'; return yn1_result; + } + +void check_slope_line() +{ + slope=paramstr(4); + +/* if slope='' then fillchar(slope,sizeof(slope),'n');*/ + + if (slope[1]!='1') not_through_bootstrap(); + + if (yn1(2)) syntax(); + + soundfx=yn1(3); + cl_override=yn1(4); + keyboardclick=yn1(5); /* 6 - see below */ + demo=yn1(7); + zoomy=yn1(8); + numlockhold=yn1(9); + use_joy_a=yn1(10); + + { + joysetup& with = js; + + with.xmid=value(paramstr( 5)); + with.ymid=value(paramstr( 6)); + with.xmin=value(paramstr( 7)); + with.ymin=value(paramstr( 8)); + with.xmax=value(paramstr( 9)); + with.ymax=value(paramstr(10)); + with.centre=value(paramstr(11)); + + undo_js(); + } + + switch (slope[6]) { + case 'l': log_setup(paramstr(12),false); break; + case 'p': log_setup(paramstr(12),true); break; + } +} + +void get_extra_data() +{ + if (! reloaded) return; + + move(mem[storage_seg*storage_ofs+300],js,sizeof(js)); + + undo_js(); +} + +class unit_incline_initialize { + public: unit_incline_initialize(); +}; +static unit_incline_initialize incline_constructor; + +unit_incline_initialize::unit_incline_initialize() { +/* writeln('Load code: ',paramstr(1)); + writeln('Seg & ofs: ',paramstr(2),':',paramstr(3)); + writeln('Slope line: ',paramstr(4)); + writeln('Log file: ',paramstr(5)); + writeln('File to load: ',paramstr(6)); + readln;*/ + + filetoload=paramstr(13); + filename_specified = filetoload != ""; + + logging=false; + + if ((paramcount<3) || + ((paramstr(1)!="Go") && (paramstr(1)!="et"))) not_through_bootstrap(); + + reloaded=paramstr(1)=="et"; + + get_storage_addr(); + + get_extra_data(); + + check_slope_line(); +} diff --git a/engines/avalanche/incline.h b/engines/avalanche/incline.h new file mode 100644 index 0000000000..4b252a146e --- /dev/null +++ b/engines/avalanche/incline.h @@ -0,0 +1,10 @@ +#ifndef __incline_h__ +#define __incline_h__ + + + +/* This unit has NO externally-callable procedures. Also note that + it MUST be called *first* (so if you load AVALOT.PAS and press f7 + twice you get to the "begin" statement.) */ + +#endif diff --git a/engines/avalanche/initxf.cpp b/engines/avalanche/initxf.cpp new file mode 100644 index 0000000000..964aa51422 --- /dev/null +++ b/engines/avalanche/initxf.cpp @@ -0,0 +1,32 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + +struct inirex { + varying_string<12> a; + word num; +}; + +text i; +file<inirex> o; +inirex x; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + assign(i,"v:init0.dat"); reset(i); + assign(o,"v:init.avd"); rewrite(o); + + while (! eof(i)) + {; + i >> x.a >> NL; + i >> x.num >> NL; + o << x; + output << '.'; + } + + close(i); close(o); + output << NL; +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/inputtes.cpp b/engines/avalanche/inputtes.cpp new file mode 100644 index 0000000000..0c7300bfc8 --- /dev/null +++ b/engines/avalanche/inputtes.cpp @@ -0,0 +1,47 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +integer gd,gm; +fonttype font; +varying_string<79> current; +char r; + +void plottext() +{ + byte x,y; +; + for( y=0; y <= 7; y ++) + {; + for( x=1; x <= length(current); x ++) + mem[0xa000*12880+y*80+x]=font[current[x]][y]; + fillchar(mem[0xa000*12881+y*80+x],79-x,'\0'); + } +} + +void loadfont() +{ + file<fonttype> f; +; + assign(f,"c:\\thomas\\ttsmall.fnt"); reset(f); + f >> font; close(f); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\turbo"); + loadfont(); + setfillstyle(1,6); bar(0,0,640,200); + current=""; + do { + r=readkey(); + current=current+r; + plottext(); + } while (!false); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/intro.cpp b/engines/avalanche/intro.cpp new file mode 100644 index 0000000000..5d34d69fc9 --- /dev/null +++ b/engines/avalanche/intro.cpp @@ -0,0 +1,596 @@ +#include "ptoc.h" + + +/*$I c:\sleep5\DSMI.INC*/ +/*#include "Dos.h"*/ +#include "graph.h" +/*#include "Crt.h"*/ + + /* This is a stand-alone program. */ + +/* 0, black, remains 0. + Other numbers: the bits take precedence from the left. + e.g. for 9 = 1001, => fourth bit. + + First 1 is in: + + Fourth bit: 63 (egaWhite) + Third bit: 57 (egaLightBlue) + Second bit: 7 (light grey) + First bit: 1 (blue). */ + +const palettetype our_palette = + {16, + /* sic */ +{{ 0, 1, 57, 57, 7, 7, 7, 7, 63, 63, 63, 63, 63, 63, 63, 63}}}; + + const integer scardcount = 13; + + const array<0,scardcount-1,integer> soundcards = + {{1,2,6,3,4,5,8,9,10,7,7,7,7}}; + +typedef matrix<'\0','\377',1,16,byte> fonttype; + +fonttype f; +matrix<0,39,1,16,byte> next_line; + +byte next_bitline; + +byte displaycounter; + +boolean cut_out; + +word cut_out_time; + +array<1,117,varying_string<40> > x; + +byte this_line; + +word* skellern; +boolean nomusic; + +/*$L intro.obj*/ +extern void introduction(); + +void graphmode(integer mode) +{ + registers regs; + + regs.ax=mode; + intr(0x10,regs); +} + +/* Firstly, port[$3C4]:=2; port[$3CF]:=4;, + Then port[$3C5]:=1 shl bit; port[$3CF]:=bit;. */ + +void loadfont() +{ + file<fonttype> ff; + + assign(ff,"avalot.fnt"); + reset(ff); + ff >> f; + close(ff); +} + +void calc_next_line() + /* This proc sets up next_line. */ +{ + string l; + byte fv,ff; + boolean oddlen; + byte start; + byte this_; + + fillchar(next_line,sizeof(next_line),'\0'); /* All blanks. */ + + if (this_line==117) + { + cut_out=true; + return; + } + + l=x[this_line]; + this_line += 1; + + start=(20-length(l) / 2)-1; + oddlen=odd(length(l)); + + for( fv=1; fv <= length(l); fv ++) + for( ff=1; ff <= 16; ff ++) + { + this_=f[l[fv]][ff]; + if (oddlen) + { /* Odd, => 4 bits shift to the right. */ + next_line[start+fv][ff] += this_ << 4; + next_line[start+fv-1][ff] += (cardinal)this_ >> 4; + } else + { /* Even, => no bit shift. */ + next_line[start+fv][ff]=this_; + } + } + next_bitline=1; +} + +void display() +{ + byte fv,ff; + + + if (next_bitline == 17) calc_next_line(); + + if (cut_out) + { + if (nomusic) + cut_out_time -= 1; + else + if (ampgetmodulestatus != md_playing) cut_out_time=0; + return; + } + + move(mem[0xa000*40],mem[0xa000*0],7960); + for( fv=0; fv <= 39; fv ++) + mem[0xa1f1*8+fv]=next_line[fv][next_bitline]; + next_bitline += 1; + +} + +void plot_a_star(integer x,integer y) +{ + byte ofs; + + ofs=x % 8; + x=x / 8; + mem[0xa000*x+y*40] += (cardinal)128 >> ofs; +} + +void plot_some_stars(integer y) +{ + byte fv,times; + + switch (Random(7)) { + case 1: times=1; break; + case 2: times=2; break; + case 3: times=3; break; + default: return; + } + + for( fv=1; fv <= times; fv ++) + plot_a_star(Random(320),y); +} + +void starry_starry_night() +{ + integer y; + byte bit; + + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + + for( bit=0; bit <= 2; bit ++) + { + port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( y=1; y <= 200; y ++) + plot_some_stars(y); + } +} + +void setupgraphics() /* Fix this proc. This prog SHOULDN'T use the + Graph unit. */ +{ + integer gd,gm; + + gd=3; gm=1; initgraph(gd,gm,""); +} + +void shovestars() +{ + move(mem[0xa000*0],mem[0xa000*40],7960); + fillchar(mem[0xa000*0],40,'\0'); + plot_some_stars(0); +} + +void do_next_line() +{ + byte bit; + + port[0x3c4]=2; port[0x3ce]=4; + + for( bit=0; bit <= 3; bit ++) + { + port[0x3c5]=1 << bit; port[0x3cf]=bit; + + switch (bit) { + case 0: if ((displaycounter % 10)==0) shovestars(); break; + case 1: if ((displaycounter % 2)==0) shovestars(); break; + case 2: shovestars(); break; + case 3: display(); break; /* The text. */ + } + } + + if (displaycounter==40) displaycounter=0; + +} + +void load_text() +{ + word fv; + char* c; + byte thisline; + + + c=addr(introduction()); + thisline=0; + fillchar(x,sizeof(x),'\0'); + + for( fv=1; fv <= 2456; fv ++) + { + switch (*c) { + case '\15': thisline += 1; break; + case '\12':/*nop*/; break; + default: x[thisline]=x[thisline]+*c; + } + + c += 1; + } +} + +void check_params() +{ + word s,o; integer e; + + if (paramstr(1)!="jsb") exit(0); + val(paramstr(2),s,e); if (e!=0) exit(0); + val(paramstr(3),o,e); if (e!=0) exit(0); + skellern=ptr(s,o+1); +} + +integer getsoundhardware(psoundcard scard) +{ + integer sc,i,autosel,select; + char ch; + integer e; + + + +integer getsoundhardware_result; +Lagain: + sc=detectgus(scard); + if (sc!=0) sc=detectpas(scard); + if (sc!=0) sc=detectaria(scard); + if (sc!=0) sc=detectsb(scard); + + /* if no sound card found, zero scard */ + if (sc!=0) fillchar(scard,sizeof(tsoundcard),0); + + autosel=-1; +/* if sc=0 then + for i:=0 to scardcount-1 do + if scard^.ID=soundcards[i].ID then begin + { Set auto selection mark } + autosel:=i+1; + break; + end;*/ + + /* Print the list of sound cards */ + + val(paramstr(13),select,e); + + /* Default entry? */ + if (select==0) select=autosel; + if (select!=autosel) { + /* clear all assumptions */ + sc=-1; + fillchar(scard,sizeof(tsoundcard),0); + scard->id=soundcards[select-1]; /* set correct ID */ + } + + /* Query I/O address */ + if (scard->id==id_dac) scard->ioport=0x378; + + /* Read user input */ + val(paramstr(15),i,e); + + if (i!=0) scard->ioport=i; + if (sc!=1) /* Not autodetected */ + switch (scard->id) { + case id_sb16: + case id_pas16: + case id_wss: + case id_aria: + case id_gus : scard->samplesize=2; + break; /* 16-bit card */ + case id_sbpro: + case id_pas: + case id_pasplus: scard->stereo=true; + break; /* enable stereo */ + default: { + scard->samplesize=1; + scard->stereo=false; + } + } + + if (scard->id!=id_dac) { + val(paramstr(17),i,e); + + if (i!=0) scard->dmairq=i; + + val(paramstr(16),i,e); + + if (i!=0) scard->dmachannel=i; + } else { + /* Select correct DAC */ + scard->maxrate=44100; + if (select==11) { + scard->stereo=true; + scard->dmachannel=1; /* Special 'mark' */ + scard->maxrate=60000; + } else + if (select==12) { + scard->stereo=true; + scard->dmachannel=2; + scard->maxrate=60000; + if (scard->ioport==0) scard->ioport=0x378; + } else + if (select==13) { + scard->dmachannel=0; + scard->ioport=0x42; /* Special 'mark' */ + scard->maxrate=44100; + } + } + +/* writeln('Your selection: ',select,' at ',scard^.ioPort, + ' using IRQ ',scard^.dmaIRQ,' and DMA channel ',scard^.dmaChannel); + readln;*/ + + getsoundhardware_result=0; +return getsoundhardware_result; +} + +tsoundcard scard; +tmcpstruct mcpstrc; +tdds dds; +pmodule module; +tsdi_init sdi; +integer e, +bufsize; +char ch; +boolean v86, +vdsok; +longint a,rate, +tempseg; +string answer; +pointer temp; +word flags; +word curch; +byte modulevolume; +array<0,4,tsampleinfo> sample; +array<0,31,word> voltable; + +int main(int argc, const char* argv[]) +{ + + pio_initialize(argc, argv); + check_params(); + + nomusic=paramstr(13)=='0'; + + if (! nomusic) + { + /* Read sound card information */ + if (getsoundhardware(&scard)==-1) exit(1); + + + /* Initialize Timer Service */ + tsinit; + atexit(&tsclose); + if (scard.id==id_gus) { + /* Initialize GUS player */ + #ifndef DPMI + scard.extrafield[2]=1; /* GUS DMA transfer does not work in V86 */ + #endif + gusinit(&scard); + atexit(&gusclose); + + /* Initialize GUS heap manager */ + gushminit; + + /* Init CDI */ + cdiinit; + + /* Register GUS into CDI */ + cdiregister(&cdi_gus,0,31); + + /* Add GUS event player engine into Timer Service */ + tsaddroutine(&gusinterrupt,gus_timer); + } else { + /* Initialize Virtual DMA Specification */ + #ifndef DPMI + vdsok=vdsinit==0; + #else + vdsok=false; + #endif + + fillchar(mcpstrc,sizeof(tmcpstruct),0); + + /* Query for sampling rate */ + val(paramstr(14),a,e); + if (a>4000) rate=a; else rate=21000; + + /* Query for quality */ + mcpstrc.options=mcp_quality; + + switch (scard.id) { + case id_sb : { + sdi=sdi_sb; + scard.maxrate=22000; + } + break; + case id_sbpro : { + sdi=sdi_sbpro; + scard.maxrate=22000; + } + break; + case id_pas: + case id_pasplus: + case id_pas16 : { + sdi=sdi_pas; + scard.maxrate=44100; + } + break; + case id_sb16 : { + sdi=sdi_sb16; + scard.maxrate=44100; + } + break; + case id_aria : { + sdi=sdi_aria; + scard.maxrate=44100; + } + break; + case id_wss : { + sdi=sdi_wss; + scard.maxrate=48000; + } + break; + #ifndef DPMI + case id_dac : sdi=sdi_dac; break; /* Only available in real mode */ + #endif + } + + mcpinitsounddevice(sdi,&scard); + a=mcp_tablesize; + mcpstrc.reqsize=0; + + /* Calculate mixing buffer size */ + bufsize=(longint)(2800*(integer)(scard.samplesize) << (byte)(scard.stereo))* + (longint)(rate) / (longint)(22000); + mcpstrc.reqsize=0; + if ((mcpstrc.options & mcp_quality)>0) + if (scard.samplesize==1) a += mcp_qualitysize; else + a=mcp_tablesize16+mcp_qualitysize16; + if ((longint)(bufsize)+(longint)(a)>65500) bufsize=longint(65500)-a; + + #ifdef DPMI + dpmiversion((byte)(e),(byte)(e),(byte)(e),flags); + v86=(flags & 2)==0; + #endif + + /* Allocate volume table + mixing buffer */ + #ifdef DPMI + + /* In the V86 mode, the buffer must be allocated below 1M */ + if (v86) { + tempseg=0; + dpmiallocdos((a+longint(bufsize)) / longint(16)+longint(1),flags,(word)(tempseg)); + } else { + #endif + getmem(temp,a+longint(bufsize)); + if (temp==nil) exit(2); + #ifdef DPMI + tempseg=seg(temp); + } + #else + tempseg=seg(temp)+ofs(temp) / 16+1; + #endif + mcpstrc.bufferseg=tempseg; + mcpstrc.bufferphysical=-1; + + if (vdsok && (scard.id!=id_dac)) { + dds.size=bufsize; + dds.segment=tempseg; + dds.offset=0; + + /* Lock DMA buffer if VDS present */ + if (vdslockdma(&dds)==0) mcpstrc.bufferphysical=dds.address; + } + if (mcpstrc.bufferphysical==-1) + #ifdef DPMI + mcpstrc.bufferphysical=dpmigetlinearaddr(tempseg); + #else + mcpstrc.bufferphysical=(longint)(tempseg) << 4; + #endif + + mcpstrc.buffersize=bufsize; + mcpstrc.samplingrate=rate; + /* Initialize Multi Channel Player */ + if (mcpinit(&mcpstrc)!=0) exit(3); + atexit(&mcpclose); + + /* Initialize Channel Distributor */ + cdiinit; + + /* Register MCP into CDI*/ + cdiregister(&cdi_mcp,0,31); + } + + /* Try to initialize AMP */ + if (ampinit(0)!=0) exit(3); + atexit(&close); + + /* Hook AMP player routine into Timer Service */ + tsaddroutine(&interrupt,amp_timer); + + #ifndef DPMI + /* If using DAC, then adjust DAC timer */ + if (scard.id==id_dac) setdactimer(tsgettimerrate); + #endif + + if (scard.id!=id_gus) mcpstartvoice; else gusstartvoice; + + /* Load an example AMF */ + module=amploadmod("glover.mod",0); + if (module==nil) exit(4); + + /* Is it MCP, Quality mode and 16-bit card? */ + if ((scard.id!=id_gus) && ((mcpstrc.options & mcp_quality)>0) + && (scard.samplesize==2)) { + /* Open module+2 channels with amplified volumetable (4.7 gain) */ + for( a=1; a <= 32; a ++) voltable[a-longint(1)]=a*longint(150) / longint(32); + cdisetupchannels(0,module->channelcount+2,&voltable); + } else { + /* Open module+2 channels with regular volumetable */ + cdisetupchannels(0,module->channelcount+2,nil); + } + + curch=module->channelcount; + modulevolume=64; + + /***/ ampplaymodule(module,0); + } + + setupgraphics(); + + randseed=177; checkbreak=false; + + load_text(); + + this_line=1; + + graphmode(0xd); + loadfont(); + + next_bitline=17; + displaycounter=0; + + cut_out_time=333; + + setallpalette(our_palette); + + starry_starry_night(); + + while ((cut_out_time>0) && (! keypressed())) + { + + *skellern=0; + + do_next_line(); + + displaycounter += 1; + + do {; } while (!(*skellern>0)); + } + + if (! nomusic) ampstopmodule; + graphmode(3); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/ints.cpp b/engines/avalanche/ints.cpp new file mode 100644 index 0000000000..71c2d47577 --- /dev/null +++ b/engines/avalanche/ints.cpp @@ -0,0 +1,29 @@ +#include "ptoc.h" + + /* Avalot interrupt handler */ +/*#include "Dos.h"*/ + +/*$F+*/ +registers r; +void() old1b; + +boolean quicko; + +void new1b() /* interrupt; */ +{; + quicko=true; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + getintvec(0x1b,&old1b); + setintvec(0x1b,addr(new1b())); + quicko=false; + do {; } while (!quicko); + setintvec(0x1b,&old1b); +/* r.ah:=$02; intr($16,r); + writeln(r.al and 12); { Only checks Ctrl and Alt. Both on = 12. } + until false;*/ +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/joysetup.cpp b/engines/avalanche/joysetup.cpp new file mode 100644 index 0000000000..0c07a35961 --- /dev/null +++ b/engines/avalanche/joysetup.cpp @@ -0,0 +1,97 @@ +#include "ptoc.h" + + /* Avalot joystick setup routines. To be incorporated + into Setup2 whenever I get a chance. */ +/*#include "Joystick.h"*/ +/*#include "Crt.h"*/ + + +struct joysetup { + word xmid,ymid,xmin,ymin,xmax,ymax; + byte centre; /* Size of centre in tenths */ +}; + +joysetup js; +file<joysetup> jf; + +boolean detect() +{ + word x,y,xo,yo; + byte count; +boolean detect_result; +; + count=0; + if (joystickpresent) + {; + detect_result=true; + return detect_result; + } + readjoya(xo,yo); + do { + if (count<7) count += 1; /* Take advantage of "flutter" */ + if (count==6) + {; + output << "The Bios says you don't have a joystick. However, it's often wrong" << NL; + output << "about such matters. So, do you? If you do, move joystick A to" << NL; + output << "continue. If you don't, press any key to cancel." << NL; + } + readjoya(x,y); + } while (!((keypressed()) | (x!=xo) || (y!=yo))); + detect_result=~ keypressed(); +return detect_result; +} + +void display() +{; + {; + gotoxy(20,10); output << "X min: " << js.xmin << " "; + gotoxy(20,11); output << "X max: " << js.xmax << " "; + gotoxy(20,12); output << "Y min: " << js.ymin << " "; + gotoxy(20,13); output << "Y max: " << js.ymax << " "; + } +} + +void getmaxmin() +{ + word x,y; +; + output << "Rotate the joystick around in a circle, as far from the centre as it" << NL; + output << "can get. Then click a button." << NL; + {; + js.xmax=0; js.xmin=maxint; + js.ymax=0; js.ymin=maxint; + } + do { + readjoya(x,y); + {; + if (x<js.xmin) js.xmin=x; + if (y<js.ymin) js.ymin=y; + if (x>js.xmax) js.xmax=x; + if (y>js.ymax) js.ymax=y; + display(); + } + } while (!(buttona1 | buttona2)); + do {; } while (!(~ (buttona1 | buttona2))); + output << NL; + output << "Thank you. Now please centre your joystick and hit a button." << NL; + do {; } while (!(buttona1 | buttona2)); + readjoya(js.xmid,js.ymid); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + textattr=2; + clrscr; + output << "Avalot joystick setup routine- by TT. Thanks go to David B. Howorth." << NL; + output << NL; + if (detect()) output << "You've got a joystick!" << NL; else return 0; + getmaxmin(); + do { + output << "Centring factor\? (3-9)"; + input >> js.centre >> NL; + } while (!(set::of(range(1,9), eos).has(js.centre))); + assign(jf,"v:joytmp.dat"); + rewrite(jf); jf << js; close(jf); /* write it all out to disk. */ +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/joystick.cpp b/engines/avalanche/joystick.cpp new file mode 100644 index 0000000000..20f803ec11 --- /dev/null +++ b/engines/avalanche/joystick.cpp @@ -0,0 +1,183 @@ +#include "ptoc.h" + +#define __joystick_implementation__ + + +/* +Copyright (c) 1989, 1990 David B. Howorth + +Requires Turbo Pascal 5.0 or later. + +Unit last revised May 9, 1989. +This comment last revised October 22, 1990. + +This file, when compiled to disk, creates JOYSTICK.TPU, a Turbo Pascal unit +containing all necessary routines for joystick control. The routines can +be demonstrated by running the accompanying program JOYDEMO (after first +compiling JOYSTICK.PAS to disk). + +For further information see the accompanying file, JOYSTICK.DOC. + +Permission is granted to distribute this file and the accompanying files +(JOYDEMO.PAS and JOYSTICK.DOC) provided (1) all three files are distributed +together and (2) no fee is charged. + +Permission is granted to include compiled versions of the routines in these +files in any program, commercial or noncommercial, provided only that if the +program is distributed, whether commercially or noncommercially, a copy +(including any documentation) be sent to me; and, if you distribute your +program as shareware, treat me as registered. My address is 01960 SW Palatine +Hill Road, Portland, Oregon 97219. +*/ + +#include "joystick.h" + + +/*#include "Dos.h"*/ + + +typedef void(*readjoyproc)(byte a,byte b,word& c,word& d); +typedef boolean(*buttonfunc)(byte a); + +readjoyproc readjoy; +buttonfunc button; +registers reg; + +/*----------------------------- private routines ----------------------------*/ + +boolean newbios() +{ + char decadechar /*absolute $F000:$FFFB*/; + char yearchar /*absolute $F000:$FFFC*/; + + boolean newbios_result; + newbios_result = (set::of('9','0', eos).has(decadechar)) /*an optimistic view of software life*/ + || ((decadechar == '8') && (set::of(range('4','9'), eos).has(yearchar))); + return newbios_result; +} + +/*$F+*/ + +void oldreadjoy(byte xbit,byte ybit, word& xaxis, word& yaxis) +{; +/* +inline( + $BA/$01/$02/ {mov dx, 201h ;load dx with joystick port address } + $C4/$BE/>XAxis/ {les di, XAxis[bp] ;load es with segment and di w/offset } + $8A/$66/<xbit/ {mov ah, xbit[bp] ;set appropriate bit in ah } + $E8/$0C/$00/ {call SUBR } + $C4/$BE/>YAxis/ {les di, YAxis[bp] } + $8A/$66/<ybit/ {mov ah, ybit[bp] ;set appropriate bit in ah } + $E8/$02/$00/ {call SUBR } + $EB/$1D/ {jump short END ;we're done! } + {SUBR: ;first wait, if necessary, until } + { ; relevant bit is 0: } + $B9/$FF/$FF/ { mov cx, 0ffffh ;fill cx to the brim } + $EC/ {WAIT: in al, dx ;get input from port 201h } + $84/$E0/ { test al, ah ;is the relevant bit 0 yet? } + $E0/$FB/ { loopne WAIT ;if not, go back to wait } + + $B9/$FF/$FF/ { mov cx, 0ffffh ;fill cx to the brim again } + $FA/ { cli ;disable interrupts } + $EE/ { out dx, al ;'nudge' port 201h } + $EC/ {AGAIN: in al, dx ;get input from port 201h } + $84/$E0/ { test al, ah ;is the relevant bit 0 yet? } + $E0/$FB/ { loopne AGAIN ;if not, go back to AGAIN } + $FB/ { sti ;reenable interrupts } + $F7/$D9/ { neg cx ;negative cx } + $81/$C1/$FF/$FF/{ add cx, 0ffffh ;add 0ffffh back to value in cx } + $26/ { es: ;segment override } + $89/$0D/ { mov [di], cx ;store value of cx in location } + { ; of relevant variable } + $C3); { ret } + {END: } +*/ +} /* OldReadJoy */ + +void newreadjoy(byte which, byte meaningless, word& xaxis, word& yaxis) +{ + reg.ah = 0x84; + reg.dx = 1; + intr(0x15,reg); + if (which == 1) + { + xaxis = reg.ax; + yaxis = reg.bx; + } + else { + xaxis = reg.cx; + yaxis = reg.dx; + } +} + +boolean oldbutton(byte mask) +{ boolean oldbutton_result; + oldbutton_result = ((port[0x201] & mask) == 0); return oldbutton_result; +} + +boolean newbutton(byte mask) +{ + boolean newbutton_result; + reg.ah = 0x84; + reg.dx = 0; + intr(0x15,reg); + newbutton_result = ((reg.al & mask) == 0); + return newbutton_result; +} + +/*$F-*/ + +/*----------------------------- public routines -----------------------------*/ + +void readjoya(word& xaxis, word& yaxis) +{ readjoy(1,2,xaxis, yaxis); } + +void readjoyb(word& xaxis, word& yaxis) +{ readjoy(4,8,xaxis, yaxis); } + +boolean buttona1() +{ boolean buttona1_result; + buttona1_result = button(0x10); return buttona1_result; +} + +boolean buttona2() +{ boolean buttona2_result; + buttona2_result = button(0x20); return buttona2_result; +} + +boolean buttonb1() +{ boolean buttonb1_result; + buttonb1_result = button(0x40); return buttonb1_result; +} + +boolean buttonb2() +{ boolean buttonb2_result; + buttonb2_result = button(0x80); return buttonb2_result; +} + +boolean joystickpresent() +{ + boolean joystickpresent_result; + intr(0x11,reg); + joystickpresent_result = ((reg.ax & 0x1000) != 0); + return joystickpresent_result; +} + +/*------------------------------ initialization -----------------------------*/ + +class unit_joystick_initialize { + public: unit_joystick_initialize(); +}; +static unit_joystick_initialize joystick_constructor; + +unit_joystick_initialize::unit_joystick_initialize() { + if (newbios()) + { /* use BIOS routines */ + readjoy = newreadjoy; + button = newbutton; + } + else { /* use work-around routines */ + readjoy = oldreadjoy; + button = oldbutton; + } +} diff --git a/engines/avalanche/joystick.h b/engines/avalanche/joystick.h new file mode 100644 index 0000000000..0a3147eda2 --- /dev/null +++ b/engines/avalanche/joystick.h @@ -0,0 +1,22 @@ +#ifndef __joystick_h__ +#define __joystick_h__ + + +void readjoya(word& xaxis, word& yaxis); +/* Reads the X and Y coordinates of Joystick A. */ + +void readjoyb(word& xaxis, word& yaxis); +/* Reads the X and Y coordinates of Joystick B. */ + +boolean buttona1(); +boolean buttona2(); +boolean buttonb1(); +boolean buttonb2(); +/* These four functions return the status (true = in; false = out) of each + of the buttons on joystick A and B. On most models, Button #1 is the + top button. */ + +boolean joystickpresent(); +/* This function indicates whether a joystick is installed. */ + +#endif diff --git a/engines/avalanche/loading.cpp b/engines/avalanche/loading.cpp new file mode 100644 index 0000000000..4e48cb50a0 --- /dev/null +++ b/engines/avalanche/loading.cpp @@ -0,0 +1,23 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; +byte a /*absolute $A000:1200*/; +byte bit; +untyped_file f; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + assign(f,"c:\\sleep\\test.ega"); reset(f,1); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a,12000); + } + close(f); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/logger.cpp b/engines/avalanche/logger.cpp new file mode 100644 index 0000000000..5029dab2ab --- /dev/null +++ b/engines/avalanche/logger.cpp @@ -0,0 +1,210 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + LOGGER Handles the logging. */ + +#define __logger_implementation__ + + +#include "logger.h" + + +/*#include "Gyro.h"*/ +/*#include "Trip5.h"*/ + + +const char divide[] = "--- oOo ---"; + +/* Epson codes: + + startwith=''; + endwith=''; + double_width = #14; { shift out (SO) } + double_off = #20; { device control 4 (DC4) } + italic = #27+'4'; { switches italics on... } + italic_off = #27+'5'; { and off. } + emph_on = #27+#69; + emph_off = #27+#70; + divide_indent = 15; + +*/ + + /* L'jet codes: */ + +const string startwith = string('\33')+'\50'+"10J"+'\130'; +const string endwith = string('\33')+'\105'; +const string italic = string('\33')+'\50'+'\163'+'\61'+'\123'; /* switches italics on... */ +const string italic_off = string('\33')+'\50'+'\163'+'\60'+'\123'; /* and off. */ +const string emph_on = string('\33')+'\50'+'\163'+'\63'+'\102'; +const string emph_off = string('\33')+'\50'+'\163'+'\60'+'\102'; +const string double_width = emph_on; /* There IS no double-width. */ +const string double_off = emph_off; /* So we'll have to use bold. */ +const string quote = 'ª'; +const string unquote = 'º'; +const string copyright = "(c)"; +const integer divide_indent = 30; + +string scroll_line; +byte scroll_line_length; + +void centre(byte size,byte x) /* Prints req'd number of spaces. */ +{ + byte fv; +; + if (~ logging) return; + for( fv=1; fv <= size-(x / 2); fv ++) + output << logfile << ' '; +} + +void log_setup(string name, boolean printing) /* Sets up. */ +{; + assign(logfile,name); + rewrite(logfile); + output << logfile << startwith; + log_epson=printing; + logging=true; + + if (! printing) { quote='"'; unquote='"'; copyright="(c)"; } +} + +void log_divider() /* Prints the divider sign. */ +{ + byte fv; +; + if (~ logging) return; + if (log_epson) + {; + output << logfile << string(' ')+double_width; + for( fv=1; fv <= divide_indent; fv ++) output << logfile << ' '; + output << logfile << string(' ')+double_off; + } else + for( fv=1; fv <= 36; fv ++) output << logfile << ' '; + output << logfile << divide << NL; +} + +void log_command(string x) /* Prints a command */ +{; + if (~ logging) return; + if (log_epson) + output << logfile << double_width+'>'+double_off+' '+italic+x+italic_off << NL; + else + output << logfile << string("> ")+x << NL; +} + +void log_addstuff(string x) +{; + if (~ logging) return; + scroll_line=scroll_line+x; +} + +void log_scrollchar(string x) /* print one character */ +{ + varying_string<2> z; +; + if (~ logging) return; + switch (x[1]) { + case '`': z=quote; break; /* Open quotes: "66" */ + case '"': z=unquote; break; /* Close quotes: "99" */ + case '\357': z=copyright; break; /* Copyright sign. */ + default: z=x; + } + log_addstuff(z); + scroll_line_length += length(z); +} + +void log_italic() +{; + if (~ logging) return; + if (log_epson) + log_addstuff(italic); + else + log_addstuff("*"); +} + +void log_roman() +{; + if (~ logging) return; + if (log_epson) + log_addstuff(italic_off); + else + log_addstuff("*"); +} + +void log_epsonroman() /* This only sends the Roman code if you're on Epson.*/ +{; + if (~ logging) return; + if (log_epson) log_addstuff(italic_off); +} + +void log_scrollline() /* Set up a line for the scroll driver */ +{; + scroll_line_length=0; + scroll_line=""; +} + +void log_scrollendline(boolean centred) +{ + byte x,fv; +; + if (~ logging) return; + x=17; + if (centred) x += (50-scroll_line_length) / 2; + for( fv=1; fv <= x; fv ++) output << logfile << ' '; + output << logfile << scroll_line << NL; +} + +void log_bubbleline(byte linenum,byte whom, string x) +{ + byte fv; +; + if (~ logging) return; + if (linenum==1) + {; + for( fv=1; fv <= 15; fv ++) output << logfile << ' '; + output << logfile << italic+tr[whom].a.name+": "+italic_off+x << NL; + } else + {; + for( fv=1; fv <= 17; fv ++) output << logfile << ' '; + output << logfile << x << NL; + } +} + +void log_newline() +{; + if (logging) output << logfile << NL; +} + +void log_newroom(string where) +{ + byte fv; +; + if (~ logging) return; + for( fv=1; fv <= 20; fv ++) output << logfile << ' '; + if (log_epson) output << logfile << emph_on; + output << logfile << string('(')+where+')'; + if (log_epson) output << logfile << emph_off; + output << logfile << NL; +} + +void log_aside(string what) + /* This writes "asides" to the printer. For example, moves in Nim. */ +{; + if (~ logging) return; + output << logfile << " (" << italic << what << italic_off << ')' << NL; + /* "What" is what to write. */ +} + +void log_score(word credit,word now) +{ + byte fv; +; + if (~ logging) return; + for( fv=1; fv <= 50; fv ++) output << logfile << ' '; + output << logfile << "Score " << italic << "credit : " << credit << italic_off << " total : " << now << NL; +} + + diff --git a/engines/avalanche/logger.h b/engines/avalanche/logger.h new file mode 100644 index 0000000000..016bfb6258 --- /dev/null +++ b/engines/avalanche/logger.h @@ -0,0 +1,33 @@ +#ifndef __logger_h__ +#define __logger_h__ + + +void log_setup(string name, boolean printing); + +void log_divider(); /* Prints the divider sign. */ + +void log_command(string x); /* Prints a command */ + +void log_scrollchar(string x); /* print one character */ + +void log_italic(); + +void log_roman(); + +void log_epsonroman(); + +void log_scrollline(); /* Set up a line for the scroll driver */ + +void log_scrollendline(boolean centred); + +void log_bubbleline(byte linenum,byte whom, string x); + +void log_newline(); + +void log_newroom(string where); + +void log_aside(string what); + +void log_score(word credit,word now); + +#endif diff --git a/engines/avalanche/lucerna.cpp b/engines/avalanche/lucerna.cpp new file mode 100644 index 0000000000..e268ac9ecf --- /dev/null +++ b/engines/avalanche/lucerna.cpp @@ -0,0 +1,1489 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + LUCERNA The screen, [keyboard] and mouse handler. */ + +#define __lucerna_implementation__ + + +#include "lucerna.h" + + +#include "Graph.h" +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ +#include "trip5.h" +#include "Acci.h" +#include "pingo.h" +#include "scrolls.h" +#include "enhanced.h" +#include "dropdown.h" +#include "logger.h" +#include "visa.h" +#include "celer.h" +#include "timeout.h" +#include "basher.h" +#include "sequence.h" + + +/*$V-*/ /*$S-*/ +boolean fxhidden; array<0,3,palettetype> fxpal; + +void callverb(char n) +{ + if (n==pardon) + { + display(string("The f5 key lets you do a particular action in certain ")+ + "situations. However, at the moment there is nothing "+ + "assigned to it. You may press alt-A to see what the "+ + "current setting of this key is."); + } else + { + weirdword=false; polite=true; verb=n; + do_that(); + } +} + +void draw_also_lines() +{ + byte ff; + byte squeaky_code; + + switch (visible) { + case m_virtual : { squeaky_code = 1; off_virtual(); } break; + case m_no : squeaky_code = 2; break; + case m_yes : { squeaky_code = 3; off(); } break; + } + + setactivepage(2); + cleardevice(); + setcolor(15); rectangle(0,45,639,160); + for( ff=1; ff <= 50; ff ++) + { linetype& with = lines[ff]; + if (x1!=maxint) + { + setcolor(with.col); line(x1,y1,x2,y2); + }} + + switch (squeaky_code) { + case 1 : on_virtual(); break; + case 2 :; break; /* zzzz, it was off anyway */ + case 3 : on(); break; + } +} + +void load_also(string n); + +static untyped_file f; + + +static string nextstring() +{ + byte l; string x; + + string nextstring_result; + blockread(f,l,1); blockread(f,x[1],l); x[0]=chr(l); nextstring_result=x; + return nextstring_result; +} + +static void unscramble(); + +static void scram1(string& x) +{ + byte fz; +; + for( fz=1; fz <= length(x); fz ++) + x[fz]=chr(ord(x[fz]) ^ 177); +} + + + +static void unscramble() +{ + byte fv,ff; + + for( fv=0; fv <= 30; fv ++) + for( ff=0; ff <= 1; ff ++) + if (also[fv][ff]!=nil) + scram1(*also[fv][ff]); + scram1(listen); + scram1(flags); +/* for fz:=1 to length(also[fv,ff]^) do + also[fv,ff]^[fz]:=chr(ord(also[fv,ff]^[fz]) xor 177);*/ +} + +void load_also(string n) +{ + byte minnames; byte ff,fv; + + + for( fv=0; fv <= 30; fv ++) + for( ff=0; ff <= 1; ff ++) + if (also[fv][ff]!=nil) { delete also[fv][ff]; also[fv][ff]=nil; } + assign(f,string("also")+n+".avd"); +/*$I-*/ reset(f,1); /*$I+*/ if (ioresult!=0) return; /* no Also file */ + seek(f,128); blockread(f,minnames,1); + for( fv=0; fv <= minnames; fv ++) + { + for( ff=0; ff <= 1; ff ++) + { + also[fv][ff] = new string; + *also[fv][ff]=nextstring(); + } + *also[fv][0]=string('\235')+*also[fv][0]+'\235'; + } + fillchar(lines,sizeof(lines),0xff); + + fv=getpixel(0,0); blockread(f,fv,1); + blockread(f,lines,sizeof(lines[1])*fv); + blockread(f,fv,1); fillchar(peds,sizeof(peds),'\261'); + blockread(f,peds,sizeof(peds[1])*fv); + blockread(f,numfields,1); blockread(f,fields,sizeof(fields[1])*numfields); + blockread(f,magics,sizeof(magics)); + blockread(f,portals,sizeof(portals)); + blockread(f,flags,sizeof(flags)); + blockread(f,listen[0],1); + blockread(f,listen[1],length(listen)); + draw_also_lines(); + + setactivepage(1); close(f); + unscramble(); + for( fv=0; fv <= minnames; fv ++) + *also[fv][0]=string(',')+*also[fv][0]+','; +} + +void load(byte n) /* Load2, actually */ +{ + byte a0; /*absolute $A000:800;*/ + byte a1; /*absolute $A000:17184;*/ + byte bit; + untyped_file f; varying_string<2> xx; + boolean was_virtual; + + was_virtual=visible==m_virtual; + if (was_virtual) off_virtual(); else off(); + clear_vmc(); + + xx=strf(n); flesh_colours(); + assign(f,string("place")+xx+".avd"); reset(f,1); + seek(f,146); blockread(f,roomname,30); + /* Compression method byte follows this... */ + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); move(a0,a1,12080); + } + close(f); load_also(xx); load_chunks(xx); + + copy03(); bit=getpixel(0,0); + log_newroom(roomname); + + if (was_virtual) on_virtual(); else on(); +} + +void zoomout(integer x,integer y) +{ + integer x1,y1,x2,y2; + byte fv; + + setcolor(white); setwritemode(xorput); + setlinestyle(dottedln,0,1); + + for( fv=1; fv <= 20; fv ++) + { + x1=x-(x / 20)*fv; + y1=y-((y-10) / 20)*fv; + x2=x+(((639-x) / 20)*fv); + y2=y+(((161-y) / 20)*fv); + + rectangle(x1,y1,x2,y2); + delay(17); + rectangle(x1,y1,x2,y2); + } + setwritemode(copyput); setlinestyle(0,0,1); +} + +void find_people(byte room) +{ + char fv; + + for( fv='\227'; fv <= '\262'; fv ++) + if (whereis[fv]==room) + { + if (fv<'\257') him=fv; else her=fv; + } +} + +void exitroom(byte x) +{ + nosound; + forget_chunks(); + seescroll=true; /* This stops the trippancy system working over the + length of this procedure. */ + + { dnatype& with = dna; + switch (x) { + case r__spludwicks: { + lose_timer(reason_avariciustalks); + /* He doesn't HAVE to be talking for this to work. It just deletes it IF it + exists. */ with.avaricius_talk=0; + } + break; + case r__bridge: if (with.drawbridge_open>0) + { + with.drawbridge_open=4; /* Fully open. */ + lose_timer(reason_drawbridgefalls); + } + break; + case r__outsidecardiffcastle: lose_timer(reason_cardiffsurvey); break; + + case r__robins: lose_timer(reason_getting_tied_up); break; + }} + + interrogation=0; /* Leaving the room cancels all the questions automatically. */ + + seescroll=false; /* Now it can work again! */ + + dna.last_room=dna.room; + if (dna.room!=r__map) + dna.last_room_not_map=dna.room; +} + +void new_town() /* You've just entered a town from the map. */ +{ + standard_bar(); + + switch (dna.room) { + case r__outsidenottspub: /* Entry into Nottingham. */ + if ((dna.rooms[r__robins]>0) && (dna.been_tied_up) && + (! dna.taken_mushroom)) + dna.mushroom_growing=true; + break; + case r__wisewomans: /* Entry into Argent. */ + { + if (dna.talked_to_crapulus && (! dna.lustie_is_asleep)) + { + dna.spludwicks_here=! ((dna.rooms[r__wisewomans] % 3)==1); + dna.crapulus_will_tell=! dna.spludwicks_here; + } else + { + dna.spludwicks_here=true; + dna.crapulus_will_tell=false; + } + if (dna.box_contents==wine) dna.winestate=3; /* Vinegar */ + } + break; + } + + if (dna.room!=r__outsideducks) + { + if ((dna.obj[onion]) && ! (dna.onion_in_vinegar)) + dna.rotten_onion=true; /* You're holding the onion */ + } +} + +void enterroom(byte x,byte ped); + +static void put_geida_at(byte whichped, byte& ped) +{ + if (ped==0) return; + tr[2].init(5,false); /* load Geida */ + apped(2,whichped); + tr[2].call_eachstep=true; + tr[2].eachstep=procgeida_procs; +} + +void enterroom(byte x,byte ped) +{ + + seescroll=true; /* This stops the trippancy system working over the + length of this procedure. */ + + find_people(x); + dna.room=x; if (ped!=0) dna.rooms[x] += 1; + + load(x); + + if ((dna.rooms[x]==0) && (! flagset('S'))) points(1); + whereis[pavalot]=dna.room; + if (dna.geida_follows) whereis[pgeida]=x; + roomtime=0; + + { dnatype& with = dna; + if ((with.last_room==r__map) && (with.last_room_not_map!=with.room)) + new_town();} + + switch (x) { + case r__yours: if (dna.avvy_in_bed) + { + show_one(3); + set_up_timer(100,procarkata_shouts,reason_arkata_shouts); + } + break; + + case r__outsideyours: if (ped>0) + { + if (! dna.talked_to_crapulus) + { + + whereis[pcrapulus]=r__outsideyours; + tr[2].init(8,false); /* load Crapulus */ + + if (dna.rooms[r__outsideyours]==1) + { + apped(2,4); /* Start on the right-hand side of the screen. */ + tr[2].walkto(5); /* Walks up to greet you. */ + } else + { + apped(2,5); /* Starts where he was before. */ + tr[2].face=3; + } + + tr[2].call_eachstep=true; + tr[2].eachstep=procface_avvy; /* He always faces Avvy. */ + + } else whereis[pcrapulus]=r__nowhere; + + if (dna.crapulus_will_tell) + { + tr[2].init(8,false); + apped(2,2); + tr[2].walkto(4); + set_up_timer(20,proccrapulus_splud_out,reason_crapulus_says_spludwick_out); + dna.crapulus_will_tell=false; + } + } + break; + + case r__outsidespludwicks: + if ((dna.rooms[r__outsidespludwicks]==1) && (ped==1)) + { + set_up_timer(20,procbang,reason_explosion); + dna.spludwicks_here=true; + } + break; + + case r__spludwicks: + if (dna.spludwicks_here) + { + if (ped>0) + { + tr[2].init(2,false); /* load Spludwick */ + apped(2,2); + whereis['\227']=r__spludwicks; + } + + dna.dogfoodpos = 0; /* Also Spludwick pos. */ + + tr[2].call_eachstep =true; + tr[2].eachstep=procgeida_procs; + } else whereis['\227']=r__nowhere; + break; + + case r__brummieroad: + { + if (dna.geida_follows) put_geida_at(5, ped); + if (dna.cwytalot_gone) + { + magics[lightred].op=nix; + whereis[pcwytalot]=r__nowhere; + } else + { + if (ped>0) + { + tr[2].init(4,false); /* 4=Cwytalot*/ + tr[2].call_eachstep=true; + tr[2].eachstep=procfollow_avvy_y; + whereis[pcwytalot]=r__brummieroad; + + if (dna.rooms[r__brummieroad]==1) /* First time here... */ + { + apped(2,2); /* He appears on the right of the screen... */ + tr[2].walkto(4); /* ...and he walks up... */ + } else + { /* You've been here before. */ + apped(2,4); /* He's standing in your way straight away... */ + tr[2].face=left; + } + } + } + } + break; + + case r__argentroad: + { dnatype& with = dna; + if ((with.cwytalot_gone) && (! with.cwytalot_in_herts) && (ped==2) && + (dna.rooms[r__argentroad]>3)) + { + tr[2].init(4,false); /* 4=Cwytalot again*/ + apped(2,1); + tr[2].walkto(2); + tr[2].vanishifstill=true; + with.cwytalot_in_herts=true; + /*whereis[#157]:=r__Nowhere;*/ /* can we fit this in? */ + set_up_timer(20,proc_cwytalot_in_herts,reason_cwytalot_in_herts); + }} + break; + + case r__bridge: + { + if (dna.drawbridge_open==4) /*open*/ + { + show_one(3); /* Position of drawbridge */ + magics[green].op=nix; /* You may enter the drawbridge. */ + } + if (dna.geida_follows) put_geida_at(ped+3, ped); /* load Geida */ + } + break; + + case r__robins: + { + if (ped>0) + { + if (! dna.been_tied_up) + { /* A welcome party... or maybe not... */ + tr[2].init(6,false); + apped(2,2); + tr[2].walkto(3); + set_up_timer(36,procget_tied_up,reason_getting_tied_up); + } + } + + if (dna.been_tied_up) + { + whereis[probinhood]=0; whereis[pfriartuck]=0; + } + + if (dna.tied_up) show_one(2); + + if (! dna.mushroom_growing) show_one(3); + } + break; + + case r__outsidecardiffcastle: + { + if (ped>0) + switch (dna.cardiff_things) { + case 0 : { /* You've answered NONE of his questions. */ + tr[2].init(9,false); + apped(2,2); + tr[2].walkto(3); + set_up_timer(47,proccardiffsurvey,reason_cardiffsurvey); + } + break; + case 5 : magics[2].op=nix; break; /* You've answered ALL his questions. => nothing happens. */ + default: { /* You've answered SOME of his questions. */ + tr[2].init(9,false); + apped(2,3); + tr[2].face=right; + set_up_timer(3,proccardiff_return,reason_cardiffsurvey); + } + } + if (dna.cardiff_things<5) + interrogation=dna.cardiff_things; else interrogation=0; + } + break; + + case r__map: + { /* You're entering the map. */ + dawn(); setactivepage(cp); + if (ped>0) zoomout(peds[ped].x,peds[ped].y); + setactivepage(1-cp); + + { dnatype& with = dna; + if ((with.obj[wine]) && (with.winestate!=3)) + { + dixi('q',9); /* Don't want to waste the wine! */ + with.obj[wine]=false; + objectlist(); + }} + + dixi('q',69); + } + break; + + case r__catacombs: + { + if (set::of(0,3,5,6, eos).has(ped)) + { + dnatype& with = dna; + + switch (ped) { + case 3 : { with.cat_x=8; with.cat_y=4; } break; /* Enter from oubliette */ + case 5 : { with.cat_x=8; with.cat_y=7; } break; /* Enter from du Lustie's */ + case 6 : { with.cat_x=4; with.cat_y=1; } break; /* Enter from Geida's */ + } + dna.enter_catacombs_from_lusties_room=true; + catamove(ped); + dna.enter_catacombs_from_lusties_room=false; + } + } + break; + + case r__argentpub: { + if (dna.wonnim) show_one(1); /* No lute by the settle. */ + dna.malagauche=0; /* Ready to boot Malagauche */ + if (dna.givenbadgetoiby) + { show_one(8); show_one(9); } + } + break; + + case r__lustiesroom: { + dna.dogfoodpos=1; /* Actually, du Lustie pos. */ + if (tr[1].whichsprite==0) /* Avvy in his normal clothes */ + set_up_timer(3,proccallsguards,reason_du_lustie_talks); + else + if (! dna.entered_lusties_room_as_monk) /*already*/ + /* Presumably, Avvy dressed as a monk. */ + set_up_timer(3,procgreetsmonk,reason_du_lustie_talks); + + if (dna.geida_follows) + { + put_geida_at(5, ped); + if (dna.lustie_is_asleep) show_one(5); + } + } + break; + + case r__musicroom: { + if (dna.jacques_awake>0) + { + dna.jacques_awake=5; + show_one(2); + show_one(4); + magics[brown].op=nix; + whereis[pjacques]=0; + } + if (ped!=0) + { + show_one(6); + first_show(5); then_show(7); + start_to_close(); + } + } + break; + + case r__outsidenottspub: if (ped==2) + { + show_one(3); first_show(2); + then_show(1); then_show(4); + start_to_close(); + } + break; + + case r__outsideargentpub: if (ped==2) { + show_one(6); + first_show(5); then_show(7); + start_to_close(); + } + break; + + case r__wisewomans: { + tr[2].init(11,false); + if ((dna.rooms[r__wisewomans]==1) && (ped>0)) + { + apped(2,2); /* Start on the right-hand side of the screen. */ + tr[2].walkto(4); /* Walks up to greet you. */ + } else + { + apped(2,4); /* Starts where she was before. */ + tr[2].face=3; + } + + tr[2].call_eachstep=true; + tr[2].eachstep=procface_avvy; /* She always faces Avvy. */ + } + break; + + case r__insidecardiffcastle: + if (ped>0) + { + tr[2].init(10,false); /* Define the dart. */ + first_show(1); + if (dna.arrow_in_the_door) then_show(3); else then_show(2); + if (dna.taken_pen) show_one(4); + start_to_close(); + } else + { + show_one(1); + if (dna.arrow_in_the_door) show_one(3); else show_one(2); + } + break; + + case r__avvysgarden: if (ped==1) { + show_one(2); + first_show(1); then_show(3); + start_to_close(); + } + break; + + case r__entrancehall:case r__insideabbey: if (ped==2) { + show_one(2); + first_show(1); then_show(3); + start_to_close(); + } + break; + + case r__aylesoffice: if (dna.ayles_is_awake) show_one(2); break; /* Ayles awake. */ + + case r__geidas: put_geida_at(2, ped); break; /* load Geida */ + + case r__easthall:case r__westhall: if (dna.geida_follows) put_geida_at(ped+2, ped); break; + + case r__lusties: if (dna.geida_follows) put_geida_at(ped+6, ped); break; + + case r__nottspub: { + if (dna.sitting_in_pub) show_one(3); + dna.dogfoodpos=1; /* Actually, du Lustie pos. */ + } + break; + + case r__outsideducks: if (ped==2) + { /* Shut the door */ + show_one(3); + first_show(2); then_show(1); + then_show(4); start_to_close(); + } + break; + case r__ducks: dna.dogfoodpos=1; break; /* Actually, Duck pos. */ + + } + + seescroll=false; /* Now it can work again! */ + +} + +void thinkabout(char z, boolean th) /* Hey!!! Get it and put it!!! */ +{ + const integer x = 205; const integer y = 170; const integer picsize = 966; + const bytefield thinkspace = + {25, 170, 32, 200}; + untyped_file f; pointer p; byte fv; + + + thinks=z; z -= 1; + + if (th) + { /* Things */ + assign(f,"thinks.avd"); wait(); getmem(p,picsize); + reset(f,1); seek(f,ord(z)*picsize+65); blockread(f,p,picsize); off(); + close(f); + } else + { /* People */ + assign(f,"folk.avd"); + wait(); + getmem(p,picsize); + reset(f,1); + + fv=ord(z)-149; + if (fv>=25) fv -= 8; + if (fv==20) fv -= 1; /* Last time... */ + + seek(f,fv*picsize+65); + blockread(f,p,picsize); + off(); + close(f); + } + + setactivepage(3); + putimage(x,y,p,0); + setactivepage(1-cp); + + for( fv=0; fv <= 1; fv ++) + getset[fv].remember(thinkspace); + + freemem(p,picsize); + on(); thinkthing=th; +} + +void load_digits() /* Load the scoring digits & rwlites */ +{ + const integer digitsize = 134; + const integer rwlitesize = 126; + untyped_file f; char fv; byte ff; + + assign(f,"digit.avd"); reset(f,1); + for( fv='0'; fv <= '9'; fv ++) + { + getmem(digit[fv],digitsize); blockread(f,digit[fv],digitsize); + } + for( ff=0; ff <= 8; ff ++) + { + getmem(rwlite[ff],rwlitesize); blockread(f,rwlite[ff],rwlitesize); + } + close(f); +} + +void toolbar() +{ + untyped_file f; word s; byte fv; pointer p; + + assign(f,"useful.avd"); reset(f,1); + s=filesize(f)-40; getmem(p,s); + seek(f,40); + blockread(f,p,s); + close(f); +/* off;*/ + + setcolor(15); /* (And sent for chrysanthemums...) Yellow and white. */ + setfillstyle(1,6); + for( fv=0; fv <= 1; fv ++) + { + setactivepage(fv); putimage(5,169,p,0); + if (demo) + { + bar(264,177,307,190); + outtextxy(268,188,"Demo!"); /* well... actually only white now. */ + } + } + +/* on;*/ + freemem(p,s); + oldrw=177; showrw(); +} + +void showscore() +{ + const bytefield scorespace = {33, 177, 39, 200}; + varying_string<3> q; byte fv; + + if (demo) return; + + str(dna.score,q); while (q[0]<'\3') q=string('0')+q; off(); + setactivepage(3); + for( fv=1; fv <= 3; fv ++) + if (lastscore[fv]!=q[fv]) + putimage(250+fv*15,177,digit[q[fv]],0); + + for( fv=0; fv <= 1; fv ++) + getset[fv].remember(scorespace); + + setactivepage(1-cp); + on(); lastscore=q; +} + +void points(byte num) /* Add on no. of points */ +{ + byte q,fv; + + for( q=1; q <= num; q ++) + { + dna.score += 1; + if (soundfx) for( fv=1; fv <= 97; fv ++) sound(177+dna.score*3); nosound; + } + log_score(num,dna.score); showscore(); +} + +void topcheck() +{ + { menuset& with = ddm_m; /* Menuset */ + getmenu(mpx);} /* Do this one */ +} + +void mouseway() +{ + byte col; + + off(); col=getpixel(mx,my); on(); + { triptype& with = tr[1]; + { dnatype& with1 = dna; + switch (col) { + case green: { dna.rw=up; rwsp(1,up); showrw(); } break; + case brown: { dna.rw=down; rwsp(1,down); showrw(); } break; + case cyan: { dna.rw=left; rwsp(1,left); showrw(); } break; + case lightmagenta: { dna.rw=right; rwsp(1,right); showrw(); } break; + case red:case white:case lightcyan:case yellow: { stopwalking(); showrw(); } break; + }}} +} + +void inkey() +{ + char r; + + + if (demo) return; /* Demo handles this itself. */ + + if (mousetext=="") + { /* read keyboard */ + readkeye(); + if ((inchar==' ') && ((shiftstate & 8)>0)) + { + inchar='\0'; extd='#'; /* alt-spacebar = alt-H */ + } + } else + { + if (mousetext[1]=='`') mousetext[1]='\15'; /* Backquote = return in a macro */ + inchar=mousetext[1]; mousetext=copy(mousetext,2,255); + } +} + +void posxy() +{ + varying_string<3> xs,ys; + + setfillstyle(1,0); setcolor(10); + do { + check(); + if (mpress==1) + { + str(mx,xs); str(my,ys); + off(); bar(400,160,500,168); + outtextxy(400,168,xs); outtextxy(440,168,string(": ")+ys); on(); + } + } while (!(my==0)); + bar(400,161,640,168); +} + +void fxtoggle() +{ + byte page_; + const bytefield soundled = + {52, 175, 55, 177}; + + soundfx=! soundfx; + if (soundfx) + { + if (! fxhidden) + { /* ...but *not* when the screen's dark. */ + sound(1770); delay(77); nosound; + } + setfillstyle(1,cyan); + } else + setfillstyle(1,black); + setactivepage(3); bar(419,175,438,177); + setactivepage(1-cp); + for( page_=0; page_ <= 1; page_ ++) getset[page_].remember(soundled); +} + +void objectlist() +{ + char fv; + + dna.carrying=0; + if (thinkthing && ! dna.obj[thinks]) + thinkabout(money,a_thing); /* you always have money */ + for( fv='\1'; fv <= numobjs; fv ++) + if (dna.obj[fv]) + { + dna.carrying += 1; objlist[dna.carrying]=fv; + } +} + +void verte() +{ + byte what; + + if (! dna.user_moves_avvy) return; + { + triptype& with = tr[1]; /* that's the only one we're interested in here */ + + + if (mx<(cardinal)with.x) what=1; else + if (mx>(unsigned char)(with.x+with.a.xl)) what=2; else + what=0; /* On top */ + + if (my<(cardinal)with.y) what += 3; else + if (my>(unsigned char)(with.y+with.a.yl)) what += 6; + + switch (what) { + case 0: stopwalking(); break; /* Clicked on Avvy- no movement */ + case 1: rwsp(1,left); break; + case 2: rwsp(1,right); break; + case 3: rwsp(1,up); break; + case 4: rwsp(1,ul); break; + case 5: rwsp(1,ur); break; + case 6: rwsp(1,down); break; + case 7: rwsp(1,dl); break; + case 8: rwsp(1,dr); break; + } /* no other values are possible... */ + + showrw(); + + } +} + +void checkclick() +{ + bytefield b; + + check(); ontoolbar=slow_computer && ((my>=169) || (my<=10)); + + if (mrelease>0) after_the_scroll=false; + switch (my) { + case RANGE_11(0,10): newpointer(1); + break; /* up arrow */ + case RANGE_11(159,169): newpointer(8); + break; /* I-beam */ + case 170 ... 200: newpointer(2); break; /* screwdriver */ + default: + { + if (! ddmnow) /* Dropdown can handle its own pointers. */ + { + if (((keystatus & 1)==1) && (my>=11) && (my<=158)) + { + newpointer(7); /* Mark's crosshairs */ + verte(); + /* Normally, if you click on the picture, you're guiding Avvy around. */ + } else + newpointer(4); /* fletch */ + } + } + } + + if (mpress>0) + { + switch (mpy) { + case RANGE_11(0,10): if (dropsok) topcheck(); + break; + case 11 ... 158: if (! dropsok) + mousetext=string('\15')+mousetext; + break; /* But otherwise, it's + equivalent to pressing Enter. */ + case RANGE_11(159,169): { /* Click on command line */ + cursor_off(); curpos=(mx-16) / 8; + if (curpos>length(current)+1) curpos=length(current)+1; + if (curpos<1) curpos=1; + cursor_on(); + } + break; + case 170 ... 200: switch (mpx) { /* bottom check */ + case 0 ... 207: mouseway(); break; + case 208 ... 260: { /* Examine the thing */ + do { check(); } while (!(mrelease>0)); + if (thinkthing) + { + thing=thinks; thing += 49; + person=pardon; + } else + { + person=thinks; + thing=pardon; + } + callverb(vb_exam); + } + break; + case 261 ... 319: { + do { checkclick(); } while (!(mrelease>0)); + callverb(vb_score); + } + break; + case 320 ... 357: { tr[1].xs=walk; newspeed(); } break; + case 358 ... 395: { tr[1].xs=run; newspeed(); } break; + case 396 ... 483: fxtoggle(); break; /* "sound" */ +/* 484..534: begin { clock } + off; if getpixel(mx,my)=14 then mousetext:='#'+mousetext; on; + end;*/ + case 535 ... 640: mousetext=string('\15')+mousetext; break; + } + break; + } + } + +/* if mrelease>0 then + begin + if (cw<>177) and (mry>10) then + begin to_do:=(((mrx-20) div 100)*20)+(mry div 10); closewin; end; + end;*/ +} + +void mouse_init() +{ + r.ax=0; + intr(0x33,r); /* Returns- no. keys in bx and whether present in ax. */ + wait(); +} + +void mousepage(word page_) +{ + boolean onstate,wason; + + if (visible!=m_virtual) + { + onstate=oncandopageswap; + oncandopageswap=false; + wason=visible==m_yes; + if (wason) off(); + { + void& with = r; ax=29; bx=page_; } intr(0x33,r); + if (wason) on(); + oncandopageswap=onstate; + } +} + +void errorled() +{ + byte fv; + + state(0); + for( fv=0; fv <= 1; fv ++) + { + setactivepage(fv); + off(); setfillstyle(1,red); bar(419,184,438,186); on(); + } + for( fv=177; fv >= 1; fv --) + { + sound(177+(fv*177177) / 999); + delay(1); nosound; + } + for( fv=0; fv <= 1; fv ++) + { + setactivepage(fv); + off(); setfillstyle(1,black); bar(419,184,438,186); on(); + } + state(defaultled); setactivepage(1-cp); +} + +shortint fades(shortint x) +{ + byte r,g,b; + + shortint fades_result; + r=x / 16; x=x % 16; + g=x / 4; b=x % 4; + if (r>0) r -= 1; if (g>0) g -= 1; if (b>0) b -= 1; + fades_result=(16*r+4*g+b); +/* fades:=x-1;*/ + return fades_result; +} + +void dusk(); + +static void fadeout(byte n) +{ + byte fv; + + getpalette(fxpal[n]); + for( fv=1; fv <= fxpal[n].size-1; fv ++) + fxpal[n].colors[fv]=fades(fxpal[n].colors[fv]); + setallpalette(fxpal[n]); + /*delay(50);*/ slowdown(); +} + +void dusk() +{ + byte fv; + + setbkcolor(0); + if (fxhidden) return; fxhidden=true; + getpalette(fxpal[0]); for( fv=1; fv <= 3; fv ++) fadeout(fv); +} + +void dawn(); + +static void fadein(byte n) +{ + setallpalette(fxpal[n]); + /*delay(50);*/ slowdown(); +} + +void dawn() +{ + byte fv; + + if ((holdthedawn) || (! fxhidden)) return; fxhidden=false; + for( fv=3; fv >= 0; fv --) fadein(fv); + { dnatype& with = dna; + if ((with.room==r__yours) && (with.avvy_in_bed) && (with.teetotal)) background(14);} +} + +void showrw() +{ + byte page_; + + { + dnatype& with = dna; + + if (oldrw==with.rw) return; + oldrw=with.rw; off(); + for( page_=0; page_ <= 1; page_ ++) + { + setactivepage(page_); putimage(0,161,rwlite[with.rw],0); + } on(); + setactivepage(1-cp); + } +} + +void mblit(byte x1,byte y1,byte x2,byte y2, byte f,byte t) /* assembler; */ +/* The Minstrel Blitter */ +/* asm +{ ofsfr:=f*$4000+x1+y1*80; + ofsto:=t*$4000+x1+y1*80;} + + mov bx,80; { We're multiplying by 80. } + mov al,y1; + mul bl; { AX now contains y1*80. } + xor cx,cx; { Zero CX. } + mov cl,x1; { CX now equals x1 } + add ax,cx; { AX now contains x1+y1*80. } + mov si,ax; + mov di,ax; + + mov ax,$4000; + mov bl,f; + mul bx; { Note that this is a *word*! } + add si,ax; + + mov ax,$4000; + mov bl,t; + mul bx; { Note that this is a *word*! } + add di,ax; + + push ds; { *** <<<< *** WE MUST PRESERVE THIS! } + cld; { Clear Direction flag - we're going forwards! } + + mov ax,$A000; { The screen memory. } + mov ds,ax; + mov es,ax; { The same. } + + { AH stores the number of bytes to copy. } + { len:=(x2-x1)+1; } + + mov ah,x2; + sub ah,x1; + inc ah; + + { Firstly, let's decide how many times we're going round. } + + mov cl,y2; { How many numbers between y1 and y2? } + sub cl,y1; + inc cl; { Inclusive reckoning (for example, from 3 to 5 is 5-3+1=3 turns. } + + { We'll use SI and DI to be Ofsfr and Ofsto. } + + @Y_axis_loop: + push cx; + + + { OK... We've changed this loop from a for-next loop. "Bit" is + represented by CX. } + +{ port[$3c4]:=2; port[$3ce]:=4; } + mov dx,$3c4; + mov al,2; + out dx,al; + mov dx,$3ce; + mov al,4; + out dx,al; + + mov cx,4; { We have to copy planes 3, 2, 1 and Zero. We'll add 1 to the + number, because at zero it stops. } + + mov bx,3; { This has a similar function to that of CX. } + + @start_of_loop: + + push cx; + +{ port[$3C5]:=1 shl bit; } + mov dx,$3C5; + mov al,1; + mov cl,bl; { BL = bit. } + shl al,cl; + out dx,al; +{ port[$3CF]:=bit; } + mov dx,$3CF; + mov al,bl; { BL = bit. } + out dx,al; + +{ move(mem[$A000:ofsfr],mem[$A000:ofsto],len); } + + xor ch,ch; { Clear CH. } + mov cl,ah; + + repz movsb; { That's all we need to say! } + + mov cl,ah; + sub si,cx; { This is MUCH, MUCH faster than pushing and popping them! } + sub di,cx; + + pop cx; { Get the loop count back again. } + dec bx; { One less... } + loop @start_of_loop; { Until cx=0. } + + add si,80; { Do the next line... } + add di,80; + + pop cx; + loop @Y_axis_loop; + + pop ds; { Get it back again (or we'll be in trouble with TP!) } +*/ +{; +} + +void blitfix() +{ + byte fv; + + fv=getpixel(0,0); /* perform read & so cancel Xor effect! */ +} + +void clock(); +const integer xm = 510; +const integer ym = 183; +static arccoordstype ah,am; +static word nh; + +static void calchand(word ang,word length, arccoordstype& a, byte c) +{ + if (ang>900) { a.xend=177; return; } + setcolor(c); arc(xm,ym,449-ang,450-ang,length); getarccoords(a); +} + + +static void hand(arccoordstype a, byte c) +{ + if (a.xend==177) return; + setcolor(c); + line(xm,ym,a.xend,a.yend); /* "With a do-line???!", Liz said. */ +} + + +static void chime() +{ + word gd,gm,fv; + + if ((oh==17717) || (! soundfx)) return; /* too high- must be first time around */ + fv=h % 12; if (fv==0) fv=12; wait(); + for( gd=1; gd <= fv; gd ++) + { + for( gm=1; gm <= 3; gm ++) + { + sound((gd % 3)*64+140-gm*30); delay(50-gm*12); + } + nosound; if (gd!=fv) delay(100); + } +} + + + +static void refresh_hands() +{ + const bytefield clockspace = {61, 166, 66, 200}; + byte page_; + + for( page_=0; page_ <= 1; page_ ++) + getset[page_].remember(clockspace); +} + + + +static void plothands() +{ +/* off;*/ + setactivepage(3); + calchand(onh,14,ah,yellow); calchand(om*6,17,am,yellow); + hand(ah,brown); hand(am,brown); + calchand(nh,14,ah,brown); calchand(m*6,17,am,brown); + hand(ah,yellow); hand(am,yellow); + setactivepage(1-cp); + + refresh_hands(); + +/* on;*/ +} + +void clock() +{ /* ...Clock. */ + gettime(h,m,s,s1); + nh=(h % 12)*30+m / 2; + if (oh!=h) { plothands(); chime(); } + if (om!=m) plothands(); + if ((h==0) && (oh!=0) && (oh!=17717)) + display(string("Good morning!\r\rYes, it's just past midnight. Are you having")+ + " an all-night Avvy session? Glad you like the game that much!"); + oh=h; onh=nh; om=m; +} + +void flip_page() +{ + if (! ddm_o.menunow) + { + cp=1-cp; + setvisualpage(cp); + setactivepage(1-cp); + /*mousepage(cp);*/ + } + +} + +void delavvy() +{ + byte page_; + + off(); + { triptype& with = tr[1]; + for( page_=0; page_ <= 1; page_ ++) + mblit(with.x / 8,with.y,(with.x+with.a.xl) / 8+1,with.y+with.a.yl,3,page_);} + blitfix(); + on(); +} + +void gameover() +{ + byte fv; integer sx,sy; + + dna.user_moves_avvy=false; + + sx=tr[1].x; + sy=tr[1].y; + { + triptype& with = tr[1]; + + done(); + init(12,true); /* 12 = Avalot falls */ + tr[1].step=0; + appear(sx,sy,0); + } + set_up_timer(3,procavalot_falls,reason_falling_over); +/* display(^m^m^m^m^m^m^i^i^i^i^i^i^s'Z'^v);*/ + alive=false; +} + +/* OK. There are two kinds of redraw: Major and Minor. Minor is what happens + when you load a game, etc. Major redraws EVERYTHING. */ + +void minor_redraw() +{ + byte fv; + + dusk(); + enterroom(dna.room,0); /* Ped unknown or non-existant. */ + + for( fv=0; fv <= 1; fv ++) + { + cp=1-cp; + getback(); + } + + { + dnatype& with = dna; + + lastscore="TJA"; /* impossible digits */ + showscore(); + } + + dawn(); +} + +void major_redraw() +{ + byte fv; + + dusk(); + setactivepage(0); cleardevice(); + + toolbar(); + copy03(); + + enterroom(dna.room,0); /* 0 = ped unknown or non-existant. */ + for( fv=0; fv <= 1; fv ++) { cp=1-cp; getback(); } + + om=177; + clock(); + + thinkabout(thinks,thinkthing); standard_bar(); + soundfx=! soundfx; fxtoggle(); + for( fv=0; fv <= 1; fv ++) { cp=1-cp; getback(); } + plottext(); + ledstatus=177; state(2); + + { + dnatype& with = dna; + + lastscore="TJA"; /* impossible digits */ + showscore(); + } + + dawn(); +} + +word bearing(byte whichped) + /* Returns the bearing from ped Whichped to Avvy, in degrees. */ +{ + const real rad2deg = 180/pi; + + word bearing_result; + { pedtype& with = peds[whichped]; + if (tr[1].x==with.x) + bearing_result=0; /* This would cause a division by zero if we let it through. */ + else + /* + bearing:=trunc(((arctan((tr[1].y-y)/(tr[1].x-x)))*rad2deg)+90) mod 360*/ + { + if (tr[1].x<with.x) + bearing_result=trunc(atan((real)((tr[1].y-with.y))/(tr[1].x-with.x))*rad2deg)+90; + else + bearing_result=trunc(atan((real)((tr[1].y-with.y))/(tr[1].x-with.x))*rad2deg)+270; + }} + return bearing_result; +} + +void flesh_colours() /* assembler; +asm + mov ax,$1012; + mov bx,21; { 21 = light pink (why?) } + mov cx,1; + mov dx,seg @flesh; + mov es,dx; + mov dx,offset @flesh; + int $10; + + mov dx,seg @darkflesh; + mov es,dx; + mov dx,offset @darkflesh; + mov bx,5; { 5 = dark pink. } + int $10; + + jmp @TheEnd; + + @flesh: + db 56,35,35; + + @darkflesh: + db 43,22,22; + + @TheEnd: */ +{; +} + +void sprite_run() + /* A sprite run is performed before displaying a scroll, if not all the + sprites are still. It performs two fast cycles, only using a few of + the links usually used, and without any extra animation. This should + make the sprites the same on both pages. */ +{ + byte fv; + + + doing_sprite_run=true; + + for( fv=0; fv <= 1; fv ++) + { + get_back_loretta(); + trippancy_link(); + + flip_page(); + } + + doing_sprite_run=false; + +} + +void fix_flashers() +{ ledstatus=177; oldrw=177; state(2); showrw(); } + +class unit_lucerna_initialize { + public: unit_lucerna_initialize(); +}; +static unit_lucerna_initialize lucerna_constructor; + +unit_lucerna_initialize::unit_lucerna_initialize() { + fxhidden=false; oh=17717; om=17717; + if (atbios) atkey="f1"; else atkey="alt-"; +} diff --git a/engines/avalanche/lucerna.h b/engines/avalanche/lucerna.h new file mode 100644 index 0000000000..a602f8c026 --- /dev/null +++ b/engines/avalanche/lucerna.h @@ -0,0 +1,76 @@ +#ifndef __lucerna_h__ +#define __lucerna_h__ + + +#include "gyro.h" + + + void callverb(char n); + + void draw_also_lines(); + + void mouse_init(); + + void mousepage(word page_); + + void load(byte n); + + void exitroom(byte x); + + void enterroom(byte x,byte ped); + + void thinkabout(char z, boolean th); /* Hey!!! Get it and put it!!! */ + + void load_digits(); /* Load the scoring digits & rwlites */ + + void toolbar(); + + void showscore(); + + void points(byte num); /* Add on no. of points */ + + void mouseway(); + + void inkey(); + + void posxy(); + + void fxtoggle(); + + void objectlist(); + + void checkclick(); + + void errorled(); + + void dusk(); + + void dawn(); + + void showrw(); + + void mblit(byte x1,byte y1,byte x2,byte y2, byte f,byte t); /* The Minstrel Blitter */ + + void blitfix(); + + void clock(); + + void flip_page(); + + void delavvy(); + + void gameover(); + + void minor_redraw(); + + void major_redraw(); + + word bearing(byte whichped); + + void flesh_colours(); + + void sprite_run(); + + void fix_flashers(); + +#endif diff --git a/engines/avalanche/magic2.cpp b/engines/avalanche/magic2.cpp new file mode 100644 index 0000000000..03f54d04fe --- /dev/null +++ b/engines/avalanche/magic2.cpp @@ -0,0 +1,37 @@ +#include "ptoc.h" + + +#include "graph.h" + + +const longint pagetop = 81920; +const word nextcode = 17717; + +integer gd,gm; +file<word> magic,out; +word next,gg; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + assign(magic,"v:magicirc.avd"); reset(magic); + assign(out,"v:magic2.avd"); rewrite(out); + move(mem[0xa000*0],mem[0xa000*pagetop],16000); + while (! eof(magic)) + {; + magic >> next; + if (next!=nextcode) + mem[0xa000*next]=255; + else + {; + for( gg=0; gg <= 16000; gg ++) + if (mem[0xa000*gg]!=mem[0xa000*gg+pagetop]) + out << gg; + out << nextcode; + move(mem[0xa000*0],mem[0xa000*pagetop],16000); + } + } + close(magic); close(out); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/magidraw.cpp b/engines/avalanche/magidraw.cpp new file mode 100644 index 0000000000..282eb5d189 --- /dev/null +++ b/engines/avalanche/magidraw.cpp @@ -0,0 +1,34 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + + +const word nextcode = 17717; + +integer gd,gm; +untyped_file magic; /* of word;*/ +word next; +array<1,16401,word> buffer; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + assign(magic,"v:magic2.avd"); reset(magic,1); + blockread(magic,buffer,sizeof(buffer)); + close(magic); +/* while not eof(magic) do*/ + for( gd=1; gd <= 16401; gd ++) + {; +/* read(magic,next); + if next<>nextcode then*/ + if (buffer[gd]!=nextcode) + mem[0xa000*buffer[gd]]=255; + else + delay(1); + } +/* close(magic);*/ +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/magishuf.cpp b/engines/avalanche/magishuf.cpp new file mode 100644 index 0000000000..09db4d286d --- /dev/null +++ b/engines/avalanche/magishuf.cpp @@ -0,0 +1,60 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ + + +const word nextcode = 17717; + +typedef array<1,8000,word> big; +typedef array<1,16401,word> circle; + +big b; +file<big> f; +registers r; +word gd; +circle c; +file<circle> fc; + +void melt(byte c) +{; + for( gd=1; gd <= 8000; gd ++) + {; + mem[0xa000*b[gd]]=c; + if ((gd % 17)==0) delay(1); + } +} + +void magicirc(byte cc) +{; + for( gd=1; gd <= 16401; gd ++) + {; + if (c[gd]!=nextcode) + {; + if (odd(c[gd])) mem[0xa000*c[gd] / 2]=cc; + } else + delay(1); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + r.ax=13; intr(0x10,r); + assign(f,"d:shuffle.avd"); reset(f); f >> b; close(f); + assign(fc,"v:magic2.avd"); reset(fc); fc >> c; close(fc); +/* repeat + melt(170); magicirc(85); + magicirc(170); melt(85); + magicirc(170); magicirc(85); + melt(170); melt(85); + until keypressed;*/ + do { + melt(255); magicirc(0); + magicirc(255); melt(0); + magicirc(255); magicirc(0); + melt(255); melt(0); + } while (!keypressed()); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/make!.cpp b/engines/avalanche/make!.cpp new file mode 100644 index 0000000000..447f540b8a --- /dev/null +++ b/engines/avalanche/make!.cpp @@ -0,0 +1,62 @@ +#include "ptoc.h" + + /* Phew! */ +#include "graph.h" + +/*$S-*/ +integer gd,gm; +untyped_file f; +text t; +string x; + +boolean subpix(integer x,integer y) +{boolean subpix_result; +; + subpix_result=getpixel(x,y)==15; +return subpix_result; +} + +byte pixel(integer x,integer y) +{byte pixel_result; +; + pixel_result=(byte)( + subpix(x*4,y*2) || + subpix(x*4+1,y*2) || + subpix(x*4+2,y*2) || + subpix(x*4+3,y*2) || + subpix(x*4,y*2+1) || + subpix(x*4+1,y*2+1) || + subpix(x*4+2,y*2+1) || + subpix(x*4+3,y*2+1) + )*15; +return pixel_result; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=1; initgraph(gd,gm,"o:"); + assign(f,"v:logo.avd"); reset(f,1); + for( gd=0; gd <= 180; gd ++) + blockread(f,mem[0xa000*(gd*80)],53); + close(f); + for( gd=1; gd <= 106; gd ++) + for( gm=0; gm <= 145; gm ++) + putpixel(gd,gm+181,pixel(gd,gm)); + assign(t,"d:avalot.txt"); + rewrite(t); + for( gm=1; gm <= 36; gm ++) + {; + x=""; + for( gd=1; gd <= 106; gd ++) + switch (getpixel(gd,gm*2+181)*2+getpixel(gd,gm*2+182)) { + case 0: x=x+' '; break; + case 15: x=x+'Ü'; break; + case 30: x=x+'ß'; break; + case 45: x=x+'Û'; break; + } + t << x << NL; + } + close(t); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/makeregi.cpp b/engines/avalanche/makeregi.cpp new file mode 100644 index 0000000000..574d346660 --- /dev/null +++ b/engines/avalanche/makeregi.cpp @@ -0,0 +1,142 @@ +#include "ptoc.h" + + /* regname's name starts at $7D1 (2001). */ + +const array<1,56,char> padding = +"For all the Etruscan armies were ranged beneath his eye"; + +text txi,txo; +string x,y; +word fv; +file<byte> f; +byte sum,n; +string name,number; + +string chkname,chknum,regname,regnum; + + + char decode1(char c) + { + byte b; + + char decode1_result; + b=ord(c)-32; + decode1_result=chr(( (b & 0xf) << 3) + ((cardinal)(b & 0x70) >> 4)); + return decode1_result; + } + + char encode1(char c) + { + byte b; + + char encode1_result; + b=ord(c); + b=( (cardinal)(b & 0x78) >> 3) + ((b & 0x7) << 4); + encode1_result=chr(b+32); + return encode1_result; + } + + char encode2(char c) + { + char encode2_result; + encode2_result=chr((((ord(c) & 0xf) << 2)+0x43)); + return encode2_result; + } + + string enc1(string x) + { + string y; byte fv; + + string enc1_result; + y=x; for( fv=1; fv <= length(y); fv ++) y[fv]=encode1(y[fv]); + enc1_result=y; + return enc1_result; + } + + string enc2(string x) + { + string y; byte fv; + + string enc2_result; + y=x; for( fv=1; fv <= length(y); fv ++) y[fv]=encode2(y[fv]); + enc2_result=y; + return enc2_result; + } + + boolean checker(string proper,string check) + { + byte fv; boolean ok; + + boolean checker_result; + ok=true; + for( fv=1; fv <= length(proper); fv ++) + if ((ord(proper[fv]) & 0xf)!=((cardinal)(ord(check[fv])-0x43) >> 2)) + ok=false; + + checker_result=ok; + return checker_result; + } + + void unscramble() + { + byte namelen,numlen; + + + namelen=107-ord(x[1]); numlen=107-ord(x[2]); + + regname=copy(x,3,namelen); + regnum=copy(x,4+namelen,numlen); + chkname=copy(x,4+namelen+numlen,namelen); + chknum=copy(x,4+namelen+numlen+namelen,numlen); + + for( fv=1; fv <= namelen; fv ++) regname[fv]=decode1(regname[fv]); + for( fv=1; fv <= numlen; fv ++) regnum[fv]=decode1(regnum[fv]); + + if ((! checker(regname,chkname)) || (! checker(regnum,chknum))) + { + output << "CHECK ERROR: " << regname << '/' << chkname << ';' << regnum << '/' << chknum << '.' << NL; + exit(0); + } else output << "--- Passed both checks. ---" << NL; + } + +int main(int argc, const char* argv[]) +{ + + pio_initialize(argc, argv); + output << "Name? "; input >> name >> NL; + output << "Number? "; input >> number >> NL; + + x=string(chr(107-ord(name[0])))+chr(107-ord(number[0])); + + + x=x+enc1(name)+'J'+enc1(number)+enc2(name)+enc2(number); + + number=""; fv=1; + while ((length(number)+length(x))<57) + { + number=number+padding[fv-1]; fv=fv+1; + } + x=x+enc1(number); + + + output << x << NL; output << NL; + unscramble(); + + assign(txi,"v:register.raw"); reset(txi); + assign(txo,"a:register.dat"); rewrite(txo); + + for( fv=1; fv <= 53; fv ++) + { + txi >> y >> NL; txo << y << NL; + } + + txi >> y >> NL; txo << x << NL; + + while (! eof(txi)) + { + txi >> y >> NL; txo << y << NL; + } + + close(txi); close(txo); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/makesez.cpp b/engines/avalanche/makesez.cpp new file mode 100644 index 0000000000..50e58109e6 --- /dev/null +++ b/engines/avalanche/makesez.cpp @@ -0,0 +1,47 @@ +#include "ptoc.h" + + + +struct sezheader { + array<1,2,char> initials; /* should be "TT" */ + word gamecode; + word revision; /* as 3- or 4-digit code (eg v1.00 = 100) */ + longint chains; /* number of scroll chains */ + longint size; /* total size of all scroll chains */ +}; + +const string crlf = string('\15')+'\12'; +const string tabs = string('\11')+'\11'+'\11'+'\11'+'\11'+'\11'+'\11'; +const char eof_ = '\32'; + +untyped_file sez; +sezheader header; +string x; +char check; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + fillchar(x,sizeof(x),'\261'); + x=string("This is a Sez file for an Avvy game, and its contents are subject")+crlf+ + "to copyright. Have fun with the game!"+crlf+crlf+tabs+"tt"+crlf+crlf+ + "[Lord Avalot D'Argent]"+crlf+crlf+eof_+ + crlf+crlf+"Thomas was here!"; + {; + header.initials="TT"; + header.gamecode=2; /* code for Avalot */ + header.revision=100; /* version 1.00 */ + header.chains=0; /* no chains */ + header.size=0; /* empty! */ + } + check='\261'; + assign(sez,"avalot.sez"); + rewrite(sez,1); + blockwrite(sez,x[1],255); + blockwrite(sez,header,sizeof(header)); + blockwrite(sez,check,1); + x=string('\0')+'\0'+'\0'+"Thomas was here, too!"+crlf+crlf+"Good luck..."; + blockwrite(sez,x[1],39); /* footer */ + close(sez); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/makevmou.cpp b/engines/avalanche/makevmou.cpp new file mode 100644 index 0000000000..5ed388531c --- /dev/null +++ b/engines/avalanche/makevmou.cpp @@ -0,0 +1,270 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Squeak.h"*/ +/*#include "Crt.h"*/ + +/*$R+*/ + +struct mp { /* mouse-pointer */ + matrix<0,1,0,15,word> mask; + integer horzhotspot,verthotspot; +}; + +struct vmctype { /* Virtual Mouse Cursor */ + pointer andpic,xorpic; + array<0,1,pointer> backpic; + array<0,1,pointtype> wherewas; + byte picnumber; + shortint ofsx,ofsy; +}; + +const array<1,9,arrowtype> mps = +{{{ /* 1 - up-arrow */ + ((65151,64575,64575,63519,63519,61455,61455,57351,57351,49155,49155,64575,64575,64575,64575,64575), + (0,384,384,960,960,2016,2016,4080,4080,8184,384,384,384,384,384,0)), + 8, + 0}, + +{ /* 2 - screwdriver */ + ((8191,4095,2047,34815,50175,61951,63743,64543,65039,65031,65027,65281,65408,65472,65505,65523), + (0,24576,28672,12288,2048,1024,512,256,224,176,216,96,38,10,12,0)), + 0, + 0}, + +{ /* 3 - right-arrow */ + ((65535,65535,64639,64543,7,1,0,1,7,64543,64639,65535,65535,65535,65535,65535), + (0,0,0,384,480,32760,32766,32760,480,384,0,0,0,0,0,0)), + 15, + 6}, + +{ /* 4 - fletch */ + ((255,511,1023,2047,1023,4607,14591,31871,65031,65283,65281,65280,65280,65409,65473,65511), + (0,10240,20480,24576,26624,17408,512,256,128,88,32,86,72,20,16,0)), + 0, + 0}, + +{ /* 5 - hourglass */ + ((0,0,0,34785,50115,61455,61455,63519,63519,61839,61455,49155,32769,0,0,0), + (0,32766,16386,12300,2064,1440,1440,576,576,1056,1440,3024,14316,16386,32766,0)), + 8, + 7}, + +{ /* 6 - TTHand */ + ((62463,57855,57855,57855,57471,49167,32769,0,0,0,0,32768,49152,57344,61441,61443), + (3072,4608,4608,4608,4992,12912,21070,36937,36873,36865,32769,16385,8193,4097,2050,4092)), + 4, + 0}, + +{ /* 7- Mark's crosshairs */ + ((65535,65151,65151,65151,65151,0,65151,65151,65151,65151,65535,65535,65535,65535,65535,65535), + (0,384,384,384,384,65535,384,384,384,384,0,0,0,0,0,0)), + 8, + 5}, + +{ /* 8- I-beam. */ + ((65535,65535,63631,63503,63503,65087,65087,65087,65087,65087,63503,63503,63631,65535,65535,65535), + (0,0,0,864,128,128,128,128,128,128,128,864,0,0,0,0)), + 8, + 7}, + +{ /* 9- Question mark. */ + ((511,1023,2047,31,15,8199,32647,65415,63503,61471,61503,61695,63999,63999,61695,61695), + (65024,33792,34816,34784,40976,57224,32840,72,1936,2080,2496,2304,1536,1536,2304,3840)), + 0, + 0}}}; + +const integer mouse_size = 134; + +const array<1,134,char> mice_header = + string("Mouse file copyright (c) 1993. I saw a mouse! Where? SQUEEAAAKK!!! Cheese ")+ /* 74 */ + "cheese cheese. Cheddar, Stilton, Double Gloucester. Squeak."+'\32'; /* 60 */ + +integer gd,gm; +matrix<0,50,1,40,word> a /*absolute $A000:0i*/; +byte fv; +vmctype vmc; +byte plot; integer plx,ply; + +word swapbits(word a) +{word swapbits_result; +; + swapbits_result=lo(a)*256+hi(a); +return swapbits_result; +} + +void plot_vmc(integer xx,integer yy, byte page_) +{; + {; + xx=xx+vmc.ofsx; + yy=yy+vmc.ofsy; + + getimage(xx,yy,xx+15,yy+15,vmc.backpic[page_]); + putimage(xx,yy,vmc.andpic,andput); + putimage(xx,yy,vmc.xorpic,xorput); + { + pointtype& with1 = vmc.wherewas[page_]; + ; + with1.x=xx; + with1.y=yy; + } + } +} + +void wipe_vmc(byte page_) +{; + { pointtype& with1 = vmc.wherewas[page_]; + if (with1.x!=maxint) + putimage(with1.x,with1.y,vmc.backpic[page_],0);} +} + +void setup_vmc() +{ + byte fv; +; +/* gd:=imagesize(0,0,15,15);*/ + + {; + getmem(vmc.andpic,mouse_size); + getmem(vmc.xorpic,mouse_size); + + for( fv=0; fv <= 1; fv ++) + {; + getmem(vmc.backpic[fv],mouse_size); + vmc.wherewas[fv].x=maxint; + } + } +} + +void show_off_mouse() +{; + + setcolor(14); settextstyle(0,0,2); + + for( gm=0; gm <= 1; gm ++) + {; + setactivepage(gm); + setfillstyle(1,blue); bar(0,0,getmaxx(),getmaxy()); + outtextxy(400,20,chr(48+gm)); + } + + gd=0; + do { + setactivepage(gd); + setvisualpage(1-gd); + gd=1-gd; + + delay(56); + + getbuttonstatus; + wipe_vmc(gd); + + if (plot>0) + {; + putpixel(plx,ply,red); + plot -= 1; + } + + plot_vmc(mx,my,gd); + + if ((mkey==left) && (plot==0)) + {; + plot=2; + plx=mx; + ply=my; + } + + } while (!(mkey==right)); + + for( gm=0; gm <= 1; gm ++) + {; + setactivepage(1-gm); + wipe_vmc(gm); + } + + setvisualpage(0); + setactivepage(0); +} + +void grab_cursor(byte n) +{; + getimage(32*n-16, 0,32*n-1,15,vmc.andpic); + getimage(32*n-16,20,32*n-1,35,vmc.xorpic); +} + +void save_mice() +{ + untyped_file f; + byte fv; +; + assign(f,"v:mice.avd"); + rewrite(f,1); + + blockwrite(f,mice_header,mouse_size); + + for( fv=1; fv <= 9; fv ++) + {; + grab_cursor(fv); + putimage(100,100,vmc.xorpic,0); + blockwrite(f,vmc.andpic,mouse_size); + blockwrite(f,vmc.xorpic,mouse_size); + } + + close(f); +} + +void load_a_mouse(byte which) +{ + untyped_file f; +; + assign(f,"v:mice.avd"); + reset(f,1); + seek(f,mouse_size*2*(which-1)+134); + + {; + blockread(f,vmc.andpic,mouse_size); + blockread(f,vmc.xorpic,mouse_size); + close(f); + { + void& with1 = mps[which]; + ; + vmc.ofsx=-horzhotspot; + vmc.ofsy=-verthotspot; + + setminmaxhorzcurspos(horzhotspot,624+horzhotspot); + setminmaxvertcurspos(verthotspot,199); + } + } + +} + +void draw_mouse_cursors() +{; + for( fv=1; fv <= 9; fv ++) + for( gm=0; gm <= 1; gm ++) + for( gd=0; gd <= 15; gd ++) + a[gd+gm*20][fv*2]=swapbits(mps[fv].mask[gm][gd]); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + resetmouse; + setup_vmc(); + + draw_mouse_cursors(); + + + save_mice(); + +/* grab_cursor(3);*/ +/* load_a_mouse(4); + setgraphicscursor(mps[4]); + + show_off_mouse; + on; repeat getbuttonstatus until mkey=left; off; + show_off_mouse;*/ +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/menuxf.cpp b/engines/avalanche/menuxf.cpp new file mode 100644 index 0000000000..1919b118de --- /dev/null +++ b/engines/avalanche/menuxf.cpp @@ -0,0 +1,48 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; + +void load() /* Load2, actually */ +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; + + assign(f,"maintemp.avd"); reset(f,1); + /* Compression method byte follows this... */ + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + bit=getpixel(0,0); +} + +void save() +{ + byte bit; untyped_file f; + + assign(f,"v:mainmenu.avd"); + rewrite(f,1); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,mem[0xa000*48*80],59*80); + } + close(f); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + gd=3; gm=1; initgraph(gd,gm,""); + load(); /* Between 48 and 107. */ + + save(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/minstran.cpp b/engines/avalanche/minstran.cpp new file mode 100644 index 0000000000..824fc806bc --- /dev/null +++ b/engines/avalanche/minstran.cpp @@ -0,0 +1,37 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; +pointer p; word s; + +void mblit(integer x1,integer y1,integer x2,integer y2) /* Minstrel Blitter */ +{ + integer yy,len,pp; byte bit; const integer offset = 16384; +; + x1=x1 / 8; len=((x2 / 8)-x1)+1; + for( yy=y1; yy <= y2; yy ++) + {; + pp=yy*80+x1; + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(mem[0xa000*offset+pp],mem[0xa000*pp],len); + } + } +} + +const integer fx1 = 100; const integer fy1 = 100; const integer fx2 = 135; const integer fy2 = 145; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + setactivepage(1); setfillstyle(7,9); bar(0,0,640,200); + mblit(fx1,fy1,fx2,fy2); + s=imagesize(fx1,fy1,fx2,fy2); getmem(p,s); + getimage(fx1,fy1,fx2,fy2,p); setactivepage(0); + putimage(fx1+100,fy1,p,0); freemem(p,s); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/newsprit.cpp b/engines/avalanche/newsprit.cpp new file mode 100644 index 0000000000..073e546f25 --- /dev/null +++ b/engines/avalanche/newsprit.cpp @@ -0,0 +1,124 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + + +const string crlf = string('\15')+'\12'; const char eof_ = '\32'; +const array<1,177,char> trip5head = + string("Sprite*.AVD ... data file for Trippancy Five")+crlf+crlf+ + "[Thorsoft relocatable fiveplane sprite image format]"+crlf+crlf+ + "Thomas Thurman was here. ... Have fun!"+crlf+crlf+eof_+ + "±±±±±±± * G. I. E. D. ! * "; + +const array<1,4,char> tripid = string('\x30')+'\x1'+'\x75'+'\261'; + +const array<1,50,char> trip5foot = crlf+crlf+ + " and that's it! Enjoy the game. "+'\3'+crlf+crlf+ + "\n\n\n\n\n\n\n"+"tt"; + +struct adxotype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +struct adxtype { + varying_string<12> name; /* name of character */ + varying_string<16> comment; /* comment */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ + byte accinum; /* the number according to Acci (1=Avvy, etc.) */ +}; + +varying_string<2> sn; +adxotype oa; +adxtype a; +matrix<1,24,0,1,pointer> pic; /* the pictures themselves */ +array<1,16000,byte> aa; +untyped_file out; +integer bigsize; + +void copyaoa() +{; + {; + a.name=oa.name; + a.comment="Transferred"; + a.num=oa.num; + a.xl=oa.xl; + a.yl=oa.yl; + a.seq=oa.seq; + a.size=oa.size; + a.fgc=oa.fgc; + a.bgc=oa.bgc; + } +} + +void setup() +{ + integer gd,gm; +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); +} + +string strf(longint x) +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +void save() +{ + byte sort,n; + word fv,ff; char r; byte xw; + byte nxl,nyl; + word soa; +; + cleardevice(); + {; + a.xl=45; a.yl=10; a.num=1; a.seq=1; + a.size=imagesize(0,0,a.xl,a.yl); + soa=sizeof(a); + + assign(out,"v:sprite10.avd"); rewrite(out,1); + blockwrite(out,trip5head,177); + blockwrite(out,tripid,4); + blockwrite(out,soa,2); + blockwrite(out,a,soa); + + nxl=a.xl; nyl=a.yl; + xw=nxl / 8; + if ((nxl % 8)>0) xw += 1; + + for( n=1; n <= a.num; n ++) + {; + getimage( 0,0,a.xl,a.yl,aa); + for( fv=0; fv <= nyl; fv ++) + blockwrite(out,aa[5+fv*xw*4],xw); + + getimage(100,0,100+a.xl,a.yl,aa); + blockwrite(out,aa[5],a.size-6); + } + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + setup(); + save(); + + blockwrite(out,trip5foot,50); + close(out); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/nim.cpp b/engines/avalanche/nim.cpp new file mode 100644 index 0000000000..e5da17adff --- /dev/null +++ b/engines/avalanche/nim.cpp @@ -0,0 +1,381 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Dos.h"*/ + + +const array<false,true,varying_string<7> > names = {{"Avalot","Dogfood"}}; + +array<1,3,byte> old,stones; +array<0,3,0,22,1,7,byte> stonepic; /* picture of Nimstone */ +byte turns; +boolean dogfoodsturn; byte fv; byte stonesleft; + +boolean clicked; + +byte row,number; + +boolean squeak; +shortint mnum,mrow; + +registers r; + +void resetmouse() +{; + r.ax=0; intr(0x33,r); + squeak=r.ax>0; +} + +void show() +{; + r.ax=1; intr(0x33,r); +} + +void hide() +{; + r.ax=2; intr(0x33,r); +} + +void chalk(integer x,integer y, string z) +{ + const array<0,3,byte> greys = {{0,8,7,15}}; + byte fv; +; + for( fv=0; fv <= 3; fv ++) + {; + setcolor(greys[fv]); + outtextxy(x-fv,y,z); + sound(fv*100*length(z)); delay(3); nosound; delay(30); + } +} + +void setup() +{ + untyped_file f; + integer gd,gm; + byte bit; +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + + assign(f,"c:\\avalot\\nim.avd"); + reset(f,1); + seek(f,41); + for( gm=0; gm <= 22; gm ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,stonepic[bit][gm],7); + } + for( gd=1; gd <= 3; gd ++) + for( gm=0; gm <= 22; gm ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,mem[0xa000*3200+gd*2800+gm*80],7); + } + for( gm=0; gm <= 36; gm ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,mem[0xa000*400+49+gm*80],30); + } + close(f); + + gd=getpixel(0,0); /* clear codes */ + setcolor(4); rectangle(394,50,634,197); + setfillstyle(1,6); bar(395,51,633,196); + rectangle(10,5,380,70); bar(11,6,379,69); + setcolor(15); + outtextxy(475,53,"SCOREBOARD:"); + setcolor(14); + outtextxy(420,63,"Turn:"); + outtextxy(490,63,"Player:"); + outtextxy(570,63,"Move:"); + + for( gd=1; gd <= 3; gd ++) stones[gd]=gd+2; + + turns=0; dogfoodsturn=true; + + chalk(27,15,"Take pieces away with:"); + chalk(77,25,"1) the mouse (click leftmost)"); + chalk(53,35,"or 2) the keyboard:"); + chalk(220,35,string('\30')+'/'+'\31'+": choose row,"); + chalk(164,45,string("+/- or ")+'\33'+'/'+'\32'+": more/fewer,"); + chalk(204,55,"Enter: take stones."); + + row=1; number=1; fillchar(old,sizeof(old),'\0'); stonesleft=12; + resetmouse(); +} + +void plotstone(byte x,byte y) +{ + byte fv,bit; word ofs; +; + ofs=3200+y*2800+x*8; + for( fv=0; fv <= 22; fv ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(stonepic[bit][fv],mem[0xa000*ofs+fv*80],7); + } +} + +void board() +{ + byte fv,ff; +; + for( fv=1; fv <= 3; fv ++) + for( ff=1; ff <= stones[fv]; ff ++) + plotstone(ff,fv); +} + +void startmove() +{ + varying_string<2> tstr; integer ypos; +; + turns += 1; str(turns,2,tstr); ypos=63+turns*10; + dogfoodsturn=! dogfoodsturn; + chalk(433,ypos,tstr); + chalk(493,ypos,names[dogfoodsturn]); + old=stones; +} + +void show_changes() +{ + byte fv,ff,fq; +; + chalk(573,63+turns*10,string(chr(64+row))+chr(48+number)); + for( fv=1; fv <= 3; fv ++) + if (old[fv]>stones[fv]) + for( ff=stones[fv]+1; ff <= old[fv]; ff ++) + for( fq=0; fq <= 22; fq ++) fillchar(mem[0xa000*3200+fv*2800+ff*8+fq*80],7,'\0'); + stonesleft -= number; +} + +void checkmouse(); + +static void blip() {; sound(1771); delay(3); nosound; clicked=false; } + +void checkmouse() +{; + {; ax=5; bx=0; } intr(0x33,r); + clicked=r.bx>0; + if (clicked) + {; /* The mouse was clicked. Where? */ + mrow=(dx-38) / 35; + if ((mrow<1) || (mrow>3)) blip(); + mnum=stones[mrow]-(cx / 64)+1; + if ((mnum<1) || (mnum>(unsigned char)stones[mrow])) blip(); + } +} + +void takesome(); + +static void less() {; if (number>1) number -= 1; } + +void takesome() +{ + char r; byte sr; +; + number=1; + do { + do { + sr=stones[row]; + if (sr==0) {; row=row % 3+1; number=1; } + } while (!(sr!=0)); + if (number>sr) number=sr; + setcolor(1); rectangle(63+(sr-number)*64,38+35*row,54+sr*64,63+35*row); + /* Wait for choice */ + show(); + do { checkmouse(); } while (!(keypressed() || clicked)); + if (keypressed()) r=upcase(readkey()); + hide(); + + setcolor(0); rectangle(63+(sr-number)*64,38+35*row,54+sr*64,63+35*row); + + if (clicked) + {; + number=mnum; + row=mrow; + return; + } else + {; + switch (r) { + case '\0': switch (readkey()) { + case 'H': if (row>1) row -= 1; break; /* Up */ + case 'P': if (row<3) row += 1; break; /* Down */ + case 'K': number += 1; break; + case 'M': less(); break; + case 'I': row=1; break; /* PgUp */ + case 'Q': row=3; break; /* PgDn */ + case 'G': number=5; break; /* Home- check routine will knock this down to size */ + case 'O': number=1; break; /* End */ + } + break; + case '+': number += 1; break; + case '-': less(); break; + case RANGE_3('A','C'): row=ord(r)-64; + break; + case RANGE_5('1','5'): number=ord(r)-48; + break; + case '\15': return; break; /* Enter was pressed */ + } + } + } while (!false); +} + +void endofgame() +{ + char rr; +; + chalk(595,63+turns*10,"Wins!"); + outtextxy(100,190,"- - - Press any key... - - -"); + while (keypressed()) rr=readkey(); + do { ax=5; bx=0; intr(0x33,r); } while (!(keypressed() || (bx>0))); + if (keypressed()) rr=readkey(); +} + +void dogfood(); + /* AI procedure to play the game */ +const matrix<1,3,1,2,byte> other = {{{{2,3}},{{1,3}},{{1,2}}}}; + + +static byte live,fv,ff,matches,thisone,where; + +static array<1,3,byte> r,sr; +static array<1,3,boolean> inap; + +static boolean lmo; /* Let Me Out! */ + +static byte ooo; /* Odd one out */ + + +static boolean find(byte x) + /* This gives True if there's a pile with x stones in. */ +{ + boolean q; byte p; +boolean find_result; +; + q=false; + for( p=1; p <= 3; p ++) if (stones[p]==x) {; q=true; inap[p]=true; } + find_result=q; +return find_result; +} + + + +static void find_ap(byte start,byte stepsize) +{ + byte ff; +; + matches=0; + fillchar(inap,sizeof(inap),'\0'); /* blank 'em all */ + for( ff=0; ff <= 2; ff ++) if (find(start+ff*stepsize)) matches += 1; + else thisone=ff; + + /* Now.. Matches must be 0, 1, 2, or 3. + 0/1 mean there are no A.P.s here, so we'll keep looking, + 2 means there is a potential A.P. that we can create (ideal!), and + 3 means that we're already in an A.P. (Trouble!). */ + + switch (matches) { + case 2: {; + for( ff=1; ff <= 3; ff ++) /* find which one didn't fit the A.P. */ + if (! inap[ff]) ooo=ff; + if (stones[ooo]>(start+thisone*stepsize)) /* check it's possible! */ + {; /* create an A.P. */ + row=ooo; /* already calculated */ + /* Start+thisone*stepsize will give the amount we SHOULD have here. */ + number=stones[row]-(start+thisone*stepsize); lmo=true; return; + } + } + break; + case 3: {; /* we're actually IN an A.P! Trouble! Oooh dear. */ + row=r[3]; number=1; lmo=true; return; /* take 1 from the largest pile */ + } + break; + } +} + +void dogfood() +{ + boolean sorted; byte temp; + +; + live=0; lmo=false; + for( fv=1; fv <= 3; fv ++) + {; + if (stones[fv]>0) + {; + live += 1; + r[live]=fv; sr[live]=stones[fv]; + } + } + switch (live) { + case 1: /* Only one is free- so take 'em all */ + {; row=r[1]; number=stones[r[1]]; return; } + break; + case 2: /* Two are free- make them equal */ + {; + if (sr[1]>sr[2]) + {; row=r[1]; number=sr[1]-sr[2]; return; } else /* T > b */ + if (sr[1]<sr[2]) + {; row=r[2]; number=sr[2]-sr[1]; return; } else /* B > t */ + {; row=r[1]; number=1; return; } /* B = t... oh no, we've lost! */ + } + break; + case 3: /* Ho hum... this'll be difficult! */ + {; + /* There are three possible courses of action when we have 3 lines left: + 1) Look for 2 equal lines, then take the odd one out. + 2) Look for A.P.s, and capitalise on them. + 3) Go any old where. */ + + for( fv=1; fv <= 3; fv ++) /* Look for 2 equal lines */ + if (stones[other[fv][1]]==stones[other[fv][2]]) + {; + row=fv; /* this row */ number=stones[fv]; /* all of 'em */ return; + } + + do { + sorted=true; + for( fv=1; fv <= 2; fv ++) + if (sr[fv]>sr[fv+1]) + {; + temp=sr[fv+1]; sr[fv+1]=sr[fv]; sr[fv]=temp; + temp= r[fv+1]; r[fv+1]= r[fv]; r[fv]=temp; + sorted=false; + } + } while (!sorted); + /* Now we look for A.P.s ... */ + for( fv=1; fv <= 3; fv ++) + {; + find_ap(fv,1); /* there are 3 "1"s */ + if (lmo) return; /* cut-out */ + } + find_ap(1,2); /* only "2" possible */ + if (lmo) return; + + /* A.P. search must have failed- use the default move. */ + row=r[3]; number=1; return; + } + break; + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + setup(); + board(); + do { + startmove(); + if (dogfoodsturn) dogfood(); else takesome(); + stones[row] -= number; + show_changes(); + } while (!(stonesleft==0)); + endofgame(); /* Winning sequence is A1, B3, B1, C1, C1, btw. */ +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/nimdraw.cpp b/engines/avalanche/nimdraw.cpp new file mode 100644 index 0000000000..afcac6d850 --- /dev/null +++ b/engines/avalanche/nimdraw.cpp @@ -0,0 +1,94 @@ +#include "ptoc.h" + + +#include "graph.h" + + +const string header = string("Datafile for Avalot, copyright (c) 1992.")+'\32'; + +integer gd,gm,x,y; +untyped_file f; +byte bit; + +void plot(char ch, byte x) +{; + setcolor(blue); outtextxy(x*80+4,0,ch); outtextxy(x*80+10,0,ch); + setcolor(lightblue); outtextxy(x*80+5,0,ch); outtextxy(x*80+9,0,ch); + setcolor(darkgray); outtextxy(x*80+6,0,ch); outtextxy(x*80+8,0,ch); + setcolor(yellow); outtextxy(x*80+7,0,ch); +} + +void load() +{ + byte z; + array<1,4,pointer> a; + varying_string<12> check; + untyped_file f; word s; +; + assign(f,"c:\\avalot\\nimstone.avd"); reset(f,1); + seek(f,85); z=3; + s=imagesize(0,0,getmaxx(),75); + getmem(a[z],s); + blockread(f,a[z],s); + putimage(0,7,a[z],0); + freemem(a[z],s); close(f); +} + +void spludge(integer x,integer y, string z) +{ + shortint dx,dy; +; + setcolor(15); + for( dx=-1; dx <= 1; dx ++) + for( dy=-1; dy <= 1; dy ++) + outtextxy(x+dx,y+dy,z); + setcolor(0); + outtextxy(x,y,z); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + load(); + settextstyle(4,0,0); setusercharsize(2,1,1,1); + plot('A',1); + plot('B',2); + plot('C',3); +/* rectangle(gd*80,7,56+gd*80,29); */ + + setfillstyle(1,1); setcolor(9); + fillellipse( 97,104,6,4); fillellipse(321,104,6,4); + fillellipse( 97,131,6,4); fillellipse(321,131,6,4); + bar(97,100,321,134); + bar(92,104,326,131); + setfillstyle(1,9); + bar(91,103, 91,131); bar(327,104,327,131); + bar(98, 99,321, 99); bar( 97,135,321,135); + + settextstyle(2,0,0); setusercharsize(20,10,11,10); + spludge( 99,100,"The Ancient Game of"); + settextstyle(1,0,0); setusercharsize(40,10,10,10); + spludge( 99,105,"NIM"); + + /* now save it all! */ + + assign(f,"c:\\avalot\\nim.avd"); + rewrite(f,1); + blockwrite(f,header[1],length(header)); + for( gd=0; gd <= 3; gd ++) + for( gm=7; gm <= 29; gm ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,mem[0xa000*gd*10+gm*80],7); + } + for( gm=99; gm <= 135; gm ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,mem[0xa000*11+gm*80],30); + } + close(f); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/nimunit.cpp b/engines/avalanche/nimunit.cpp new file mode 100644 index 0000000000..0becd47d10 --- /dev/null +++ b/engines/avalanche/nimunit.cpp @@ -0,0 +1,443 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + NIM UNIT A unit version of the pub game (Nim). */ + +#define __nimunit_implementation__ + + +#include "nimunit.h" + + +const array<false,true,varying_string<7> > names = {{"Avalot","Dogfood"}}; + +array<1,3,byte> old,stones; +array<0,3,0,22,1,7,byte> stonepic; /* picture of Nimstone */ +byte turns; +boolean dogfoodsturn; byte fv; byte stonesleft; + +boolean clicked; + +byte row,number; + +boolean squeak; +shortint mnum,mrow; + +void chalk(integer x,integer y, string z) +{ + const array<0,3,byte> greys = {{0,8,7,15}}; + byte fv; + + for( fv=0; fv <= 3; fv ++) + { + setcolor(greys[fv]); + outtextxy(x-fv,y,z); + sound(fv*100*length(z)); delay(3); nosound; delay(30); + } +} + +void setup() +{ + const integer page3 = 0xac00; + byte gd,gm; + untyped_file f; + byte bit; + + setactivepage(3); + setvisualpage(3); + cleardevice(); + dawn(); + + assign(f,"nim.avd"); + reset(f,1); + seek(f,41); + for( gm=0; gm <= 22; gm ++) + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,stonepic[bit][gm],7); + } + for( gd=1; gd <= 3; gd ++) + for( gm=0; gm <= 22; gm ++) + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,mem[page3*3200+gd*2800+gm*80],7); + } + for( gm=0; gm <= 36; gm ++) + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,mem[page3*400+49+gm*80],30); + } + close(f); + + gd=getpixel(0,0); /* clear codes */ + setcolor(4); rectangle(394,50,634,197); + setfillstyle(1,6); bar(395,51,633,196); + rectangle(10,5,380,70); bar(11,6,379,69); + setcolor(15); + outtextxy(475,53,"SCOREBOARD:"); + setcolor(14); + outtextxy(420,63,"Turn:"); + outtextxy(490,63,"Player:"); + outtextxy(570,63,"Move:"); + + for( gd=1; gd <= 3; gd ++) stones[gd]=gd+2; + + turns=0; dogfoodsturn=true; + + chalk(27,15,"Take pieces away with:"); + chalk(77,25,"1) the mouse (click leftmost)"); + chalk(53,35,"or 2) the keyboard:"); + chalk(220,35,string('\30')+'/'+'\31'+": choose row,"); + chalk(164,45,string("+/- or ")+'\33'+'/'+'\32'+": more/fewer,"); + chalk(204,55,"Enter: take stones."); + + row=1; number=1; fillchar(old,sizeof(old),'\0'); stonesleft=12; + + /* Set up mouse. */ + off_virtual(); + oncandopageswap=false; + + setactivepage(3); + setvisualpage(3); +} + +void plotstone(byte x,byte y) +{ + byte fv,bit; word ofs; + + ofs=3200+y*2800+x*8; + for( fv=0; fv <= 22; fv ++) + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(stonepic[bit][fv],mem[0xac00*ofs+fv*80],7); + } +} + +void board() +{ + byte fv,ff; + + for( fv=1; fv <= 3; fv ++) + for( ff=1; ff <= stones[fv]; ff ++) + plotstone(ff,fv); +} + +void startmove() +{ + varying_string<2> tstr; integer ypos; + + turns += 1; str(turns,2,tstr); ypos=63+turns*10; + dogfoodsturn=! dogfoodsturn; + chalk(433,ypos,tstr); + chalk(493,ypos,names[dogfoodsturn]); + old=stones; +} + +void show_changes() +{ + byte fv,ff,fq; varying_string<2> move; + + move=string(chr(64+row))+chr(48+number); + chalk(573,63+turns*10,move); + log_aside(names[dogfoodsturn]+" plays "+move+'.'); + + for( fv=1; fv <= 3; fv ++) + if (old[fv]>stones[fv]) + for( ff=stones[fv]+1; ff <= old[fv]; ff ++) + for( fq=0; fq <= 22; fq ++) fillchar(mem[0xac00*3200+fv*2800+ff*8+fq*80],7,'\0'); + stonesleft -= number; +} + +void checkmouse(); + +static void blip() { note(1771); delay(3); nosound; clicked=false; } + +void checkmouse() +{ + xycheck(); /* Check the mouse */ + clicked=keystatus>0; + if (clicked) + { + void& with = r; + /* The mouse was clicked. Where? */ + mrow=(my-38) / 35; + if ((mrow<1) || (mrow>3)) blip(); + mnum=stones[mrow]-(mx / 64)+1; + if ((mnum<1) || (mnum>(unsigned char)stones[mrow])) blip(); + } +} + +void takesome(); + +static void less() { if (number>1) number -= 1; } + +void takesome() +{ + char r; byte sr; + + number=1; + do { + do { + sr=stones[row]; + if (sr==0) { row=row % 3+1; number=1; } + } while (!(sr!=0)); + if (number>sr) number=sr; + setcolor(1); rectangle(63+(sr-number)*64,38+35*row,54+sr*64,63+35*row); + /* Wait for choice */ + on(); + do { checkmouse(); } while (!(keypressed() || clicked)); + if (keypressed()) r=upcase(readkey()); + off(); + + setcolor(0); rectangle(63+(sr-number)*64,38+35*row,54+sr*64,63+35*row); + + if (clicked) + { + number=mnum; + row=mrow; + return; + } else + { + switch (r) { + case '\0': switch (readkey()) { + case 'H': if (row>1) row -= 1; break; /* Up */ + case 'P': if (row<3) row += 1; break; /* Down */ + case 'K': number += 1; break; + case 'M': less(); break; + case 'I': row=1; break; /* PgUp */ + case 'Q': row=3; break; /* PgDn */ + case 'G': number=5; break; /* Home- check routine will knock this down to size */ + case 'O': number=1; break; /* End */ + } + break; + case '+': number += 1; break; + case '-': less(); break; + case RANGE_3('A','C'): row=ord(r)-64; + break; + case RANGE_5('1','5'): number=ord(r)-48; + break; + case '\15': return; break; /* Enter was pressed */ + } + } + } while (!false); +} + +void endofgame() +{ + char rr; + + chalk(595,63+turns*10,"Wins!"); + outtextxy(100,190,"- - - Press any key... - - -"); + while (keypressed()) rr=readkey(); + do { check(); } while (!(mpress==0)); + + { void& with = r; do { check(); } while (!(keypressed() || (mrelease>0)));} + if (keypressed()) rr=readkey(); + + mousepage(cp); + off(); + on_virtual(); +} + +void dogfood(); + /* AI procedure to play the game */ +const matrix<1,3,1,2,byte> other = {{{{2,3}},{{1,3}},{{1,2}}}}; + + +static byte live,fv,ff,matches,thisone,where; + +static array<1,3,byte> r,sr; +static array<1,3,boolean> inap; + +static boolean lmo; /* Let Me Out! */ + +static byte ooo; /* Odd one out */ + + +static boolean find(byte x) + /* This gives True if there's a pile with x stones in. */ +{ + boolean q; byte p; + + boolean find_result; + q=false; + for( p=1; p <= 3; p ++) if (stones[p]==x) { q=true; inap[p]=true; } + find_result=q; + return find_result; +} + + + +static void find_ap(byte start,byte stepsize) +{ + byte ff; + + matches=0; + fillchar(inap,sizeof(inap),'\0'); /* blank 'em all */ + for( ff=0; ff <= 2; ff ++) if (find(start+ff*stepsize)) matches += 1; + else thisone=ff; + + /* Now.. Matches must be 0, 1, 2, or 3. + 0/1 mean there are no A.P.s here, so we'll keep looking, + 2 means there is a potential A.P. that we can create (ideal!), and + 3 means that we're already in an A.P. (Trouble!). */ + + switch (matches) { + case 2: { + for( ff=1; ff <= 3; ff ++) /* find which one didn't fit the A.P. */ + if (! inap[ff]) ooo=ff; + if (stones[ooo]>(start+thisone*stepsize)) /* check it's possible! */ + { /* create an A.P. */ + row=ooo; /* already calculated */ + /* Start+thisone*stepsize will give the amount we SHOULD have here. */ + number=stones[row]-(start+thisone*stepsize); lmo=true; return; + } + } + break; + case 3: { /* we're actually IN an A.P! Trouble! Oooh dear. */ + row=r[3]; number=1; lmo=true; return; /* take 1 from the largest pile */ + } + break; + } +} + +void dogfood() +{ + boolean sorted; byte temp; + + + live=0; lmo=false; + for( fv=1; fv <= 3; fv ++) + { + if (stones[fv]>0) + { + live += 1; + r[live]=fv; sr[live]=stones[fv]; + } + } + switch (live) { + case 1: /* Only one is free- so take 'em all */ + { row=r[1]; number=stones[r[1]]; return; } + break; + case 2: /* Two are free- make them equal */ + { + if (sr[1]>sr[2]) + { row=r[1]; number=sr[1]-sr[2]; return; } else /* T > b */ + if (sr[1]<sr[2]) + { row=r[2]; number=sr[2]-sr[1]; return; } else /* B > t */ + { row=r[1]; number=1; return; } /* B = t... oh no, we've lost! */ + } + break; + case 3: /* Ho hum... this'll be difficult! */ + { + /* There are three possible courses of action when we have 3 lines left: + 1) Look for 2 equal lines, then take the odd one out. + 2) Look for A.P.s, and capitalise on them. + 3) Go any old where. */ + + for( fv=1; fv <= 3; fv ++) /* Look for 2 equal lines */ + if (stones[other[fv][1]]==stones[other[fv][2]]) + { + row=fv; /* this row */ number=stones[fv]; /* all of 'em */ return; + } + + do { + sorted=true; + for( fv=1; fv <= 2; fv ++) + if (sr[fv]>sr[fv+1]) + { + temp=sr[fv+1]; sr[fv+1]=sr[fv]; sr[fv]=temp; + temp= r[fv+1]; r[fv+1]= r[fv]; r[fv]=temp; + sorted=false; + } + } while (!sorted); + /* Now we look for A.P.s ... */ + for( fv=1; fv <= 3; fv ++) + { + find_ap(fv,1); /* there are 3 "1"s */ + if (lmo) return; /* cut-out */ + } + find_ap(1,2); /* only "2" possible */ + if (lmo) return; + + /* A.P. search must have failed- use the default move. */ + row=r[3]; number=1; return; + } + break; + } +} + +void play_nim() /* Plays the game. Only procedure in this unit to + be declared in the interface section. */ +{ + byte groi; + + if (dna.wonnim) + { /* Already won the game. */ + dixi('Q',6); + return; + } + + if (! dna.asked_dogfood_about_nim) + { + dixi('q',84); + return; + } + + dixi('Q',3); + dna.playednim += 1; + dusk(); + oncandopageswap=false; + copypage(3,1-cp); /* Store old screen. */ groi=getpixel(0,0); + off(); + + setup(); + board(); + on(); + mousepage(3); + + do { + startmove(); + if (dogfoodsturn) dogfood(); else takesome(); + stones[row] -= number; + show_changes(); + } while (!(stonesleft==0)); + endofgame(); /* Winning sequence is A1, B3, B1, C1, C1, btw. */ + + dusk(); off(); + oncandopageswap=true; + copypage(1-cp,3); /* Restore old screen. */ groi=getpixel(0,0); + on(); dawn(); + + if (dogfoodsturn) + { /* Dogfood won - as usual */ + log_aside("He won."); + if (dna.playednim==1) /* Your first game */ + dixi('Q',4); /* Goody! Play me again? */ + else + dixi('Q',5); /* Oh, look at that! I've won again! */ + pennycheck(4); /* And you've just lost 4d! */ + } else + { /* You won - strange! */ + log_aside("You won."); + dixi('Q',7); /* You won! Give us a lute! */ + dna.obj[lute]=true; + objectlist(); + dna.wonnim=true; + show_one(1); /* Show the settle with no lute on it. */ + points(7); /* 7 points for winning! */ + } + + if (dna.playednim==1) points(3); /* 3 points for playing your 1st game. */ + +} + + /* No init part. */ diff --git a/engines/avalanche/nimunit.h b/engines/avalanche/nimunit.h new file mode 100644 index 0000000000..5e3386d47f --- /dev/null +++ b/engines/avalanche/nimunit.h @@ -0,0 +1,18 @@ +#ifndef __nimunit_h__ +#define __nimunit_h__ + + +#include "gyro.h" + #include "Graph.h" + /*#include "Crt.h"*/ +#include "pingo.h" +#include "visa.h" +#include "lucerna.h" +#include "logger.h" +#include "celer.h" + + + void play_nim(); + + +#endif diff --git a/engines/avalanche/oldfiler.cpp b/engines/avalanche/oldfiler.cpp new file mode 100644 index 0000000000..c54a4696be --- /dev/null +++ b/engines/avalanche/oldfiler.cpp @@ -0,0 +1,260 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ +#include "graph.h" +/*#include "Dos.h"*/ +/*#include "Rodent.h"*/ + +/*$V-*/ + +const char more[] = " (more) "; +const string up = string('-')+'\30'+more+'\30'; +const string down = string('+')+'\31'+more+'\31'; + +const graphcursmasktype fletch = /* Mask 4 in Avalot */ + {( + (255,511,1023,2047,1023,4607,14591,31871,65031,65283,65281,65280,65280,65409,65473,65511), + (0,10240,20480,24576,26624,17408,512,256,128,88,32,86,72,20,16,0)), + 0, + 0}; + +string cdir; +matrix<0,2,1,18,varying_string<15> > info; +matrix<0,2,1,100,varying_string<15> > possible; +byte fv; +array<0,2,byte> light,page_; +array<0,2,boolean> blank; +byte chtcode,where; +string answer; + +void split(string x) +{ + byte fv; +; + x=copy(x,4,255); if (x=="") {; blank[0]=true; return; } + x=x+'\\'; possible[0][1]="b\\"; fv=2; + while (pos("\\",x)!=0) + {; + possible[0][fv]=string('b')+copy(x,1,pos("\\",x)-1); fv += 1; + x=copy(x,pos("\\",x)+1,255); + } + possible[0][fv-1]=""; +} + +void block(integer x1,integer y1,integer x2,integer y2, string x) +{; + bar(x1,y1,x2,y2); + setcolor( 9); outtextxy(x1+(x2-x1) / 2-1,y1+5,x); + setcolor(15); outtextxy(x1+(x2-x1) / 2+1,y1+6,x); +} + +void message(string x) +{; + block(5,189,640,200,x); +} + +void bigbar(byte x) +{; + bar(15+210*x,36,210+210*x,187); +} + +void getem(); + + +static void sub_getem(char prefix, string spec, byte attrib,byte infonum) +{ + searchrec s; byte fv; +; + fv=0; + findfirst(spec,attrib,s); + while ((doserror==0) && (fv<100)) + {; + if (((s.attr & attrib)>0) && (s.name[1]!='.')) + {; /* circumvent inclusive searching! */ + fv += 1; + possible[infonum][fv]=string(prefix)+s.name; + } + findnext(s); + } + if (fv==0) blank[infonum]=true; +} + +void getem() + +{; + message("Please wait... scanning directory..."); + sub_getem('a',"*.asg",archive+hidden,1); /* Scan for .ASG files */ + sub_getem('f',"*.*",directory,2); /* Scan for sub-directories */ +} + +void minisc(string& x) /* Converts to lower-case */ +{ + byte fv; +; + for( fv=1; fv <= length(x); fv ++) + if ((x[fv]>='A') && (x[fv]<='Z')) x[fv] += 32; +} + +void showall() +{ + byte fv,ff; +; + for( fv=0; fv <= 2; fv ++) + {; + bigbar(fv); /* blank out anything else */ + if (blank[fv]) + {; /* nothing here at all */ +/* setcolor(14); + outtextxy(113+210*fv,43,'(Nothing here!)'); */ + setcolor(14); settextstyle(0,0,2); + outtextxy(113+210*fv, 77,"Nothing"); + outtextxy(113+210*fv,100,"here!"); + settextstyle(0,0,1); + } else + {; /* something here- what? */ + setcolor(11); + for( ff=0; ff <= 15; ff ++) + {; + info[fv][ff+2]=possible[fv][page_[fv]*15+ff+1]; minisc(info[fv][ff+2]); + } + if (page_[fv]>0) info[fv][1]=up; else info[fv][1]=""; + if (possible[fv][page_[fv]*15+17]!="") + info[fv][18]=down; else info[fv][18]=""; + for( ff=1; ff <= 18; ff ++) + {; + outtextxy(113+210*fv,35+ff*8,copy(info[fv][ff],2,255)); + } + } + } + block(5,12,640,22,cdir); +} + +void changedir(string x) +{; + + chdir(x); getdir(0,cdir); +} + +void drawup() +{ + integer gd; +; + block( 15, 0,630,10,"Choose an .ASG file to load or save."); + block( 15,24,210,34,"Looking back:"); + block(225,24,420,34,"Here:"); + block(435,24,630,34,"Looking forwards:"); + for( gd=0; gd <= 2; gd ++) bigbar(gd); /* just to tide us over the wait... */ + showall(); +} + +void setup() +{; + settextjustify(1,1); setfillstyle(1,1); + fillchar(blank,sizeof(blank),'\0'); fillchar( info,sizeof( info),'\0'); + fillchar(possible,sizeof(possible),'\0'); + fillchar( page_,sizeof( page_),'\0'); + split(cdir); getem(); drawup(); +} + +void setup1() +{ + integer gd,gm; +; + gd=3; gm=0; initgraph(gd,gm,""); answer=""; + getdir(0,cdir); resetmouse; setgraphicscursor(fletch); + fillchar(light,sizeof(light),'\0'); + setup(); +} + +void clickwait() +{ + const array<1,4,varying_string<30> > msg = + {{"change to another drive.", + "return to a lower directory.", + "use the file named.", + "enter a sub-directory."}}; + byte oldcht; /* Click Here To... code */ +; + showmousecursor; oldcht=177; + do { + if (mousey<38) chtcode=1; else + switch (mousex) { + case 0 ... 210: chtcode=2; break; + case 211 ... 421: chtcode=3; break; + default: chtcode=4; + } + if (oldcht!=chtcode) + {; + hidemousecursor; message(string("Click here to ")+msg[chtcode]); + showmousecursor; oldcht=chtcode; + } + } while (!leftmousekeypressed); + hidemousecursor; where=((mousey-39) / 8)+1; +} + +void blip() +{; + sound(32); delay(3); nosound; +} + +void do_cht() +{ + char r; byte fv; string x; +; + if (chtcode==1) + {; /* change drives */ + message("Enter the drive letter (e.g. A)..."); + r=readkey(); + changedir(string(r)+':'); setup(); + } else + {; + x=info[chtcode-2][where]; r=x[1]; x=copy(x,2,255); + switch (r) { + case 'b': {; /* back some dirs */ + if (x=='\\') x=""; + for( fv=where-1; fv >= 3; fv --) + x=copy(info[0][fv],2,255)+'\\'+x; + changedir(string('\\')+x); + setup(); + } + break; + case 'f': {; /* sub-directory */ + changedir(x); + setup(); + } + break; + case '+': {; /* scroll one panel down */ + page_[chtcode-2] += 1; + drawup(); + } + break; + case '-': {; /* scroll one panel up */ + page_[chtcode-2] -= 1; + drawup(); + } + break; + case 'a': answer=x; break; + } + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + setup1(); + do { + clickwait(); + do_cht(); + } while (!(answer!="")); + if (length(cdir)>3) cdir=cdir+'\\'; + answer=cdir+answer; + closegraph(); + output << "Routine completed." << NL; + output << "Answer: " << answer << NL; + output << "Hit Enter:"; input >> NL; +return EXIT_SUCCESS; +} + + + diff --git a/engines/avalanche/oldhighs.cpp b/engines/avalanche/oldhighs.cpp new file mode 100644 index 0000000000..1aed0c5026 --- /dev/null +++ b/engines/avalanche/oldhighs.cpp @@ -0,0 +1,249 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + + +struct scoretype { + varying_string<39> name; + word score; +}; + +struct ratetype { + varying_string<10> rank; + word lowest; +}; + +struct tabletype { + array<1,12,scoretype> a; + byte light; +}; + +const array<1,9,ratetype> ratings = + {{{"Rubbish", 0}, + {"Beginner", 1}, + {"Poor", 10}, + {"Average", 30}, + {"Fair", 50}, + {"Not bad", 70}, + {"Good", 100}, + {"Great", 200}, + {"Fantastic!", 330}}}; + +integer gd,gm; +tabletype table; + +byte ratingname(word x) +{ + byte fv; +byte ratingname_result; +; + for( fv=9; fv >= 1; fv --) + if (x>=ratings[fv].lowest) + {; + ratingname_result=fv; + return ratingname_result; + } /* bad style */ +return ratingname_result; +} + +void title(); + +const string message = "A v a l o t : H i g h - S c o r e s"; + + +static void sayfast(integer x,integer y) +{ + integer anchor; byte fv; +; + anchor=-296; + for( fv=1; fv <= length(message); fv ++) + {; + if (message[fv-1]!='\40') outtextxy(x+anchor,y-8,message[fv-1]); + anchor += 16; + } +} + +void title() +{ + const array<0,6,byte> shades = + {{blue,lightgray,darkgray,blue,lightblue,blue,darkgray}}; + byte x; + integer len; + +; + settextstyle(0,0,2); /*settextjustify(1,1);*/ + len=textheight(message); + for( x=6; x >= 0; x --) + {; + setcolor(shades[x]); + sayfast(320-x*2,20-x); + if (x>0) + {; + sayfast(320+x*2,20-x); + sayfast(320+x*2,20+x); + sayfast(320-x*2,20+x); + } + } +} + +void newtable() +{ + const array<1,12,varying_string<15> > names = + {{"Mike","Liz","Thomas","Mark","Mandy","Andrew","Lucy Tryphena","", + "Thanks to all","who helped...","","Have fun!"}}; + byte fv; +; + fillchar(table,sizeof(table),'\261'); + for( fv=1; fv <= 12; fv ++) + { + scoretype& with = table.a[fv]; + ; + with.name=names[fv]; + with.score=193-fv*16; + } + table.light=1; +} + +string strf(longint x) /* From Gyro. Delete when integrated. */ +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +void sparkle(integer x,integer y, string z) +{; + setcolor(cyan); outtextxy(x-1,y-1,z); + setcolor(blue); outtextxy(x+1,y+1,z); + setcolor(white); outtextxy(x ,y ,z); +} + +void drawtable() +{ + byte fv,last,now; +; + setfillstyle(1,8); + bar( 0, 40,105, 58); bar(110, 40,400, 58); + bar(405, 40,490, 58); bar(495, 40,640, 58); + bar( 5, 60,105,181); bar(110, 60,400,181); + bar(405, 60,490,181); bar(495, 60,635,181); + bar( 0,185,640,190); + setcolor(lightred); settextstyle(0,0,1); settextjustify(0,0); + outtextxy( 45,55,"Number:"); + outtextxy(120,55,"Name:"); + outtextxy(420,55,"Score:"); + outtextxy(500,55,"Rating:"); + setcolor(white); last=177; + for( fv=1; fv <= 12; fv ++) + { + scoretype& with = table.a[fv]; + ; + settextjustify(righttext,bottomtext); + sparkle(100,60+fv*10,strf(fv)+'.'); + sparkle(455,60+fv*10,strf(with.score)); + if (fv==table.light) sparkle(70,60+fv*10,string("ÍÍ")+'\20'); + + settextjustify(lefttext,bottomtext); + sparkle(120,60+fv*10,with.name); + now=ratingname(with.score); + if (now!=last) + sparkle(510,60+fv*10,ratings[ratingname(with.score)].rank); + else + sparkle(517,57+fv*10,",,"); + last=now; + } +} + +void message1(string x) +{; + setfillstyle(1,8); bar(0,190,640,200); + settextjustify(1,1); sparkle(320,195,x); +} + +void sorthst() +{ + byte fv; boolean ok; scoretype temp; +; + do { + ok=true; + for( fv=1; fv <= 11; fv ++) + if (table.a[fv].score<table.a[fv+1].score) + {; + temp=table.a[fv]; table.a[fv]=table.a[fv+1]; table.a[fv+1]=temp; /* swap 'em */ + table.light=fv; /* must be- that's the only unsorted one */ + ok=false; /* So, we try again. */ + } + } while (!ok); +} + +void entername(); +static integer x,y; + + +static void cursor(byte col) +{; + setcolor(col); + outtextxy(x,y,"?"); +} + +void entername() +{ + varying_string<34> i;char r; integer counter; byte flash; + +; + y=60+table.light*10; i=""; settextjustify(2,0); counter=999; flash=0; + do { + x=128+length(i)*8; + do { + counter += 1; + if (counter==1000) + {; + cursor(4+flash*10); + flash=1-flash; + counter=0; + } + delay(1); + } while (!keypressed()); + cursor(8); + sound(17177); r=readkey(); nosound; + if (r=='\10') {; + if (i[0]>'\0') {; + bar(x-17,y-10,x-8,y); + i[0] -= 1; sparkle(x-16,y,i[length(i)]); + } + } else {; + if ((i[0]<'\42') && (r!='\15')) {; + sparkle(x,y,r); + i=i+r; + } + } + counter=999; + } while (!(r=='\15')); +} + +void newscore(word sc) +{; + { scoretype& with = table.a[12]; + if (sc>with.score) + {; + with.name=""; with.score=sc; table.light=10; sorthst(); drawtable(); + message1("Well done! Please enter your name, then press Return..."); + entername(); + } else drawtable();} /* too low for score */ + message1("Press Space to continue..."); + do {; } while (!(keypressed() && (readkey()=='\40'))); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + title(); + newtable(); + newscore(/*177*/0); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/oldincln.cpp b/engines/avalanche/oldincln.cpp new file mode 100644 index 0000000000..252d8b36c3 --- /dev/null +++ b/engines/avalanche/oldincln.cpp @@ -0,0 +1,249 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + INCLINE The command-line parser. */ + +#define __incline_implementation__ + + +#include "oldincln.h" + +#include "gyro.h" +#include "logger.h" + + +const integer bug_twonames = 255; +const integer bug_pandl = 254; +const integer bug_weirdswitch = 253; +const integer bug_invalidini = 252; +const integer bug_notyesorno = 251; + +byte fv; +char t; +string bugline; +boolean usingp,usingl; +boolean zoomy,numlockhold; + +boolean filename_specified; + +string inihead,initail; /* For reading the .INI file. */ + + +void linebug(byte which) +{; + output << "AVALOT : "; + switch (which) { + case bug_twonames : output << "You may only specify ONE filename." << NL; break; + case bug_pandl : output << "/p and /l cannot be used together." << NL; break; + case bug_weirdswitch : output << "Unknown switch (\"" << bugline << + "\"). Type AVALOT /? for a list of switches." << NL; + break; + case bug_invalidini: output << "Invalid line in AVALOT.INI (\"" << bugline << "\")" << NL; break; + case bug_notyesorno: output << "Error in AVALOT.INI: \"" << inihead << "\" must be \"yes\" or \"no.\"" << NL; break; + } + exit(which); +} + +void syntax() +{; + assign(output,""); rewrite(output); + output << NL; + output << string("Lord Avalot d'Argent\n\n(c) ")+copyright+" Mark, Mike and Thomas Thurman." << NL; + output << string("~~~~~~~~~~~~~~~~~~~~~\n\n")+vernum << NL; + output << NL; + output << "Syntax:" << NL; + output << "\n/?\ndisplays this screen," << NL; + output << "\n/O\noverrides EGA check," << NL; + output << "\n/L<f>\nlogs progress to <f>, default AVVY.LOG," << NL; + output << "\n/P<x>\nlogs with Epson codes to <x>, default PRN," << NL; + output << "\n/Q\ncancels sound effects," << NL; + output << "\n/S\ndisables Soundblaster," << NL; + output << "\n/Z\ngoes straight into the game." << NL; + output << NL; + output << "\n\n\n\n\n\n\n... Have fun!" << NL; + exit(177); +} + +void upstr(string& x) +{ + byte fv; +; + for( fv=1; fv <= length(x); fv ++) x[fv]=upcase(x[fv]); +} + +boolean yesno() +{boolean yesno_result; +; + if (initail=="YES") yesno_result=true; else + if (initail=="NO") yesno_result=false; else + linebug(bug_notyesorno); +return yesno_result; +} + +void ini_parse() +{; + upstr(inihead); + upstr(initail); + + if (inihead=="QUIET") soundfx=! yesno(); else + if (inihead=="ZOOMYSTART") zoomy=yesno(); else + if (inihead=="NUMLOCKHOLD") numlockhold=yesno(); else + if (inihead=="LOADFIRST") filetoload=initail; else + if (inihead=="OVERRIDEEGACHECK") cl_override=yesno(); else + if (inihead=="KEYBOARDCLICK") keyboardclick=yesno(); +} + +void strip_ini() +{ + byte fv; +; + if (inihead=="") return; + + /* Firstly, delete any comments. */ + fv=pos(";",inihead); + if (fv>0) Delete(inihead,fv,255); + + /* Lose the whitespace... */ + + while (inihead[length(inihead)]==' ') inihead[0] -= 1; + while ((inihead!="") && (inihead[1]==' ')) Delete(inihead,1,1); + + /* It's possible that now we'll end up with a blank line. */ + + if ((inihead=="") || (inihead[1]=='[')) return; + + fv=pos("=",inihead); + + if (fv==0) + {; /* No "="! Weird! */ + bugline=inihead; + linebug(bug_invalidini); + } + + initail=copy(inihead,fv+1,255); + inihead[0]=chr(fv-1); +} + +void load_ini() +{ + text ini; +; + assign(ini,"AVALOT.INI"); + reset(ini); + + while (! eof(ini)) + {; + ini >> inihead >> NL; + strip_ini(); + if (inihead!="") ini_parse(); + } + + close(ini); +} + +void parse(string x); +static string arg; + +static string getarg(string otherwis) +{string getarg_result; +; + if (arg=="") getarg_result=otherwis; else getarg_result=""; +return getarg_result; +} + +void parse(string x) + +{; + switch (x[1]) { + case '/':case '-': {; + arg=copy(x,3,255); + switch (upcase(x[2])) { + case '?': syntax(); break; + case 'O': cl_override=true; break; + case 'L': if (! usingp) + {; + log_setup(getarg("avvy.log"),false); + usingl=true; + } else {; close(logfile); linebug(bug_pandl); } + break; + case 'P': if (! usingl) + {; + log_setup(getarg("prn"),true); + usingp=true; + } else {; close(logfile); linebug(bug_pandl); } + break; + case 'Q': soundfx=false; break; + case 'Z': zoomy=true; break; + case 'K': keyboardclick=true; break; + case 'D': demo=true; break; + default: {; + bugline=x; + linebug(bug_weirdswitch); + } + } + } + break; + case '*': {; + inihead=copy(x,2,255); + strip_ini(); + if (inihead!="") ini_parse(); + } + break; + default: {; /* filename */ + if (filename_specified) + linebug(bug_twonames); + else + filetoload=x; + filename_specified=true; + } + } +} + +void not_through_bootstrap() +{ + output << "Avalot must be loaded through the bootstrap." << NL; + exit(0); +} + +void get_storage_addr() +{ + integer e; + + val(paramstr(2),storage_seg,e); if (e!=0) not_through_bootstrap(); + val(paramstr(3),storage_ofs,e); if (e!=0) not_through_bootstrap(); + skellern=storage_ofs+1; +} + +class unit_incline_initialize { + public: unit_incline_initialize(); +}; +static unit_incline_initialize incline_constructor; + +unit_incline_initialize::unit_incline_initialize() {; + filetoload=""; + usingl=false; + usingp=false; + logging=false; + cl_override=false; + soundfx=true; + zoomy=false; + numlockhold=false; + filename_specified=false; + keyboardclick=false; + + load_ini(); + + if ((paramcount<3) || + ((paramstr(1)!="Go") && (paramstr(1)!="et"))) not_through_bootstrap(); + + reloaded=paramstr(1)=="et"; + + get_storage_addr(); + + for( fv=4; fv <= paramcount; fv ++) + parse(paramstr(fv)); +} diff --git a/engines/avalanche/oldincln.h b/engines/avalanche/oldincln.h new file mode 100644 index 0000000000..a0db659f92 --- /dev/null +++ b/engines/avalanche/oldincln.h @@ -0,0 +1,10 @@ +#ifndef __oldincln_h__ +#define __oldincln_h__ + + + +/* This unit has NO externally-callable procedures. Also note that + it MUST be called *first* (so if you load AVALOT.PAS and press f7 + twice you get to the "begin" statement.) */ + +#endif diff --git a/engines/avalanche/oldtrip.cpp b/engines/avalanche/oldtrip.cpp new file mode 100644 index 0000000000..5e0fb99c4c --- /dev/null +++ b/engines/avalanche/oldtrip.cpp @@ -0,0 +1,448 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + TRIP4 Trippancy IV- "Trip Oop". */ + +#define __trip4_implementation__ + /* Trippancy IV (Trip Oop) */ +#include "oldtrip.h" + + +/*#include "Scrolls.h"*/ +/*#include "Lucerna.h"*/ +/*#include "Gyro.h"*/ +/*#include "Dropdown.h"*/ + + +void copier(integer x1,integer y1,integer x2,integer y2,integer x3,integer y3,integer x4,integer y4); + + +static boolean dropin(integer xc,integer yc,integer x1,integer y1,integer x2,integer y2) +/* Dropin returns True if the point xc,yc falls within the 1-2 rectangle. */ +{boolean dropin_result; +; + dropin_result=((xc>=x1) && (xc<=x2) && (yc>=y1) && (yc<=y2)); +return dropin_result; +} + + + +static integer lesser(integer a,integer b) +{integer lesser_result; +; + if (a<b) lesser_result=a; else lesser_result=b; +return lesser_result; +} + + + +static integer greater(integer a,integer b) +{integer greater_result; +; + if (a>b) greater_result=a; else greater_result=b; +return greater_result; +} + +void copier(integer x1,integer y1,integer x2,integer y2,integer x3,integer y3,integer x4,integer y4) + +{; + if (dropin(x3,y3,x1,y1,x2,y2) + || dropin(x3,y4,x1,y1,x2,y2) + || dropin(x4,y3,x1,y1,x2,y2) + || dropin(x4,y4,x1,y1,x2,y2)) + {; /* Overlaps */ + mblit(lesser(x1,x3),lesser(y1,y3),greater(x2,x4),greater(y2,y4),1,0); + } else + {; /* Doesn't overlap- copy both of them seperately */ + mblit(x3,y3,x4,y4,1,0); /* backwards- why not...? */ + mblit(x1,y1,x2,y2,1,0); + } +} + +void loadtrip() +{ + byte gm; +; + for( gm=1; gm <= numtr; gm ++) tr[gm].original(); + tr[1].init(0); +} + +byte checkfeet(integer x1,integer x2,integer oy,integer y, byte yl) +{ + byte a,c; integer fv,ff; +byte checkfeet_result; +; + a=0; setactivepage(2); if (x1<0) x1=0; if (x2>639) x2=639; + if (oy<y) + for( fv=x1; fv <= x2; fv ++) + for( ff=oy+yl; ff <= y+yl; ff ++) + {; + c=getpixel(fv,ff); + if (c>a) a=c; + } else + for( fv=x1; fv <= x2; fv ++) + for( ff=y+yl; ff <= oy+yl; ff ++) + {; + c=getpixel(fv,ff); + if (c>a) a=c; + } + checkfeet_result=a; setactivepage(1); +return checkfeet_result; +} + +void touchcol(byte tc); +static boolean bug; + +static void fr(byte a,byte b) {; fliproom(a,b); bug=false; } + +void touchcol(byte tc) +{; + bug=true; /* j.i.c. */ + switch (dna.room) { + case 1: fr(2,3); break; + case 2: {; /* main corridor */ + switch (tc) { + case 1: fr(3,1); break; /* to the other corridor */ + case 2: fr(2,1); break; /* to this corridor! Fix this later... */ + } + } + break; + case 3: {; /* turn corridor */ + switch (tc) { + case 1: fr(2,1); break; /* to the other corridor */ + case 2: fr(12,1); break; /* through Spludwick's door */ + } + } + break; + case 12: fr(3,2); break; + } + if (bug) + {; + setactivepage(0); + display(string('\7')+"Unknown touchcolour ("+strf(tc)+')'+" in "+strf(dna.room) + +'.'); setactivepage(1); tr[1].bounce(); + } +} + +triptype* triptype::init(byte spritenum) +{ + integer gd,gm; word s; untyped_file f; varying_string<2> xx; byte sort,n; + word bigsize; pointer p,q; +; + str(spritenum,xx); assign(f,string("c:\\avalot\\sprite")+xx+".avd"); + reset(f,1); seek(f,59); + blockread(f,a,sizeof(a)); blockread(f,bigsize,2); + setactivepage(3); + for( sort=0; sort <= 1; sort ++) + {; + mark(q); getmem(p,bigsize); + blockread(f,p,bigsize); + off; putimage(0,0,p,0); release(q); n=1; + { adxtype& with = a; + for( gm=0; gm <= (with.num / with.seq)-1; gm ++) /* directions */ + for( gd=0; gd <= with.seq-1; gd ++) /* steps */ + {; + getmem(pic[n][sort],a.size); /* grab the memory */ + getimage((gm / 2)*(with.xl*6)+gd*with.xl,(gm % 2)*with.yl, + (gm / 2)*(with.xl*6)+gd*with.xl+with.xl-1,(gm % 2)*with.yl+with.yl-1, + pic[n][sort]); /* grab the pic */ + n += 1; + }} on; + } + close(f); setactivepage(0); + + x=0; y=0; quick=true; visible=false; getmem(behind,a.size); + homing=false; ix=0; iy=0; step=0; check_me=a.name=="Avalot"; +return this; +} + +void triptype::original() +{; + quick=false; +} + +void triptype::getback() +{; + tax=x; tay=y; + off; /*getimage(x,y,x+a.xl,y+a.yl,behind^);*/ + mblit(x,y,x+a.xl,y+a.yl,1,3); on; +} + +void triptype::andexor() +{ + byte picnum; /* Picnum, Picnic, what ye heck */ +; + picnum=face*a.seq+step+1; off; + putimage(x,y,pic[picnum][0],andput); + putimage(x,y,pic[picnum][1],xorput); on; +} + +void triptype::turn(byte whichway) +{; + face=whichway; +} + +void triptype::appear(integer wx,integer wy, byte wf) +{; + x=(wx / 8)*8; y=wy; ox=wx; oy=wy; turn(wf); visible=true; ix=0; iy=0; +} + +void triptype::walk() +{ + byte tc; +; + ox=x; oy=y; + if ((ix==0) && (iy==0)) return; + if (homing) homestep(); + x=x+ix; y=y+iy; + if (check_me) {; + tc=checkfeet(x,x+a.xl,oy,y,a.yl); + { void& with = magics[tc]; + switch (op) { + case exclaim: blip; break; + case bounces: bounce(); break; + case transport: fliproom(hi(data),lo(data)); break; + }} + } +/* if x<0 then x:=0; else if x+a.xl>640 then x:=640-a.xl;*/ + if (y<0) y=0; /* else if y+a.yl>161 then y:=161-a.yl; */ + step += 1; if (step==a.seq) step=0; getback(); +} + +void triptype::bounce() +{; setactivepage(1); putback(); x=ox; y=oy; stopwalk(); return; } + +void triptype::do_it() +{; + if (((ix!=0) || (iy!=0)) & (~ ddm_o.menunow)) + {; + off; copier(ox,oy,ox+a.xl,oy+a.yl,x,y,x+a.xl,y+a.yl); + putback(); on; + } +} + +void triptype::putback() +{; +/* putimage(tax,tay,behind^,0);*/ mblit(tax,tay,tax+a.xl,tay+a.yl,3,1); +} + +void triptype::walkto(integer xx,integer yy) +{; + speed(xx-x,yy-y); hx=xx; hy=yy; homing=true; +} + +void triptype::stophoming() +{; + homing=false; +} + +void triptype::homestep() +{ + integer temp; +; + if ((hx==x) && (hy==y)) + {; /* touching the target */ + homing=false; return; + } + ix=0; iy=0; + if (hy!=y) + {; + temp=hy-y; if (temp>4) iy=4; else if (temp<-4) iy=-4; else iy=temp; + } + if (hx!=x) + {; + temp=hx-x; if (temp>4) ix=4; else if (temp<-4) ix=-4; else ix=temp; + } +} + +void triptype::speed(shortint xx,shortint yy) +{; + ix=xx; iy=yy; + if ((ix==0) && (iy==0)) return; /* no movement */ + if (ix==0) + {; /* No horz movement */ + if (iy<0) turn(up); else turn(down); + } else + {; + if (ix<0) turn(left); else turn(right); + } +} + +void triptype::stopwalk() +{; + ix=0; iy=0; homing=false; +} + +void triptype::chatter() +{; + talkx=x+a.xl / 2; talky=y; talkf=a.fgc; talkb=a.bgc; +} + + +getsettype* getsettype::init() +{; + numleft=0; /* initialise array pointer */ + return this; +} + +void remember(fieldtype r) +{; + numleft += 1; + gs[numleft]=r; +} + +void recall() +{void recall_result; +; + recall_result=gs[numleft]; + numleft -= 1; +return recall_result; +} + +void rwsp(byte t,byte r) +{ + const integer xs = 4; const integer ys = 2; +; + { triptype& with = tr[t]; switch (r) { + case up: speed( 0,-ys); break; case down: speed( 0, ys); break; case left: speed(-xs, 0); break; + case right: speed( xs, 0); break; case ul: speed(-xs,-ys); break; case ur: speed( xs,-ys); break; + case dl: speed(-xs, ys); break; case dr: speed( xs, ys); break; + }} +} + +void apped(byte trn,byte np) +{; + { + triptype& with = tr[trn]; + ; { void& with1 = peds[np]; appear(with.x-with.a.xl / 2,with.y-with.a.yl,dir);} + rwsp(trn,tr[trn].face); } +} + +void trippancy(); + +static boolean allstill() +{ + boolean xxx; byte fv; +boolean allstill_result; +; + xxx=true; + for( fv=1; fv <= numtr; fv ++) + { triptype& with = tr[fv]; + if (with.quick && ((with.ix!=0) || (with.iy!=0))) xxx=false;} + allstill_result=xxx; +return allstill_result; +} + +void trippancy() +{ + byte fv; +; + if ((ddm_o.menunow) | ontoolbar | seescroll | allstill()) return; + setactivepage(1); + for( fv=1; fv <= numtr; fv ++) + { triptype& with = tr[fv]; + if (with.quick) + {; + walk(); + if (with.visible && ((with.ix!=0) || (with.iy!=0))) andexor(); + do_it(); + }} + setactivepage(0); +} + +void tripkey(char dir); + +static void stopwalking() +{; + tr[1].stopwalk(); dna.rw=stopped; +} + +void tripkey(char dir) +{; + { triptype& with = tr[1]; + {; + switch (dir) { + case 'H': if (rw!=up) + {; rw=up; rwsp(1,rw); } else stopwalking(); + break; + case 'P': if (rw!=down) + {; rw=down; rwsp(1,rw); } else stopwalking(); + break; + case 'K': if (rw!=left) + {; rw=left; rwsp(1,rw); } else stopwalking(); + break; + case 'M': if (rw!=right) + {; rw=right; rwsp(1,rw); } else stopwalking(); + break; + case 'I': if (rw!=ur) + {; rw=ur; rwsp(1,rw); } else stopwalking(); + break; + case 'Q': if (rw!=dr) + {; rw=dr; rwsp(1,rw); } else stopwalking(); + break; + case 'O': if (rw!=dl) + {; rw=dl; rwsp(1,rw); } else stopwalking(); + break; + case 'G': if (rw!=ul) + {; rw=ul; rwsp(1,rw); } else stopwalking(); + break; + case 'L': stopwalking(); break; + } + }} +} + +void fliproom(byte room,byte ped) +{; + dusk; tr[1].putback(); dna.room=room; load(room); apped(1,ped); + oldrw=dna.rw; dna.rw=tr[1].face; showrw; dawn; +} + +boolean infield(byte x) /* returns True if you're within field "x" */ +{ + integer ux,uy; +boolean infield_result; +; + { + triptype& with = tr[1]; + ; + ux=with.x; + uy=with.y+with.a.yl; + } + { + void& with = fields[x]; + ; + infield_result=(ux>=x1) && (ux<=x2) && (uy>=y1) && (uy<=y2); + } +return infield_result; +} + +boolean neardoor() /* returns True if you're near a door! */ +{ + integer ux,uy; byte fv; boolean nd; +boolean neardoor_result; +; + if (numfields<9) + {; /* there ARE no doors here! */ + neardoor_result=false; + return neardoor_result; + } + { + triptype& with = tr[1]; + ; + ux=with.x; + uy=with.y+with.a.yl; + } nd=false; + for( fv=9; fv <= numfields; fv ++) + { + void& with = fields[fv]; + ; + if ((ux>=x1) && (ux<=x2) && (uy>=y1) && (uy<=y2)) nd=true; + } + neardoor_result=nd; +return neardoor_result; +} + diff --git a/engines/avalanche/oldtrip.h b/engines/avalanche/oldtrip.h new file mode 100644 index 0000000000..dc36efd2d6 --- /dev/null +++ b/engines/avalanche/oldtrip.h @@ -0,0 +1,95 @@ +#ifndef __oldtrip_h__ +#define __oldtrip_h__ + + +#include "graph.h" +/*#include "Crt.h"*/ + + +const integer maxgetset = 10; + +struct adxtype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +class triptype { +public: + adxtype a; /* vital statistics */ + byte face,step; + integer x,y; /* current xy coords */ + integer ox,oy; /* last xy coords */ + integer tax,tay; /* "behind" taken at... */ + shortint ix,iy; /* amount to move sprite by, each step */ + matrix<1,24,0,1,pointer> pic; /* the pictures themselves */ + boolean quick,visible,homing,check_me; + pointer behind; /* what's behind you */ + integer hx,hy; /* homing x & y coords */ + + triptype* init(byte spritenum); /* loads & sets up the sprite */ + void original(); /* just sets Quick to false */ + void andexor(); /* drops sprite onto screen 1 */ + void turn(byte whichway); /* turns him round */ + void appear(integer wx,integer wy, byte wf); /* switches him on */ + void bounce(); /* bounces off walls. */ + void walk(); /* prepares for do_it, andexor, etc. */ + void do_it(); /* Actually copies the picture over */ + void getback(); /* gets background before sprite is drawn */ + void putback(); /* ...and wipes sprite from screen 1 */ + void walkto(integer xx,integer yy); /* home in on a point */ + void stophoming(); /* self-explanatory */ + void homestep(); /* calculates ix & iy for one homing step */ + void speed(shortint xx,shortint yy); /* sets ix & iy, non-homing, etc */ + void stopwalk(); /* Stops the sprite from moving */ + void chatter(); /* Sets up talk vars */ +}; + +class getsettype { +public: + array<1,maxgetset,fieldtype> gs; + byte numleft; + + getsettype* init(); + void remember(fieldtype r); + void recall(); +}; + +const integer up = 0; +const integer right = 1; +const integer down = 2; +const integer left = 3; +const integer ur = 4; const integer dr = 5; const integer dl = 6; const integer ul = 7; +const integer stopped = 8; + +const integer numtr = 5; /* current max no. of sprites */ + +void trippancy(); + +void loadtrip(); + +void tripkey(char dir); + +void apped(byte trn,byte np); + +void fliproom(byte room,byte ped); + +boolean infield(byte x); /* returns True if you're within field "x" */ + +boolean neardoor(); /* returns True if you're near a door! */ + + +#ifdef __trip4_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN array<1,numtr,triptype> tr; +#undef EXTERN +#define EXTERN extern + + +#endif diff --git a/engines/avalanche/omtest.cpp b/engines/avalanche/omtest.cpp new file mode 100644 index 0000000000..52b1a0373e --- /dev/null +++ b/engines/avalanche/omtest.cpp @@ -0,0 +1,177 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Oopmenu.h"*/ +/*#include "Rodent.h"*/ +/*#include "Crt.h"*/ +/*#include "Enhanced.h"*/ + +varying_string<5> st; +byte fv; + +void graphics() + { + integer gd,gm; ; gd=3; gm=0; initgraph(gd,gm,""); } + +/*$F+ ... All ddm__procs and do__procs must be compiled in Far-Call state. */ + +void ddm__file() +{; + {; + start_afresh; + opt("Load...",'L',"f3",true); + opt("Save...",'S',"f2",false); + opt("Save As...",'A',"ctrl-f2",false); + opt("OS Shell...",'O',"f2",true); + opt("Untrash screen",'U',"f11",true); + display; + } +} + +void ddm__heart() +{; + {; + start_afresh; + opt("About...",'A',"shift-f10",true); + opt("Boss Key",'B',"alt-B",true); + opt("Help...",'H',"f1",true); + opt("Status screen",'S',"f12",true); + opt("Quit",'Q',"f10",true); + display; + } +} + +void ddm__action() +{; + {; + start_afresh; + opt("Get up",'G',"",true); + opt("Open door",'O',"",true); + opt("Pause game",'P',"",true); + opt("Look around",'L',"",true); + opt("Inventory",'I',"Tab",true); + opt("Do the boogie",'b',"",true); + display; + } +} + +void ddm__objects() +{; + {; + start_afresh; + opt("Bell",'B',"",true); + opt("Wine",'W',"",true); + opt("Chastity Belt",'C',"",true); + opt("Crossbow Bolt",'t',"",true); + opt("Crossbow",'r',"",true); + opt("Potion",'P',"",true); + display; + } +} + +void ddm__people() +{; + {; + start_afresh; + opt("Avalot",'A',"",true); + opt("Spludwick",'S',"",true); + opt("Arkata",'k',"",true); + opt("Dogfood",'D',"",true); + opt("Geida",'G',"",true); + display; + } +} + +void ddm__use() +{; + {; + start_afresh; + opt("Drink",'D',"",true); + opt("Wear",'W',"",true); + opt("Give to [du Lustie]",'G',"",true); + display; + } +} + +void do__stuff() +{ + varying_string<2> st; +; + str(o.choicenum+1,st); + setfillstyle(1,6); setcolor(14); + bar(0,177,640,200); + outtextxy(320,177,string("You just chose: ")+st); +} + +void do__heart() +{; + switch (o.choicenum) { + case 0: outtextxy(100,100,"A really funny game!"); break; + case 1: outtextxy(100,120,"You ought to be working!"); break; + case 2: outtextxy(100,140,"No help available, so THERE!"); break; + case 3: outtextxy(100,160,"Everything's COOL and FROODY!"); break; + case 4: exit(0); break; + } +} + +/*$F- ... End of ddm__procs */ + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + graphics(); + setfillstyle(6,6); bar(0,0,639,199); + resetmouse; + m.init; o.init; + {; + create('H','\3','#',ddm__heart(),do__heart()); + create('F',"File",'!',ddm__file(),do__stuff()); + create('A',"Action",'\36',ddm__action(),do__stuff()); + create('O',"Objects",'\30',ddm__objects(),do__stuff()); + create('P',"People",'\31',ddm__people(),do__stuff()); + create('W',"With",'\21',ddm__use(),do__stuff()); + update; + } + do { + showmousecursor; + do { + getbuttonpressinfo(1); + getbuttonreleaseinfo(1); + getbuttonstatus; + if (menunow) o.lightup; + } while (!((buttonpresscount>0) || (buttonreleasecount>0) | keypressede)); + hidemousecursor; + if (buttonpresscount>0) + {; + if (mousey>10) + {; + if (! ((o.firstlix) & + ((mousex>=flx1) && (mousex<=flx2) && + (mousey>=12) && (mousey<=fly)))) + {; /* Clicked OUTSIDE the menu. */ + if (o.menunow) wipe; + setcolor(2); for( fv=1; fv <= 17; fv ++) circle(mousex,mousey,fv*3); + setcolor(0); for( fv=1; fv <= 17; fv ++) circle(mousex,mousey,fv*3); + } + } else + {; /* Clicked on menu bar */ + m.getmenu(mousex); + } + } else + {; /* NOT clicked button... */ + if (buttonreleasecount>0) + {; + if ((firstlix) & + ((mousex>=flx1) && (mousex<=flx2) && + (mousey>=12) && (mousey<=fly))) + select((mousey-14) / 10); + } else + {; /* NOT clicked or released button, so must be keypress */ + readkeye; + parsekey(inchar,extd); + } + } + } while (!false); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/oopmenu.cpp b/engines/avalanche/oopmenu.cpp new file mode 100644 index 0000000000..5c1b13f08b --- /dev/null +++ b/engines/avalanche/oopmenu.cpp @@ -0,0 +1,295 @@ +#include "ptoc.h" + +#define __oopmenu_implementation__ + + +#include "oopmenu.h" + + +/*#include "Crt.h"*/ +#include "graph.h" +/*#include "Rodent.h"*/ +/*#include "Dos.h"*/ + + +const integer indent = 40; +const integer spacing = 83; + +const integer menu_b = blue; +const integer menu_f = yellow; +const integer menu_border = black; +const integer highlight_b = lightblue; +const integer highlight_f = yellow; +const integer disabled = lightgray; + +/* menu_b = lightgray; + menu_f = black; + menu_border = black; + highlight_b = black; + highlight_f = white; + disabled = darkgray;*/ + +/* Built-in mouse routine */ + +char r; +byte fv; + +void chalk(integer x,integer y, char t, string z) +{ + byte p; +; + outtextxy(x,y,z); + p=pos(t,z); if (p==0) return; p -= 1; + outtextxy(x+p*8,y+1,"_"); +} + +void say(integer x,integer y, char t, string z, byte f,byte b) +{; + settextjustify(0,2); setfillstyle(1,b); setcolor(f); + bar(x-3,y-1,x+textwidth(z)+3,y+textheight(z)+1); + chalk(x,y,t,z); +} + +void mblit(integer x1,integer y1,integer x2,integer y2, byte f,byte t) /* NOT The Minstrel Blitter */ +{ + pointer p,q; word s; +; + mark(q); + s=imagesize(x1,y1,x2,y2); getmem(p,s); + setactivepage(f); getimage(x1,y1,x2,y2,p); + setactivepage(t); putimage(x1,y1,p,0); + setactivepage(0); release(q); +} + +void onemenu::start_afresh() +{; + number=0; width=0; firstlix=false; oldy=0; highlightnum=0; +} + +onemenu* onemenu::init() +{; + menunow=false; + return this; +} + +void onemenu::opt(string n, char tr, string key, boolean val) +{ + integer l; +; + number += 1; + l=textwidth(n+key)+30; if (width<l) width=l; + { + optiontype& with = oo[number]; + ; + with.title=n; + with.trigger=tr; + with.shortcut=key; + with.valid=val; + } +} + +void onemenu::displayopt(byte y,byte b,byte f,byte d) +{; + { + optiontype& with = oo[y]; + ; + if (with.valid) setcolor(f); else setcolor(d); + if (b!=177) + {; + setfillstyle(1,b); + bar(flx1,3+y*10,flx2,12+y*10); + } + settextjustify(2,2); + if (with.shortcut>"") outtextxy(flx2,4+y*10,with.shortcut); + settextjustify(0,2); + chalk(left+3,4+y*10,with.trigger,with.title); + } +} + +void onemenu::display() +{ + byte y; +; + setfillstyle(1,menu_b); setcolor(menu_border); + firstlix=true; + flx1=left-2; flx2=left+width; fly=14+number*10; + mblit(flx1-3,11,flx2+1,fly+1,0,1); + menunow=true; + + bar(flx1,12,flx2,fly); + rectangle(flx1-1,11,flx2+1,fly+1); + + setcolor(menu_f); settextjustify(0,2); + displayopt(1,highlight_b,highlight_f,177); + for( y=2; y <= number; y ++) + { optiontype& with = oo[y]; displayopt(y,177,menu_f,disabled);} +} + +void onemenu::wipe() +{; + { headtype& with = m.ddms[o.menunum]; say(flx1+2,1,with.trigger,with.title,menu_f,menu_b);} + mblit(flx1-3,11,flx2+1,fly+1,1,0); + menunow=false; firstlix=false; +} + +void onemenu::movehighlight(shortint add) +{ + shortint hn; +; + if (add!=0) + {; + hn=highlightnum+add; + if ((hn<0) || (hn>=(unsigned char)number)) return; + highlightnum=hn; + } + hidemousecursor; + displayopt(oldy+1,menu_b,menu_f,disabled); + displayopt(highlightnum+1,highlight_b,highlight_f,disabled); + showmousecursor; + oldy=highlightnum; +} + +void onemenu::lightup() /* This makes the menu highlight follow the mouse.*/ +{; + if ((mousex<flx1) || (mousex>flx2) + || (mousey<=12) || (mousey>fly-3)) return; + highlightnum=(mousey-12) / 10; + if (highlightnum==oldy) return; + movehighlight(0); +} + +void onemenu::select(byte n) /* Choose which one you want. */ +{; + if (! oo[n+1].valid) return; + choicenum=n; + m.ddms[menunum].do_choose(); + wipe(); +} + +void onemenu::keystroke(char c) +{ + byte fv; +; + c=upcase(c); + for( fv=1; fv <= number; fv ++) + if (upcase(oo[fv].trigger)==c) select(fv-1); +} + +void bleep() +{; + sound(177); delay(7); nosound; +} + + headtype* headtype::init + (char trig,char alttrig, string name, byte p, proc dw,proc dc) + {; + trigger=trig; alttrigger=alttrig; title=name; + position=p; xpos=(position-1)*spacing+indent; + xright=xpos+textwidth(name)+3; + do_setup=dw; do_choose=dc; + return this; + } + + void headtype::display() + {; + say(xpos,1,trigger,title,menu_f,menu_b); + } + + void headtype::highlight() + {; + say(xpos,1,trigger,title,highlight_f,highlight_b); + {; + o.left=xpos; + o.menunow=true; o.menunum=position; + } + } + + boolean headtype::extdparse(char c) + {boolean extdparse_result; + ; + if (c!=alttrigger) {; extdparse_result=true; return extdparse_result; } + extdparse_result=false; + return extdparse_result; + } + + menuset* menuset::init() + {; + howmany=0; + return this; + } + + void menuset::create(char t, string n, char alttrig, proc dw,proc dc) + {; + howmany += 1; + ddms[howmany].init(t,alttrig,n,howmany,dw,dc); + } + + void menuset::update() + { + byte fv; + ; + setfillstyle(1,menu_b); bar(0,0,640,10); + for( fv=1; fv <= howmany; fv ++) ddms[fv].display(); + } + + void menuset::extd(char c) + { + byte fv; + ; + fv=1; + while ((fv<=howmany) && (ddms[fv].extdparse(c))) fv += 1; + if (fv>howmany) return; getmenu(fv*spacing-indent); + } + + void menuset::getmenu(integer x) + { + byte fv; + ; + fv=0; + do { + fv += 1; + if ((x>ddms[fv].xpos-3) && (x<ddms[fv].xright)) + { headtype& with = ddms[fv]; + {; + if (o.menunow) + {; + wipe(); /* get rid of menu */ + if (o.menunum==with.position) return; /* click on own highlight */ + } + highlight(); do_setup(); + return; + }} + } while (!(fv>howmany)); + } + +void parsekey(char r,char re) +{; + switch (r) { + case '\0': {; + switch (re) { + case 'K': {; + wipe(); + m.getmenu((o.menunum-2)*spacing+indent); + } + break; + case 'M': {; + wipe(); + m.getmenu((o.menunum*spacing+indent)); + } + break; + case 'H': movehighlight(-1); break; + case 'P': movehighlight(1); break; + default: m.extd(re); + } + } + break; + case '\33': if (o.menunow) wipe(); break; + case '\15': select(o.highlightnum); break; + default: + {; + if (o.menunow) keystroke(r); else + kbuffer=kbuffer+r+re; + } + } +} + diff --git a/engines/avalanche/oopmenu.h b/engines/avalanche/oopmenu.h new file mode 100644 index 0000000000..ee928e2050 --- /dev/null +++ b/engines/avalanche/oopmenu.h @@ -0,0 +1,82 @@ +#ifndef __oopmenu_h__ +#define __oopmenu_h__ + + +typedef void(*proc)(); + +class headtype { +public: + varying_string<8> title; + char trigger,alttrigger; + byte position; + integer xpos,xright; + proc do_setup,do_choose; + + headtype* init + (char trig,char alttrig, string name, byte p, proc dw,proc dc); + void display(); + void highlight(); + boolean extdparse(char c); +}; + +struct optiontype { + string title; + char trigger; + varying_string<9> shortcut; + boolean valid; +}; + +class onemenu { +public: + array<1,12,optiontype> oo; + byte number; + integer width,left; + boolean firstlix; + integer flx1,flx2,fly; + byte oldy; /* used by Lightup */ + boolean menunow; /* Is there a menu now? */ + byte menunum; /* And if so, which is it? */ + byte choicenum; /* Your choice? */ + byte highlightnum; + + void start_afresh(); + void opt(string n, char tr, string key, boolean val); + void display(); + void wipe(); + void lightup(); + void displayopt(byte y,byte b,byte f,byte d); + void movehighlight(shortint add); + void select(byte n); + void keystroke(char c); + onemenu* init(); +}; + +class menuset { +public: + array<1,8,headtype> ddms; + byte howmany; + + menuset* init(); + void create(char t, string n, char alttrig, proc dw,proc dc); + void update(); + void extd(char c); + void getmenu(integer x); +}; + + + +#ifdef __oopmenu_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN onemenu o; +EXTERN menuset m; +EXTERN string kbuffer; +#undef EXTERN +#define EXTERN extern + + + void parsekey(char r,char re); + +#endif diff --git a/engines/avalanche/overlap.cpp b/engines/avalanche/overlap.cpp new file mode 100644 index 0000000000..973bafb79f --- /dev/null +++ b/engines/avalanche/overlap.cpp @@ -0,0 +1,53 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +integer gd,gm; + +void flash(integer x1,integer y1,integer x2,integer y2) +{; + setcolor(14); rectangle(x1,y1,x2,y2); + sound(x1+x2); delay(100); nosound; delay(500); + setcolor( 9); rectangle(x1,y1,x2,y2); delay(500); +} + +boolean dropin(integer xc,integer yc,integer x1,integer y1,integer x2,integer y2) +/* Dropin returns True if the point xc,yc falls within the 1-2 rectangle. */ +{boolean dropin_result; +; + dropin_result=((xc>=x1) && (xc<=x2) && (yc>=y1) && (yc<=y2)); +return dropin_result; +} + +void test(integer x1,integer y1,integer x2,integer y2,integer x3,integer y3,integer x4,integer y4) +{; + cleardevice(); + rectangle(x1,y1,x2,y2); + rectangle(x3,y3,x4,y4); + flash(x1,y1,x2,y2); + flash(x3,y3,x4,y4); + + if (dropin(x3,y3,x1,y1,x2,y2) + || dropin(x3,y4,x1,y1,x2,y2) + || dropin(x4,y3,x1,y1,x2,y2) + || dropin(x4,y4,x1,y1,x2,y2)) + {; /* Overlaps */ + flash(x1,y1,x4,y4); + } else + {; /* Doesn't overlap- flash 'em both again */ + flash(x3,y3,x4,y4); /* backwards- why not...? */ + flash(x1,y1,x2,y2); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=1; initgraph(gd,gm,""); setcolor(9); + test(100,50,200,100,400,200,600,250); + test(100,50,200,100,120, 70,220,120); + test(100,50,200,100,150, 50,250,100); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/overscro.cpp b/engines/avalanche/overscro.cpp new file mode 100644 index 0000000000..6e0b9fca7a --- /dev/null +++ b/engines/avalanche/overscro.cpp @@ -0,0 +1,53 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + setactivepage(1); setcolor(9); + settextstyle(0,0,2); + outtextxy(0, 0,"This is a test to see whether you can"); + outtextxy(0, 20,"scroll text over the top of a picture."); + outtextxy(0, 40,"I was wondering whether it would work."); + outtextxy(0, 60,"Well, does it, or not?"); + outtextxy(0, 80,"If so, it could be useful for the"); + outtextxy(0,100,"Avalot title sequence."); + outtextxy(0,120,"Good, isn't it?"); + outtextxy(0,140,"The quick brown fox jumps over the"); + outtextxy(0,160,"lazy dog..."); + outtextxy(0,180,"This is the last line..."); + setactivepage(0); + gm=0; + for( gd=0; gd <= 640; gd ++) + {; + gm += 1; if (gm==8) gm=1; setcolor(gm); + line(gd,0,gm,350); + line(640-gd,0,640-gm,350); + } +/* for gd:=1 to 15 do + begin; + setfillstyle(1,gd); bar(gd*20,10,gd*20+19,100); + end;*/ +/* setfillstyle(1,6); bar(100,100,500,100);*/ gd=getpixel(0,0); + for( gm=8; gm <= 15; gm ++) setpalette(gm,egayellow); + for( gd=0; gd <= 199; gd ++) + {; + port[0x3c4]=2; port[0x3cf]=4; port[0x3c5]=8; port[0x3cf]=0; + move(mem[0xa000*80],mem[0xa000*0],16000); + port[0x3c4]=2; port[0x3cf]=4; port[0x3c5]=8; port[0x3cf]=0; + move(mem[0xa000*gd*80+16384],mem[0xa000*15920],80); + } +/* for gd:=0 to 199 do + begin; + port[$3C4]:=2; port[$3CF]:=4; port[$3C5]:=8; port[$3CF]:=0; + move(mem[$A000*160],mem[$A000*0],15920); + port[$3C4]:=2; port[$3CF]:=4; port[$3C5]:=8; port[$3CF]:=0; + move(mem[$A000*gd*80+16384],mem[$A000*15920],80); + move(mem[$A000*15920],mem[$A000*15840],80); + end;*/ +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/particle.cpp b/engines/avalanche/particle.cpp new file mode 100644 index 0000000000..e4c5b3ed91 --- /dev/null +++ b/engines/avalanche/particle.cpp @@ -0,0 +1,233 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +/*$R+*/ + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +struct markertype { + word length; + longint offset; + byte checksum; +}; + +string rawname; +array<0,1999,char> buffer,was; +word bufpos,bufsize; +fonttype font; +integer cpos; +char r; +boolean ok; + +const char marker = '\33'; + +void cursor() +{ + byte fv; +; + for( fv=12; fv <= 15; fv ++) + mem[0xa000*cpos+fv*80]=~(mem[0xa000*cpos+fv*80]); +} + +void xy() +{; + cpos=(bufpos / 80)*1280+(bufpos % 80); +} + +void show() +{ + word fv,orig,y; +; + for( fv=0; fv <= 1999; fv ++) + if (buffer[fv]!=was[fv]) + {; + orig=(fv / 80)*1280+(fv % 80); + for( y=0; y <= 15; y ++) + mem[0xa000*orig+y*80]=(byte)(font[buffer[fv]][y]); + } + xy(); + move(buffer,was,sizeof(buffer)); +} + +void sizeup() +{; + do { + switch (buffer[bufsize]) { + case marker: return; break; /* we've found it OK! */ + case '\0': bufsize -= 1; break; + default: bufsize += 1; + } + } while (!false); +} + +void graphics() +{ + integer gd,gm; + file<fonttype> fontfile; +; + gd=3; gm=1; initgraph(gd,gm,"c:\\bp\\bgi"); + assign(fontfile,"c:\\thomas\\lanche.fnt"); + reset(fontfile); fontfile >> font; close(fontfile); +} + +void helpscreen(); + +static byte l,fv; + +static void addon(char b, string st) +{; + buffer[3+80*l]=b; b -= 64; + buffer[5+80*l]=b; + move(st[1],buffer[7+80*l],length(st)); + l += 1; +} + +void helpscreen() +{ + array<0,1999,char> temp; + char r; +; + l=0; move(buffer,temp,2000); fillchar(buffer,sizeof(buffer),'\0'); + addon('B',"Bubble"); + addon('C',"Centre text"); + addon('D',"Don't add \20 (at end)"); + addon('F',"Italic Font"); + addon('G',"Bell"); + addon('H',"Not allocated (=backspace)"); + addon('I',"Not allocated (=tab)"); + addon('L',"Left-justify text"); + addon('K',"Keyboard input"); + addon('M',"Carriage return (same as \r key)"); + addon('P',"Scroll (Paragraph break)"); + addon('Q',"Yes/no scroll (question)"); + addon('R',"Roman font"); + addon('S',"Fix to sprite"); + addon('U',"Money (in œsd format)"); + addon('V',"View icon (number from ^S)"); + show(); do { r=readkey(); } while (!(! keypressed())); + cleardevice(); + fillchar(was,sizeof(was),'\0'); move(temp,buffer,2000); show(); +} + +void edit_it(); + +static void legit(char r) +{; /* it's a legit keystroke */ + move(buffer[bufpos],buffer[bufpos+1],1999-bufpos); + buffer[bufpos]=r; + bufpos += 1; show(); +} + +void edit_it() +{ + byte fv; +; + bufpos=0; + fillchar(was,sizeof(was),'\0'); show(); + do { + cursor(); r=readkey(); cursor(); + switch (r) { + case '\0': switch (readkey()) { /* extd keystrokes */ + case 'K': if (bufpos>0) {; bufpos -= 1; xy(); } break; /* Left */ + case 'M': if (bufpos<bufsize) {; bufpos += 1; xy(); } break; /* Right */ + case 'H': if (bufpos>80) {; bufpos -= 80; xy(); } break; /* Up */ + case 'P': if (bufpos<(cardinal)bufsize-79) {; bufpos += 80; xy(); } break; /* Down */ + case 's': if (bufpos>10) {; bufpos -= 10; xy(); } break; + case 't': if (bufpos<(cardinal)bufsize-10) {; bufpos += 10; xy(); } break; + case 'G': {; bufpos=0; xy(); } break; /* Home */ + case 'O': {; bufpos=bufsize; xy(); } break; /* End */ + case 'S': if (bufpos<bufsize) {; /* Del */ + move(buffer[bufpos+1],buffer[bufpos],1999-bufpos); show(); + } + break; + case ';': helpscreen(); break; + case 'A': legit('\357'); break; /* copyright symbol */ + case 'B': legit('\221'); break; /* uppercase AE */ + case 'C': legit('\222'); break; /* lowercase AE */ + } + break; + case '\10': if (bufpos>0) {; /* backspace */ + bufpos -= 1; + move(buffer[bufpos+1],buffer[bufpos],1999-bufpos); + show(); + } + break; + case '\33': {; + restorecrtmode(); + return; + } + break; /* end of editing */ + default: legit(r); + } + sizeup(); + } while (!false); +} + +void loadit() +{ + untyped_file f; +; + if (pos(".",rawname)==0) rawname=rawname+".raw"; + fillchar(buffer,sizeof(buffer),'\0'); + /*$I-*/ + assign(f,rawname); + reset(f,1); + if (ioresult!=0) + {; + output << string('\7')+"New file!"+'\7' << NL; + buffer[0]=marker; + return; + } + bufsize=filesize(f); + blockread(f,buffer,bufsize); + close(f); + while (buffer[bufsize]=='\0') bufsize -= 1; + if (buffer[bufsize]!=marker) + {; /* add on a marker */ + bufsize += 1; + buffer[bufsize]=marker; + } +} + +void saveit() +{ + untyped_file f; +; + output << "Saving " << rawname << ", " << bufsize << " bytes..." << NL; + assign(f,rawname); rewrite(f,1); + blockwrite(f,buffer,bufsize); + close(f); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + output << "Filename of .RAW file?"; input >> rawname >> NL; + loadit(); + ok=false; + do { + graphics(); + edit_it(); + output << "Now what?" << NL; + output << NL; + output << " Filename: " << rawname << NL; + output << " Size of text: " << bufsize << NL; + output << " Cursor position: " << bufpos << NL; + output << NL; + output << " C) Cancel this & continue edit" << NL; + output << " S) Save under current name" << NL; + output << " A) Save under a different name" << NL; + output << " X) Exit & lose all changes." << NL; + output << NL; + output << "Pick one!" << NL; + do { r=upcase(readkey()); } while (!(set::of('C','S','A','X', eos).has(r))); + switch (r) { + case 'X': ok=true; break; + case 'S': {; saveit(); exit(0); } break; + } + } while (!ok); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/pictemp.cpp b/engines/avalanche/pictemp.cpp new file mode 100644 index 0000000000..144d956853 --- /dev/null +++ b/engines/avalanche/pictemp.cpp @@ -0,0 +1,65 @@ +#include "ptoc.h" + + +#include "graph.h" + + +const integer picsize = 966; + +integer gd,gm; +untyped_file f; +pointer p; + +void save() +{ + varying_string<40> adf; untyped_file f; byte z; array<1,2,pointer> c; +string nam,screenname; + const string header = + string("This is a file from an Avvy game, and its contents are subject to ")+ + "copyright."+'\15'+'\12'+'\15'+'\12'+"Have fun!"+'\32'; + byte a /*absolute $A000:1200i*/; + byte bit; +; + nam="d:thingtmp.avd"; + screenname="Temp."; + assign(f,nam); + + assign(f,nam); rewrite(f,1); blockwrite(f,header[1],146); + blockwrite(f,screenname,31); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,a,12080); + } + close(f); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + + assign(f,"thinks.avd"); + getmem(p,picsize); + reset(f,1); + seek(f,65); + gd=10; gm=20; + + while (gm<120) + {; + if (! eof(f)) + blockread(f,p,picsize); + putimage(gd,gm,p,0); + gd += 70; + + if (gd==640) + {; + gd=10; gm += 40; + } + + } + + close(f); freemem(p,picsize); + save(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/pictemp2.cpp b/engines/avalanche/pictemp2.cpp new file mode 100644 index 0000000000..54e9e0dafa --- /dev/null +++ b/engines/avalanche/pictemp2.cpp @@ -0,0 +1,64 @@ +#include "ptoc.h" + + /* Get 'em back! */ +#include "graph.h" + + +const integer picsize = 966; +const integer number_of_objects = 17; + +const array<1,65,char> thinks_header = + string("This is an Avalot file, which is subject to copyright. Have fun.")+'\32'; + +integer gd,gm; +untyped_file f; +pointer p; +byte noo; + +void load() +{ + byte a0 /*absolute $A000:1200*/; + byte bit; + untyped_file f; +; + assign(f,"d:thingtmp.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); bit=getpixel(0,0); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + + load(); noo=0; + + assign(f,"thinks.avd"); + getmem(p,picsize); + rewrite(f,1); + blockwrite(f,thinks_header,65); + gd=10; gm=20; + + while (noo<=number_of_objects) + {; + getimage(gd,gm,gd+59,gm+29,p); + putimage(gd,gm,p,notput); + blockwrite(f,p,picsize); + gd += 70; + + if (gd==640) + {; + gd=10; gm += 40; + } + + noo += 1; + } + + close(f); freemem(p,picsize); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/pingo.cpp b/engines/avalanche/pingo.cpp new file mode 100644 index 0000000000..1bb3066bff --- /dev/null +++ b/engines/avalanche/pingo.cpp @@ -0,0 +1,229 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + PINGO Full-screen sub-parts of the game. */ + +#define __pingo_implementation__ + + +#include "pingo.h" + + +#include "graph.h" +#include "gyro.h" +#include "lucerna.h" +/*#include "Crt.h"*/ +#include "trip5.h" +#include "scrolls.h" + + +void dplot(integer x,integer y, string z) +{; + setcolor( 9); outtextxy(x,y ,z); + setcolor(11); outtextxy(x,y-1,z); +} + +void bosskey() +/*const + months : array[0..11] of char = 'JFMAMJJASOND'; + title = 'Net Profits'; + fish = #224; { à } +var fv:byte; gd,gm:integer; r:char; +begin; + dusk; delavvy; + setactivepage(3); mousepage(3); setvisualpage(3); off; + cleardevice; setfillstyle(xhatchfill,11); + settextstyle(1,0,4); settextjustify(1,1); + dplot(320,10,title); + settextstyle(1,0,0); setusercharsize(4,3,7,12); + for fv:=0 to 11 do + begin; + dplot(26+fv*52,187,months[fv]); + bar(fv*52,177-fv*14,51+fv*52,180); + rectangle(fv*52,177-fv*14,51+fv*52,180); + end; + settextstyle(0,0,1); + for fv:=1 to 177 do + begin; + gd:=random(630); gm:=random(160)+30; + setcolor(lightred); outtextxy(gd ,gm ,fish); + setcolor(yellow); outtextxy(gd+1,gm-1,fish); + end; + newpointer(6); { TTHand } + dawn; on; setbkcolor(1); repeat check until (mpress>0) or keypressed; + while keypressed do r:=readkey; setbkcolor(0); settextjustify(0,0); + dusk; setvisualpage(0); setactivepage(0); mousepage(0); dawn; + copy02;*/ +{ + byte fv; +; + dusk(); + off_virtual(); + for( fv=0; fv <= 1; fv ++) + {; + setactivepage(fv); + cleardevice(); + } + load(98); off(); + setactivepage(1); setvisualpage(1); + settextjustify(1,0); setcolor(8); + outtextxy(320,177,"Graph/Histo/Draw/Sample: \"JANJUN93.GRA\": (W3-AB3)"); + outtextxy(320,190,"Press any key or click the mouse to return."); + settextjustify(2,0); + on(); mousepage(1); newpointer(1); dawn(); + do { check(); } while (!((mpress>0) || keypressed())); + off(); on_virtual(); + major_redraw(); + + mousepage(cp); +} + +void copy02() /* taken from Wobble (below) */ +{ + byte a0 /*absolute $A000:0*/; byte a2/*absolute $A800:0*/; byte bit; +; + off(); + for( bit=0; bit <= 3; bit ++) {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; + port[0x3cf]=bit; + move(a0,a2,16000); + } on(); +} + +void copy03() /* taken from Wobble (below) */ +{ + byte a0 /*absolute $A000:0*/; byte a2/*absolute $AC00:0*/; byte bit; + byte squeaky_code; + + switch (visible) { + case m_virtual : { squeaky_code = 1; off_virtual(); } break; + case m_no : squeaky_code = 2; break; + case m_yes : { squeaky_code = 3; off(); } break; + } + + for( bit=0; bit <= 3; bit ++) {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; + port[0x3cf]=bit; + move(a0,a2,16000); + } + + switch (squeaky_code) { + case 1 : on_virtual(); break; + case 2 :; break; /* zzzz, it was off anyway */ + case 3 : on(); break; + } + +} + +void copypage(byte frp,byte top) /* taken from Copy02 (above) */ +{ + byte bit; +; + off(); + for( bit=0; bit <= 3; bit ++) {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; + port[0x3cf]=bit; + move(mem[0xa000*frp*pagetop],mem[0xa000*top*pagetop],16000); + } on(); +} + +void wobble() +{ + byte bit; + byte a2 /*absolute $A800:80i*/; +; + off(); + setactivepage(2); bit=getpixel(0,0); + cleardevice(); + for( bit=0; bit <= 3; bit ++) {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; + port[0x3cf]=bit; + move(mem[0xa000*cp*pagetop],a2,16000); + } + for( bit=0; bit <= 25; bit ++) + {; + setvisualpage(2); delay(bit*7); + setvisualpage(cp); delay(bit*7); + } + bit=getpixel(0,0); + draw_also_lines(); + setactivepage(1-cp); on(); +} + +void zonk(); + +static void zl(integer x1,integer y1,integer x2,integer y2) +{; + setlinestyle(0,0,3); setcolor( 1); line(x1,y1,x2,y2); + setlinestyle(0,0,1); setcolor(11); line(x1,y1,x2,y2); +} + +void zonk() +{ + integer xx,yy; +/* a0:byte absolute $A000:0; a3:byte absolute $A000:245760;*/ byte bit,fv; +; + off(); + copypage(3,1-cp); + { + triptype& with = tr[1]; + ; xx=with.x+with.a.xl / 2; yy=with.y; } + + setactivepage(3); cleardevice(); +/* for bit:=0 to 3 do begin; + port[$3C4]:=2; port[$3CE]:=4; + port[$3C5]:=1 shl bit; + port[$3CF]:=bit; + move(a0,a3,16000); + end;*/ + copypage(cp,3); off(); + zl(640,0,0,yy / 4); + zl(0,yy / 4,640,yy / 2); + zl(640,yy / 2,xx,yy); setbkcolor(yellow); + + for( bit=0; bit <= 255; bit ++) + {; + note(270-bit); setvisualpage(3); + note(2700-10*bit); delay(5); nosound; + note(270-bit); setvisualpage(cp); + note(2700-10*bit); delay(5); nosound; + } setactivepage(0); setbkcolor(black); on(); state(2); + copypage(1-cp,3); +} + +void winning_pic() +{ + byte bit; + untyped_file f; + char r; + + dusk(); + + assign(f,"finale.avd"); + reset(f,1); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,mem[0xa000*0],16000); + } + close(f); blitfix(); + + setvisualpage(0); + + dawn(); + + do { check(); } while (!(keypressed() || (mrelease>0))); + while (keypressed()) r=readkey(); + major_redraw(); +} + + diff --git a/engines/avalanche/pingo.h b/engines/avalanche/pingo.h new file mode 100644 index 0000000000..fdb49b7048 --- /dev/null +++ b/engines/avalanche/pingo.h @@ -0,0 +1,19 @@ +#ifndef __pingo_h__ +#define __pingo_h__ + + +void bosskey(); + +void copy02(); + +void copy03(); + +void copypage(byte frp,byte top); + +void wobble(); + +void zonk(); + +void winning_pic(); + +#endif diff --git a/engines/avalanche/plottest.cpp b/engines/avalanche/plottest.cpp new file mode 100644 index 0000000000..80f7937ca5 --- /dev/null +++ b/engines/avalanche/plottest.cpp @@ -0,0 +1,42 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; byte fv; +matrix<1,35,0,39,byte> a; +array<0,3,0,4,1,35,byte> b; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + for( gd=0; gd <= 39; gd ++) + for( gm=1; gm <= 35; gm ++) + a[gm][gd]=(gd+gm) % 16; + for( gd=0; gd <= 39; gd ++) + for( gm=1; gm <= 35; gm ++) + putpixel(gd+100,gm+100,a[gm][gd]); + + fillchar(b,sizeof(b),'\0'); + for( gm=1; gm <= 35; gm ++) + for( gd=0; gd <= 39; gd ++) + {; + for( fv=0; fv <= 3; fv ++) + {; + b[fv][gd / 8][gm]=(b[fv][gd / 8][gm] << 1); + b[fv][gd / 8][gm] += ((cardinal)(a[gm][gd] & (1 << fv)) >> fv); + } + } + + for( gd=1; gd <= 35; gd ++) + for( gm=0; gm <= 4; gm ++) + {; + for( fv=0; fv <= 3; fv ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << fv; port[0x3cf]=fv; + mem[0xa000*gd*80+gm]=b[fv][gm][gd]; + } + } +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/preview1.cpp b/engines/avalanche/preview1.cpp new file mode 100644 index 0000000000..aff9f1b5e5 --- /dev/null +++ b/engines/avalanche/preview1.cpp @@ -0,0 +1,122 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + + +array<0,3,palettetype> fxpal; + +void load() +{ + byte a0 /*absolute $A000:800*/; + byte bit; + untyped_file f; + + + assign(f,"preview2.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + + close(f); + bit=getpixel(0,0); + + settextjustify(1,1); + setcolor(3); + outtextxy(320,166,"...This is a preview of things to come..."); + setcolor(14); + outtextxy(320,176,"AVAROID"); + outtextxy(320,183,"(a space so dizzy)"); + setcolor(9); + outtextxy(320,194,"the next Avvy adventure-- in 256 colours."); + setcolor(7); + outtextxy(590,195,"Any key..."); +} + +void setup() +{ + integer gd,gm; + palettetype p; + + if (paramstr(1)!="jsb") exit(255); + gd=3; gm=0; initgraph(gd,gm,""); + getpalette(fxpal[0]); + + fillchar(p.colors,sizeof(p.colors),'\0'); /* Blank out the screen. */ + p.size=16; setallpalette(p); +} + +void wait() +{ + word w; char r; + + w=0; + do { + delay(1); w += 1; + } while (!(keypressed() || (w==15000))); + + while (keypressed()) r=readkey(); /* Keyboard sink. */ +} + +void show(byte n) +{ + setallpalette(fxpal[n]); + delay(55); +} + +shortint fades(shortint x) +{ + byte r,g,b; + + shortint fades_result; + r=x / 16; x=x % 16; + g=x / 4; b=x % 4; + if (r>0) r -= 1; if (g>0) g -= 1; if (b>0) b -= 1; + fades_result=(16*r+4*g+b); +/* fades:=x-1;*/ + return fades_result; +} + +void dawn(); + +static void calc(byte n) +{ + byte fv; + + fxpal[n]=fxpal[n-1]; + + for( fv=1; fv <= fxpal[n].size-1; fv ++) + fxpal[n].colors[fv]=fades(fxpal[n].colors[fv]); +} + +void dawn() +{ + byte fv; + + for( fv=1; fv <= 3; fv ++) calc(fv); + + for( fv=3; fv >= 0; fv --) show(fv); +} + +void dusk() +{ + byte fv; + + for( fv=1; fv <= 3; fv ++) show(fv); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + setup(); + load(); + dawn(); + wait(); + dusk(); + closegraph(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/qintro.cpp b/engines/avalanche/qintro.cpp new file mode 100644 index 0000000000..3843d80872 --- /dev/null +++ b/engines/avalanche/qintro.cpp @@ -0,0 +1,277 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ +#include "graph.h" +/*#include "Crt.h"*/ + + /* This is a stand-alone program. */ + +/* 0, black, remains 0. + Other numbers: the bits take precedence from the left. + e.g. for 9 = 1001, => fourth bit. + + First 1 is in: + + Fourth bit: 63 (egaWhite) + Third bit: 57 (egaLightBlue) + Second bit: 7 (light grey) + First bit: 1 (blue). */ + +const palettetype our_palette = + {16, + /* sic */ +{{ 0, 1, 57, 57, 7, 7, 7, 7, 63, 63, 63, 63, 63, 63, 63, 63}}}; + +typedef matrix<'\0','\377',1,16,byte> fonttype; + +fonttype f; +matrix<0,39,1,16,byte> next_line; + +byte next_bitline; + +byte displaycounter; + +boolean cut_out; + +word cut_out_time; + +array<1,117,varying_string<40> > x; + +byte this_line; + +word* skellern; + +/*$L intro.obj*/ +extern void introduction(); + +void graphmode(integer mode) +{ + registers regs; + + regs.ax=mode; + intr(0x10,regs); +} + +/* Firstly, port[$3C4]:=2; port[$3CF]:=4;, + Then port[$3C5]:=1 shl bit; port[$3CF]:=bit;. */ + +void loadfont() +{ + file<fonttype> ff; + + assign(ff,"avalot.fnt"); + reset(ff); + ff >> f; + close(ff); +} + +void calc_next_line() + /* This proc sets up next_line. */ +{ + string l; + byte fv,ff; + boolean oddlen; + byte start; + byte this_; + + fillchar(next_line,sizeof(next_line),'\0'); /* All blanks. */ + + if (this_line==117) + { + cut_out=true; + return; + } + + l=x[this_line]; + this_line += 1; + + start=(20-length(l) / 2)-1; + oddlen=odd(length(l)); + + for( fv=1; fv <= length(l); fv ++) + for( ff=1; ff <= 16; ff ++) + { + this_=f[l[fv]][ff]; + if (oddlen) + { /* Odd, => 4 bits shift to the right. */ + next_line[start+fv][ff] += this_ << 4; + next_line[start+fv-1][ff] += (cardinal)this_ >> 4; + } else + { /* Even, => no bit shift. */ + next_line[start+fv][ff]=this_; + } + } + next_bitline=1; +} + +void display() +{ + byte fv,ff; + + + if (next_bitline == 17) calc_next_line(); + + if (cut_out) + { + cut_out_time -= 1; + return; + } + + move(mem[0xa000*40],mem[0xa000*0],7960); + for( fv=0; fv <= 39; fv ++) + mem[0xa1f1*8+fv]=next_line[fv][next_bitline]; + next_bitline += 1; + +} + +void plot_a_star(integer x,integer y) +{ + byte ofs; + + ofs=x % 8; + x=x / 8; + mem[0xa000*x+y*40] += (cardinal)128 >> ofs; +} + +void plot_some_stars(integer y) +{ + byte fv,times; + + switch (Random(7)) { + case 1: times=1; break; + case 2: times=2; break; + case 3: times=3; break; + default: return; + } + + for( fv=1; fv <= times; fv ++) + plot_a_star(Random(320),y); +} + +void starry_starry_night() +{ + integer y; + byte bit; + + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + + for( bit=0; bit <= 2; bit ++) + { + port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( y=1; y <= 200; y ++) + plot_some_stars(y); + } +} + +void setupgraphics() /* Fix this proc. This prog SHOULDN'T use the + Graph unit. */ +{ + integer gd,gm; + + gd=3; gm=1; initgraph(gd,gm,""); +} + +void shovestars() +{ + move(mem[0xa000*0],mem[0xa000*40],7960); + fillchar(mem[0xa000*0],40,'\0'); + plot_some_stars(0); +} + +void do_next_line() +{ + byte bit; + + port[0x3c4]=2; port[0x3ce]=4; + + for( bit=0; bit <= 3; bit ++) + { + port[0x3c5]=1 << bit; port[0x3cf]=bit; + + switch (bit) { + case 0: if ((displaycounter % 10)==0) shovestars(); break; + case 1: if ((displaycounter % 2)==0) shovestars(); break; + case 2: shovestars(); break; + case 3: display(); break; /* The text. */ + } + } + + if (displaycounter==40) displaycounter=0; + +} + +void load_text() +{ + word fv; + char* c; + byte thisline; + + + c=addr(introduction()); + thisline=0; + fillchar(x,sizeof(x),'\0'); + + for( fv=1; fv <= 2456; fv ++) + { + switch (*c) { + case '\15': thisline += 1; break; + case '\12':/*nop*/; break; + default: x[thisline]=x[thisline]+*c; + } + + c += 1; + } +} + +void check_params() +{ + word s,o; integer e; + + if (paramstr(1)!="jsb") exit(0); + val(paramstr(2),s,e); if (e!=0) exit(0); + val(paramstr(3),o,e); if (e!=0) exit(0); + skellern=ptr(s,o+1); +} + +int main(int argc, const char* argv[]) +{ + + pio_initialize(argc, argv); + check_params(); + + setupgraphics(); + + randseed=177; checkbreak=false; + + load_text(); + + this_line=1; + + graphmode(0xd); + loadfont(); + + next_bitline=17; + displaycounter=0; + + cut_out_time=333; + + setallpalette(our_palette); + + starry_starry_night(); + + while ((cut_out_time>0) && (! keypressed())) + { + + *skellern=0; + + do_next_line(); + + displaycounter += 1; + + do {; } while (!(*skellern>0)); + } + + graphmode(3); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/qstars.cpp b/engines/avalanche/qstars.cpp new file mode 100644 index 0000000000..3a31a9e67a --- /dev/null +++ b/engines/avalanche/qstars.cpp @@ -0,0 +1,237 @@ +#include "ptoc.h" + + /* Demonstration of the Bigo II system. */ +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Rodent.h"*/ +/*#include "Tommys.h"*/ + +integer gd,gm; + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +boolean reverse; +word spinnum; +array<0,1,fonttype> f; +file<fonttype> ff; +array<0,7,0,15,0,79,byte> strip; +byte across; +word w; byte y; +byte charnum; +byte cfont; /* current font. 0=roman, 1=italic. */ + +char* c; + +const integer colours = 12; /* Run Workout to see possible values of these two. */ +const integer steps = 6; /* 60,30,20,15,12,10,6,5,4,3,2,1 */ +const integer gmtop = 360 / steps; + +/*$L credits.obj*/ extern void credits(); + +void bigo2(string date) +{ + integer gd,gm; + byte c; + palettetype p; + untyped_file f; pointer pp; word s; + + + getpalette(p); + setvisualpage(1); setactivepage(0); + assign(f,"logo.avd"); reset(f,1); + for( gd=7; gd <= 194; gd ++) + blockread(f,mem[0xa000*(gd*80)],53); + close(f); + s=imagesize(0,7,415,194); getmem(pp,s); getimage(0,7,415,194,pp); + + cleardevice(); + for( gd=1; gd <= 64; gd ++) + { + for( gm=0; gm <= gmtop; gm ++) + { + c=(c % colours)+1; +/* putpixel(trunc(sin(gm*steps*n)*gd*6)+320, + trunc(cos(gm*steps*n)*gd*3)+175,c); */ + if (c>5) continue_; + setcolor(c); arc(320,175,gm*steps,gm*steps+1,gd*6); + } + if (keypressed()) { closegraph(); exit(0); } + } + settextstyle(0,0,1); setcolor(13); + outtextxy(550,343,"(press any key)"); + + putimage(112,0,pp,orput); freemem(pp,s); + resetmouse; setvisualpage(0); +} + +void nextchar() /* Sets up charnum & cline for the next character. */ +{ + + c += 1; +} + +void getchar() +{ + do { + nextchar(); + + switch (*c) { + case '@': { cfont=1; nextchar(); } break; + case '^': { cfont=0; nextchar(); } break; + case '%': { closegraph(); exit(0); } break; + } + + } while (!((*c!='\15') && (*c!='\12'))); + + for( w=0; w <= 7; w ++) + for( y=0; y <= 15; y ++) + move(strip[w][y][1],strip[w][y][0],79); + + for( w=0; w <= 7; w ++) + for( y=0; y <= 15; y ++) + strip[w][y][79]=(byte)((strip[7][y][78] << (w+1)))+ + ((cardinal)f[cfont][*c][y] >> (7-w)); + + across=0; +} + +void scrolltext() +{ + byte c,w,y; + + across += 1; + if (across==8) getchar(); + + for( y=0; y <= 15; y ++) + for( w=0; w <= 1; w ++) + move(strip[across][y][0],mem[0xa000*24000+(y*2+w)*80],80); +} + +void do_stuff() +{ + switch (spinnum) { + case 50 ... 110: { + setfillstyle(1,14); + bar(0,315+(spinnum-50) / 3,640,315+(spinnum-50) / 3); + bar(0,316-(spinnum-50) / 3,640,316-(spinnum-50) / 3); + if (spinnum>56) + { + setfillstyle(1,13); + bar(0,315+(spinnum-56) / 3,640,315+(spinnum-56) / 3); + bar(0,316-(spinnum-56) / 3,640,316-(spinnum-56) / 3); + } + } + break; + case 150 ... 198: { + setfillstyle(1,0); + bar(0,315+(spinnum-150) / 3,640,315+(spinnum-150) / 3); + bar(0,316-(spinnum-150) / 3,640,316-(spinnum-150) / 3); + } + break; + case 200: scrolltext(); break; + } +} + +void setcol(byte which,byte what) +/*var dummy:byte;*/ +{; +/* setpalette(which,what); + asm +(* mov dx,$3DA; + in ax,dx; + + or ah,ah; + + mov dx,$3C0; + mov al,which; + out dx,al; + + mov dx,$3C0; + mov al,what; + out dx,al; + end; +(* dummy:=port[$3DA]; + port[$3C0]:=which; port[$3C0]:=what;*/ +} + +void bigo2go() +{ + palettetype p; byte c; boolean lmo; + boolean altnow,altbefore; + + for( gd=0; gd <= 13; gd ++) p.colors[gd]=0; + + setcol(13,24); /* murk */ setcol(14,38); /* gold */ + setcol(15,egawhite); /* white- of course */ + p.colors[13]=24; p.colors[14]=38; p.colors[15]=egawhite; + + /***/ + + p.colors[5]=egawhite; + p.colors[4]=egalightcyan; + p.colors[3]=egacyan; + p.colors[2]=egalightblue; + p.colors[1]=egablue; + + /***/ + + c=1; p.size=16; lmo=false; + setallpalette(p); + + do { +/* if reverse then + begin + dec(c); if c=0 then c:=colours; + end else + begin + inc(c); if c>colours then c:=1; + end; + for gm:=1 to colours do + case p.colors[gm] of + egaWhite: begin p.colors[gm]:=egaLightcyan; setcol(gm,egaLightCyan); end; + egaLightcyan: begin p.colors[gm]:=egaCyan; setcol(gm,egaCyan); end; + egaCyan: begin p.colors[gm]:=egaLightblue; setcol(gm,egaLightblue); end; + egaLightblue: begin p.colors[gm]:=egaBlue; setcol(gm,egaBlue); end; + egaBlue: begin p.colors[gm]:=0; setcol(gm,0); end; + end; + p.colors[c]:=egaWhite; setcol(c,egaWhite); + + AltBefore:=AltNow; AltNow:=testkey(sAlt);*/ + + if (anymousekeypressed) lmo=true; + if (keypressed()) lmo=true; + + /* if (AltNow=True) and (AltBefore=False) then reverse:=not reverse;*/ + + do_stuff(); + if (spinnum<200) spinnum += 1; + } while (!lmo); +} + +void parse_cline() +{ + integer e; + + if (paramstr(1)!="jsb") + { + output << "Not a standalone program." << NL; exit(255); + } +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + parse_cline(); + + gd=3; gm=1; initgraph(gd,gm,""); + assign(ff,"avalot.fnt"); reset(ff); ff >> f[0]; close(ff); + assign(ff,"avitalic.fnt"); reset(ff); ff >> f[1]; close(ff); + + c=addr(credits()); c -= 1; + + fillchar(strip,sizeof(strip),'\0'); + reverse=false; spinnum=0; across=7; charnum=1; cfont=0; + bigo2("1189"); /* 1189? 79? 2345? 1967? */ + bigo2go(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/rawupd.cpp b/engines/avalanche/rawupd.cpp new file mode 100644 index 0000000000..a911e1d918 --- /dev/null +++ b/engines/avalanche/rawupd.cpp @@ -0,0 +1,71 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ + +searchrec s; +string x,y; +longint hash_time,s_time; +boolean s_exists; + +void find_out_about_s(string name) +{ + searchrec ss; +; + findfirst(name,anyfile,ss); + s_exists=doserror==0; + + if (s_exists) + s_time=ss.time; +} + +void get_y() +{ + y=x; + if (set::of(range('0','9'), eos).has(x[2])) + y[1]='h'; else + if (x[3]=='K') + y[1]='a'; else + y[1]='s'; +} + +void rename_it() +{ + untyped_file f; + + output << x << " -> " << y; + assign(f,x); reset(f); rename(f,y); close(f); + output << " ...done." << NL; +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + output << NL; + findfirst("#*.*",anyfile,s); + while (doserror==0) + { + x=s.name; + get_y(); + hash_time=s.time; + output << format(x,15); clreol; + find_out_about_s(y); + if (s_exists) + { + output << ": s exists and is "; + if (s_time<hash_time) + output << "NEWER!" << NL; + else if (s_time==hash_time) + output << string("equal.")+'\15'; + else output << "older." << NL; + } else + { + output << " ... NO S FOUND! Renaming..."; + rename_it(); + } + + findnext(s); + } + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/readsez.cpp b/engines/avalanche/readsez.cpp new file mode 100644 index 0000000000..744d221fd0 --- /dev/null +++ b/engines/avalanche/readsez.cpp @@ -0,0 +1,80 @@ +#include "ptoc.h" + + + +struct markertype { + word length; + longint offset; + byte checksum; +}; + +struct sezheader { + array<1,2,char> initials; /* should be "TT" */ + word gamecode; + word revision; /* as 3- or 4-digit code (eg v1.00 = 100) */ + longint chains; /* number of scroll chains */ + longint size; /* total size of all chains */ +}; + +untyped_file f; +longint number; +markertype marker; +sezheader sezhead; +array<0,1999,char> x; +word fv; +byte sum; + +byte sumup() +{ + word fv; byte total; +byte sumup_result; +; + total=0; + for( fv=0; fv <= marker.length; fv ++) + {; + total += ord(x[fv]); + } + sumup_result=total; +return sumup_result; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + output << "READ-SEZ by TT." << NL; output << NL; + assign(f,"avalot.sez"); reset(f,1); + seek(f,255); blockread(f,sezhead,sizeof(sezhead)); + {; + if (sezhead.initials!="TT") + {; + output << "Not a valid Sez file!" << NL; + exit(0); + } + output << "Number of chains in file = " << sezhead.chains << NL; + output << "Total size of all chains = " << sezhead.size << " bytes." << NL; + } + output << NL; + output << "Number of scrollchain to display?"; input >> number >> NL; + seek(f,longint(262)+number*longint(7)); blockread(f,marker,7); + {; + output << "Scrollchain no. " << number << NL; + output << "Length: " << marker.length << NL; + output << "Offset: " << marker.offset << NL; + output << NL; + output << "Contents:" << NL; + seek(f,longint(270)+sezhead.chains*longint(7)+marker.offset); + blockread(f,x,marker.length+1); + for( fv=0; fv <= marker.length; fv ++) x[fv] -= 3+177*fv*marker.length; /* unscramble */ + for( fv=0; fv <= marker.length; fv ++) output << x[fv]; + output << NL; sum=sumup(); + output << "Checksum in file: " << marker.checksum << ". Actual value: " << sum << '.' << NL; + output << NL; + if (sum!=marker.checksum) + {; + output << "Bleargh! Checksum failed!" << NL; + exit(0); + } + } + close(f); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/reginam.cpp b/engines/avalanche/reginam.cpp new file mode 100644 index 0000000000..c85dee39a9 --- /dev/null +++ b/engines/avalanche/reginam.cpp @@ -0,0 +1,91 @@ +#include "ptoc.h" + + +const array<1,36,char> letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; +varying_string<30> name; +varying_string<5> number; + +void alphanum(); + +static string z; + +static byte p; + + +static void replace(char what,char whatwith) +{; + p=pos(what,z); if (p>0) z[p]=whatwith; +} + +void alphanum() +{ + byte fv; + +; + z=""; + for( fv=1; fv <= length(name); fv ++) + if (set::of(range('A','Z'), eos).has(name[fv])) + z=z+'7'+name[fv]; else + z=z+upcase(name[fv]); + replace(' ','1'); + replace('.','2'); + replace('-','3'); + replace('\'','4'); + replace('"','5'); + replace('!','6'); + replace(',','9'); + replace('?','0'); + + for( fv=1; fv <= length(number); fv ++) + number[fv]=upcase(number[fv]); + + name=z+'8'+number; +} + +void scramble() +{ + byte fv,what; +; + for( fv=1; fv <= length(name); fv ++) + {; + what=pos(name[fv],letters); + what += 177; + what += (fv+1)*3; + name[fv]=letters[(what % 36)+1-1]; + } +} + +void checks() +{ + byte fv,total; +; + total=177; + for( fv=1; fv <= length(name); fv ++) + total += ord(name[fv]); + name=string('T')+name+letters[total % 36-1]; +} + +void negate() +{ + byte fv; +; + name[1]='N'; + for( fv=2; fv <= length(name); fv ++) + name[fv]=letters[37-pos(name[fv],letters)-1]; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + output << "Registrant's name?"; input >> name >> NL; + output << "And number (eg, A1)?"; input >> number >> NL; + alphanum(); + output << "Name = " << name << NL; + scramble(); + output << "Scrambled = " << name << NL; + checks(); + output << "With checks = " << name << NL; + negate(); + output << "Or, negated, = " << name << NL; +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/sackb1.cpp b/engines/avalanche/sackb1.cpp new file mode 100644 index 0000000000..800738821c --- /dev/null +++ b/engines/avalanche/sackb1.cpp @@ -0,0 +1,52 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + SACKBLASTER-1 The temporary mod player. */ + +/* This is SackBlaster version 1.0, using Mark J. Cox's MODOBJ routines. + When Cameron finishes his mod player I'll use his routines, DV. However, + this will do for the time being. */ + +#define __sackb1_implementation__ + + +#include "sackb1.h" + + +/*$L v:MOD-obj.OBJ*/ /* Link in Object file */ +/*$F+*/ /* force calls to be 'far'*/ + +extern void modvolume(integer v1,integer v2,integer v3,integer v4); /*Can do while playing*/ +extern void moddevice(integer& device); +extern void modsetup(integer& status,integer device,integer mixspeed,integer pro,integer loop,string& stri); +extern void modstop(); +extern void modinit(); +/*$F-*/ + +void sb_start(string md) +{ + integer dev,mix,stat,pro,loop; + + modinit(); + dev=7; /* Sound Blaster */ + mix = 10000; /*use 10000 normally */ + pro = 0; /*Leave at 0*/ + loop =4; /*4 means mod will play forever*/ + modvolume (255,255,255,255); /* Full volume */ + modsetup ( stat, dev, mix, pro, loop, md ); +} + +void sb_stop() +{; + modstop(); +} + +void sb_link() /* At the moment, this does nothing. */ +{; +} + + diff --git a/engines/avalanche/sackb1.h b/engines/avalanche/sackb1.h new file mode 100644 index 0000000000..b671da2a76 --- /dev/null +++ b/engines/avalanche/sackb1.h @@ -0,0 +1,14 @@ +#ifndef __sackb1_h__ +#define __sackb1_h__ + + +/*#include "Crt.h"*/ + + +void sb_start(string md); + +void sb_stop(); + +void sb_link(); /* At the moment, this does nothing. */ + +#endif diff --git a/engines/avalanche/sackb3.cpp b/engines/avalanche/sackb3.cpp new file mode 100644 index 0000000000..b48379d364 --- /dev/null +++ b/engines/avalanche/sackb3.cpp @@ -0,0 +1,23 @@ +#include "ptoc.h" + +/*$M 16384,0,0*/ + + /* to demonstrate the SBVoice Unit */ + /* Copyright 1991 Amit K. Mathur, Windsor, Ontario */ + +/*#include "SBVoice.h"*/ + + +int main(int argc, const char* argv[]) +{ +pio_initialize(argc, argv); +if (paramcount>0) { + loadvoice(paramstr(1),0,0); + sb_output(seg(soundfile),ofs(soundfile)+26); + do { + output << "Demo of the SBVoice Unit, Copyright 1991 by Amit K. Mathur --- "; + } while (!(statusword==0)); +} else + output << "Usage: DEMO [d:\\path\\]filename.voc" << NL; +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/sackblas.cpp b/engines/avalanche/sackblas.cpp new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/engines/avalanche/sackblas.cpp diff --git a/engines/avalanche/saving.cpp b/engines/avalanche/saving.cpp new file mode 100644 index 0000000000..6f35a21ada --- /dev/null +++ b/engines/avalanche/saving.cpp @@ -0,0 +1,48 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; +byte a /*absolute $A000:(15*80)*/; +byte bit; +untyped_file f; + +void load(string nam) +{ + byte z; + array<1,4,pointer> a; + untyped_file f; word s; + string check; +; + assign(f,nam); + reset(f,1); + blockread(f,check,41); + blockread(f,check,13); + blockread(f,check,31); + s=imagesize(0,0,getmaxx(),75); + for( z=1; z <= 2; z ++) + {; + getmem(a[z],s); + blockread(f,a[z],s); + setactivepage(0); + putimage(0,15+(z-1)*75,a[z],0); + freemem(a[z],s); + } + close(f); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + load("d:britain.avd"); + assign(f,"c:\\sleep\\test.ega"); rewrite(f,1); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,a,12000); + } + close(f); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/scr_1.cpp b/engines/avalanche/scr_1.cpp new file mode 100644 index 0000000000..5118cd8558 --- /dev/null +++ b/engines/avalanche/scr_1.cpp @@ -0,0 +1,89 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + + +const varying_string<4> codes = " ßÜÛ"; + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +byte x,xx,y; +string title,fn; +file<fonttype> f; +fonttype font; +byte code; + + +typedef array<1,3840,byte> atype; + +void save() +{ + file<atype> f; + word fv; + atype a /*absolute $B800:0*/; +; + assign(f,"TEXT1.SCR"); + rewrite(f); f << a; close(f); +} + +void centre(byte y, string z) +{; + gotoxy(40-length(z) / 2,y); output << z; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; +/* write('Title?'); readln(title); + write('Font?'); readln(fn); */ + textattr=0; clrscr; + title="Bug Alert!"; fn=""; + for( xx=1; xx <= 77; xx ++) + {; + gotoxy(Random(80)+1,Random(24)+1); + switch (Random(2)) { + case 0: textattr=red; break; + case 1: textattr=lightred; break; + } + switch (Random(4)) { + case 0: output << '*'; break; + case 1: output << '\17'; break; + case 2: output << 'ù'; break; + case 3: output << 'ú'; break; + } + } + textattr=12; + assign(f,"c:\\thomas\\ttsmall.fnt"); + reset(f); f >> font; close(f); + for( y=0; y <= 3; y ++) + {; + for( x=1; x <= length(title); x ++) + {; + for( xx=7; xx >= 0; xx --) + {; + code=(byte)(((1 << xx) & font[title[x]][y*2])>0)+ + (byte)(((1 << xx) & font[title[x]][y*2+1])>0)*2; + gotoxy(1+x*8-xx,y+1); + if (code>0) output << codes[code+1-1]; + } + } + /*if wherex<>1 then writeln;*/ + } + textattr=red; + centre(7,"An internal error has just occurred within the program."); + + textattr=white; gotoxy(26, 9); output << "Error number: "; + textattr=lightred; output << " "; + textattr=white; gotoxy(27,10); output << "at location: "; + textattr=lightred; output << " "; + centre(12,"This screen should never come up..."); + centre(13,"but it just has!"); + textattr=15; + centre(15,"So, please tell Thorsoft about this as soon as"); + centre(16,"possible, so that we can fix it."); + textattr=red; + centre(20,"Thanks..."); + save(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/scr_2.cpp b/engines/avalanche/scr_2.cpp new file mode 100644 index 0000000000..7a88efce95 --- /dev/null +++ b/engines/avalanche/scr_2.cpp @@ -0,0 +1,113 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + + +const varying_string<4> codes = " ßÜÛ"; + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +byte x,xx,y; +string qq; +file<fonttype> f; +fonttype font; +byte code; + + +typedef array<1,3840,byte> atype; + +void save() +{ + file<atype> f; + word fv; + atype a /*absolute $B800:0*/; +; + assign(f,"TEXT2.SCR"); + rewrite(f); f << a; close(f); +} + +void centre(byte y, string z) +{ + byte fv; +; + for( fv=1; fv <= length(z); fv ++) + {; + gotoxy(39-length(z) / 2+fv,y); + if (odd(fv+y)) textattr=2; else textattr=cyan; + if (z[fv]!='\40') output << z[fv]; + } +} + +void line(byte yy, string title) +{ + const integer offset = 5; +; + for( y=1; y <= 6; y ++) + {; + qq=""; + for( x=1; x <= length(title); x ++) + {; + for( xx=7; xx >= 0; xx --) + {; + code=(byte)(((1 << xx) & font[title[x]][y*2-offset])>0)+ + (byte)(((1 << xx) & font[title[x]][y*2+1-offset])>0)*2; + qq=qq+codes[code+1-1]; + } + } + centre(y+yy,qq); + } +} + +void chips() +{ + byte fv,x,y; +; + for( fv=0; fv <= 1; fv ++) + {; + textattr=120; + for( y=2; y <= 6; y ++) + {; + gotoxy(fv*67+3,y); output << " "; if (fv==1) output << ' '; + } + gotoxy(fv*67+4,4); + if (fv==0) output << "RAM"; else output << "CRAM"; + textattr=7; + for( x=0; x <= 1; x ++) + for( y=2; y <= 6; y ++) + {; gotoxy(fv*67+2+x*(6+fv),y); output << 'ð'; } + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + textattr=0; clrscr; + chips(); + assign(f,"c:\\thomas\\ttsmall.fnt"); + reset(f); f >> font; close(f); + line(0,"Out of"); + line(4,"memory!"); + centre(11,"Yes, RAM cram strikes again- Avvy has just run out of RAM (not the"); + centre(12,"hydraulic, woolly or village kinds.) Fortunately, there are a few things"); + centre(13,"you can do about this:"); + textattr=3; + for( xx=15; xx <= 17; xx ++) + {; + gotoxy(23,xx); output << '\20'; + } + textattr=2; + gotoxy(25,15); output << "Don't run Avvy in a DOS shell."; + gotoxy(25,16); output << "If that fails, try un-installing your TSRs."; + gotoxy(25,17); output << "If you've got DOS 5ù0 or above, try using"; + gotoxy(28,18); textattr=3; output << "dos=high"; + textattr=2; output << ','; + textattr=3; output << " loadhigh"; + textattr=2; output << " and"; + textattr=3; output << " devicehigh"; + textattr=2; output << '.'; + gotoxy(28,19); output << "See your DOS manual for details..."; + centre(23,"Sorry for any inconvenience..."); + save(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/scr_3.cpp b/engines/avalanche/scr_3.cpp new file mode 100644 index 0000000000..0c866fc7da --- /dev/null +++ b/engines/avalanche/scr_3.cpp @@ -0,0 +1,93 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + + +const varying_string<4> codes = " ßÜÛ"; + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +byte x,xx,y; +string qq; +file<fonttype> f; +fonttype font; +byte code; + + +typedef array<1,3840,byte> atype; + +void save() +{ + file<atype> f; + word fv; + atype a /*absolute $B800:0*/; +; + assign(f,"TEXT3.SCR"); + rewrite(f); f << a; close(f); +} + +void centre(byte y, string z) +{ + byte fv; +; + for( fv=1; fv <= length(z); fv ++) + {; + gotoxy(39-length(z) / 2+fv,y); + if (z[fv]!='\40') output << z[fv]; + } +} + +void line(byte cx,byte cy, string title) +{; + for( y=0; y <= 4; y ++) + {; + qq=""; + for( x=1; x <= length(title); x ++) + {; + for( xx=7; xx >= 0; xx --) + {; + code=(byte)(((1 << xx) & font[title[x]][y*2])>0)+ + (byte)(((1 << xx) & font[title[x]][y*2+1])>0)*2; + qq=qq+codes[code+1-1]; + } + } + gotoxy(cx,cy+y); output << qq; + } +} + +void big_t() +{ + text t; + string x; + byte y; +; + assign(t,"c:\\avalot\\t.txt"); reset(t); y=1; + while (! eof(t)) + {; + t >> x >> NL; + gotoxy(1,y); output << x; y += 1; + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + textattr=4; clrscr; + assign(f,"c:\\thomas\\ttsmall.fnt"); + reset(f); f >> font; close(f); + textattr=4; line(19,4,"hanks"); + textattr=6; line(23,8,"for"); + line(7,12,"playing"); textattr += 8; + line(12,16,"Avalot."); + textattr=12; big_t(); + textattr=8; gotoxy(40,2); output << "(c) 1994, Mike, Mark and Thomas Thurman."; + textattr=11; gotoxy(50,10); output << "* Goodbyte! *"; + textattr=10; gotoxy(9,20); output << '\20'; + textattr=12; output << " If you'd like to see yet more of these games, then don't forget to"; + gotoxy(12,21); output << "register, or your"; clreol; + gotoxy(12,22); output << "for the rest of your life!"; + gotoxy(60,22); output << "(Only joking!)"; + save(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/scr_4.cpp b/engines/avalanche/scr_4.cpp new file mode 100644 index 0000000000..605a1dc51b --- /dev/null +++ b/engines/avalanche/scr_4.cpp @@ -0,0 +1,89 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + + +const varying_string<4> codes = " ÞÝÛ"; + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +byte x,xx,y; +string qq; +file<fonttype> f; +fonttype font; +byte code; + +void centre(byte y, string z) +{ + byte fv; +; + for( fv=1; fv <= length(z); fv ++) + {; + gotoxy(39-length(z) / 2+fv,y); + if (z[fv]!='\40') output << z[fv]; + } +} + +void line(byte cy, string title) +{; + for( y=0; y <= 6; y ++) + {; + qq=""; + for( x=1; x <= length(title); x ++) + {; + for( xx=3; xx >= 0; xx --) + {; + code=(byte)(((1 << (xx*2)) & font[title[x]][y])>0)+ + (byte)(((1 << (xx*2+1)) & font[title[x]][y])>0)*2; + qq=qq+codes[code+1-1]; + } + } + centre(cy+y,qq); + } +} + +void big_t() +{ + text t; + string x; + byte y; +; + assign(t,"c:\\avalot\\t.txt"); reset(t); y=1; + while (! eof(t)) + {; + t >> x >> NL; + gotoxy(1,y); output << x; y += 1; + } +} + +void box(byte x1,byte y1,byte x2,byte y2, string z) +{ + byte fv; +; + gotoxy(x1,y1); output << z[1]; /* tl */ + gotoxy(x2,y1); output << z[2]; /* tr */ + gotoxy(x1,y2); output << z[3]; /* bl */ + gotoxy(x2,y2); output << z[4]; /* br */ + for( fv=y1+1; fv <= y2-1; fv ++) + {; + gotoxy(x1,fv); output << z[5]; /* verticals */ + gotoxy(x2,fv); output << z[6]; + } + gotoxy(x1+1,y1); for( fv=x1+1; fv <= x2-1; fv ++) output << z[7]; + gotoxy(x1+1,y2); for( fv=x1+1; fv <= x2-1; fv ++) output << z[8]; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + textattr=26; clrscr; + assign(f,"c:\\thomas\\ttsmall.fnt"); + reset(f); f >> font; close(f); + line(3,"CONGRATULATIONS!"); + textattr=30; box(4,1,74,11,"ɻȼººÍÍ"); + textattr=33; box(6,2,72,10,"/\\\\/°°Üß"); + textattr=30; centre(12,"Well done!"); + textattr=27; centre(14,"You completed the game!"); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/scr_5.cpp b/engines/avalanche/scr_5.cpp new file mode 100644 index 0000000000..e90e55e455 --- /dev/null +++ b/engines/avalanche/scr_5.cpp @@ -0,0 +1,93 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + + +const varying_string<4> codes = " ßÜÛ"; + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +byte x,xx,y; +string qq; +file<fonttype> f; +fonttype font; +byte code; + + +typedef array<1,3840,byte> atype; + +void save() +{ + file<atype> f; + word fv; + atype a /*absolute $B800:0*/; +; + assign(f,"TEXT5.SCR"); + rewrite(f); f << a; close(f); +} + +void line(byte cx,byte cy, string title) +{; + for( y=0; y <= 4; y ++) + {; + qq=""; + for( x=1; x <= length(title); x ++) + {; + for( xx=7; xx >= 0; xx --) + {; + code=(byte)(((1 << xx) & font[title[x]][y*2])>0)+ + (byte)(((1 << xx) & font[title[x]][y*2+1])>0)*2; + qq=qq+codes[code+1-1]; + } + } + gotoxy(cx,cy+y); output << qq; + } +} + +void uline() +{ + byte fv,ff; +; + for( fv=1; fv <= 10; fv ++) + {; + gotoxy(16-fv,21-fv); textattr=fv; + for( ff=1; ff <= fv; ff ++) output << "ÄÍÍ-"; + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + textattr=0; clrscr; + assign(f,"c:\\thomas\\ttsmall.fnt"); + reset(f); f >> font; close(f); + textattr=11; + line( 1, 3,"Two at"); + line( 3, 7,"once?!"); + textattr=9; gotoxy(55,4); output << string('\4')+'\377'; + textattr=3; output << "You're trying to run"; + gotoxy(54,5); output << "two copies of Avalot"; + gotoxy(54,6); output << "at once."; + gotoxy(57,8); output << "Although this "; textattr=9; output << "is"; + textattr=3; + gotoxy(54,9); output << "usually possible, it's"; + gotoxy(54,10); output << "probably more sensible"; + gotoxy(54,11); output << "to type "; + textattr=7; output << "EXIT "; + textattr=3; output << "now, which"; + gotoxy(54,12); output << "should return you to the"; + gotoxy(54,13); output << "first copy in memory."; + + textattr=11; gotoxy(55,15); output << "BUT:"; textattr=9; + gotoxy(40,16); output << "If you want to run two copies anyway,"; + gotoxy(40,17); output << "or you think that I've got it wrong,"; + gotoxy(40,18); output << "(even computers can make mistakes!) then"; + gotoxy(40,19); output << "try running the game again, but this time"; + gotoxy(40,20); output << "use "; textattr=7; output << "/i "; + textattr=9; output << "on the command line."; + uline(); + + save(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/scr_9.cpp b/engines/avalanche/scr_9.cpp new file mode 100644 index 0000000000..e1363470fd --- /dev/null +++ b/engines/avalanche/scr_9.cpp @@ -0,0 +1,21 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + +text t; +string x; +byte fv; +untyped_file f; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + assign(f,"v:paralogo.scr"); + clrscr; + reset(f,1); + blockread(f,mem[0xb800*0],4000); + close(f); + gotoxy(1,1); insline; + gotoxy(1,23); clreol; +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/scrolls.cpp b/engines/avalanche/scrolls.cpp new file mode 100644 index 0000000000..4a2a0d9fc0 --- /dev/null +++ b/engines/avalanche/scrolls.cpp @@ -0,0 +1,781 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + SCROLLS The scroll driver. */ +/* $D-*/ +#define __scrolls_implementation__ + +/*$V-*/ + +#include "scrolls.h" + +#include "lucerna.h" + #include "Graph.h" + /*#include "Crt.h"*/ +#include "trip5.h" +#include "enhanced.h" + /*#include "Dos.h"*/ +#include "logger.h" + #include "Acci.h" +#include "basher.h" +#include "visa.h" +#include "timeout.h" + + +const integer roman = 0; +const integer italic = 1; + +const integer halficonwidth = 19; /* Half the width of an icon. */ + +integer dix,diy; +array<roman,italic,raw> ch; +byte cfont; /* Current font */ + +integer dodgex,dodgey; +byte param; /* For using arguments code */ + +byte use_icon; + +void state(byte x) /* Sets "Ready" light to whatever */ +{ + byte page_; + + if (ledstatus==x) return; /* Already like that! */ + switch (x) { + case 0: setfillstyle(1,black); break; /* Off */ + case 1: setfillstyle(9,green); break; /* Half-on (menus) */ + case 2: setfillstyle(1,green); break; /* On (kbd) */ + case 3: setfillstyle(6,green); break; /* Hit a key */ + } + super_off(); + for( page_=0; page_ <= 1; page_ ++) + { setactivepage(page_); bar(419,195,438,197); } super_on(); + ledstatus=x; +} + +void easteregg() +{ + word fv,ff; + + background(15); + for( fv=4; fv <= 100; fv ++) + for( ff=0; ff <= 70; ff ++) + { sound(fv*100+ff*10); delay(1); } + nosound; setcolor(10); + settextstyle(0,0,3); settextjustify(1,1); outtextxy(320,100,"GIED"); + settextstyle(0,0,1); settextjustify(0,2); + background(0); +} + +void say(integer x,integer y, string z) /* Fancy FAST screenwriting */ +{ + const integer locol = 2; + byte xx,yy,ox,bit,lz,t; integer yp; boolean offset; + matrix<1,12,1,80,byte> itw; + + offset=x % 8==4; x=x / 8; lz=length(z); ox=0; + log_scrollline(); + + for( xx=1; xx <= lz; xx ++) + { + switch (z[xx]) { + case '\22': { cfont=roman; log_roman(); } break; + case '\6': { cfont=italic; log_italic(); } break; + default: { + ox += 1; + for( yy=1; yy <= 12; yy ++) itw[yy][ox]=~ ch[cfont][z[xx]][yy+1]; + log_scrollchar(z[xx]); + } + } + } + + lz=ox; + if (offset) + { /* offsetting routine */ + lz += 1; + for( yy=1; yy <= 12; yy ++) + { + bit=240; itw[yy][lz]=255; + for( xx=1; xx <= lz; xx ++) + { + t=itw[yy][xx]; + itw[yy][xx]=bit+t / 16; + bit=t << 4; + } + } + } + yp=x+y*80+(1-cp)*pagetop; + for( yy=1; yy <= 12; yy ++) + { + yp += 80; + for( bit=0; bit <= locol; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + move(itw[yy],mem[0xa000*yp],lz); + } + } +} + +/* Here are the procedures that Scroll calls */ /* So they must be... */ /*$F+*/ + +void normscroll() +{ + const array<1,8,char> egg = string("\20\f\25\7\b")+"***"; + const array<1,8,char> e = "(c) 1994"; + char r; + boolean oktoexit; + + state(3); seescroll=true; + off_virtual(); + on(); newpointer(4); + mousepage(1-cp); + + if (demo) get_demorec(); + + do { + do { + check(); /* was "checkclick;" */ + + #ifdef RECORD slowdown(); basher::count += 1; #endif + + if (demo) + { + if (demo_ready()) flush(); + if (keypressede()) exit(0); + } else + if (keypressede()) flush(); + } while (!((mrelease>0) || (buttona1()) || (buttonb1()))); + + + if (mrelease==0) + { + inkey(); + if (aboutscroll) + { + move(e[2-1],e[1-1],7); + e[8-1]=inchar; + if (egg==e) easteregg(); + } + oktoexit=set::of('\15','\33','+','#', eos).has(inchar); + if (! oktoexit) errorled(); + } + + } while (!((oktoexit) || (mrelease>0))); + #ifdef RECORD record_one(); #endif + screturn=r=='#'; /* "back door" */ + state(0); seescroll=false; mousepage(cp); off(); +} + +void dialogue() +{ + char r; + + state(3); seescroll=true; r='\0'; + newpointer(6); on(); + mousepage(1-cp); + do { + do { + check(); + if (mrelease>0) + { + if ((mx>=(cardinal)dix-65) && (my>=(cardinal)diy-24) && (mx<=(cardinal)dix- 5) && (my<=(cardinal)diy-10)) + r='Y'; + if ((mx>=(cardinal)dix+ 5) && (my>=(cardinal)diy-24) && (mx<=(cardinal)dix+65) && (my<=(cardinal)diy-10)) + r='N'; + } else + if (keypressede()) + { + inkey(); + r=upcase(inchar); + } + } while (!(r!='\0')); + } while (!(set::of('Y','N','O','J', eos).has(r))); /* Yes, Ja, Oui, or No, Non, Nein */ + screturn=r!='N'; + state(0); seescroll=false; mousepage(cp); off(); +} + +void music_scroll(); + + +static void store_(byte what, tunetype& played) +{ + move(played[2],played[1],sizeof(played)-1); + played[31]=what; +} + + + +static boolean they_match(tunetype& played) +{ + byte fv,mistakes; + + boolean they_match_result; + mistakes=0; + + for( fv=1; fv <= sizeof(played); fv ++) + if (played[fv]!=tune[fv]) + { + mistakes += 1; + } + + they_match_result=mistakes<5; + return they_match_result; +} + +void music_scroll() +{ + char r; + byte value; + + byte last_one,this_one; + + tunetype played; + + + state(3); seescroll=true; on(); + newpointer(4); + do { + do { + check(); /* was "checkclick;" */ + if (keypressede()) flush(); + } while (!((mpress>0) || (buttona1()) || (buttonb1()))); + + if (mpress==0) + { + inkey(); + r=upcase(inchar); if (r=='Z') r='Y'; /* Euro keyboards */ + + value=pos(r,keys); + + if (value>0) + { + + last_one=this_one; + this_one=value; + + sound(notes[this_one]); + delay(100); + nosound; + + if (! dna.ringing_bells) + { /* These handle playing the right tune. */ + + if (this_one<last_one) + store_(lower, played); else + + if (this_one==last_one) + store_(same, played); else + + store_(higher, played); + + if (they_match(played)) + { + screturn=true; + off(); + state(0); seescroll=false; + + set_up_timer(8,procjacques_wakes_up,reason_jacques_waking_up); + return; + } + + } + + } + + } + + } while (!((set::of('\15','\33','+','#', eos).has(r)) || (mpress>0))); + screturn=false; + off(); + state(0); seescroll=false; +} + +/* ThatsAll, so put us back to */ /*$F-*/ + +void resetscrolldriver() /* phew */ +{ + scrollbells=0; cfont=roman; log_epsonroman(); use_icon=0; + interrogation=0; /* always reset after a scroll comes up. */ +} + +void dingdongbell() /* Pussy's in the well. Who put her in? Little... */ +{ + byte fv; + + for( fv=1; fv <= scrollbells; fv ++) errorled(); /* ring the bell "x" times */ +} + +void dodgem() /* This moves the mouse pointer off the scroll so that + you can read it. */ +{ + xycheck(); /* Mx & my now contain xy pos of mouse */ + dodgex=mx; dodgey=my; /* Store 'em */ + hopto(dodgex,underscroll); /* Move the pointer off the scroll. */ +} + +void undodgem() /* This is the opposite of Dodgem. It moves the + mouse pointer back, IF you haven't moved it in the meantime. */ +{ + xycheck(); + if ((mx==(cardinal)dodgex) && (my==(cardinal)underscroll)) + /* No change, so restore the pointer's original position. */ + hopto(dodgex,dodgey); +} + +void geticon(integer x,integer y, byte which) +{ + untyped_file f; + pointer p; + + assign(f,"icons.avd"); + reset(f,1); + which -= 1; + seek(f,which*426); + getmem(p,426); + blockread(f,p,426); + putimage(x,y,p,0); + freemem(p,426); + close(f); +} + +void block_drop(string fn, integer xl,integer yl,integer y) +{ + untyped_file f; byte bit; + integer fv; word st; + + st=(y-1)*80+(40-xl / 2)+((1-cp)*pagetop); + + assign(f,fn+".avd"); + reset(f,1); + + for( fv=1; fv <= yl; fv ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,mem[0xa000*st+(fv*80)],xl); + } + + close(f); + bit=getpixel(0,0); +} + +void drawscroll(proc gotoit) /* This is one of the oldest procs in the game. */ +{ + byte b,groi; integer lx,ly,mx,my,ex,ey; boolean centre; + byte icon_indent; + + off_virtual(); + setvisualpage(cp); setactivepage(1-cp); + oncandopageswap=false; /* On can now no longer swap pages. So we can + do what we want without its interference! */ + log_epsonroman(); /* Scrolls always START with Roman. */ + lx=0; ly=scrolln*6; + for( b=1; b <= scrolln; b ++) + { + ex=length(scroll[b])*8; if (lx<ex) lx=ex; + } + mx=320; my=100; /* Getmaxx & getmaxy div 2, both. */ + lx=lx / 2; ly -= 2; + + if (set::of(range(1,34), eos).has(use_icon)) lx += halficonwidth; + + off(); +/* mblit(mx-lx-46,my-ly-6,mx+lx+15,my+ly+6,0,3);*/ + setfillstyle(1,7); + setcolor(7); + pieslice(mx+lx,my-ly,360,90,15); + pieslice(mx+lx,my+ly,270,360,15); + setcolor(4); + arc(mx+lx,my-ly,360,90,15); + arc(mx+lx,my+ly,270,360,15); + bar(mx-lx-30,my+ly+6,mx+lx,my+ly); + bar(mx-lx-30,my-ly-6,mx+lx,my-ly); + bar(mx-lx-15,my-ly,mx+lx+15,my+ly); + setfillstyle(1,8); + pieslice(mx-lx-31,my-ly,360,180,15); + pieslice(mx-lx-31,my+ly,180,360,15); + setfillstyle(1,4); + bar(mx-lx-30,my-ly-6,mx+lx,my-ly-6); + bar(mx-lx-30,my+ly+6,mx+lx,my+ly+6); + bar(mx-lx-15,my-ly,mx-lx-15,my+ly); + bar(mx+lx+15,my-ly,mx+lx+15,my+ly); + ex=mx-lx; ey=my-ly; + mx -= lx; my -= ly+2; + setcolor(0); centre=false; + + switch (use_icon) { + case 0: icon_indent=0; break; /* No icon. */ + case 1 ... 33: { /* Standard icon */ + geticon(mx,my+ly / 2,use_icon); + icon_indent=53; + } + break; + case 34: { block_drop("about",28,76,15); icon_indent=0; } break; + case 35: { block_drop("gameover",52,59,71); icon_indent=0; } break; + } + + for( b=1; b <= scrolln; b ++) + { + switch (scroll[b][length(scroll[b])]) { + case '\3' : { centre=true; scroll[b][0] -= 1; } break; + case '\14' : { centre=false; scroll[b][0] -= 1; } break; + case '\21' : { settextjustify(1,1); + dix=mx+lx; diy=my+ly; scroll[b][1]='\40'; groi=getpixel(0,0); +/* inc(diy,14);*/ + shbox(dix-65,diy-24,dix- 5,diy-10,"Yes."); + shbox(dix+ 5,diy-24,dix+65,diy-10,"No."); + } + break; + } + + if (centre) + say(320-length(scroll[b])*4+icon_indent,my,scroll[b]); + else + say(mx+icon_indent,my,scroll[b]); + log_scrollendline(centre); + my += 12; + } + + underscroll=my+3; + setvisualpage(1-cp); dingdongbell(); + my=getpixel(0,0); dropsok=false; dodgem(); + + gotoit(); + + undodgem(); dropsok=true; + log_divider(); + setvisualpage(cp); mousepage(cp); off(); +/* mblit(ex-46,ey-6,ex+lx*2+15,ey+ly*2+6,3,0);*/ + mblit((ex-46) / 8,ey-6,1+(ex+lx*2+15) / 8,ey+ly*2+6,cp,1-cp); + blitfix(); + oncandopageswap=true; /* Normality again */ + on(); settextjustify(0,0); /*sink*/ + resetscrolldriver(); + if (mpress>0) after_the_scroll=true; +} + +void bubble(proc gotoit) +{ + integer xl,yl,my,xw,yw; byte fv; array<1,3,pointtype> p; + pointer rp1,rp2; /* replace: 1=bubble, 2=pointer */ + integer xc; /* x correction */ + + setvisualpage(cp); setactivepage(1-cp); + oncandopageswap=false; /* On can now no longer swap pages. So we can + do what we want without its interference! */ + mousepage(1-cp); /* Mousepage */ + + setfillstyle(1,talkb); setcolor(talkb); off(); + + xl=0; yl=scrolln*5; + for( fv=1; fv <= scrolln; fv ++) + if (textwidth(scroll[fv])>xl) xl=textwidth(scroll[fv]); + xl=xl / 2; + + xw=xl+18; yw=yl+7; + my=yw*2-2; xc=0; + + if ((talkx-xw)<0) xc=-(talkx-xw); + if ((talkx+xw)>639) xc=639-(talkx+xw); + + p[1].x=talkx-10; p[1].y=yw; + p[2].x=talkx+10; p[2].y=yw; + p[3].x=talkx; p[3].y=talky; + +/* mblit(talkx-xw+xc,7,talkx+xw+xc,my,0,3); + mblit(talkx-10,my,talkx+10,talky,0,3);*/ + bar(xc+talkx-xw+10,7,talkx+xw-10+xc,my); + bar(xc+talkx-xw,12,talkx+xw+xc,my-5); + pieslice(xc+talkx+xw-10,12,360,90,9); /* TR */ + pieslice(xc+talkx+xw-10,my-5,270,360,9); /* BR */ + pieslice(xc+talkx-xw+10,12,90,180,9); /* TL */ + pieslice(xc+talkx-xw+10,my-5,180,270,9); /* BL */ + fillpoly(3,p.body()); + + setcolor(talkf); yl -= 3; settextjustify(1,2); + for( fv=0; fv <= scrolln-1; fv ++) + outtextxy(talkx+xc,(fv*10)+12,scroll[fv+1]); + for( fv=1; fv <= scrolln; fv ++) /* These should be separate loops. */ + log_bubbleline(fv,param,scroll[fv]); + log_divider(); + + setvisualpage(1-cp); + dingdongbell(); + oncandopageswap=false; + on(); dropsok=false; gotoit(); off(); dropsok=true; + mblit((talkx-xw+xc) / 8,7,1+(talkx+xw+xc) / 8,my,3,1-cp); + mblit((talkx-10) / 8,my,1+(talkx+10) / 8,talky,3,1-cp); + blitfix(); + + setvisualpage(cp); + settextjustify(0,0); on(); /*sink;*/ + oncandopageswap=true; + resetscrolldriver(); + if (mpress>0) after_the_scroll=true; +} + +boolean ask(string question) +{ + boolean ask_result; + display(question+'\15'+'\21'); + if (screturn && (Random(2)==0)) /* half-and-half chance */ + { + display("...Positive about that?\23I\26\r\21"); /* be annoying! */ + if (screturn && (Random(4)==3)) /* another 25% chance */ + display("\n100% certain\??!\n\26\r\21"); /* be very annoying! */ + } + ask_result=screturn; + return ask_result; +} + +void resetscroll() +{ + scrolln=1; fillchar(scroll,sizeof(scroll),'\0'); +} + +void natural() /* Natural state of bubbles */ +{ + talkx=320; talky=200; talkb=8; talkf=15; +} + +string lsd() +{ + string x; + + string lsd_result; + if (dna.pence<12) + { /* just pence */ + x=strf(dna.pence)+'d'; + } else + if (dna.pence<240) + { /* shillings & pence */ + x=strf(dna.pence / longint(12))+'/'; + if ((dna.pence % longint(12))==0) x=x+'-'; else x=x+strf(dna.pence % longint(12)); + } else /* L, s & d */ + x=string('œ')+strf(dna.pence / longint(240))+'.'+strf((dna.pence / longint(12)) % longint(20))+'.'+ + strf(dna.pence % longint(12)); + if (dna.pence>12) x=x+" (that's "+strf(dna.pence)+"d)"; + lsd_result=x; + return lsd_result; +} + +void calldrivers(); + /* Was the mouse cursor virtual on entry to this proc? */ + +static void strip(string& q) +{ + while (pos("\40",q[length(q)])>0) q[0] -= 1; /* strip trailing spaces */ +} + + + +static void solidify(byte n) +{ + if (pos("\40",scroll[n])==0) return; /* no spaces */ + /* so there MUST be a space there, somewhere... */ + do { + scroll[n+1]=string(scroll[n][length(scroll[n])])+scroll[n+1]; + scroll[n][0] -= 1; + } while (!(scroll[n][length(scroll[n])]=='\40')); + strip(scroll[n]); +} + +void calldrivers() +{ + word fv; byte nn; char nnn; boolean mouthnext; + boolean call_spriterun; /* Only call sprite_run the FIRST time. */ + + boolean was_virtual; + + + nosound; state(0); screturn=false; mouthnext=false; + call_spriterun=true; + + switch (buffer[bufsize]) { + case '\4': bufsize -= 1; break; /* ^D = (D)on't include pagebreak */ + case '\2':case '\21':; break; /* ^B = speech (B)ubble, ^Q = (Q)uestion in dialogue box */ + default: { + bufsize += 1; buffer[bufsize]='\20'; + } + } + for( fv=1; fv <= bufsize; fv ++) + if (mouthnext) + { + if (buffer[fv]=='\23') param=0; else + switch (buffer[fv]) { + case RANGE_10('0','9'): param=ord(buffer[fv])-48; + break; + case RANGE_26('A','Z'): param=ord(buffer[fv])-55; + break; + } + mouthnext=false; + } else + switch (buffer[fv]) { + case '\20': { + if ((scrolln==1) && (scroll[1]=="")) flush(); + + if (call_spriterun) sprite_run(); + call_spriterun=false; + + was_virtual=visible==m_virtual; + if (was_virtual) off_virtual(); + drawscroll(normscroll); + if (was_virtual) on_virtual(); + resetscroll(); + if (screturn) return; + } + break; + case '\7': scrollbells += 1; break; /* #7 = "Bel" */ + case '\2': { + if ((scrolln==1) && (scroll[1]=="")) flush(); + + if (call_spriterun) sprite_run(); + call_spriterun=false; + switch (param) { + case 0: natural(); break; /* Not attached: generic bubble with no speaker. */ + case RANGE_9(1,9): if ((param>numtr) || (! tr[param].quick)) + { /* not valid */ + errorled(); + natural(); + } + else tr[param].chatter(); + break; /* Normal sprite talking routine. */ + case 10 ... 36: { + quasiped_type& with = quasipeds[param]; + /* Quasi-peds. (This routine performs the same + thing with QPs as triptype.chatter does with the + sprites.) */ + { + pedtype& with1 = peds[with.whichped]; + + talkx=with1.x; talky=with1.y; /* Position. */ + } + talkf=with.fgc; talkb=with.bgc; /* Colours. */ + } + break; + default: { errorled(); natural(); } /* not valid */ + } + + was_virtual=visible==m_virtual; + if (was_virtual) off_virtual(); + bubble(normscroll); + if (was_virtual) on_virtual(); + resetscroll(); + if (screturn) return; + } + break; + case '\25': { + { dnatype& with = dna; + switch (param) { + case 1: display(lsd()+'\4'); break; /* insert cash balance (recursion) */ + case 2: display(words[first_password+with.pass_num].w+'\4'); break; + case 3: display(with.like2drink+'\4'); break; + case 4: display(with.favourite_song+'\4'); break; + case 5: display(with.worst_place_on_earth+'\4'); break; + case 6: display(with.spare_evening+'\4'); break; + /* ... */ + case 9: display(strf(with.cat_x)+','+strf(with.cat_y)+'\4'); break; + case 10: switch (with.box_contents) { + case '\0': { /* Sixpence. */ + dixi('q',37); /* You find the sixpence. */ + with.pence += 6; + with.box_contents=nowt; + points(2); return; + } + break; + case nowt: display("nothing at all. It's completely empty."); break; + default: display(get_better(with.box_contents)+'.'); + } + break; + case 11: { + nn=1; + for( nnn='\1'; nnn <= numobjs; nnn ++) + if (with.obj[nnn]) + { + nn += 1; + display(get_better(nnn)+", "+'\4'); + } + } + break; + }} + } + break; + case '\26': use_icon=param; break; + case '\15': scrolln += 1; break; + case '\21': { + if (call_spriterun) sprite_run(); + call_spriterun=false; + + scrolln += 1; scroll[scrolln]='\21'; + was_virtual=visible==m_virtual; + if (was_virtual) off_virtual(); + drawscroll(dialogue); + if (was_virtual) on_virtual(); + resetscroll(); + } + break; + case '\23' : mouthnext=true; break; + case '\11' : for( nn=1; nn <= 9; nn ++) scroll[scrolln]=scroll[scrolln]+' '; + break; + default: + { /* add new char */ + if (length(scroll[scrolln])==50) + { + solidify(scrolln); + scrolln += 1; + } + scroll[scrolln]=scroll[scrolln]+buffer[fv]; + } + } +} + +void display(string z) +{ + bufsize=length(z); + move(z[1],buffer,bufsize); + calldrivers(); +} + +void loadfont() +{ + file<raw> f; + + assign(f,"avalot.fnt"); reset(f); f >> ch[0]; close(f); + assign(f,"avitalic.fnt"); reset(f); f >> ch[1]; close(f); + assign(f,"ttsmall.fnt"); reset(f); f >> little; close(f); +} + +void okay() +{ + display("Okay!"); +} + +void musical_scroll() +{ + boolean was_virtual; + + display(string("To play the harp...\r\rUse these keys:\r\n")+ + "Q W E R T Y U I O P [ ]\r\rOr press Enter to stop playing.\4"); + + sprite_run(); + + was_virtual=visible==m_virtual; + if (was_virtual) off_virtual(); + drawscroll(music_scroll); + if (was_virtual) on_virtual(); + resetscroll(); +} + +class unit_scrolls_initialize { + public: unit_scrolls_initialize(); +}; +static unit_scrolls_initialize scrolls_constructor; + +unit_scrolls_initialize::unit_scrolls_initialize() { + loadfont(); + resetscrolldriver(); +} diff --git a/engines/avalanche/scrolls.h b/engines/avalanche/scrolls.h new file mode 100644 index 0000000000..d71ec5d5e2 --- /dev/null +++ b/engines/avalanche/scrolls.h @@ -0,0 +1,33 @@ +#ifndef __scrolls_h__ +#define __scrolls_h__ + + +#include "gyro.h" +#include "joystick.h" + + +const boolean aboutscroll = false; /* Is this the about box? */ + +void state(byte x); /* Sets "Ready" light to whatever */ + +void drawscroll(proc gotoit); /* This is one of the oldest procs in the game. */ + +void bubble(proc gotoit); + +void resetscroll(); + +void calldrivers(); + +void display(string z); + +boolean ask(string question); + +void natural(); + +string lsd(); + +void okay(); /* Says "Okay!" */ + +void musical_scroll(); + +#endif diff --git a/engines/avalanche/sequence.cpp b/engines/avalanche/sequence.cpp new file mode 100644 index 0000000000..00c838a95a --- /dev/null +++ b/engines/avalanche/sequence.cpp @@ -0,0 +1,92 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + SEQUENCE The sequencer. */ + +#define __sequence_implementation__ + + +#include "sequence.h" + + +/*#include "Gyro.h"*/ +/*#include "Timeout.h"*/ +/*#include "Celer.h"*/ +/*#include "Trip5.h"*/ + + +void then_show(byte what) +{ + byte fv; +; + for( fv=1; fv <= seq_length; fv ++) + if (seq[fv]==0) + {; + seq[fv]=what; + return; + } +} + +void first_show(byte what) +{; + /* First, we need to blank out the entire array. */ + fillchar(seq,sizeof(seq),'\0'); + + /* Then it's just the same as then_show. */ + then_show(what); + +} + +void then_flip(byte where,byte ped) +{; + then_show(now_flip); + + dna.flip_to_where=where; + dna.flip_to_ped=ped; +} + +void start_to_close() +{; + lose_timer(reason_sequencer); + set_up_timer(7,procsequence,reason_sequencer); +} + +void start_to_open() +{; + dna.user_moves_avvy=false; /* They can't move. */ + stopwalking; /* And they're not moving now. */ + start_to_close(); /* Apart from that, it's the same thing. */ +} + +void call_sequencer(); + + /* This proc is called by Timeout when it's time to do another frame. */ +static void shove_left() +{; + move(seq[2],seq[1],seq_length-1); /* Shift everything to the left. */ +} + +void call_sequencer() +{; + switch (seq[1]) { + case 0: return; break; /* No more routines. */ + case 1 ... 176: {; /* Show a frame. */ + show_one(seq[1]); + shove_left(); + } + break; + case 177: {; + user_moves_avvy=true; + fliproom(flip_to_where,flip_to_ped); /* 177 = Flip room. */ + if (seq[1]==177) shove_left(); + } + break; + } + + start_to_close(); /* Make sure this proc gets called again. */ +} + diff --git a/engines/avalanche/sequence.h b/engines/avalanche/sequence.h new file mode 100644 index 0000000000..a6c59a6126 --- /dev/null +++ b/engines/avalanche/sequence.h @@ -0,0 +1,32 @@ +#ifndef __sequence_h__ +#define __sequence_h__ + + +const integer now_flip = 177; + +const integer seq_length = 10; + + +#ifdef __sequence_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN array<1,seq_length,byte> seq; +#undef EXTERN +#define EXTERN extern + + +void first_show(byte what); + +void then_show(byte what); + +void then_flip(byte where,byte ped); + +void start_to_close(); + +void start_to_open(); + +void call_sequencer(); + +#endif diff --git a/engines/avalanche/setup.cpp b/engines/avalanche/setup.cpp new file mode 100644 index 0000000000..60f91e38f1 --- /dev/null +++ b/engines/avalanche/setup.cpp @@ -0,0 +1,1268 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ +/*#include "Tommys.h"*/ +#include "joystick.h" + + +const integer selected = 0x60; /* Background for selected lines of text. */ + +typedef array<1,400,varying_string<80> > mobytype; + +typedef set byteset; /* Define its typemark. */ + +enum option {_overrideegacheck, _zoomystart, _loadfirst, _numlockhold, _usemouse, + _controller, _logging, _logfile, + + _joystickinstalled, _joytop, _joybottom, _joyleft, _joyright, _joymidx, + _joymidy, _joycentringfactor, _whichjoy, _quiet, _soundcard, + _baseaddress, _irq, _dma, + _samplerate, _keyboardclick, + + _printer, + + option_error, last_option}; + + +mobytype* moby; +word mobylength; +byte background; /* The current background colour, times 16. */ +byte line; /* Which line you're on in the menus. */ + +string registrant,reginum; + +byte num_printers; +array<1,10,string> printers; +string this_printer; + +/* THE STATUS VARIABLES: */ + + /* general */ + +boolean override_ega; +boolean skip_loading_screens; +string load_particular; +boolean force_numlock; +boolean ignore_mouse; +boolean use_keyboard; +boolean log_to_printer; +boolean log_to_file; +string log_filename; +string autotype; + + /* joystick */ + +boolean has_a_joystick; +word jtop,jbottom,jleft,jright,jmidx,jmidy; +byte jcentre; +word whichjoy; + + /* sound */ + +boolean suppress_sfx; +byte your_card; +longint samplerate; +longint sound_addr,sound_irq,sound_dma; +boolean wants_keyclick; + + /* registration */ + +string regname,regnum,chkname,chknum; + + +string trim_and_caps(string this_) +{ + byte fv; + + string trim_and_caps_result; + while ((this_[1]==' ') && (this_!="")) + Delete(this_,1,1); /* Strip leading blanks. */ + while ((this_[length(this_)]==' ') && (this_!="")) + this_[0] -= 1; /* Strip trailing blanks. */ + for( fv=1; fv <= length(this_); fv ++) this_[fv]=upcase(this_[fv]);/* And capitalise. */ + trim_and_caps_result=this_; + return trim_and_caps_result; +} + +option string_2_option(string field) +{ + + option string_2_option_result; + field=trim_and_caps(field); + + if (field=="OVERRIDEEGACHECK") string_2_option_result=_overrideegacheck; else + if (field=="ZOOMYSTART") string_2_option_result=_zoomystart; else + if (field=="LOADFIRST") string_2_option_result=_loadfirst; else + if (field=="NUMLOCKHOLD") string_2_option_result=_numlockhold; else + if (field=="USEMOUSE") string_2_option_result=_usemouse; else + if (field=="CONTROLLER") string_2_option_result=_controller; else + if (field=="LOGGING") string_2_option_result=_logging; else + if (field=="LOGFILE") string_2_option_result=_logfile; else + + /* joystick */ + + if (field=="JOYSTICKINSTALLED") string_2_option_result=_joystickinstalled; else + if (field=="JOYTOP") string_2_option_result=_joytop; else + if (field=="JOYBOTTOM") string_2_option_result=_joybottom; else + if (field=="JOYLEFT") string_2_option_result=_joyleft; else + if (field=="JOYRIGHT") string_2_option_result=_joyright; else + if (field=="JOYMIDX") string_2_option_result=_joymidx; else + if (field=="JOYMIDY") string_2_option_result=_joymidy; else + if (field=="JOYCENTRINGFACTOR") string_2_option_result=_joycentringfactor; else + if (field=="WHICHJOY") string_2_option_result=_whichjoy; else + + /* sound */ + + if (field=="QUIET") string_2_option_result=_quiet; else + if (field=="SOUNDCARD") string_2_option_result=_soundcard; else + if (field=="SAMPLERATE") string_2_option_result=_samplerate; else + if (field=="KEYBOARDCLICK") string_2_option_result=_keyboardclick; else + if (field=="BASEADDRESS") string_2_option_result=_baseaddress; else + if (field=="IRQ") string_2_option_result=_irq; else + if (field=="DMA") string_2_option_result=_dma; else + + /* printer */ + + if (field=="PRINTER") string_2_option_result=_printer; else + + + string_2_option_result=option_error; + + return string_2_option_result; +} + +void clear_to(byte colour) +{ + window(1,1,80,24); background=colour*16; textattr=background; clrscr; +} + +void centre(byte where,byte colour, string what) +{ + textattr=background+colour; + gotoxy(40-length(what) / 2,where); + output << what; +} + +void load_file() +{ + text t; + + mobylength=0; + /*$I-*/ + assign(t,"avalot.ini"); + reset(t); + /*$I+*/ + + if (ioresult!=0) /* No file. */ + { + output << "SETUP: Avalot.ini not found!" << NL; + exit(255); + } + + while (! eof(t)) + { + mobylength += 1; /* Preincrement mode. */ + t >> (*moby)[mobylength] >> NL; + } + + close(t); + +} + +string strhf(longint x) /* assume x is +ve */ +{ + const array<0,16,char> hexdigits = "0123456789ABCDEF"; + string y; longint v; + + string strhf_result; + v=x; y=""; + + while (v!=0) + { + y=string(hexdigits[v % longint(16)-1])+y; + v=v / longint(16); + } + + strhf_result=string('$')+y; + return strhf_result; +} + +void update_moby(); + +static byte fv; + +static string field; + + +static void get_field(string x) +{ + if (pos(";",x)!=0) x=copy(x,1,pos(";",x)-1); + + if (pos("=",x)==0) + field=""; + else + { + field=copy(x,0,pos("=",x)-1); + while (field[1]==' ') field=copy(field,2,255); + } +} + + + +static string yn1(boolean x) + { string yn1_result; + if (x) yn1_result="Yes"; else yn1_result="No"; return yn1_result; + } + + + +static string kj(boolean x) + { string kj_result; + if (x) kj_result="Keyboard"; else kj_result="Joystick"; return kj_result; + } + + + +static string put_logcodes() +{ + byte q; + + string put_logcodes_result; + q=(byte)(log_to_file)+(byte)(log_to_printer)*2; + + switch (q) { + case 0: put_logcodes_result="No"; break; + case 1: put_logcodes_result="Disk"; break; + case 2: put_logcodes_result="Printer"; break; + } + return put_logcodes_result; +} + + + +static string card() +{ + string card_result; + switch (your_card) { + case 0: card_result="None"; break; + case 1: card_result="SB"; break; + case 2: card_result="SBPro"; break; + case 3: card_result="SB16"; break; + case 4: card_result="Pas"; break; + case 5: card_result="PasPlus"; break; + case 6: card_result="Pas16"; break; + case 7: card_result="Aria"; break; + case 8: card_result="WinSound"; break; + case 9: card_result="Gravis"; break; + case 10: card_result="DacLPT"; break; + case 11: card_result="StereoDacs"; break; + case 12: card_result="StereoOn1"; break; + case 13: card_result="Speaker"; break; + } + return card_result; +} + + + + +static void entail(string x) +{ + string before,after; + + before=copy((*moby)[fv],1,pos("=",(*moby)[fv])-1); + + if (pos(";",(*moby)[fv])==0) + { + (*moby)[fv]=before+'='+x; + } else + { + after=copy((*moby)[fv],pos(";",(*moby)[fv]),255); + + (*moby)[fv]=before+'='+x+' '; + while (length((*moby)[fv])<25) (*moby)[fv]=(*moby)[fv]+' '; + + (*moby)[fv]=(*moby)[fv]+after; + } +} + +void update_moby() +{ + option o; + + + + + + for( fv=1; fv <= mobylength; fv ++) + { + get_field((*moby)[fv]); + + if (field!="") + { + o=string_2_option(field); + + if (o==_overrideegacheck) entail(yn1(override_ega)); else + if (o==_zoomystart) entail(yn1(skip_loading_screens)); else + if (o==_loadfirst) entail(load_particular); else + if (o==_numlockhold) entail(yn1(force_numlock)); else + if (o==_usemouse) entail(yn1(ignore_mouse)); else + if (o==_controller) entail(kj(use_keyboard)); else + if (o==_logging) entail(put_logcodes()); else + if (o==_logfile) entail(log_filename); else + + /* joystick */ + + if (o==_joystickinstalled) entail(yn1(has_a_joystick)); else + if (o==_joytop) entail(strf(jtop)); else + if (o==_joybottom) entail(strf(jbottom)); else + if (o==_joyleft) entail(strf(jleft)); else + if (o==_joyright) entail(strf(jright)); else + if (o==_joymidx) entail(strf(jmidx)); else + if (o==_joymidy) entail(strf(jmidy)); else + if (o==_joycentringfactor) entail(strf(jcentre)); else + if (o==_whichjoy) entail(strf(whichjoy)); else + + /* sound */ + + if (o==_quiet) entail(yn1(suppress_sfx)); else + if (o==_soundcard) entail(card()); else + if (o==_samplerate) entail(strf(samplerate)); else + if (o==_baseaddress) entail(strhf(sound_addr)); else + if (o==_irq) entail(strf(sound_irq)); else + if (o==_dma) entail(strf(sound_dma)); else + if (o==_keyboardclick) entail(yn1(wants_keyclick)); else + + /* printer */ + + if (o==_printer) entail(this_printer); + + } + } +} + +void save_file() +{ + text t; + word fv; + + textattr=10; + update_moby(); + + clear_to(black); + centre(14,14,"Saving..."); + + assign(t,"avalot.ini"); + rewrite(t); + + for( fv=1; fv <= mobylength; fv ++) + { + t << (*moby)[fv] << NL; + } + + close(t); +} + +boolean detect() +{ + word x,y,xo,yo; + byte count; + + boolean detect_result; + count=0; + if (joystickpresent()) + { + detect_result=true; + return detect_result; + } + readjoya(xo,yo); + do { + if (count<7) count += 1; /* Take advantage of "flutter" */ + if (count==6) + { + centre(7,1,"The Bios says you don't have a joystick. However, it's often wrong"); + centre(8,1,"about such matters. So, do you? If you do, move joystick A to"); + centre(9,1,"continue. If you don't, press any key to cancel."); + } + readjoya(x,y); + } while (!((keypressed()) | (x!=xo) || (y!=yo))); + detect_result=~ keypressed(); + return detect_result; +} + +void display() +{ + gotoxy(28,10); output << jleft << " "; + gotoxy(28,11); output << jright; + gotoxy(28,12); output << jtop << " "; + gotoxy(28,13); output << jbottom; +} + +void readjoy(word& x,word& y) +{ + if (whichjoy==1) readjoya(x,y); else readjoyb(x,y); +} + +void getmaxmin() +{ + word x,y; char r; + + clear_to(green); + centre(5,1,"Rotate the joystick around in a circle, as far from the centre as it"); + centre(6,1,"can get. Then press any key."); + centre(7,1,"Press Esc to cancel this part."); + centre(16,1,"(To reset these figures, set \"Do you have a joystick?\" to No, then Yes.)"); + + gotoxy(20,10); output << "Left :"; + gotoxy(20,11); output << "Right :"; + gotoxy(20,12); output << "Top :"; + gotoxy(20,13); output << "Bottom:"; + + + if (jleft==0) jleft=maxint; + if (jtop==0) jtop=maxint; + do { + readjoy(x,y); + if (x<jleft) jleft=x; + if (y<jtop) jtop=y; + if (x>jright) jright=x; + if (y>jbottom) jbottom=y; + display(); + } while (!keypressed()); + + do { r=readkey(); } while (!(~ keypressed())); + if (r=='\33') return; + + centre(19,1,"Thank you. Now please centre your joystick and hit a button."); + do {; } while (!(buttona1() || buttona2())); + + readjoya(jmidx,jmidy); + + has_a_joystick=true; +} + +void joysetup() +{ + clear_to(green); + if (! detect()) return; + getmaxmin(); +} + +byte choose_one_of(byteset which); + +static shortint direction; + + +static void move(shortint d) +{ + direction=d; line=line+d; +} + + + +static void highlight(word where,word how) +{ + byte fv; + + where=where*160-159; + for( fv=0; fv <= 79; fv ++) + mem[0xb800*where+fv*2]=(mem[0xb800*where+fv*2] & 0xf)+how; +} + +byte choose_one_of(byteset which) + +{ + const integer upwards = -1; + const integer downwards = 1; + + boolean done; + char r; + + + byte choose_one_of_result; + done=false; direction=1; + do { + while (! (which.has(line))) + { + line=line+direction; + if (line>26) line=1; + if (line==0) line=26; + } + + highlight(line,selected); + r=readkey(); + highlight(line,background); + switch (r) { + case '\0': switch (readkey()) { + case cup: move(upwards); break; + case cdown: move(downwards); break; + } + break; + case creturn: done=true; break; + case cescape: { + choose_one_of_result=15; /* bottom line is always 15. */ + return choose_one_of_result; + } + break; + } + + } while (!done); + + choose_one_of_result=line; + return choose_one_of_result; +} + +void bottom_bar(); +static void load_regi_info(); + + +static char decode1(char c) +{ + byte b; + + char decode1_result; + b=ord(c)-32; + decode1_result=chr(( (b & 0xf) << 3) + ((cardinal)(b & 0x70) >> 4)); + return decode1_result; +} + + + +static char decode2(char c) +{ + char decode2_result; + decode2_result=chr( ((ord(c) & 0xf) << 2) + 0x43); + return decode2_result; +} + + + +static boolean checker(string proper,string check) +{ + byte fv; boolean ok; + + boolean checker_result; + ok=true; + for( fv=1; fv <= length(proper); fv ++) + if ((ord(proper[fv]) & 0xf)!=((cardinal)(ord(check[fv])-0x43) >> 2)) + ok=false; + + checker_result=ok; + return checker_result; +} + + +static void load_regi_info() +{ + text t; + byte fv; + string x; + byte namelen,numlen; + string namechk,numchk; + + + /*$I-*/ + assign(t,"register.dat"); reset(t); + /*$I+*/ + + if (ioresult!=0) + { + registrant=""; + return; + } + + for( fv=1; fv <= 53; fv ++) t >> NL; + t >> x >> NL; + close(t); + + namelen=107-ord(x[1]); numlen=107-ord(x[2]); + + registrant=copy(x,3,namelen); + reginum=copy(x,4+namelen,numlen); + namechk=copy(x,4+namelen+numlen,namelen); + numchk=copy(x,4+namelen+numlen+namelen,numlen); + + for( fv=1; fv <= namelen; fv ++) registrant[fv]=decode1(registrant[fv]); + for( fv=1; fv <= numlen; fv ++) reginum[fv]=decode1(reginum[fv]); + + if ((! checker(registrant,namechk)) || (! checker(reginum,numchk))) + { registrant="\?\"!?"; reginum="(."; } +} + +void bottom_bar() +{ + load_regi_info(); + textattr=96; background=96; + window(1,1,80,25); + gotoxy(1,25); clreol; + if (registrant=="") + centre(25,15,"Unregistered copy."); + else + centre(25,15,string("Registered to ")+registrant+" ("+reginum+")."); +} + +void new_menu() +{ + line=1; /* now that we've got a new menu. */ +} + +string two_answers(string ans_true,string ans_false, boolean which) +{ + string two_answers_result; + if (which) + two_answers_result=string(" (")+ans_true+')'; + else + two_answers_result=string(" (")+ans_false+')'; + return two_answers_result; +} + +string yes_or_no(boolean which) +{ + string yes_or_no_result; + yes_or_no_result=two_answers("yes","no",which); + return yes_or_no_result; +} + +string give_name(string what) +{ + string give_name_result; + if (what=="") + give_name_result=" (none)"; + else + give_name_result=string(" (\"")+what+"\")"; + return give_name_result; +} + +string sound_card(byte which) +{ + string sound_card_result; + switch (which) { + case 0: sound_card_result="none"; break; + case 1: sound_card_result="SoundBlaster"; break; + case 2: sound_card_result="SoundBlaster Pro"; break; + case 3: sound_card_result="SoundBlaster 16"; break; + case 4: sound_card_result="Pro Audio Spectrum"; break; + case 5: sound_card_result="Pro Audio Spectrum+"; break; + case 6: sound_card_result="Pro Audio Spectrum 16"; break; + case 7: sound_card_result="Aria"; break; + case 8: sound_card_result="Windows Sound System or compatible"; break; + case 9: sound_card_result="Gravis Ultrasound"; break; + case 10: sound_card_result="DAC on LPT1"; break; + case 11: sound_card_result="Stereo DACs on LPT1 and LPT2"; break; + case 12: sound_card_result="Stereo-on-1 DAC on LPT"; break; + case 13: sound_card_result="PC speaker"; break; + } + return sound_card_result; +} + +void get_str(string& n) +{ + string x; + char r; + + clear_to(black); + centre(3,3,"Enter the new value. Press Enter to accept, or Esc to cancel."); + x=""; + + do { + + r=readkey(); + + switch (r) { + case cbackspace: if (x[0]>'\0') x[0] -= 1; break; + case creturn: { + n=x; + return; + } + break; + case cescape: return; break; + + default: + if (x[0]<'\106') x=x+r; + } + + + centre(7,2,string(' ')+x+' '); + + } while (!false); + +} + +void get_num(longint& n) +{ + string x; + char r; + integer e; + + clear_to(black); + centre(3,3,"Enter the new value. Press Enter to accept, or Esc to cancel."); + centre(4,3,"Precede with $ for a hex value."); + x=""; + + do { + + r=upcase(readkey()); + + switch (r) { + case cbackspace: if (x[0]>'\0') x[0] -= 1; break; + case creturn: { + val(x,n,e); + return; + } + break; + case cescape: return; break; + + default: + if ((x[0]<'\106') && + ((set::of(range('0','9'), eos).has(r)) || ((x[1]=='$') && (set::of(range('A','F'), eos).has(r))) || + ((x=="") && (r=='$')))) + x=x+r; + } + + + centre(7,2,string(' ')+x+' '); + + } while (!false); + +} + +void general_menu() +{ + new_menu(); + do { + clear_to(blue); + + centre( 3,15,"General Menu"); + + centre( 5, 7,string("Override EGA check?")+yes_or_no(override_ega)); + centre( 6, 7,string("Skip loading screens?")+yes_or_no(skip_loading_screens)); + centre( 7, 7,string("Load a particular file by default?")+give_name(load_particular)); + centre( 8, 7,string("Force NumLock off?")+yes_or_no(force_numlock)); +/* centre( 9, 7,'Ignore the mouse?'+yes_or_no(ignore_mouse));*/ + centre(10, 7,string("Default controller?")+two_answers("keyboard","joystick",use_keyboard)); + centre(12, 7,string("Log to printer?")+yes_or_no(log_to_printer)); + centre(13, 7,string("Log to file?")+yes_or_no(log_to_file)); + centre(14, 7,string("Filename to log to?")+give_name(log_filename)); + + centre(15,15,"Return to main menu."); + + switch (choose_one_of(set::of(5,6,7,8,/*9,*/10,12,13,14,15, eos))) { + case 5: override_ega=! override_ega; break; + case 6: skip_loading_screens=! skip_loading_screens; break; + case 7: get_str(load_particular); break; + case 8: force_numlock=! force_numlock; break; +/* 9: ignore_mouse:=not ignore_mouse;*/ + case 10: use_keyboard=! use_keyboard; break; + case 12: { + log_to_printer=! log_to_printer; + if (log_to_file && log_to_printer) log_to_file=false; + } + break; + case 13: { + log_to_file=! log_to_file; + if (log_to_file && log_to_printer) log_to_printer=false; + } + break; + case 14: get_str(log_filename); break; + case 15: { new_menu(); return; } break; + } + + } while (!false); +} + +void joystick_menu() +{ + new_menu(); + do { + clear_to(green); + + centre(3,15,"Joystick Menu"); + + centre(5,14,string("Do you have a joystick?")+yes_or_no(has_a_joystick)); + centre(6,14,string("Which joystick to use? ")+chr(whichjoy+48)); + centre(7,14,"Select this one to set it up."); + + centre(15,15,"Return to main menu"); + + switch (choose_one_of(set::of(5,6,7,15, eos))) { + case 5: { + has_a_joystick=! has_a_joystick; + if (! has_a_joystick) + { jleft=0; jright=0; jtop=0; jbottom=0; } + } + break; + case 6: whichjoy=3-whichjoy; break; /* Flips between 2 and 1. */ + case 7: joysetup(); break; + case 15: { new_menu(); return; } break; + } + + } while (!false); +} + +void cycle(byte& what, byte upper_limit) +{ + if (what==upper_limit) + what=0; + else + what += 1; +} + +void sound_menu() +{ + new_menu(); + do { + clear_to(cyan); + + centre(3, 0,"Sound menu"); + + centre(5, 0,string("Do you want to suppress sound effects?")+yes_or_no(suppress_sfx)); + centre(6, 0,string("Sound output device\? (")+sound_card(your_card)+')'); + centre(7, 0,string("Sampling rate\? (")+strf(samplerate)+"Hz)"); + centre(8, 0,string("Base address\? (")+strhf(sound_addr)+" *hex*)"); + centre(9, 0,string("IRQ\? (")+strf(sound_irq)+')'); + centre(10,0,string("DMA\? (")+strf(sound_dma)+')'); + centre(11,0,string("Do you want keyclick?")+yes_or_no(wants_keyclick)); + + centre(15,15,"Return to main menu"); + + centre(17,1,"WARNING: Incorrect values of IRQ and DMA may damage your computer!"); + centre(18,1,"Read AVALOT.INI for the correct values."); + + switch (choose_one_of(set::of(5,6,7,8,9,10,11,15, eos))) { + case 5: suppress_sfx=! suppress_sfx; break; + case 6: cycle(your_card,13); break; + case 7: get_num(samplerate); break; + case 8: get_num(sound_addr); break; + case 9: get_num(sound_irq); break; + case 10: get_num(sound_dma); break; + case 11: wants_keyclick=! wants_keyclick; break; + case 15: { new_menu(); return; } break; + } + + } while (!false); +} + +void printer_menu() +{ + byte fv; + byteset chooseable_lines; + + new_menu(); + + chooseable_lines=set::of(15, eos); + for( fv=1; fv <= num_printers; fv ++) + chooseable_lines=chooseable_lines+set::of(fv+8, eos); + + do { + clear_to(red); + + centre(3,15,"Printer menu"); + + centre(5,15,"Select one of the following printers:"); + centre(6,15,string("The current choice is ")+this_printer+'.'); + + for( fv=1; fv <= num_printers; fv ++) + centre(8+fv,14,printers[fv]); + + centre(15,15,"Return to main menu"); + + fv=choose_one_of(chooseable_lines); + + if (fv==15) { new_menu(); return; } + + this_printer=printers[fv-8]; + + } while (!false); +} + +void regi_split(string x) +{ + byte fv; + + regname[0]=chr(107-ord(x[1])); chkname[0]=regname[0]; + regnum[0]=chr(107-ord(x[2])); chknum[0]=chknum[0]; + + move(x[3],regname[1],ord(regname[0])); + for( fv=1; fv <= length(regname); fv ++) + regname[fv]=chr(abs(((ord(regname[fv])-33)-177*fv) % 94)+33); +} + + +void registration_menu() +{ + char r; + text t,o; + string x; + byte fv; + + clear_to(black); + + centre(3,15,"REGISTRATION"); + centre(5,14,"Please insert the disk you were sent when you registered"); + centre(6,14,"into any drive, and press its letter. For example, if the"); + centre(7,14,"disk is in drive A:, press A."); + centre(9,14,"Press Esc to cancel this menu."); + + do { r=upcase(readkey()); } while (!(set::of('\33',range('A','Z'), eos).has(r))); if (r=='\33') return; + + /*$I-*/ + assign(t,string(r)+":\\REGISTER.DAT"); + reset(t); + /*$I+*/ + if (ioresult!=0) + { + centre(17,15,"But it isn't in that drive..."); + centre(19,15,"Press any key."); + r=readkey(); + return; + } + for( fv=1; fv <= 54; fv ++) t >> x >> NL; + regi_split(x); + + /* Copy the file... */ + + assign(o,"register.dat"); rewrite(o); reset(t); + + while (! eof(t)) + { + t >> x >> NL; o << x << NL; + } + close(t); close(o); + + centre(17,15,"Done! Press any key..."); + bottom_bar(); + r=readkey(); + +} + +void menu() +{ + bottom_bar(); + new_menu(); + do { + clear_to(black); + + centre(3,15,"Avalot Setup - Main Menu"); + + centre(5, 9,"General setup"); + centre(6,10,"Joystick setup"); + centre(7,11,"Sound setup"); + centre(8,12,"Printer setup"); + centre(9,14,"REGISTRATION setup"); + + centre(15,15,"--- EXIT SETUP ---"); + + switch (choose_one_of(set::of(5,6,7,8,9,15, eos))) { + case 5: general_menu(); break; + case 6: joystick_menu(); break; + case 7: sound_menu(); break; + case 8: printer_menu(); break; + case 9: registration_menu(); break; + case 15: { + new_menu(); + clear_to(lightgray); + centre(3,0,"Quit: would you like to save changes?"); + centre(5,1,"Quit and SAVE changes."); + centre(6,1,"Quit and DON'T save changes."); + centre(15,0,"Cancel and return to the main menu."); + switch (choose_one_of(set::of(5,6,15, eos))) { + case 5: { + save_file(); + return; + } + break; + case 6: return; break; + } + new_menu(); + } + break; + } + + } while (!false); +} + +void defaults() /* Sets everything to its default value. */ +{ + /* general */ + + override_ega=false; + skip_loading_screens=false; + load_particular=""; + force_numlock=true; + ignore_mouse=false; + use_keyboard=true; + log_to_printer=false; + log_to_file=false; + log_filename="avalot.log"; + + /* joystick */ + + has_a_joystick=false; + /* jtop,jbottom,jleft,jright,jmidx,jmidy need no initialisation. */ + + /* sound */ + + suppress_sfx=false; + your_card=0; /* none */ + wants_keyclick=false; + + /* other stuff */ + + registrant=""; + + num_printers=0; this_printer="??"; +} + +void parse_file(); + +const integer parse_weird_field = 1; + +const integer parse_not_yes_or_no = 2; + +const integer parse_not_numeric = 3; + +const integer parse_not_kbd_or_joy = 4; + +const integer parse_weird_logcode = 5; + +const integer parse_weird_card = 6; + + +static varying_string<80> this_,thiswas; + +static boolean error_found,ignoring; + + +static void error(byte what) +{ + textattr=15; + if (! error_found) + { + clrscr; textattr=12; + output << "SETUP: *** ERROR FOUND IN AVALOT.INI! ***" << NL; textattr=15; + } + output << ' '; + switch (what) { + case parse_weird_field: output << "Unknown identifier on the left"; break; + case parse_not_yes_or_no: output << "Value on the right should be Yes or No"; break; + case parse_not_numeric: output << "Value on the right is not numeric"; break; + case parse_not_kbd_or_joy: output << "Value on the right should be Keyboard or Joystick"; break; + case parse_weird_logcode: output << "Value on the right should be No, Printer or Disk"; break; + case parse_weird_card: output << "Never heard of the card"; break; + } + output << " in:" << NL; textattr=10; output << thiswas << NL; + error_found=true; +} + + + +static boolean yesno(string x) +{ + boolean yesno_result; + if (x=="YES") + yesno_result=true; + else if (x=="NO") + yesno_result=false; + else + { + error(parse_not_yes_or_no); + yesno_result=false; + } + return yesno_result; +} + + + +static boolean kbdjoy(string x) +{ + boolean kbdjoy_result; + if (x=="KEYBOARD") + kbdjoy_result=true; + else if (x=="JOYSTICK") + kbdjoy_result=false; + else + { + error(parse_not_kbd_or_joy); + kbdjoy_result=false; + } + return kbdjoy_result; +} + + + +static word numeric(string x) +{ + const varying_string<15> hexdigits = "0123456789ABCDEF"; + word answer; integer e; + + word numeric_result; + if (x[1]=='$') + { + answer=0; + for( e=2; e <= length(x); e ++) + { + answer=answer << 4; + answer += pos(upcase(x[e]),hexdigits)-1; + } + } else + { + val(x,answer,e); + if (e!=0) error(parse_not_numeric); + } + numeric_result=answer; + return numeric_result; +} + + + +static void get_logcodes(string x) +{ + if (x=="NO") { log_to_file=false; log_to_printer=false; } else + if (x=="DISK") { log_to_file=true; log_to_printer=false; } else + if (x=="PRINTER") { log_to_file=false; log_to_printer=true; } else + error(parse_weird_logcode); +} + + + +static void get_card(string x) +{ + if (x=="NONE") your_card=0; else + if (x=="SB") your_card=1; else + if (x=="SBPRO") your_card=2; else + if (x=="SB16") your_card=3; else + if (x=="PAS") your_card=4; else + if (x=="PASPLUS") your_card=5; else + if (x=="PAS16") your_card=6; else + if (x=="ARIA") your_card=7; else + if (x=="WINSOUND") your_card=8; else + if (x=="GRAVIS") your_card=9; else + if (x=="DACLPT") your_card=10; else + if (x=="STEREODACS") your_card=11; else + if (x=="STEREOON1") your_card=12; else + if (x=="SPEAKER") your_card=13; else + error(parse_weird_card); +} + +void parse_file(){ + + + word where; + byte position; + varying_string<80> field,data,pure_data; + option o; + + + error_found=false; + ignoring=false; + + for( where=1; where <= mobylength; where ++) + { + this_=(*moby)[where]; thiswas=this_; + + position=pos(";",this_); + if (position>0) this_=copy(this_,1,position-1); + + if (this_=="") continue_; /* Don't carry on if by now it's empty. */ + + if (this_[1]=='[') + { + ignoring=! (trim_and_caps(this_)=="[END]"); + + if (copy(this_,1,8)=="[printer") + { + num_printers += 1; + printers[num_printers]=copy(this_,10,length(this_)-10); + } + } + + if (ignoring) continue_; + + position=pos("=",this_); + field=trim_and_caps(copy(this_,1,position-1)); if (field=="") continue_; + pure_data=copy(this_,position+1,255); + data=trim_and_caps(pure_data); + o=string_2_option(field); + + /* general */ + + if (o==_overrideegacheck) override_ega=yesno(data); else + if (o==_zoomystart) skip_loading_screens=yesno(data); else + if (o==_loadfirst) load_particular=data; else + if (o==_numlockhold) force_numlock=yesno(data); else + if (o==_usemouse) ignore_mouse=yesno(data); else + if (o==_controller) use_keyboard=kbdjoy(data); else + if (o==_logging) get_logcodes(data); else + if (o==_logfile) log_filename=data; else + + /* joystick */ + + if (o==_joystickinstalled) has_a_joystick=yesno(data); else + if (o==_joytop) jtop=numeric(data); else + if (o==_joybottom) jbottom=numeric(data); else + if (o==_joyleft) jleft=numeric(data); else + if (o==_joyright) jright=numeric(data); else + if (o==_joymidx) jmidx=numeric(data); else + if (o==_joymidy) jmidy=numeric(data); else + if (o==_joycentringfactor) jcentre=numeric(data); else + if (o==_whichjoy) whichjoy=numeric(data); else + + /* sound */ + + if (o==_quiet) suppress_sfx=yesno(data); else + if (o==_soundcard) get_card(data); else + if (o==_samplerate) samplerate=numeric(data); else + if (o==_baseaddress) sound_addr=numeric(data); else + if (o==_irq) sound_irq=numeric(data); else + if (o==_dma) sound_dma=numeric(data); else + if (o==_keyboardclick) wants_keyclick=yesno(data); else + + /* printer */ + + if (o==_printer) this_printer=pure_data; else + + /* others */ + + error(parse_weird_field); + } + + if (error_found) + { + textattr=15; + output << " Try and fix the above errors. As a last resort, try deleting or" << NL; + output << " renaming AVALOT.INI, and the default values will be used. Good luck." << NL; + exit(177); + } + } + +void clear_up() +{ + window(1,1,80,25); + textattr=31; + clrscr; + output << NL; + output << "Enjoy the game..." << NL; + output << NL; + cga_cursor_on; +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + cursor_off; + + moby = new mobytype; /* Allocate memory space */ + + defaults(); + + load_file(); + + parse_file(); + + menu(); + + delete moby; /* Deallocate memory space again */ + + clear_up(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/seu.cpp b/engines/avalanche/seu.cpp new file mode 100644 index 0000000000..9b1c1c23cc --- /dev/null +++ b/engines/avalanche/seu.cpp @@ -0,0 +1,977 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ +/*#include "Tommys.h"*/ + + +const integer msize = 100; +const integer flag = -20047; +const integer perm = -1; + +const integer avvy_shoot = 87; +const integer facing_right = 88; +const integer facing_left = 94; + +const integer avvy_y = 150; + +const integer left_margin = 10; +const integer right_margin = 605; + +const array<0,6,byte> shooting = {{87,80,81,82,81,80,87}}; + +const integer stocks = 28; + +const integer framedelaymax = 2; + +const integer maxrunners = 4; + +const integer times_a_second = /*31*/18; + +const integer flash_time = 20; /* If flash_time is <= this, the word "time" will flash. */ + /* Should be about 20. */ + +/* --- Scores for various things --- */ + +const integer score_for_hitting_face = 3; +const integer bonus_for_hitting_escaper = 5; + +struct mtype { + shortint ix,iy; + integer x,y; + byte p; + integer timeout; + boolean cameo; + byte cameo_frame; + boolean missile; + boolean wipe; +}; + +struct xtype { + word s; + pointer p; +}; + +class rectype { +public: + integer x1,y1,x2,y2; +}; + +class plottype : public rectype { +public: + byte which; +}; + +class plotmasktype : public plottype { +public: + byte whichmask; +}; + +array<1,100,xtype> x; +array<1,100,mtype> m; +matrix<0,1,1,100,rectype> r; +array<0,1,byte> rsize; +byte cp; +word score; byte time1; + +byte shiftstate; /*ABSOLUTE $40:$17; */ + +word avvypos; +word avvywas; +byte avvyanim; +byte avvyfacing; + +byte was_facing; + +boolean alt_was_pressed_before; + +byte throw_next; + +boolean firing; + +array<0,6,byte> stockstatus; + +array<1,maxrunners,struct A1 { + integer x,y; + byte frame; + byte toohigh,lowest; + shortint ix,iy; + byte framedelay; + }> running; + +varying_string<5> score_is; +varying_string<3> time_is; + +byte time_this_second; + +word escape_count; +byte escape_stock; +boolean escaping,got_out; + +array<0,6,boolean> has_escaped; + +byte count321; + +word storage_seg,storage_ofs; + +byte how_many_have_escaped; + +void flippage() +{ + setactivepage(cp); + cp=1-cp; + setvisualpage(cp); +} + +void flesh_colours() {; /*assembler; +asm + mov ax,$1012; + mov bx,21; { 21 = light pink (why?) */ + /*mov cx,1; + mov dx,seg @flesh; + mov es,dx; + mov dx,offset @flesh; + int $10; + + mov dx,seg @darkflesh; + mov es,dx; + mov dx,offset @darkflesh; + mov bx,5; { 5 = dark pink. */ + /*int $10; + + jmp @TheEnd; + + @flesh: + db 56,35,35; + + @darkflesh: + db 43,22,22; + + @TheEnd: */ + } + +boolean overlap(word a1x,word a1y,word a2x,word a2y,word b1x,word b1y,word b2x,word b2y) +{ /* By De Morgan's law: */ + boolean overlap_result; + overlap_result=(a2x>=b1x) && (b2x>=a1x) && (a2y>=b1y) && (b2y>=a1y); + return overlap_result; +} + +void getsize(byte w, integer& xx,integer& yy) +{ + array<0,1,integer> n; + + move(x[w].p,n,4); + xx=n[0]; yy=n[1]; +} + +void display(integer xx,integer yy, byte w) +{ + putimage(xx,yy,x[w].p,0); +} + +byte get_stock_number(byte x) +{ + byte get_stock_number_result; + while (has_escaped[x]) + { + x += 1; + if (x==7) x=0; + } + get_stock_number_result=x; + return get_stock_number_result; +} + +void cameo_display(integer xx,integer yy, byte w1,byte w2) +{ + putimage(xx,yy,x[w2].p,andput); + putimage(xx,yy,x[w1].p,xorput); +} + +void blankit() +{ + byte fv; + + for( fv=1; fv <= rsize[cp]; fv ++) + { rectype& with = r[cp][fv]; + bar(with.x1,with.y1,with.x2,with.y2);} + rsize[cp]=0; +} + +void blank(integer xx1,integer yy1,integer xx2,integer yy2) +{ + rsize[cp] += 1; + { + rectype& with = r[cp][rsize[cp]]; + + with.x1=xx1; + with.y1=yy1; + with.x2=xx2; + with.y2=yy2; + } +} + +void movethem() +{ + byte fv; + + for( fv=1; fv <= msize; fv ++) + { mtype& with = m[fv]; + if (with.x!=flag) + { + with.x=with.x+with.ix; + with.y=with.y+with.iy; + }} +} + +void plotthem() +{ + byte fv; integer xx,yy; + + for( fv=1; fv <= msize; fv ++) + { mtype& with = m[fv]; + if (with.x!=flag) + { + if (with.cameo) + { + cameo_display(with.x,with.y,with.p,with.cameo_frame); + if (cp==0) { with.cameo_frame += 2; with.p += 2; } + } else display(with.x,with.y,with.p); + getsize(with.p,xx,yy); + if (with.wipe) blank(with.x,with.y,with.x+xx,with.y+yy); + if (with.timeout>0) + { + with.timeout -= 1; + if (with.timeout==0) with.x=flag; + } + }} +} + +void define(integer xx,integer yy, byte pp, shortint ixx,shortint iyy, integer timetime, + boolean is_a_missile,boolean do_we_wipe) +{ + byte which; + + for( which=1; which <= msize; which ++) + { + mtype& with = m[which]; + + if (with.x==flag) + { + with.x=xx; + with.y=yy; + with.p=pp; + with.ix=ixx; + with.iy=iyy; + with.timeout=timetime; + with.cameo=false; + with.missile=is_a_missile; + with.wipe=do_we_wipe; + + return; + } + } +} + +void define_cameo(integer xx,integer yy, byte pp, integer timetime) +{ + byte which; + + for( which=1; which <= msize; which ++) + { + mtype& with = m[which]; + + if (with.x==flag) + { + with.x=xx; + with.y=yy; + with.p=pp; + with.ix=0; + with.iy=0; + with.timeout=timetime; + with.cameo=true; + with.cameo_frame=pp+1; + with.missile=false; + with.wipe=false; + + return; + } + } +} + +void get_score() +{ + byte fv; + + str(score,5,score_is); + for( fv=1; fv <= 5; fv ++) + if (score_is[fv]==' ') + score_is[fv]='0'; +} + +void get_time1() +{ + byte fv; + + str(time1,5,time_is); + for( fv=1; fv <= 3; fv ++) + if (time_is[fv]==' ') + time_is[fv]='0'; +} + +void display_const(integer x,integer y, byte what) +{ + byte page_; + + for( page_=0; page_ <= 1; page_ ++) + { + setactivepage(page_); + display(x,y,what); + } + setactivepage(1-cp); +} + +void show_stock(byte x) +{ + if (escaping && (x==escape_stock)) + { + display_const(x*90+20,30,stocks+2); + return; + } + if (stockstatus[x]>5) return; + display_const(x*90+20,30,stocks+stockstatus[x]); + stockstatus[x]=1-stockstatus[x]; +} + +void show_score() +{ + byte fv; + varying_string<5> score_was; + + score_was=score_is; get_score(); + for( fv=1; fv <= 5; fv ++) + if (score_was[fv]!=score_is[fv]) + display_const(30+fv*10,0,ord(score_is[fv])-47); +} + +void show_time() +{ + byte fv; + varying_string<3> time_was; + + time_was=time_is; get_time1(); + for( fv=1; fv <= 3; fv ++) + if (time_was[fv]!=time_is[fv]) + display_const(130+fv*10,0,ord(time_is[fv])-47); +} + +void gain(shortint howmuch) +{ + if (-howmuch>score) score=0; else + score=score+howmuch; + show_score(); +} + +void new_escape() +{ + escape_count=Random(18)*20; + escaping=false; +} + +void instructions(); + +static void nextpage() +{ + char c; + + outtextxy(400,190,"Press a key for next page >"); + c=readkey(); + cleardevice(); +} + +void instructions() +{ + display(25,25,facing_right); + outtextxy(60,35,"< Avvy, our hero, needs your help - you must move him around."); + outtextxy(80,45,"(He's too terrified to move himself!)"); + + outtextxy(0,75,"Your task is to prevent the people in the stocks from escaping"); + outtextxy(0,85,"by pelting them with rotten fruit, eggs and bread. The keys are:"); + outtextxy(80,115,"LEFT SHIFT"); outtextxy(200,115,"Move left."); + outtextxy(72,135,"RIGHT SHIFT"); outtextxy(200,135,"Move right."); + outtextxy(136,155,"ALT"); outtextxy(200,155,"Throw something."); + nextpage(); + + display(25,35,stocks); + outtextxy(80,35,"This man is in the stocks. Your job is to stop him getting out."); + outtextxy(88,45,"UNFORTUNATELY... the locks on the stocks are loose, and every"); + outtextxy(88,55,"so often, someone will discover this and try to get out."); + display(25, 85,stocks+2); + outtextxy(80, 85,"< Someone who has found a way out!"); + outtextxy(88, 95,"You MUST IMMEDIATELY hit people smiling like this, or they"); + outtextxy(88,105,"will disappear and lose you points."); + display(25,125,stocks+5); + display(25,155,stocks+4); + outtextxy(80,125,"< Oh dear!"); + nextpage(); + + outtextxy(0,35,"Your task is made harder by:"); + display(25,55,48); + outtextxy(60,55,"< Yokels. These people will run in front of you. If you hit"); + outtextxy(68,65,"them, you will lose MORE points than you get hitting people"); + outtextxy(68,75,"in the stocks. So BEWARE!"); + outtextxy(80,125,"Good luck with the game!"); + nextpage(); +} + +void setup() +{ + integer gd,gm; + untyped_file f; + char rkv; + + rkv=upcase(readkey()); + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + flesh_colours(); + + assign(f,"notts.avd"); + reset(f,1); gd=1; + score=0; time1=120; score_is="(c)94"; + time_this_second=0; + + while (! eof(f)) + { + xtype& with = x[gd]; + + blockread(f,with.s,2); + getmem(with.p,with.s); + blockread(f,with.p,with.s); + gd += 1; + } + close(f); + + if ((rkv=='I') || ((rkv=='\0') && (readkey()==cf1))) instructions(); + + for( gd=0; gd <= 6; gd ++) + { + stockstatus[gd]=Random(2); + show_stock(gd); + } + + fillchar(m,sizeof(m),'\261'); + setfillstyle(1,0); + cp=0; + flippage(); + fillchar(rsize,sizeof(rsize),'\0'); + avvywas=320; + avvypos=320; + avvyanim=1; + avvyfacing=facing_left; + + alt_was_pressed_before=false; + throw_next=74; + firing=false; + + for( gd=1; gd <= maxrunners; gd ++) + { + A1& with = running[gd]; + + with.x=flag; + } + + new_escape(); + fillchar(has_escaped,sizeof(has_escaped),'\0'); /* All false. */ + count321=255; /* Counting down. */ + + /* Set up status line. */ + + display_const(0,0,17); /* Score: */ + show_score(); /* value of score (00000 here) */ + display_const(110,0,20); /* Time: */ + show_time(); /* value of time */ + + Randomize(); + + how_many_have_escaped=0; +} + +void init_runner(integer xx,integer yy, byte f1,byte f2, shortint ixx,shortint iyy) +{ + byte fv; + + for( fv=1; fv <= maxrunners; fv ++) + { A1& with = running[fv]; + if (with.x==flag) + { + with.x=xx; with.y=yy; + with.frame=f1; + with.toohigh=f2; + with.lowest=f1; + with.ix=ixx; with.iy=iyy; + if ((with.ix==0) && (with.iy==0)) with.ix=2; /* To stop them running on the spot! */ + with.framedelay=framedelaymax; + return; + }} +} + +void titles() +{ + registers r; + byte a; /*absolute $A000:0; */ + untyped_file f; + byte bit; + + r.ax=0xd; + intr(0x10,r); + + assign(f,"shoot1.avd"); + reset(f,1); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a,8000); + } + close(f); +} +/* +procedure animate3; +begin + define(100,100,10,1,0,perm,false,true); + define( 50,20 ,30,3,3,30,false,true); + repeat; + blankit; + plotthem; + movethem; + flippage; + delay(100); + until keypressed; +end; + +procedure animate2; +var + x,n:byte; + helpx:integer; + helpdir:shortint; + helpani:byte; +begin + x:=0; n:=0; helpani:=0; + helpx:=10; helpdir:=1; + setfillstyle(1,0); + + repeat + display(x*52,0,n+28); + inc(x); inc(n); + + if x=13 then + begin + bar(helpx-2,50,helpx+5,80); + if helpdir>0 then + display(helpx,50,80-helpani) + else + display(helpx,50,86-helpani); + helpx:=helpx+helpdir*5; + if (helpx>600) or (helpx<3) then helpdir:=-helpdir; + if helpani=0 then helpani:=5 else dec(helpani); + + x:=0; +(* delay(100);*) + end; + if n=6 then n:=0; + until keypressed; +end; +*/ + +void move_avvy() +{ + if (avvywas<avvypos) + { +/* bar(avvyWas,avvy_Y,avvyPos,Avvy_Y+85);*/ + avvyfacing=facing_right; + } else if (avvywas>avvypos) + { +/* bar(avvyWas+32,Avvy_Y,avvyPos+33,Avvy_Y+85);*/ + avvyfacing=facing_left; + } + + if (! firing) + { + if (avvywas==avvypos) + avvyanim=1; + else + { + avvyanim += 1; + if (avvyanim==6) avvyanim=0; + } + } + + if (avvyfacing==avvy_shoot) + define(avvypos,avvy_y,shooting[avvyanim],0,0,1,false,true); + else + define(avvypos,avvy_y,avvyanim+avvyfacing,0,0,1,false,true); + + avvywas=avvypos; + + if (avvyfacing==avvy_shoot) + { + if (avvyanim==6) + { + avvyfacing=was_facing; + avvyanim=0; + firing=false; + } else avvyanim += 1; + } +} + +void read_kbd() +{ + + if (firing) return; + + if ((shiftstate & 8)>0) + { /* Alt - shoot */ + if ((alt_was_pressed_before) || (count321!=0)) return; + alt_was_pressed_before=true; + firing=true; + define(avvypos+27,avvy_y+5,throw_next,0,-2,53,true,true); + throw_next += 1; if (throw_next==80) throw_next=74; + avvyanim=0; + was_facing=avvyfacing; + avvyfacing=avvy_shoot; + return; + } + + alt_was_pressed_before=false; + + if ((shiftstate & 1)>0) + { /* Move right. */ + avvypos += 5; + if (avvypos>right_margin) avvypos=right_margin; + return; + } + + if ((shiftstate & 2)>0) + { /* Move left. */ + avvypos -= 5; + if (avvypos<left_margin) avvypos=left_margin; + } + +} + +void animate() +{ + byte fv; + + if (Random(10)==1) show_stock(get_stock_number(Random(6))); + for( fv=0; fv <= 6; fv ++) + if (stockstatus[fv]>5) + { + stockstatus[fv] -= 1; + if (stockstatus[fv]==8) + { + stockstatus[fv]=0; + show_stock(fv); + } + } +} + +void collision_check() +{ + byte fv; + integer dist_from_side; + byte this_stock; + + for( fv=1; fv <= 100; fv ++) + { mtype& with = m[fv]; + if (with.x!=flag) + { + if ((with.missile) && (with.y<60) && (with.timeout==1)) + { +/* sound(177); delay(1); nosound;*/ + dist_from_side=(with.x-20) % 90; + this_stock=((with.x-20) / 90); + if ((! has_escaped[this_stock]) && + (dist_from_side>17) && (dist_from_side<34)) + { + sound(999); delay(3); nosound; + define(with.x+20,with.y,26+Random(2),3,1,12,false,true); /* Well done! */ + define(this_stock*90+20,30,31,0,0,7,false,false); /* Face of man */ + define_cameo(this_stock*90+20+10,35,40,7); /* Splat! */ + define(this_stock*90+20+20,50,34+Random(5),0,2,9,false,true); /* Oof! */ + stockstatus[this_stock]=17; + gain(score_for_hitting_face); + + if ((escaping) && (escape_stock==this_stock)) + { /* Hit the escaper. */ + sound(1777); delay(1); nosound; + gain(bonus_for_hitting_escaper); + escaping=false; new_escape(); + } + } else + { + define(with.x,with.y,83+Random(3),2,2,17,false,true); /* Missed! */ + if ((! has_escaped[this_stock]) && + ((dist_from_side>3) && (dist_from_side<43))) + { + define(this_stock*90+20,30,30,0,0,7,false,false); /* Face of man */ + if (dist_from_side>35) + define_cameo(with.x-27,35,40,7); /* Splat! */ + else + define_cameo(with.x-7,35,40,7); + stockstatus[this_stock]=17; + } + } + } + }} +} + +shortint sgn(integer a) +{ + shortint sgn_result; + if (a==0) { sgn_result=0; return sgn_result; } + if (a>0) { sgn_result=1; return sgn_result; } + sgn_result=-1; + return sgn_result; +} + +void turn_around(byte who, boolean randomx) +{ + { + A1& with = running[who]; + + if (randomx) + { + if (with.ix>0) with.ix=-(Random(5)+1); else with.ix=(Random(5)+1); + } else + with.ix=-with.ix; + with.iy=-with.iy; + } +} + +void bump_folk() +{ + byte fv,ff; + + for( fv=1; fv <= maxrunners; fv ++) + if (running[fv].x!=flag) + for( ff=fv+1; ff <= maxrunners; ff ++) + if ((running[ff].x!=flag) && + overlap(running[fv].x,running[fv].y, + running[fv].x+17,running[fv].y+24, + running[ff].x,running[ff].y, + running[ff].x+17,running[ff].y+24)) + { + turn_around(fv,false); /* Opp. directions. */ + turn_around(ff,false); + } +} + +void people_running() +{ + byte fv; + + if (count321!=0) return; + for( fv=1; fv <= maxrunners; fv ++) + { A1& with = running[fv]; + if (with.x!=flag) + { + if (((with.y+with.iy)<=53) || ((with.y+with.iy)>=120)) + { + with.iy=-with.iy; + } + + if (with.ix<0) + define(with.x,with.y,with.frame,0,0,1,false,true); + else + define(with.x,with.y,with.frame+7,0,0,1,false,true); + if (with.framedelay==0) + { + with.frame += 1; if (with.frame==with.toohigh) with.frame=with.lowest; + with.framedelay=framedelaymax; + with.y=with.y+with.iy; + } else with.framedelay -= 1; + + if (((with.x+with.ix)<=0) || ((with.x+with.ix)>=620)) turn_around(fv,true); + + with.x=with.x+with.ix; + }} +} + +void update_time() +{ + if (count321!=0) return; + time_this_second += 1; + if (time_this_second < times_a_second) return; + time1 -= 1; + show_time(); + time_this_second=0; + if (time1<=flash_time) + if (odd(time1)) display_const(110,0,20); /* Normal time */ + else display_const(110,0,86); /* Flash time */ +} + +void hit_people() +{ + byte fv,ff; + + if (count321!=0) return; + for( fv=1; fv <= 100; fv ++) + { mtype& with = m[fv]; + if (with.missile && (with.x!=flag)) + for( ff=1; ff <= maxrunners; ff ++) + if ((running[ff].x!=flag) && + overlap(with.x,with.y,with.x+7,with.y+10, + running[ff].x,running[ff].y, + running[ff].x+17, + running[ff].y+24)) + { + sound(7177); +/* setcolor(4); + rectangle(x,y,x+7,y+10); + rectangle(running[ff].x,running[ff].y, + running[ff].x+17, + running[ff].y+24);*/ + nosound; + with.x=flag; + gain(-5); + define(running[ff].x+20,running[ff].y+3, + 34+Random(6),1,3,9,false,true); /* Oof! */ + define(with.x,with.y,83,1,0,17,false,true); /* Oops! */ + }} +} + +void escape_check() +{ + if (count321!=0) return; + if (escape_count>0) { escape_count -= 1; return; } + + /* Escape_count = 0; now what? */ + + if (escaping) + { + if (got_out) + { + new_escape(); escaping=false; + display_const(escape_stock*90+20,30,stocks+4); + } else + { + display_const(escape_stock*90+20,30,stocks+5); + escape_count=20; got_out=true; + define(escape_stock*90+20,50,25,0,2,17,false,true); /* Escaped! */ + gain(-10); + has_escaped[escape_stock]=true; + + how_many_have_escaped += 1; + + if (how_many_have_escaped == 7) + { + for( time1=0; time1 <= 1; time1 ++) + { + setactivepage(time1); + cleardevice(); + } + setactivepage(1-cp); + + memw[storage_seg*storage_ofs+1]=0; + do {; } while (!(memw[storage_seg*storage_ofs+1]>9)); + + setvisualpage(1-cp); + display(266,90,23); + + memw[storage_seg*storage_ofs+1]=0; + do {; } while (!(memw[storage_seg*storage_ofs+1]>72)); + + setvisualpage(cp); + + memw[storage_seg*storage_ofs+1]=0; + do {; } while (!(memw[storage_seg*storage_ofs+1]>9)); + + time1=0; + } + } + } else + { + escape_stock=get_stock_number(Random(7)); escaping=true; got_out=false; + display_const(escape_stock*90+20,30,stocks+2); /* Smiling! */ + escape_count=200; + } +} + +void check321() +{ + if (count321==0) return; + count321 -= 1; + switch (count321) { + case 84: define(320, 60,16, 2, 1,94,false,true); break; + case 169: define(320, 60,15, 0, 1,94,false,true); break; + case 254: { + define(320, 60,14,-2, 1,94,false,true); + define( 0,100,18, 2, 0,254,false,true); + } + break; + } +} + +void check_params(); + +static void not_bootstrap() +{ + output << "This is not a standalone program!" << NL; + exit(255); +} + +void check_params() +{ + integer e; + + if (paramstr(1)!="jsb") not_bootstrap(); + + val(paramstr(2),storage_seg,e); if (e!=0) not_bootstrap(); + val(paramstr(3),storage_ofs,e); if (e!=0) not_bootstrap(); + +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + check_params(); + + titles(); + setup(); + init_runner( 20, 70,48,54, Random(5)+1,Random(4)-2); + init_runner(600, 70,48,54, Random(5)+1,Random(4)-2); + init_runner(600,100,61,67,-Random(5)+1,Random(4)-2); + init_runner( 20,100,61,67,-Random(5)+1,Random(4)-2); + do { + memw[storage_seg*storage_ofs+1]=0; + + blankit(); + hit_people(); + plotthem(); + movethem(); + move_avvy(); + bump_folk(); + people_running(); + animate(); + escape_check(); + + collision_check(); + + update_time(); + + check321(); + + read_kbd(); + flippage(); + do {; } while (!(memw[storage_seg*storage_ofs+1]>0)); + + } while (!(time1==0)); + +/* textmode(259); + textattr:=1; + writeln('Your final score was: ',score,'.'); + readln;*/ + mem[storage_seg*storage_ofs]=score; + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/seu_avvy.cpp b/engines/avalanche/seu_avvy.cpp new file mode 100644 index 0000000000..fb236b95bb --- /dev/null +++ b/engines/avalanche/seu_avvy.cpp @@ -0,0 +1,90 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + + +struct adxtype { + varying_string<12> name; /* name of character */ + varying_string<16> comment; /* comment */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ + byte accinum; /* the number according to Acci (1=Avvy, etc.) */ +}; + +integer gd,gm; +untyped_file sf; +longint id; +word soa; +adxtype a; +byte xw; +array<5,2053,byte> mani; +matrix<0,35,0,4,byte> sil; +array<1,16000,byte> aa; +untyped_file outfile; + +void plotat(integer xx,integer yy) /* Does NOT cameo the picture!*/ +{ + word soaa; +; + move(mani,aa[5],sizeof(mani)); + {; + aa[1]=a.xl; aa[2]=0; aa[3]=a.yl; aa[4]=0; /* set up x&y codes */ + } + putimage(xx,yy,aa,0); + soaa=sizeof(mani); + blockwrite(outfile,soaa,2); + blockwrite(outfile,aa,sizeof(mani)); +} + +const integer shouldid = -1317732048; + +void explode(byte which) /* 0 is the first one! */ + /* Each character takes five-quarters of (a.size-6) on disk. */ +{ + byte fv,ff; word so1; /* size of one */ +; + {; + so1=a.size-6; so1 += so1 / 4; + seek(sf,183+soa+so1*which); /* First is at 221 */ +/* where:=filepos(sf);*/ + xw=a.xl / 8; if ((a.xl % 8)>0) xw += 1; + + for( fv=0; fv <= a.yl; fv ++) + blockread(sf,sil[fv],xw); + blockread(sf,mani,a.size-6); + aa[a.size-1]=0; aa[a.size]=0; /* footer */ + } + plotat(100,100); + delay(100); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + + assign(outfile,"notts.avd"); + reset(outfile,1); + seek(outfile,filesize(outfile)); + + assign(sf,"sprite0.avd"); + reset(sf,1); + + seek(sf,177); + blockread(sf,id,4); + blockread(sf,soa,2); + blockread(sf,a,soa); + + explode(1); + for( gd=6; gd <= 11; gd ++) explode(gd); + for( gd=18; gd <= 23; gd ++) explode(gd); + + close(sf); + close(outfile); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/sez.cpp b/engines/avalanche/sez.cpp new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/engines/avalanche/sez.cpp diff --git a/engines/avalanche/sezedit.cpp b/engines/avalanche/sezedit.cpp new file mode 100644 index 0000000000..946e318ebb --- /dev/null +++ b/engines/avalanche/sezedit.cpp @@ -0,0 +1,406 @@ +#include "ptoc.h" + + +/*$M 65520,0,655360*/ +/*#include "Crt.h"*/ +#include "graph.h" + + +const char marker = '\33'; +const char game[] = "Avalot"; + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +struct markertype { + word length; + longint offset; + byte checksum; +}; + +struct sezheader { + array<1,2,char> initials; /* should be "TT" */ + word gamecode; + word revision; /* as 3- or 4-digit code (eg v1.00 = 100) */ + longint chains; /* number of scroll chains */ + longint size; /* total size of all chains */ +}; + +array<0,1999,char> buffer,was; +word bufpos,bufsize; +longint chainnum; +varying_string<40> nickname; +array<1,255,char> junk; +string temp; +char r; +fonttype font; +integer cpos; +sezheader sezhead; +untyped_file f,tempf; +text nicknames; + +byte sumup() +{ + word fv; byte total; +byte sumup_result; +; + total=0; + for( fv=0; fv <= bufsize-1; fv ++) + {; + total += ord(was[fv]); + } + sumup_result=total; +return sumup_result; +} + +string findname(longint which) +{ + string x; varying_string<10> q; +string findname_result; +; + str(which,q); + reset(nicknames); + do { nicknames >> x >> NL; } while (!(x=="{go}")); + do { + nicknames >> x >> NL; + } while (!(pos(q,x)>0)); + if (eof(nicknames)) + {; + findname_result="noname"; + } else + {; + Delete(x,1,3); /* lose "{__" */ + Delete(x,pos(" ",x),255); /* lose all chars after first space */ + findname_result=x; + } + close(nicknames); +return findname_result; +} + +void cursor() +{ + byte fv; +; + for( fv=12; fv <= 15; fv ++) + mem[0xa000*cpos+fv*80]=~(mem[0xa000*cpos+fv*80]); +} + +void xy() +{; + cpos=(bufpos / 80)*1280+(bufpos % 80); +} + +void show() +{ + word fv,orig,y; +; + for( fv=0; fv <= 1999; fv ++) + if (buffer[fv]!=was[fv]) + {; + orig=(fv / 80)*1280+(fv % 80); + for( y=0; y <= 15; y ++) + mem[0xa000*orig+y*80]=(byte)(font[buffer[fv]][y]); + } + xy(); + move(buffer,was,sizeof(buffer)); +} + +void sizeup() +{; + do { + switch (buffer[bufsize]) { + case marker: return; break; /* we've found it OK! */ + case '\0': bufsize -= 1; break; + default: bufsize += 1; + } + } while (!false); +} + +void graphics() +{ + integer gd,gm; + file<fonttype> fontfile; +; + gd=3; gm=1; initgraph(gd,gm,""); + assign(fontfile,"c:\\thomas\\lanche.fnt"); + reset(fontfile); fontfile >> font; close(fontfile); +} + +void edit_it(); + +static void legit(char r) +{; /* it's a legit keystroke */ + move(buffer[bufpos],buffer[bufpos+1],1999-bufpos); + buffer[bufpos]=r; + bufpos += 1; show(); +} + +void edit_it() +{ + byte fv; +; + for( fv=1; fv <= bufsize; fv ++) buffer[fv] -= (byte)(177*bufsize); + fillchar(was,sizeof(was),'\0'); show(); + do { + cursor(); r=readkey(); cursor(); + switch (r) { + case '\0': switch (readkey()) { /* extd keystrokes */ + case 'K': if (bufpos>0) {; bufpos -= 1; xy(); } break; /* Left */ + case 'M': if (bufpos<bufsize) {; bufpos += 1; xy(); } break; /* Right */ + case 'H': if (bufpos>80) {; bufpos -= 80; xy(); } break; /* Up */ + case 'P': if (bufpos<(cardinal)bufsize-79) {; bufpos += 80; xy(); } break; /* Down */ + case 'G': {; bufpos=0; xy(); } break; /* Home */ + case 'O': {; bufpos=bufsize; xy(); } break; /* End */ + case 'S': {; /* Del */ + move(buffer[bufpos+1],buffer[bufpos],1999-bufpos); show(); + } + break; + case 'A': legit('\357'); break; /* copyright symbol */ + } + break; + case '\10': if (bufpos>0) {; /* backspace */ + bufpos -= 1; + move(buffer[bufpos+1],buffer[bufpos],1999-bufpos); + show(); + } + break; + case '\33': {; + for( fv=1; fv <= bufsize; fv ++) buffer[fv] += (byte)(177*bufsize); + restorecrtmode(); + return; + } + break; /* end of editing */ + default: legit(r); + } + sizeup(); + } while (!false); +} + +void saveit(longint ourchain, word oldsize,word newsize) +{ + array<1,17777,byte> buffer; + word numread,numwritten,total; + char check; + word fv; + markertype m; + integer sizechange; /* so's it can be +ve or -ve */ + longint wheresit; /* "offset" value for "ourchain" */ +; + assign(tempf,"sez.tmp"); + /* OK, here goes... */ + sezhead.size=sezhead.size-longint(oldsize)+longint(newsize); /* adjust our size */ + sizechange=newsize-oldsize; /* +ve if bigger, -ve if smaller, 0 if same */ + textattr=27; + + rewrite(tempf,1); reset(f,1); + seek(f,255+sizeof(sezhead)); /* bypass the junk & sezhead (they're in RAM) */ + + blockwrite(tempf,junk,255); /* move the junk... */ + blockwrite(tempf,sezhead,sizeof(sezhead)); /* and the header to new files */ + + /* Now to move the markers */ + output << "Moving markers..." << NL; + for( fv=1; fv <= sezhead.chains; fv ++) + {; + output << fv << '\15'; + blockread(f,m,sizeof(m)); + if (fv==ourchain) /* Right, this one's ours! */ + {; + wheresit=m.offset; /* recorded for later */ + m.length=newsize-1; + m.checksum=sumup(); + } else + if (fv>ourchain) + {; /* After ours- its offset will have to be changed... */ + m.offset=m.offset+longint(sizechange); + } /* Otherwise, before ours- leave it well alone */ + blockwrite(tempf,m,sizeof(m)); + } + output << "Done OK." << NL; + + /* Right, that's the markers done... thank goodness... now it's just the + chains themselves! */ + + total=0; + + output << "Updating the chains..." << NL; + while (total<=wheresit) + {; + blockread(f,buffer,1,numread); + blockwrite(tempf,buffer,numread,numwritten); + output << '.'; + total += numwritten; + } + output << NL; output << "Updating our chain..." << NL; + /* We're now in the right place (at last...) */ + for( fv=0; fv <= (bufsize-1); fv ++) was[fv] += 3+177*fv*(bufsize-1); /* scramble "was" */ + blockwrite(tempf,was,newsize); /* "was" contains what the values *were* */ + seek(f,filepos(f)+oldsize); + output << NL; output << "Copying everything else..." << NL; + while (! eof(f)) /* high-speed copy */ + {; + blockread(f,buffer,17777,numread); + blockwrite(tempf,buffer,numread); + output << '.'; + } + output << NL; + + /* Closedown */ + close(f); close(tempf); + erase(f); rename(tempf,string(game)+".SEZ"); +} + +void particular() +{ + word origsize; +; + bufsize=0; + output << "Which one\? (? for a list)"; input >> chainnum >> NL; + if ((chainnum<0) || (chainnum>sezhead.chains)) + {; + output << "Don't be silly!" << NL; return; + } + + origsize=0 /*bufsize*/; bufpos=0; cpos=0; nickname=findname(chainnum); + fillchar(buffer,sizeof(buffer),'\0'); + buffer[0]=marker; + do { + textattr=30; output << NL; + output << "SEZ EDITOR (c) 1992, Thomas Thurman." << NL; + output << NL; + output << "Editing scrollchain no." << chainnum << NL; + output << "Your text is " << bufsize << " bytes long." << NL; + output << NL; + output << "Its nickname is \"" << nickname << "\"." << NL; + output << NL; + output << "Enter a command:" << NL; + output << " S) Save the text to disk," << NL; + output << " E) Edit this particular chain," << NL; + output << " N) change the Nickname," << NL; + output << " R) Revert text to the original," << NL; + output << "Esc) Exit and do something else!" << NL; + output << NL; + output << "Your choice? "; + r=upcase(readkey()); output << r << NL; + switch (r) { + case 'N': {; + output << NL; output << "New nickname (max 40 chars, Enter to cancel)?"; + input >> temp >> NL; + if (temp!="") nickname=temp; + } + break; + case 'E': {; setgraphmode(1); edit_it(); } break; + case 'S': saveit(chainnum,origsize,bufsize); break; + case '\33': return; break; + } + } while (!false); +} + +void titles() +{ + const varying_string<7> title = "SEZedit"; + byte fv; char r; +; + settextstyle(1,0,0); + for( fv=7; fv >= 1; fv --) + {; + setcolor(fv*2); + setusercharsize(8-fv,1,8-fv,1); + outtextxy(fv*65,fv*40-30,title[fv-1]); + } + setusercharsize(17,7,1,1); setcolor(green); + outtextxy(300,10,"Thorsoft"); + outtextxy(10,310,"Press any key..."); + do { r=readkey(); } while (!(! keypressed())); + restorecrtmode(); textattr=30; clrscr; +} + +void addone() /* Adds a new, empty chain to the end of the list. */ +{ + longint fv; + markertype m; + array<1,17777,byte> buffer; + word numread; +; + assign(tempf,"sez.tmp"); + textattr=27; + rewrite(tempf,1); reset(f,1); /* f = AVALOT.SEZ (original file) */ + seek(f,255+sizeof(sezhead)); + sezhead.chains += 1; /* we're adding a new chain */ + + blockwrite(tempf,junk,255); /* move the junk */ + blockwrite(tempf,sezhead,sizeof(sezhead)); /* move the header */ + + /* Now to move the markers */ + output << "Moving markers..." << NL; + for( fv=1; fv <= sezhead.chains-longint(1); fv ++) /* -1 because we've added 1 to it */ + {; + output << fv << '\12'; + blockread(f,m,sizeof(m)); + blockwrite(tempf,m,sizeof(m)); + } + output << "Done OK." << NL; + /* Now we add a new marker onto the end! */ + {; + m.offset=sezhead.size; /* right onto the end */ + m.length=0; /* it's empty */ + } + blockwrite(tempf,m,sizeof(m)); /* write it out to disk */ + + /* Copy everything else... including the #177 check char */ + output << "Copying everything else over..." << NL; + while (! eof(f)) + {; + blockread(f,buffer,17777,numread); + blockwrite(tempf,buffer,numread); + output << '.'; + } + output << NL; + close(f); close(tempf); + erase(f); rename(tempf,string(game)+".SEZ"); +} + +void general() +{ + char r; +; + do { + textattr=31; + output << NL; output << string(game)+".SEZ" << NL; + output << NL; + output << "No. of chains: " << sezhead.chains << NL; + output << NL; + output << "Choose one of these:" << NL; + output << " A) Add a new scrollchain" << NL; + output << " E) Edit one" << NL; + output << "Esc) Exit" << NL; + output << NL; + output << "Your choice? "; + r=upcase(readkey()); output << r << NL; + switch (r) { + case 'A': addone(); break; + case 'E': particular(); break; + case '\33': exit(0); break; + } + } while (!false); +} + +void loadit() +{; + reset(f,1); + blockread(f,junk,255); + blockread(f,sezhead,sizeof(sezhead)); + close(f); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + assign(f,string(game)+".SEZ"); + assign(tempf,"sez.tmp"); + assign(nicknames,string(game)+".NIK"); + loadit(); + graphics(); + titles(); + general(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/sezunit.cpp b/engines/avalanche/sezunit.cpp new file mode 100644 index 0000000000..755f247f8d --- /dev/null +++ b/engines/avalanche/sezunit.cpp @@ -0,0 +1,76 @@ +#include "ptoc.h" + +#define __sezunit_implementation__ + + +#include "sezunit.h" + + +struct markertype { + word length; + longint offset; + byte checksum; +}; + +untyped_file f; +longint number; +markertype marker; +word fv; +byte sum; + +void sez_setup() /* This procedure sets up the Sez system (obviously!) */ +{; + + /* Set up variables */ + + fillchar(chain,sizeof(chain),'\261'); /* blank out gunk in "chain" */ + chainsize=0; /* it's empty (for now...) */ + sezerror=sezok; /* everything's fine! */ + + /* Set up AVALOT.SEZ */ + + assign(f,"avalot.sez"); reset(f,1); + seek(f,255); blockread(f,sezhead,sizeof(sezhead)); + if (ioresult!=0) {; sezerror=sezgunkyfile; return; } /* too short */ + {; + if ((sezhead.initials!="TT") || (sezhead.gamecode!=thisgamecode) + || (sezhead.revision!=thisvercode)) + {; + sezerror=sezgunkyfile; /* not a valid file */ + return; + } + } +} + +byte sumup() +{ + word fv; byte total; +byte sumup_result; +; + total=0; + for( fv=0; fv <= chainsize; fv ++) + {; + total += ord(chain[fv]); + } + sumup_result=total; +return sumup_result; +} + +void getchain(longint number) +{; + seek(f,longint(262)+number*longint(7)); blockread(f,marker,7); + {; + seek(f,longint(270)+sezhead.chains*longint(7)+marker.offset); + blockread(f,chain,marker.length+1); + for( fv=0; fv <= marker.length; fv ++) chain[fv] -= 3+177*fv*marker.length; /* unscramble */ + chainsize=marker.length; + if (sumup()!=marker.checksum) + {; + sezerror=sezhacked; + return; + } + } + close(f); + sezerror=sezok; /* nowt went wrong */ +} + diff --git a/engines/avalanche/sezunit.h b/engines/avalanche/sezunit.h new file mode 100644 index 0000000000..6b0a99ee54 --- /dev/null +++ b/engines/avalanche/sezunit.h @@ -0,0 +1,42 @@ +#ifndef __sezunit_h__ +#define __sezunit_h__ + + +/*#include "Gyro.h"*/ + + +struct sezheader { + array<1,2,char> initials; /* should be "TT" */ + word gamecode; + word revision; /* as 3- or 4-digit code (eg v1.00 = 100) */ + longint chains; /* number of scroll chains */ + longint size; /* total size of all chains */ +}; + + + +#ifdef __sezunit_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN array<0,1999,char> chain; /* This chain */ +EXTERN word chainsize; /* Length of "chain" */ +EXTERN byte sezerror; /* Error code */ +EXTERN sezheader sezhead; +#undef EXTERN +#define EXTERN extern + + + /* Error codes for "sezerror" */ +const integer sezok = 0; +const integer sezgunkyfile = 1; +const integer sezhacked = 2; + + +void sez_setup(); + +void getchain(longint number); + + +#endif diff --git a/engines/avalanche/sezxfr.cpp b/engines/avalanche/sezxfr.cpp new file mode 100644 index 0000000000..bcc460346d --- /dev/null +++ b/engines/avalanche/sezxfr.cpp @@ -0,0 +1,95 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + /*$V-*/ +text t; +string x; +matrix<1,100,1,2,string> data; +word dp,ip,fv; +array<1,20,word> index1; +array<1,20,varying_string<10> > names; +array<1,1777,longint> thumb; longint total; +untyped_file f; + +void strip() {; x=copy(x,2,255); } + +void squish(string& q) +{ + string n; boolean ctrl; byte fv; +; + ctrl=false; n=""; + for( fv=1; fv <= length(q); fv ++) + if (q[fv]=='^') ctrl=true; else + {; /* not a caret */ + if (ctrl) q[fv]=chr(ord(upcase(q[fv]))-64); + n=n+q[fv]; ctrl=false; + } + while (n[length(n)]=='\40') n[0] -= 1; /* strip trailing spaces */ + for( fv=1; fv <= length(n); fv ++) n[fv] += 177; /* scramble */ + q=n; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + dp=0; ip=0; fillchar(data,sizeof(data),'\0'); + fillchar(thumb,sizeof(thumb),'\261'); + fillchar(index1,sizeof(index1),'\3'); + assign(t,"v:sez.dat"); reset(t); + while (! eof(t)) + {; + t >> x >> NL; + switch (x[1]) { + case ';': {; textattr=lightred; strip(); } break; + case ':': {; + textattr=lightblue; strip(); + if (dp>0) squish(data[dp][2]); + dp += 1; data[dp][1]=x; + if (pos("*",x)>0) + {; /* index */ + ip += 1; index1[ip]=dp; names[ip]=copy(x,1,pos("*",x)-1); + } + } + break; + default: + {; + textattr=white; + data[dp][2]=data[dp][2]+x+'\40'; + } + } + output << x << NL; + } + squish(data[dp][2]); + + total=1; + for( fv=1; fv <= dp; fv ++) + {; + thumb[fv]=total; + total += length(data[fv][2])+1; + } + + thumb[dp+1]=total; + + /* save it all! Firstly, the Sez file... */ + + assign(f,"v:avalot.sez"); rewrite(f,1); + x=string("This is a Sez file for an Avvy game, and it's copyright!")+'\32'; + blockwrite(f,x[1],57); + blockwrite(f,dp,2); blockwrite(f,ip,2); + blockwrite(f,index1,40); + blockwrite(f,thumb,dp*4+4); + for( fv=1; fv <= dp; fv ++) + blockwrite(f,data[fv][2],length(data[fv][2])+1); + close(f); + + /* ...then the Sed file. */ + + assign(t,"v:avalot.sed"); rewrite(t); + for( fv=1; fv <= ip; fv ++) t << names[fv] << NL; + for( fv=1; fv <= dp; fv ++) t << data[fv][1] << NL; + close(t); + + /* Done! */ +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/shell1.cpp b/engines/avalanche/shell1.cpp new file mode 100644 index 0000000000..e8dfb592a3 --- /dev/null +++ b/engines/avalanche/shell1.cpp @@ -0,0 +1,36 @@ +#include "ptoc.h" + + +/*$M $800,0,0*/ +/*#include "Dos.h"*/ + +struct infotype { + matrix<128,255,1,8,byte> chars; + string data; +}; +infotype table; +pointer where; +string comspec; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + getintvec(0x1f,where); move(where,table,1280); + comspec=getenv("comspec"); + table.data=table.data+"Avalot;"; + setintvec(0x1f,&table); + output << NL; + output << "The Astounding Avvy DOS Shell... don't forget to register!" << NL; + output << NL; + output << "Use the command EXIT to return to your game." << NL; + output << NL; + output << "Remember: You *mustn't* load any TSRs while in this DOS shell." << NL; + output << NL; + output << "This includes: GRAPHICS, PRINT, DOSKEY, and pop-up programs (like Sidekick.)" << NL; + output << NL; + output << "About to execute \"" << comspec << "\"..." << NL; + swapvectors; + exec("c:\\command.com",""); + swapvectors; + setintvec(0x1f,where); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/shell2.cpp b/engines/avalanche/shell2.cpp new file mode 100644 index 0000000000..053bca9eed --- /dev/null +++ b/engines/avalanche/shell2.cpp @@ -0,0 +1,26 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ +#include "graph.h" + +struct infotype { + matrix<128,255,1,8,byte> chars; + string data; +}; +infotype table; +pointer where; +integer gd,gm; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + getintvec(0x1f,where); move(where,table,1280); + gd=1; gm=0; initgraph(gd,gm,"c:\\turbo"); + output << "Now in CGA low-res 320x200." << NL; + output << "High ASCII codes work- œœœ °±² ðððññóòôõ" << NL; + output << "And the code is..." << NL; + output << table.data << NL; + output << "Press Enter..." << NL; + input >> NL; closegraph(); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/slope.cpp b/engines/avalanche/slope.cpp new file mode 100644 index 0000000000..a4b2f8a2de --- /dev/null +++ b/engines/avalanche/slope.cpp @@ -0,0 +1,349 @@ +#include "ptoc.h" + + + +struct joysetup { + word xmid,ymid,xmin,ymin,xmax,ymax; + byte centre; /* Size of centre in tenths */ +}; + +const integer bug_twonames = 255; +const integer bug_pandl = 254; +const integer bug_weirdswitch = 253; +const integer bug_invalidini = 252; +const integer bug_notyesorno = 251; +const integer bug_weirdcard = 250; + +byte fv; +char t; +string bugline; +boolean usingp,usingl; +boolean zoomy,numlockhold; +boolean doing_syntax; +joysetup js; boolean use_joy_a; + +boolean filename_specified; +boolean soundfx; + +string inihead,initail; /* For reading the .INI file. */ + +string filetoload; + +boolean cl_override,keyboardclick,demo; + +string slopeline; + +word storage_seg,storage_ofs; + +string argon; + +longint soundcard,baseaddr,speed,irq,dma; + +string strf(longint x) +{ + string q; + + string strf_result; + str(x,q); strf_result=q; + return strf_result; +} + +void linebug(byte which) +{ + output << "AVALOT : "; + switch (which) { + case bug_twonames : output << "You may only specify ONE filename." << NL; break; + case bug_pandl : output << "/p and /l cannot be used together." << NL; break; + case bug_weirdswitch : output << "Unknown switch (\"" << bugline << + "\"). Type AVALOT /? for a list of switches." << NL; + break; + case bug_invalidini: output << "Invalid line in AVALOT.INI (\"" << bugline << "\")" << NL; break; + case bug_notyesorno: output << "Error in AVALOT.INI: \"" << inihead << "\" must be \"yes\" or \"no.\"" << NL; break; + case bug_weirdcard: output << "Unknown card: " << bugline << '.' << NL; break; + } + + exit(which); +} + +longint card(string x) +{ + longint card_result; + if (x=="NONE") card_result=0; else + if (x=="SB") card_result=1; else + if (x=="SBPRO") card_result=2; else + if (x=="SB16") card_result=3; else + if (x=="PAS") card_result=4; else + if (x=="PASPLUS") card_result=5; else + if (x=="PAS16") card_result=6; else + if (x=="ARIA") card_result=7; else + if (x=="WINSOUND") card_result=8; else + if (x=="GRAVIS") card_result=9; else + if (x=="DACLPT") card_result=10; else + if (x=="STEREODACS") card_result=11; else + if (x=="STEREOON1") card_result=12; else + if (x=="SPEAKER") card_result=13; else + linebug(bug_weirdcard); + return card_result; +} + +void upstr(string& x) +{ + byte fv; + + for( fv=1; fv <= length(x); fv ++) x[fv]=upcase(x[fv]); +} + +boolean yesno() +{ + boolean yesno_result; + if (initail=="YES") yesno_result=true; else + if (initail=="NO") yesno_result=false; else + linebug(bug_notyesorno); + return yesno_result; +} + +word value(string x) +{ + const varying_string<15> hexdigits = "0123456789ABCDEF"; + word w; integer e; + + word value_result; + if (x[1]=='$') + { + w=0; + for( e=2; e <= length(x); e ++) + { + w=w << 4; + w += pos(upcase(x[e]),hexdigits)-1; + } + value_result=w; + } else + { + val(x,w,e); + if (e==0) value_result=w; else value_result=0; + } + return value_result; +} + +void ini_parse() +{ + upstr(inihead); + upstr(initail); + + if (inihead=="QUIET") soundfx=! yesno(); else + if (inihead=="ZOOMYSTART") zoomy=yesno(); else + if (inihead=="NUMLOCKHOLD") numlockhold=yesno(); else + if (inihead=="LOADFIRST") filetoload=initail; else + if (inihead=="OVERRIDEEGACHECK") cl_override=yesno(); else + if (inihead=="KEYBOARDCLICK") keyboardclick=yesno(); else + if (inihead=="JOYTOP") js.ymin=value(initail); else + if (inihead=="JOYBOTTOM") js.ymax=value(initail); else + if (inihead=="JOYLEFT") js.xmin=value(initail); else + if (inihead=="JOYRIGHT") js.xmax=value(initail); else + if (inihead=="JOYMIDX") js.xmid=value(initail); else + if (inihead=="JOYMIDY") js.ymid=value(initail); else + if (inihead=="JOYCENTRINGFACTOR") js.centre=value(initail); else + if (inihead=="WHICHJOY") use_joy_a=value(initail)==1; else + if (inihead=="SOUNDCARD") soundcard=card(initail); else + if (inihead=="BASEADDRESS") baseaddr=value(initail); else + if (inihead=="IRQ") irq=value(initail); else + if (inihead=="DMA") dma=value(initail); else + if (inihead=="SAMPLERATE") speed=value(initail); +} + +void strip_ini() +{ + byte fv; + + if (inihead=="") return; + + /* Firstly, delete any comments. */ + fv=pos(";",inihead); + if (fv>0) Delete(inihead,fv,255); + + /* Lose the whitespace... */ + + while (inihead[length(inihead)]==' ') inihead[0] -= 1; + while ((inihead!="") && (inihead[1]==' ')) Delete(inihead,1,1); + + /* It's possible that now we'll end up with a blank line. */ + + if ((inihead=="") || (inihead[1]=='[')) return; + + fv=pos("=",inihead); + + if (fv==0) + { /* No "="! Weird! */ + bugline=inihead; + linebug(bug_invalidini); + } + + initail=copy(inihead,fv+1,255); + inihead[0]=chr(fv-1); +} + +void load_ini() +{ + text ini; + + assign(ini,"AVALOT.INI"); + reset(ini); + + while (! eof(ini)) + { + ini >> inihead >> NL; + strip_ini(); + if (inihead!="") ini_parse(); + } + + close(ini); +} + +void parse(string x); +static string arg; + +static string getarg(string otherwis) +{ + string getarg_result; + if (arg=="") getarg_result=otherwis; else getarg_result=arg; + return getarg_result; +} + +void parse(string x) + +{ + switch (x[1]) { + case '/':case '-': { + arg=copy(x,3,255); + switch (upcase(x[2])) { + case '?': doing_syntax=true; break; + case 'O': cl_override=true; break; + case 'L': if (! usingp) + { + usingl=true; + argon=getarg("avvy.log"); + } else linebug(bug_pandl); + break; + case 'P': if (! usingl) + { + usingp=true; + argon=getarg("prn"); + } else linebug(bug_pandl); + break; + case 'Q': soundfx=false; break; + case 'Z': zoomy=true; break; + case 'K': keyboardclick=true; break; + case 'D': demo=true; break; + default: { + bugline=x; + linebug(bug_weirdswitch); + } + } + } + break; + case '*': { + inihead=copy(x,2,255); + strip_ini(); + if (inihead!="") ini_parse(); + } + break; + default: { /* filename */ + if (filename_specified) + linebug(bug_twonames); + else + filetoload=x; + filename_specified=true; + } + } +} + +void make_slopeline(); + +static char yn1(boolean b) +{ + char yn1_result; + if (b) yn1_result='y'; else yn1_result='n'; + return yn1_result; +} + + + +static char pln() +{ + char pln_result; + if ((! usingp) && (! usingl)) pln_result='n'; else + if (usingp) pln_result='p'; else + if (usingl) pln_result='l'; + return pln_result; +} + +void make_slopeline() + +{ + if (argon=="") argon="nul"; + + slopeline=string('1')+yn1(doing_syntax)+yn1(soundfx)+yn1(cl_override)+ + yn1(keyboardclick)+pln()+yn1(demo)+yn1(zoomy)+yn1(numlockhold)+ + yn1(use_joy_a)+ + ' '+strf(js.xmid)+ + ' '+strf(js.ymid)+ + ' '+strf(js.xmin)+ + ' '+strf(js.ymin)+ + ' '+strf(js.xmax)+ + ' '+strf(js.ymax)+ + ' '+strf(js.centre)+ + ' '+argon+' '+filetoload; +} + +void store_slopeline() +{ + move(slopeline,mem[storage_seg*storage_ofs+3],sizeof(slopeline)); + move(js,mem[storage_seg*storage_ofs+300],sizeof(js)); + move(soundcard,mem[storage_seg*storage_ofs+5000],4); + move(baseaddr,mem[storage_seg*storage_ofs+5004],4); + move(irq,mem[storage_seg*storage_ofs+5008],4); + move(dma,mem[storage_seg*storage_ofs+5012],4); + move(speed,mem[storage_seg*storage_ofs+5016],4); +} + +void get_storage_addr(); + +static void not_through_bootstrap() +{ output << "Not standalone!" << NL; exit(255); } + +void get_storage_addr() +{ + integer e; + + if (paramstr(1)!="jsb") not_through_bootstrap(); + val(paramstr(2),storage_seg,e); if (e!=0) not_through_bootstrap(); + val(paramstr(3),storage_ofs,e); if (e!=0) not_through_bootstrap(); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + get_storage_addr(); + + filetoload=""; argon=""; + usingl=false; + usingp=false; + cl_override=false; + soundfx=true; + zoomy=false; + numlockhold=false; + filename_specified=false; + keyboardclick=false; + doing_syntax=false; + soundcard=0; baseaddr=0; irq=0; dma=0; + + load_ini(); + + for( fv=4; fv <= paramcount; fv ++) + parse(paramstr(fv)); + + make_slopeline(); + + store_slopeline(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/spread.cpp b/engines/avalanche/spread.cpp new file mode 100644 index 0000000000..57361e8b46 --- /dev/null +++ b/engines/avalanche/spread.cpp @@ -0,0 +1,306 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + + +struct adxtype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +varying_string<3> sn; +adxtype a; +matrix<1,24,0,1,pointer> pic; /* the pictures themselves */ +word bigsize; + +const array<0,15,varying_string<6> > col = + {{"Black","Blue","Green","Cyan","Red","Pink","Brown","Grey+", + "Grey-","Blue+","Green+","Cyan+","Red+","Pink+","Yellow","White"}}; +const string prompt = string('\32')+'\257'; + +void load() +{ + untyped_file f; byte gd,gm,sort,n; pointer p,q; +; + assign(f,string("v:sprite")+sn+".avd"); reset(f,1); seek(f,59); + blockread(f,a,sizeof(a)); blockread(f,bigsize,2); + setactivepage(3); + for( sort=0; sort <= 1; sort ++) + {; + mark(q); getmem(p,bigsize); + blockread(f,p,bigsize); + putimage(0,0,p,0); release(q); n=1; + for( gm=0; gm <= (a.num / a.seq)-1; gm ++) /* directions */ + for( gd=0; gd <= a.seq-1; gd ++) /* steps */ + {; + getmem(pic[n][sort],a.size); /* grab the memory */ + getimage((gm / 2)*(a.xl*6)+gd*a.xl,(gm % 2)*a.yl, + (gm / 2)*(a.xl*6)+gd*a.xl+a.xl-1,(gm % 2)*a.yl+a.yl-1, + pic[n][sort]); /* grab the pic */ + n += 1; + } + } + close(f); setactivepage(0); +} + +void save() +{ + untyped_file f; byte gd,gm,sort,n; pointer p,q; + string x; integer txl,tyl; +; + {; + txl=a.seq*a.xl*2; tyl=a.yl*2; + } + + assign(f,string("v:sprite")+sn+".avd"); + x=string("Sprite file for Avvy - Trippancy IV. Subject to copyright.")+'\32'; + rewrite(f,1); blockwrite(f,x[1],59); + + blockwrite(f,a,sizeof(a)); blockwrite(f,bigsize,2); + setactivepage(3); + for( sort=0; sort <= 1; sort ++) + {; + mark(q); getmem(p,bigsize); n=1; + for( gm=0; gm <= (a.num / a.seq)-1; gm ++) /* directions */ + for( gd=0; gd <= a.seq-1; gd ++) /* steps */ + {; + putimage((gm / 2)*(a.xl*6)+gd*a.xl,(gm % 2)*a.yl, + pic[n][sort],0); /* drop the pic */ + n += 1; + } + getimage(0,0,txl,tyl,p); + blockwrite(f,p,bigsize); release(q); + } + close(f); setactivepage(0); +} + +void setup() +{ + integer gd,gm; +; + output << "SPREAD (c) 1992, Thomas Thurman." << NL; output << NL; + output << "Enter number of SPRITE*.AVD file to edit:"; input >> sn >> NL; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); +} + +string strf(longint x) +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +void likethis() +{; + {; + setfillstyle(1,a.bgc); setcolor(a.fgc); settextstyle(0,0,1); + bar(0,190,100,200); outtextxy(12,191,"Like this!"); + } +} + +void values() +{ + byte fv; +; + settextstyle(2,0,9); setcolor(14); + outtextxy(277,0,string("Spread: editing ")+sn); setcolor(15); + for( fv=0; fv <= 3; fv ++) putimage(77+(a.xl+10)*fv,17,pic[a.seq*fv+1][1],0); + settextstyle(2,0,7); + outtextxy(0, 30,"Views:"); + {; + outtextxy(0, 50,string("N: Name: ")+a.name); + outtextxy(0, 70,string("No. of pictures: ")+strf(a.num)+" ("+strf(a.num / a.seq)+" ways)"); + outtextxy(0, 90,string("XY: Size: ")+strf(a.xl)+'x'+strf(a.yl)); + outtextxy(0,110,string("S: Stride size: ")+strf(a.seq)); + outtextxy(0,130,string("Imagesize (bytes): ")+strf(a.size)); + outtextxy(0,150,string("B: Bubble background: ")+col[a.bgc]); + outtextxy(0,170,string("F: Bubble foreground: ")+col[a.fgc]); + likethis(); + } + setcolor(lightgreen); settextstyle(0,0,1); + outtextxy(400,50,"A) Animate"); + outtextxy(400,60,"E) Edit pictures"); + outtextxy(400,70,"alt-f2) Save"); + outtextxy(400,80,"ctrl-f3) Load"); + outtextxy(400,90,"or any key to the left..."); +} + +byte ccol() +{ + byte fv; +byte ccol_result; +; + restorecrtmode(); + output << "Choose a colour- one of these..." << NL; + for( fv=0; fv <= 15; fv ++) + {; + textattr=14; output << fv << ") "; textattr=fv; output << string('\376')+'\40'; + textattr=14; output << col[fv] << NL; + } + textattr=14; + do { + output << prompt; input >> fv >> NL; + } while (!(fv<16)); + ccol_result=fv; setgraphmode(0); +return ccol_result; +} + +string cstr(string oc) +{ + string x; +string cstr_result; +; + restorecrtmode(); + output << string("Old choice is: <")+oc+'>' << NL; + output << NL; + output << "(Anything after a semi-colon will not be displayed by the game, e.g. Avvy;Monk" << NL; + output << " will be displayed as Avvy.)" << NL; + output << NL; + output << string("New choice, Enter for no change, Space+Enter for a blank?")+prompt; input >> x >> NL; + if (x=="") cstr_result=oc; else if (x==' ') cstr_result=""; else cstr_result=x; + setgraphmode(0); +return cstr_result; +} + +longint cnum(longint on) +{ + string x; longint q; integer e; +longint cnum_result; +; + restorecrtmode(); + do { + output << "Old value is: " << on << '.' << NL; + output << string("New choice, or Enter for no change?")+prompt; input >> x >> NL; + if (x=="") + {; + e=0; /* must be OK here */ q=on; + } else val(x,q,e); + if (e!=0) output << x << " isn't a number, silly!" << NL; + } while (!(e==0)); + setgraphmode(0); cnum_result=q; +return cnum_result; +} + +void animate() +{ + byte facing,step,slow,fv; +; + cleardevice(); + settextstyle(0,0,2); setcolor(12); outtextxy(0,0,"Animate"); + settextstyle(0,0,1); setcolor(15); + outtextxy(0,20,"Enter = Turn, + = Faster, - = Slower, Esc = stop this."); + facing=0; step=1; slow=100; + do { + for( fv=0; fv <= 1; fv ++) + putimage(200*fv+177,77,pic[facing*a.seq+step][fv],4-fv*4); + if (keypressed()) + switch (upcase(readkey())) { + case '\15': {; + facing += 1; if (facing*a.seq>=a.num) facing=0; + } + break; + case '\33': {; cleardevice(); return; } break; + case '+': if (slow>0) slow -= 5; break; + case '-': if (slow<255) slow += 5; break; default: output << '\7'; + } + step += 1; if (step>a.seq) step=1; + delay(slow); + } while (!false); +} + +byte tabpel(integer x,integer y) +{byte tabpel_result; +; + if (getpixel(400+x,17+y)==15) tabpel_result=17; + else tabpel_result=getpixel(500+x,17+y); +return tabpel_result; +} + +void bigpixel(integer x,integer y, byte size,byte col) +{; + if (col==17) setfillstyle(9,8); else setfillstyle(1,col); + bar(x*size,y*size,x*size+size-2,y*size+size-2); +} + +void blowup(byte n) +{ + byte fv,x,y,xyl; +; + {; + for( fv=0; fv <= 1; fv ++) putimage(400+fv*100,17,pic[n][fv],0); + xyl=200 / a.yl; + for( x=0; x <= a.xl; x ++) + for( y=0; y <= a.yl; y ++) + bigpixel(x,y,xyl,tabpel(x,y)); + } +} + +void edit(); + +static void putnum(byte x,byte p) +{ + varying_string<2> z; +; + str(x,z); outtextxy(x*53+17,87,z); putimage(x*53,100,pic[p][1],0); +} + + +static void title() +{; + cleardevice(); setcolor(11); settextstyle(0,0,2); + outtextxy(0,0,"Edit- which one?"); settextstyle(0,0,1); setcolor(15); +} + +void edit() +{ + byte fv,ra,rb; +; + {; + title(); for( fv=1; fv <= (a.num / a.seq); fv ++) putnum(fv,fv*a.seq); + do { ra=ord(readkey())-48; } while (!(ra<(a.num / a.seq))); ra -= 1; + title(); for( fv=1; fv <= a.seq; fv ++) putnum(fv,ra*a.seq+fv); + do { rb=ord(readkey())-48; } while (!(rb<a.seq)); + cleardevice(); + blowup(ra*a.seq+rb); input >> NL; + cleardevice(); + } +} + +void pickone() +{ + char r; +; + r=upcase(readkey()); + switch (r) { + case 'N': a.name=cstr(a.name); break; + case 'S': a.seq=cnum(a.seq); break; + case 'F': a.fgc=ccol(); break; + case 'B': a.bgc=ccol(); break; + case 'A': animate(); break; + case 'E': edit(); break; + case '\0': switch (readkey()) { + case 'i': save(); break; /* alt-f2 */ + } + break; + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + setup(); + do { + values(); + pickone(); + } while (!false); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/spread2.cpp b/engines/avalanche/spread2.cpp new file mode 100644 index 0000000000..96545c2bc8 --- /dev/null +++ b/engines/avalanche/spread2.cpp @@ -0,0 +1,855 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Squeak.h"*/ + +/*$V-,R+*/ + +const integer pattern = 12; /* Pattern for transparencies. */ +const fillpatterntype grey50 = {{0xaa, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0x55}}; + +struct adxtype { + varying_string<12> name; /* name of character */ + varying_string<16> comment; /* comment */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ + byte accinum; /* the number according to Acci (1=Avvy, etc.) */ +}; + +untyped_file sf; +adxtype a; +char r; +boolean adxmodi,picmodi; +array<5,2053,byte> mani; +matrix<0,99,0,10,byte> sil; +array<1,16000,byte> aa; +word soa; +byte xw; +byte leftc,rightc; +boolean lmo; +array<1,2,pointer> clip; +integer clipx,clipy; +boolean boardfull; +integer xofs,yofs; /* Distance of TL corner of cut from TL corner of pic. */ + +byte bigpix_size,bigpix_gap; /* Size & gap betwixt big pixels. */ + +void setup() +{ + const integer shouldid = -1317732048; + boolean ok; + longint id; + varying_string<2> sn; +; + output << "Sprite Editor 2 (c) 1993, Thomas Thurman." << NL; + bigpix_size=3; bigpix_gap=5; + do { + ok=true; + output << "Number of sprite?"; input >> sn >> NL; + assign(sf,string("v:\\sprite")+sn+".avd"); + reset(sf,1); + seek(sf,177); + blockread(sf,id,4); + if (id!=shouldid) + {; + output << "That isn't a valid Trip5 spritefile." << NL; + output << "Please choose another." << NL; + output << NL; + ok=false; close(sf); + } else + {; + blockread(sf,soa,2); + if (soa!=(cardinal)sizeof(a)) /* to change this, just change the "type adx=" bit.*/ + {; + output << "That spritefile contains an unknown ADX field type." << NL; + output << "Please choose another." << NL; + output << NL; + ok=false; close(sf); + } + } + } while (!ok); + blockread(sf,a,soa); + output << filepos(sf) << NL; + adxmodi=false; picmodi=false; + getmem(clip[1],a.size); getmem(clip[2],a.size); boardfull=false; +} + +string strf(longint x) +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +void centre(byte y, string z) +{; + gotoxy(40-length(z) / 2,y); output << z; +} + +void info(byte x,byte y, string p,string q) +{; + gotoxy(x,y); + textattr=6; output << p+":ú"; + textattr=11; output << q; + textattr=8; output << 'ú'; +} + +void colours(byte f,byte b) +{; + gotoxy(35,11); + textattr=6; + output << "Bubbles"; + textattr=b*16+f; + output << " like this! "; +} + +void adxinfo() +{; + {; + info( 5, 8,"Name",a.name); + info(35, 8,"Comment",a.comment); + info( 5, 9,"Width",strf(a.xl)); + info(15, 9,"Height",strf(a.yl)); + info(35, 9,"Size of one pic",strf(a.size)); + info( 5,10,"Number in a stride",strf(a.seq)); + info(35,10,"Number of strides",strf(a.num / a.seq)); + info( 5,11,"Total number",strf(a.num)); + info( 5,12,"Acci number",strf(a.accinum)); + colours(a.fgc,a.bgc); + } +} + +void status() +{; + textattr=7; + clrscr; + textattr=10; centre(3,"Sprite Editor 2 (c) 1993, Thomas Thurman."); + textattr=6; gotoxy(3,7); output << "ADX information:"; + adxinfo(); + textattr=6; + gotoxy(3,14); output << "Options:"; + gotoxy(5,15); output << "A) edit ADX information"; + gotoxy(5,16); output << "P) edit pictures"; + gotoxy(5,17); output << "S) save the ADX info (pics are saved automatically)"; +} + +void enterstring(string w, byte l, string& q) +{ + string t; +; + textattr=13; clrscr; + output << NL; + output << "Press Return for no change, Space+Return for a blank." << NL; + do { + output << "New value for " << w << " (max length " << l << ")?"; + input >> t >> NL; + } while (!(length(t)<=l)); + if (t==' ') q=""; else if (t!="") q=t; + adxmodi=true; +} + +void entercolour(string w, byte& c); +static byte fv; + +static void loseold() {; output << string('\10')+'\377'; } + + +static void drawnew() {; gotoxy(3+fv*5,11); output << '\30'; } + +void entercolour(string w, byte& c) +{; + textattr=13; clrscr; + output << NL; output << "New value for " << w << '?' << NL; + output << " Use \32\33 to move about, Enter=OK, Esc=Cancel." << NL; + for( fv=1; fv <= 15; fv ++) + {; + gotoxy(3+fv*5,10); textattr=fv; output << 'þ'; + } + fv=c; + do { + drawnew(); + r=readkey(); + switch (r) { + case '\33': return; break; /* no change to c */ + case '\15': {; + c=fv; adxmodi=true; + return; + } + break; + case '\0': switch (readkey()) { + case 'G': {; loseold(); fv= 0; drawnew(); } break; /* home */ + case 'O': {; loseold(); fv=15; drawnew(); } break; /* end */ + case 'K': if (fv> 0) {; loseold(); fv -= 1; drawnew(); } break; /* left */ + case 'M': if (fv<15) {; loseold(); fv += 1; drawnew(); } break; /* right */ + } + break; + } + } while (!false); +} + +void enternum(string w, byte& q) +{ + string t; integer e; byte r; +; + textattr=13; clrscr; + output << NL; + output << "Press Return for no change." << NL; + do { + output << "New value for " << w << '?'; + input >> t >> NL; + if (t=="") return; /* No change... */ + val(t,r,e); + } while (!(e==0)); + q=r; /* Update variable. */ + adxmodi=true; +} + +void editadx() +{ + char r; +; + do { + clrscr; + textattr=10; centre(3,"ADX Editor:"); + textattr= 9; centre(5,"N: Name, C: Comment, F: Foreground, B: Background, A: Accinum, X: eXit."); + adxinfo(); + r=upcase(readkey()); + switch (r) { + case 'N': enterstring("Name",12,a.name); break; + case 'C': enterstring("Comment",16,a.comment); break; + case 'F': entercolour("Foreground",a.fgc); break; + case 'B': entercolour("Background",a.bgc); break; + case 'A': enternum("Accinum",a.accinum); break; + case 'X':case '\33': return; break; + default: output << '\7'; + } + } while (!false); +} + +void saveit() +{ + char pak; + integer oldsoa; +; + textattr=10; clrscr; + centre(7,"Saving!"); + if (adxmodi) + {; + centre(10,"ADX information being saved..."); + seek(sf,181); /* start of ADX info */ + soa=sizeof(a); + blockread(sf,oldsoa,2); +/* if soa=oldsoa then + begin;*/ + seek(sf,181); + blockwrite(sf,soa,2); + blockwrite(sf,a,soa); + adxmodi=false; +/* end else write(#7);*/ + } else centre(10,"No changes were made to ADX..."); + centre(25,"Press any key..."); pak=readkey(); +} + +void quit() +{; + close(sf); + exit(0); +} + +void getsilmani() /* Reclaims original sil & mani arrays */ +{ + byte x,y,z; word offs; +; + + /* Sil... */ + + getimage(500,150,500+a.xl,150+a.yl,aa); + + for( x=0; x <= 3; x ++) + for( y=0; y <= a.yl; y ++) + for( z=0; z <= (a.xl / 8); z ++) + {; + offs=5+y*xw*4+xw*x+z; + sil[y][z]=aa[offs]; + } + + /* ...Mani. */ + + getimage(500,50,500+a.xl,50+a.yl,aa); + + move(aa[5],mani,sizeof(mani)); + +} + +void explode(byte which) /* 0 is the first one! */ + /* Each character takes five-quarters of (a.size-6) on disk. */ +{ + byte fv,ff; word so1; /* size of one */ +; + {; + so1=a.size-6; so1 += so1 / 4; + seek(sf,183+soa+so1*which); /* First is at 221 */ +/* where:=filepos(sf);*/ + xw=a.xl / 8; if ((a.xl % 8)>0) xw += 1; + + for( fv=0; fv <= a.yl; fv ++) + blockread(sf,sil[fv],xw); + blockread(sf,mani,a.size-6); + aa[a.size-1]=0; aa[a.size]=0; /* footer */ + } +} + +void implode(byte which) /* Writes a pic back onto the disk */ +{ + byte fv,ff; word so1; /* size of one */ +; + {; + + getsilmani(); /* Restore original arrays */ + + so1=a.size-6; so1 += so1 / 4; + seek(sf,183+soa+so1*which); /* First is at 221 */ + + xw=a.xl / 8; if ((a.xl % 8)>0) xw += 1; + + for( fv=0; fv <= a.yl; fv ++) + blockwrite(sf,sil[fv],xw); + blockwrite(sf,mani,a.size-6); + aa[a.size-1]=0; aa[a.size]=0; /* footer */ + } +} + +void plotat(integer xx,integer yy) /* Does NOT cameo the picture!*/ +{; + move(mani,aa[5],sizeof(mani)); + {; + aa[1]=a.xl; aa[2]=0; aa[3]=a.yl; aa[4]=0; /* set up x&y codes */ + } + putimage(xx,yy,aa,0); +} + +void plotsil(integer xx,integer yy) /* Plots silhouette- rarely used */ +{ + byte x,y,z; word offs; +; + for( x=0; x <= 3; x ++) + for( y=0; y <= a.yl; y ++) + for( z=0; z <= (a.xl / 8); z ++) + {; + offs=5+y*xw*4+xw*x+z; + aa[offs]=sil[y][z]; + } + + {; + aa[1]=a.xl; aa[2]=0; aa[3]=a.yl; aa[4]=0; /* set up x&y codes */ + } + + putimage(xx,yy,aa,0); + +} + +void style(byte x) +{; + if (x==16) + /*setfillstyle(pattern,8)*/setfillpattern(grey50,8); + else + setfillstyle(1,x); +} + +void bigpixel(integer x,integer y) +{; + if (getpixel(500+x,150+y)==15) + /*setfillstyle(pattern,8)*/setfillpattern(grey50,8); + else + setfillstyle(1,getpixel(500+x,50+y)); + + bar(x*bigpix_gap,y*bigpix_gap, + x*bigpix_gap+bigpix_size,y*bigpix_gap+bigpix_size); +} + +void subplot(byte y, integer x, char c) +{; + setfillstyle(1,0); bar(x,0,x+9,170); outtextxy(x+5,y*10+5,c); +} + +void plotleft() {; subplot( leftc,239,'\32'); } /* palette arrows */ +void plotright() {; subplot(rightc,351,'\33'); } + +void plotbig(byte x,byte y,byte c) +{; + style(c); + bar(x*bigpix_gap,y*bigpix_gap, + x*bigpix_gap+bigpix_size,y*bigpix_gap+bigpix_size); + if (c==16) + {; + putpixel(500+x,150+y,15); + putpixel(500+x, 50+y,0); + } else + {; + putpixel(500+x,150+y,0); + putpixel(500+x, 50+y,c); + } +} + +void changepic() +{; + mx=mx / bigpix_gap; my=my / bigpix_gap; + if ((mx>a.xl) || (my>a.yl)) return; + if (mkey==left) + plotbig(mx,my,leftc); else + plotbig(mx,my,rightc); +} + +void changecol() +{; + my=my / 10; if (my>16) return; + if (mkey==left) + {; + leftc=my; plotleft(); + } else + {; + rightc=my; plotright(); + } +} + +void showcutpic() +{; + setfillstyle(5,1); bar(20,160,40+clipx,180+clipy); + putimage(30,170,clip[2],andput); + putimage(30,170,clip[1],xorput); +} + +void movesquare(integer& xc,integer& yc, integer xl,integer yl) +{ + integer x2,y2; +; + do { + x2=xl+xc; y2=yl+yc; + setcolor(15); + do { + rectangle(xc*bigpix_gap-1,yc*bigpix_gap-1, + x2*(bigpix_gap+1)-1,y2*(bigpix_gap+1)-1); + } while (!keypressed()); + setcolor(0); rectangle(xc*bigpix_gap-1,yc*bigpix_gap-1, + x2*(bigpix_gap+1)-1,y2*(bigpix_gap+1)-1); + switch (readkey()) { + case '\0': switch (readkey()) { + case '\110': yc -= 1; break; + case '\113': xc -= 1; break; + case '\115': xc += 1; break; + case '\120': yc += 1; break; + } + break; + case '\15': return; break; + } + while ((xl+xc)>a.xl) xc -= 1; + while ((yl+yc)>a.yl) yc -= 1; + if (xc<0) xc=0; + if (yc<0) yc=0; + } while (!false); +} + +void switch_(integer& v1,integer& v2) + /* Swaps over the values of v1 and v2. */ +{ + integer temp; +; + temp=v1; v1=v2; v2=temp; +} + +void choosesquare(integer& x1,integer& y1,integer& x2,integer& y2) +{ + boolean tl; +; + do { + setcolor(15); + do { + rectangle(x1*bigpix_gap-1,y1*bigpix_gap-1, + (x2+1)*bigpix_gap-1,(y2+1)*bigpix_gap-1); + } while (!keypressed()); + setcolor(0); + rectangle(x1*bigpix_gap-1,y1*bigpix_gap-1, + (x2+1)*bigpix_gap-1,(y2+1)*bigpix_gap-1); + switch (readkey()) { + case '\0': switch (readkey()) { + case '\110': if (tl) y1 -= 1; else y2 -= 1; break; + case '\113': if (tl) x1 -= 1; else x2 -= 1; break; + case '\115': if (tl) x1 += 1; else x2 += 1; break; + case '\120': if (tl) y1 += 1; else y2 += 1; break; + } + break; + case '\11': tl=! tl; break; + case '\15': {; + if (x1>x2) switch_(x1,x2); /* Get the square the right way up. */ + if (y1>y2) switch_(y1,y2); + y2 -= y1; x2 -= x1; /* y1 & y2 have to be the OFFSETS! */ + return; + } + break; + } + if (x1<0) x1=0; if (y1<0) y1=0; + {; + if (y2>a.yl) y2=a.yl; if (x2>a.xl) x2=a.xl; + } + } while (!false); +} + +void paste() +{ + byte x,y; +; + if (! boardfull) + {; + output << '\7'; + return; + } + if (! ((clipx==a.xl) && (clipy==a.yl))) + movesquare(xofs,yofs,clipx,clipy); + putimage(500+xofs, 50+yofs,clip[1],0); + putimage(500+xofs,150+yofs,clip[2],0); + for( x=0; x <= a.xl; x ++) + for( y=0; y <= a.yl; y ++) + {; + bigpixel(x,y); + } +} + +void cut() +{; + xofs=0; yofs=0; /* From the TL. */ + {; + getimage(500, 50,500+a.xl, 50+a.yl,clip[1]); + getimage(500,150,500+a.xl,150+a.yl,clip[2]); + clipx=a.xl; clipy=a.yl; + } + showcutpic(); + boardfull=true; +} + +void cutsome() +{; + {; + choosesquare(xofs,yofs,clipx,clipy); + getimage(500+xofs, 50+yofs,500+xofs+clipx, 50+yofs+clipy,clip[1]); + getimage(500+xofs,150+yofs,500+xofs+clipx,150+yofs+clipy,clip[2]); + } + showcutpic(); + boardfull=true; +} + +boolean confirm(char c, string x) +{ + byte col; char groi; +boolean confirm_result; +; + while (keypressed()) groi=readkey(); + x=x+"? "+c+" to confirm."; + col=1; + do { + setcolor(col); outtextxy(555,5,x); + col += 1; if (col==16) col=1; + } while (!keypressed()); + confirm_result=upcase(readkey())==c; + setfillstyle(1,0); bar(470,0,640,10); +return confirm_result; +} + +void checkbutton(byte which) +{; + my=(my-12) / 25; + switch (my) { + case 0: if (confirm('S',"Save")) {; implode(which); lmo=true; } break; + case 1: if (confirm('C',"Cancel")) lmo=true; break; + case 4: cut(); break; + case 5: if (confirm('P',"Paste")) paste(); break; + case 6: cutsome(); break; + } +} + +void animate() +{; +} + +void undo() +{; +} + +void fliplr(); + +static void flipline(integer x1,integer x2,integer y) +{ + integer fv,ff; +; + for( fv=x1; fv <= x2; fv ++) putpixel(fv,0,getpixel(fv,y)); + ff=x2; + for( fv=x1; fv <= x2; fv ++) + {; + putpixel(fv,y,getpixel(ff,0)); + ff -= 1; + } +} + +void fliplr() /* Flips left-to-right. */ +{ + integer fv,ff; +; + for( fv=0; fv <= a.yl; fv ++) + {; + flipline(500,500+a.xl, 50+fv); + flipline(500,500+a.xl,150+fv); + } + for( fv=0; fv <= a.xl; fv ++) + for( ff=0; ff <= a.yl; ff ++) + bigpixel(fv,ff); +} + +void change_colours() /* Swaps one colour with another. */ +{ + byte fv,ff; +; + + if ((leftc==16) || (rightc==16)) /* See-through can't be one of the colours. */ + {; + output << '\7'; /* Bleep! */ + return; + } + + for( fv=0; fv <= a.yl; fv ++) + for( ff=0; ff <= a.xl; ff ++) + if (getpixel(500+ff,50+fv)==leftc) + putpixel(500+ff,50+fv,rightc); + + for( fv=0; fv <= a.xl; fv ++) + for( ff=0; ff <= a.yl; ff ++) + bigpixel(fv,ff); +} + +void redraw() +{ + byte x,y; +; + setfillstyle(1,0); + bar(0,0,250,200); + + for( x=0; x <= a.xl; x ++) + for( y=0; y <= a.yl; y ++) + {; + bigpixel(x,y); + } +} + +void parse(char c) /* Parses keystrokes */ +{; + switch (upcase(c)) { + case '\26':case 'P': paste(); break; + case '\3':case 'C': cut(); break; + case '\30':case 'X': cutsome(); break; + case 'A': animate(); break; + case 'U': undo(); break; + case '@': fliplr(); break; + case '!': change_colours(); break; + case '<': if (bigpix_size>1) + {; + bigpix_size -= 1; bigpix_gap -= 1; + redraw(); + } + break; + case '>': if (bigpix_size<8) + {; + bigpix_size += 1; bigpix_gap += 1; + redraw(); + } + break; + case '\33': if (confirm('X',"Exit")) lmo=true; break; + } +} + +void editone(byte which) +{ + byte x,y; +; + cleardevice(); + explode(which); + plotat(500,50); + plotsil(500,150); + for( x=0; x <= a.xl; x ++) + for( y=0; y <= a.yl; y ++) + {; + bigpixel(x,y); + } + for( y=0; y <= 16; y ++) + {; + style(y); + bar(251,y*10+1,349,y*10+9); + rectangle(250,y*10,350,y*10+10); + } + + settextstyle(0,0,1); leftc=15; rightc=16; plotleft(); plotright(); lmo=false; + + outtextxy(410, 25,"Save"); + outtextxy(410, 50,"Cancel"); + outtextxy(410, 75,"Animate"); + outtextxy(410,100,"Undo"); + outtextxy(410,125,"Cut"); + outtextxy(410,150,"Paste"); + outtextxy(410,175,"X: Cut Some"); + if (boardfull) showcutpic(); + setfillstyle(6,15); + for( y=0; y <= 7; y ++) + bar(370,y*25+12,450,y*25+12); + + do { + on; + do { + if (keypressed()) parse(readkey()); + } while (!(anyo | lmo)); + off; + + if (! lmo) + {; + getbuttonstatus; + + switch (mx) { + case 1 ... 249: changepic(); break; + case 250 ... 350: changecol(); break; + case 370 ... 450: checkbutton(which); break; + } + } + } while (!lmo); + settextstyle(2,0,7); setcolor(15); +} + +void editstride(byte which); + +static char whichc; + +static shortint first; + +static void drawup(byte& which) +{ + byte fv; +; + whichc=chr(which+48); + cleardevice(); + outtextxy(320,10,string("Edit stride ")+whichc); + first=(which-1)*a.seq-1; + for( fv=1; fv <= a.seq; fv ++) + {; + explode(fv+first); + plotat(fv*73,77); + outtextxy(17+fv*73,64,chr(fv+48)); + } + outtextxy(320,177,"Which?"); +} + +void editstride(byte which) +{ + char r; +; + drawup(which); + do { + r=readkey(); + if ((r>'0') && (r<=chr(a.seq+48))) + {; + editone(ord(r)-48+first); + drawup(which); + } + } while (!(r=='\33')); +} + +void editpics(); + +static byte nds; /* num div seq */ + +static void drawup1() +{ + byte fv; +; + setgraphmode(0); directvideo=false; settextjustify(1,1); + nds=a.num / a.seq; + settextstyle(2,0,7); + outtextxy(320,10,"Edit pictures..."); + outtextxy(320,40,"(Usually, 1=away, 2=right, 3=towards, 4=left.)"); + for( fv=1; fv <= nds; fv ++) + {; + explode((fv-1)*a.seq); + plotat(fv*73,100); + outtextxy(17+fv*73,87,chr(fv+48)); + } + outtextxy(320,60,string("There are ")+strf(nds)+" strides available."); + outtextxy(320,177,"Which do you want?"); +} + +void editpics() +{ + char r; byte which; integer e; +; + drawup1(); + do { + r=readkey(); + if ((r>'0') && (r<=chr(nds+48))) + {; + editstride(ord(r)-48); + drawup1(); + } + } while (!(r=='\33')); + restorecrtmode(); +} + +void titles() +{ + integer gd,gm; + char pak; word wait; +; + gd=3; gm=1; initgraph(gd,gm,"c:\\bp\\bgi"); + settextstyle(5,0,10); settextjustify(1,1); + gm=getmaxy() / 2; wait=0; + do { + for( gm=0; gm <= 15; gm ++) + {; + setcolor(15-gm); + for( gd=0; gd <= (150-gm*10); gd ++) + {; + outtextxy(320,124-gd,"Spread 2"); + outtextxy(320,125+gd,"Spread 2"); + if ((gd==5) && (gm==0)) wait=2345; + if ((gd==6) && (gm==0)) wait=0; + do { + if (keypressed()) + {; + while (keypressed()) pak=readkey(); + restorecrtmode(); + return; + } + if (wait>0) {; wait -= 1; delay(1); } + } while (!(wait==0)); + } + } + } while (!false); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + titles(); + setup(); + do { + status(); + r=upcase(readkey()); + switch (r) { + case 'A': editadx(); break; + case 'P': editpics(); break; + case 'S': saveit(); break; + case 'X':case '\33': quit(); break; + } + } while (!false); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/squish.cpp b/engines/avalanche/squish.cpp new file mode 100644 index 0000000000..4f8cad4f55 --- /dev/null +++ b/engines/avalanche/squish.cpp @@ -0,0 +1,455 @@ +#include "ptoc.h" + + + +/* This is the first version. Thanks to Pib. */ + +/*--------------------------------------------------------------------------*/ +/* */ +/* Global declarations for PIBLZW */ +/* */ +/*--------------------------------------------------------------------------*/ + +const integer maxbuff = 8192 /* Buffer size for input and output files */; +const integer maxtab = 4095 /* Table size - 1 ==> 2**10-1 ==> 12 bits */; +const integer no_prev = 0x7fff /* Special code for no previous character */; +const integer eof_char = -2 /* Marks end of file */; +const integer end_list = -1 /* Marks end of a list */; +const integer empty = -3 /* Indicates empty */; + +typedef varying_string<255> anystr/* General string type */; + + /* One node in parsing table. */ +struct string_table_entry { + boolean used /* Is this node used yet? */; + integer prevchar /* Code for preceding string */; + integer follchar /* Code for current character */; + integer next /* Next dupl in collision list */; +}; + +untyped_file input_file /* Input file */; +untyped_file output_file /* Output file */; + +integer inbufsize /* Count of chars in input buffer */; + +array<1,maxbuff,byte> input_buffer /* Input buffer area */; +array<1,maxbuff,byte> output_buffer /* Output buffer area */; + +integer input_pos /* Cur. pos. in input buffer */; +integer output_pos /* Cur. pos. in output buffer */; + + /* String table */ + +array<0,maxtab,string_table_entry> string_table; + +integer table_used /* # string table entries used */; +integer output_code /* Output compressed code */; +integer input_code /* Input compressed code */; +boolean if_compressing /* TRUE if compressing file */; +integer ierr /* Input/output error */; + +string header; varying_string<30> describe; byte method; + +void terminate() + +{ /* Terminate */ + /* Write any remaining characters */ + /* to output file. */ + if ( output_pos > 0 ) + blockwrite( output_file, output_buffer, output_pos ); + + ierr = ioresult; + /* Close input and output files */ + close( input_file ); + ierr = ioresult; + + close( output_file ); + ierr = ioresult; + + output << "done." << NL; + +} /* Terminate */ + +/*--------------------------------------------------------------------------*/ +/* Get_Hash_Code --- Gets hash code for given <w>C string */ +/*--------------------------------------------------------------------------*/ + +integer get_hash_code( integer prevc, integer follc ) + +{ + integer index; + integer index2; + + /* Get_Hash_Code */ + /* Get initial index using hashing */ + + integer get_hash_code_result; + index = ( ( prevc << 5 ) ^ follc ) & maxtab; + + /* If entry not already used, return */ + /* its index as hash code for <w>C. */ + + if ( ! string_table[index].used ) + get_hash_code_result = index; + else + /* If entry already used, search to */ + /* end of list of hash collision */ + /* entries for this hash code. */ + /* Do linear probe to find an */ + /* available slot. */ + { + + /* Skip to end of collision list ... */ + + while ( string_table[index].next != end_list ) + index = string_table[index].next; + + /* Begin linear probe down a bit from */ + /* last entry in collision list ... */ + + index2 = ( index + 101 ) & maxtab; + + /* Look for unused entry using linear */ + /* probing ... */ + + while ( string_table[index2].used ) + index2 = succ(integer, index2 ) & maxtab; + + /* Point prior end of collision list */ + /* to this new node. */ + + string_table[index].next = index2; + + /* Return hash code for <w>C */ + + get_hash_code_result = index2; + + } + + return get_hash_code_result; +} /* Get_Hash_Code */ + +/*--------------------------------------------------------------------------*/ +/* Make_Table_Entry --- Enter <w>C string in string table */ +/*--------------------------------------------------------------------------*/ + +void make_table_entry( integer prevc, integer follc ) + +{ /* Make_Table_Entry */ + /* Only enter string if there is room left */ + + if ( table_used <= maxtab ) + { + { + string_table_entry& with = string_table[ get_hash_code( prevc , follc ) ]; + + with.used = true; + with.next = end_list; + with.prevchar = prevc; + with.follchar = follc; + } + /* Increment count of items used */ + + table_used += 1; +/* + IF ( Table_Used > ( MaxTab + 1 ) ) THEN + BEGIN + WRITELN('Hash table full.'); + END; +*/ + } + +} /* Make_Table_Entry */ + +/*--------------------------------------------------------------------------*/ +/* Initialize_String_Table --- Initialize string table */ +/*--------------------------------------------------------------------------*/ + +void initialize_string_table() + +{ + integer i; + + /* Initialize_String_Table */ + + /* No entries used in table yet */ + table_used = 0; + /* Clear all table entries */ + for( i = 0; i <= maxtab; i ++) + { + string_table_entry& with = string_table[i]; + + with.prevchar = no_prev; + with.follchar = no_prev; + with.next = -1; + with.used = false; + } + /* Enter all single characters into */ + /* table */ + for( i = 0; i <= 255; i ++) + make_table_entry( no_prev , i ); + +} /* Initialize_String_Table */ + +/*--------------------------------------------------------------------------*/ +/* Initialize --- Initialize compression/decompression */ +/*--------------------------------------------------------------------------*/ + +void initialize() + +{ + anystr input_name /* Input file name */; + anystr output_name /* Output file name */; + + /* Initialize */ + + output << "Number of file to compress:"; input >> input_name >> NL; + output << "For the moment, I'm writing the compressed version to v:compr" << + input_name << ".avd." << NL; + output_name=string("d:compr")+input_name+".avd"; + input_name=string("d:place")+input_name+".avd"; + + output << "Wait... "; + + /* Open input file */ + + assign ( input_file , input_name ); + reset ( input_file , 1 ); + ierr = ioresult; + + blockread(input_file,header,146); + blockread(input_file,describe,30); + blockread(input_file,method,1); + + if (method==177) + {; + output << "It's already compressed!" << NL; + exit(177); + } + + /* Open output file */ + + assign ( output_file , output_name ); + rewrite( output_file , 1 ); + ierr = ioresult; + + method=177; + + blockwrite(output_file,header,146); + blockwrite(output_file,describe,30); + blockwrite(output_file,method,1); + + /* Point input point past end of */ + /* buffer to force initial read */ + input_pos = maxbuff + 1; + /* Nothing written out yet */ + output_pos = 0; + /* Nothing read in yet */ + inbufsize = 0; + /* No input or output codes yet */ + /* constructed */ + output_code = empty; + input_code = empty; + /* Initialize string hash table */ + initialize_string_table(); + +} /* Initialize */ + +/*--------------------------------------------------------------------------*/ +/* Lookup_String --- Look for string <w>C in string table */ +/*--------------------------------------------------------------------------*/ + +integer lookup_string( integer prevc, integer follc ) + +{ + integer index; + integer index2; + boolean found; + + /* Lookup_String */ + /* Initialize index to check from hash */ + + integer lookup_string_result; + index = ( ( prevc << 5 ) ^ follc ) & maxtab; + + /* Assume we won't find string */ + lookup_string_result = end_list; + /* Search through list of hash collision */ + /* entries for one that matches <w>C */ + do { + + found = ( string_table[index].prevchar == prevc ) && + ( string_table[index].follchar == follc ); + + if ( ! found ) + index = string_table[index].next; + + } while (!(found || ( index == end_list ))); + + /* Return index if <w>C found in table. */ + if (found) + lookup_string_result = index; + + return lookup_string_result; +} /* Lookup_String */ + +/*--------------------------------------------------------------------------*/ +/* Get_Char --- Read character from input file */ +/*--------------------------------------------------------------------------*/ + +void get_char( integer& c ) + +{ /* Get_Char */ + /* Point to next character in buffer */ + input_pos += 1; + /* If past end of block read in, then */ + /* reset input pointer and read in */ + /* next block. */ + + if ( input_pos > inbufsize ) + { + blockread( input_file, input_buffer, maxbuff, inbufsize ); + input_pos = 1; + ierr = ioresult; + } + /* If end of file hit, return EOF_Char */ + /* otherwise return next character in */ + /* input buffer. */ + if ( inbufsize == 0 ) + c = eof_char; + else + c = input_buffer[input_pos]; + +} /* Get_Char */ + +/*--------------------------------------------------------------------------*/ +/* Write_Char --- Write character to output file */ +/*--------------------------------------------------------------------------*/ + +void put_char( integer c ) + +{ /* Put_Char */ + /* If buffer full, write it out and */ + /* reset output buffer pointer. */ + + if ( output_pos >= maxbuff ) + { + blockwrite( output_file, output_buffer, maxbuff ); + output_pos = 0; + ierr = ioresult; + } + /* Place character in next slot in */ + /* output buffer. */ + + output_pos += 1; + output_buffer[output_pos] = c; + +} /* Put_Char */ + +/*--------------------------------------------------------------------------*/ +/* Put_Code --- Write hash code to output file. */ +/*--------------------------------------------------------------------------*/ + +void put_code( integer hash_code ) + +{ /* Put_Code */ + /* Output code word is empty. */ + /* Put out 1st 8 bits of compression */ + /* code and save last 4 bit for next */ + /* time through. */ + + if ( output_code == empty ) + { + put_char( ( (cardinal)hash_code >> 4 ) & 0xff ); + output_code = hash_code & 0xf; + } + else + /* Output code word not empty. */ + /* Put out last 4 bits of previous */ + /* code appended to 1st 4 bits of this */ + /* code. Then put out last 8 bits of */ + /* this code. */ + { + put_char( ( ( output_code << 4 ) & 0xff0 ) + + ( ( (cardinal)hash_code >> 8 ) & 0xf ) ); + put_char( hash_code & 0xff ); + output_code = empty; + } + +} /* Put_Code */ + +/*--------------------------------------------------------------------------*/ +/* Do_Compression --- Perform Lempel-Ziv-Welch compression */ +/*--------------------------------------------------------------------------*/ + +void do_compression() + +{ + integer c /* Current input character = C */; + integer wc /* Hash code value for <w>C */; + integer w /* Hash code value for <w> */; + + /* Do_Compression */ + /* Read first character ==> Step 2 */ + get_char( c ); + /* Initial hash code -- first character */ + /* has no previous string (<w> is null) */ + + w = lookup_string( no_prev , c ); + + /* Get next character ==> Step 3 */ + get_char( c ); + /* Loop over input characters until */ + /* end of file reached ==> Step 4. */ + while( c != eof_char ) + { + /* See if <w>C is in table. */ + + wc = lookup_string( w , c ); + + /* If <w>C is not in the table, */ + /* enter it into the table and */ + /* output <w>. Reset <w> to */ + /* be the code for C ==> Step 6 */ + + if ( wc == end_list ) + { + + make_table_entry( w , c ); + put_code( w ); + w = lookup_string( no_prev , c ); + + } + else /* If <w>C is in table, keep looking */ + /* for longer strings == Step 5 */ + + w = wc; + + /* Get next input character ==> Step 3 */ + get_char( c ); + + } + /* Make sure last code is */ + /* written out ==> Step 4. */ + put_code( w ); + +} /* Do_Compression */ + +/*--------------------------------------------------------------------------*/ +/* PibCompr --- Main program */ +/*--------------------------------------------------------------------------*/ + +int main(int argc, const char* argv[]) +{ /* PibCompr */ + /* We are doing compression */ + pio_initialize(argc, argv); + if_compressing = true; + /* Initialize compression */ + initialize(); + /* Perform compression */ + do_compression(); + /* Clean up and exit */ + terminate(); + + return EXIT_SUCCESS; +} /* PibCompr */ diff --git a/engines/avalanche/ss_blank.cpp b/engines/avalanche/ss_blank.cpp new file mode 100644 index 0000000000..670d12cf1d --- /dev/null +++ b/engines/avalanche/ss_blank.cpp @@ -0,0 +1,38 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ + +byte fv; +boolean test; + +boolean the_cows_come_home() +{ + registers rmove,rclick; +boolean the_cows_come_home_result; +; + rmove.ax=11; intr(0x33,rmove); + rclick.ax=3; intr(0x33,rclick); + the_cows_come_home_result= + (keypressed()) | /* key pressed */ + (rmove.cx>0) || /* mouse moved */ + (rmove.dx>0) || + (rclick.bx>0); /* button clicked */ +return the_cows_come_home_result; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + test=the_cows_come_home(); + textattr=0; clrscr; + do {; } while (!the_cows_come_home()); + textattr=30; clrscr; + output << "*** Blank Screen *** (c) 1992, Thomas Thurman. (An Avvy Screen Saver.)" << NL; + for( fv=1; fv <= 46; fv ++) output << '~'; output << NL; + output << "This program may be freely copied." << NL; + output << NL; + output << "Have fun!" << NL; +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/ss_clock.cpp b/engines/avalanche/ss_clock.cpp new file mode 100644 index 0000000000..1880ee5c06 --- /dev/null +++ b/engines/avalanche/ss_clock.cpp @@ -0,0 +1,84 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ +/*#include "Crt.h"*/ +#include "graph.h" +/*#include "Drivers.h"*/ + + +const integer width = 88; +const integer height = 8; /* width & height of string returned by "time" */ + +integer gd,gm; +integer xx,yy; +shortint ix,iy; +byte cp; +byte count; +array<0,1,pointtype> pages; +boolean test; + +boolean the_cows_come_home() +{ + registers rmove,rclick; +boolean the_cows_come_home_result; +; + rmove.ax=11; intr(0x33,rmove); + rclick.ax=3; intr(0x33,rclick); + the_cows_come_home_result= + (keypressed()) || /* key pressed */ + (rmove.cx>0) || /* mouse moved */ + (rmove.dx>0) || + (rclick.bx>0); /* button clicked */ +return the_cows_come_home_result; +} + +string time1() +{ + word h,m,s,s1; varying_string<2> hh,mm,ss; char ampm; +string time1_result; +; + gettime(h,m,s,s1); + if (h<12) + ampm='a'; + else {; + ampm='p'; + if (h==0) h=12; else h -= 12; /* 24-hr adjustment */ + } + str(h,2,hh); str(m,2,mm); str(s,2,ss); /* stringify them */ + time1_result=hh+'.'+mm+'.'+ss+' '+ampm+'m'; +return time1_result; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + test=the_cows_come_home(); + gm=registerbgidriver(&egavgadriverproc); + gd=3; gm=1; initgraph(gd,gm,""); + ix=3; iy=1; xx=177; yy=177; setcolor(11); cp=0; + setfillstyle(1,0); count=2; + do { + setactivepage(cp); setvisualpage(1-cp); cp=1-cp; + delay(20); if (count>0) count -= 1; + { + pointtype& with = pages[cp]; + ; + if (count==0) + bar(with.x,with.y,with.x+width,with.y+height); + with.x=xx; with.y=yy; /* update record for next time */ + } + outtextxy(xx,yy,time1()); + xx=xx+ix; yy=yy+iy; + if (xx<= 10) ix=Random(9)+1; if (xx>=629-width) ix=-Random(9)+1; + if (yy<= 10) iy=Random(9)+1; if (yy>=339-height) iy=-Random(9)+1; + } while (!the_cows_come_home()); + closegraph(); + textattr=30; clrscr; + output << "*** Bouncing Clock *** (c) 1992, Thomas Thurman. (An Avvy Screen Saver.)" << NL; + for( gd=1; gd <= 48; gd ++) output << '~'; output << NL; + output << "This program may be freely copied." << NL; + output << NL; + output << "Have fun!" << NL; +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/stars.cpp b/engines/avalanche/stars.cpp new file mode 100644 index 0000000000..309d9a4743 --- /dev/null +++ b/engines/avalanche/stars.cpp @@ -0,0 +1,562 @@ +#include "ptoc.h" + + /* Demonstration of the Bigo II system. */ +/* $I c:\sleep5\DSMI.INC*/ +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Rodent.h"*/ +/*#include "Tommys.h"*/ + +integer gd,gm; + +typedef matrix<'\0','\377',0,15,byte> fonttype; + +boolean reverse; +word spinnum; +array<0,1,fonttype> f; +file<fonttype> ff; +array<0,7,0,15,0,79,byte> strip; +byte across; +word w; byte y; +byte charnum; +byte cfont; /* current font. 0=roman, 1=italic. */ + +char* c; + +boolean nomusic; + +const integer colours = 12; /* Run Workout to see possible values of these two. */ +const integer steps = 6; /* 60,30,20,15,12,10,6,5,4,3,2,1 */ +const integer gmtop = 360 / steps; + + const integer scardcount = 13; + + const array<0,scardcount-1,integer> soundcards = + {{1,2,6,3,4,5,8,9,10,7,7,7,7}}; + +/*$L credits.obj*/ extern void credits(); + +void bigo2(string date) +{ + integer gd,gm; + byte c; + palettetype p; + untyped_file f; pointer pp; word s; + + + getpalette(p); + setvisualpage(1); setactivepage(0); + assign(f,"logo.avd"); reset(f,1); + for( gd=7; gd <= 194; gd ++) + blockread(f,mem[0xa000*(gd*80)],53); + close(f); + s=imagesize(0,7,415,194); getmem(pp,s); getimage(0,7,415,194,pp); + + cleardevice(); + for( gd=1; gd <= 64; gd ++) + { + for( gm=0; gm <= gmtop; gm ++) + { + c=(c % colours)+1; +/* putpixel(trunc(sin(gm*steps*n)*gd*6)+320, + trunc(cos(gm*steps*n)*gd*3)+175,c); */ + if (c>5) continue_; + setcolor(c); arc(320,175,gm*steps,gm*steps+1,gd*6); + } + if (keypressed()) { closegraph(); exit(0); } + } + settextstyle(0,0,1); setcolor(13); + outtextxy(550,343,"(press any key)"); + + putimage(112,0,pp,orput); freemem(pp,s); + resetmouse; setvisualpage(0); +} + +void nextchar() /* Sets up charnum & cline for the next character. */ +{ + + c += 1; +} + +void getchar() +{ + do { + nextchar(); + + switch (*c) { + case '@': { cfont=1; nextchar(); } break; + case '^': { cfont=0; nextchar(); } break; + case '%': if (nomusic) + { + closegraph(); exit(0); /* End of text and no music => stop. */ + } + else c=addr(credits()); + break; /* End of test, but still playing => again. */ + } + + } while (!((*c!='\15') && (*c!='\12'))); + + for( w=0; w <= 7; w ++) + for( y=0; y <= 15; y ++) + move(strip[w][y][1],strip[w][y][0],79); + + for( w=0; w <= 7; w ++) + for( y=0; y <= 15; y ++) + strip[w][y][79]=(byte)((strip[7][y][78] << (w+1)))+ + ((cardinal)f[cfont][*c][y] >> (7-w)); + + across=0; +} + +void scrolltext() +{ + byte c,w,y; + + across += 1; + if (across==8) getchar(); + + for( y=0; y <= 15; y ++) + for( w=0; w <= 1; w ++) + move(strip[across][y][0],mem[0xa000*24000+(y*2+w)*80],80); +} + +void do_stuff() +{ + switch (spinnum) { + case 50 ... 110: { + setfillstyle(1,14); + bar(0,315+(spinnum-50) / 3,640,315+(spinnum-50) / 3); + bar(0,316-(spinnum-50) / 3,640,316-(spinnum-50) / 3); + if (spinnum>56) + { + setfillstyle(1,13); + bar(0,315+(spinnum-56) / 3,640,315+(spinnum-56) / 3); + bar(0,316-(spinnum-56) / 3,640,316-(spinnum-56) / 3); + } + } + break; + case 150 ... 198: { + setfillstyle(1,0); + bar(0,315+(spinnum-150) / 3,640,315+(spinnum-150) / 3); + bar(0,316-(spinnum-150) / 3,640,316-(spinnum-150) / 3); + } + break; + case 200: scrolltext(); break; + } +} + +void setcol(byte which,byte what) +/*var dummy:byte;*/ +{; +/* setpalette(which,what); + asm +(* mov dx,$3DA; + in ax,dx; + + or ah,ah; + + mov dx,$3C0; + mov al,which; + out dx,al; + + mov dx,$3C0; + mov al,what; + out dx,al; + end; +(* dummy:=port[$3DA]; + port[$3C0]:=which; port[$3C0]:=what;*/ +} + +void bigo2go() +{ + palettetype p; byte c; boolean lmo; + boolean altnow,altbefore; + + for( gd=0; gd <= 13; gd ++) p.colors[gd]=0; + + setcol(13,24); /* murk */ setcol(14,38); /* gold */ + setcol(15,egawhite); /* white- of course */ + p.colors[13]=24; p.colors[14]=38; p.colors[15]=egawhite; + + /***/ + + p.colors[5]=egawhite; + p.colors[4]=egalightcyan; + p.colors[3]=egacyan; + p.colors[2]=egalightblue; + p.colors[1]=egablue; + + /***/ + + c=1; p.size=16; lmo=false; + setallpalette(p); + + do { +/* if reverse then + begin + dec(c); if c=0 then c:=colours; + end else + begin + inc(c); if c>colours then c:=1; + end; + for gm:=1 to colours do + case p.colors[gm] of + egaWhite: begin p.colors[gm]:=egaLightcyan; setcol(gm,egaLightCyan); end; + egaLightcyan: begin p.colors[gm]:=egaCyan; setcol(gm,egaCyan); end; + egaCyan: begin p.colors[gm]:=egaLightblue; setcol(gm,egaLightblue); end; + egaLightblue: begin p.colors[gm]:=egaBlue; setcol(gm,egaBlue); end; + egaBlue: begin p.colors[gm]:=0; setcol(gm,0); end; + end; + p.colors[c]:=egaWhite; setcol(c,egaWhite); + + AltBefore:=AltNow; AltNow:=testkey(sAlt);*/ + + if (anymousekeypressed) lmo=true; + if (keypressed()) lmo=true; + if ((! nomusic) && (ampgetmodulestatus != md_playing)) lmo=true; + + /* if (AltNow=True) and (AltBefore=False) then reverse:=not reverse;*/ + + do_stuff(); + if (spinnum<200) spinnum += 1; + } while (!lmo); +} + +void parse_cline() +{ + integer e; + + if (paramstr(1)!="jsb") + { + output << "Not a standalone program." << NL; exit(255); + } +} + +integer getsoundhardware(psoundcard scard) +{ + integer sc,i,autosel,select; + char ch; + integer e; + + + +integer getsoundhardware_result; +Lagain: + sc=detectgus(scard); + if (sc!=0) sc=detectpas(scard); + if (sc!=0) sc=detectaria(scard); + if (sc!=0) sc=detectsb(scard); + + /* if no sound card found, zero scard */ + if (sc!=0) fillchar(scard,sizeof(tsoundcard),0); + + autosel=-1; +/* if sc=0 then + for i:=0 to scardcount-1 do + if scard^.ID=soundcards[i].ID then begin + { Set auto selection mark } + autosel:=i+1; + break; + end;*/ + + /* Print the list of sound cards */ + + val(paramstr(13),select,e); + + /* Default entry? */ + if (select==0) select=autosel; + if (select!=autosel) { + /* clear all assumptions */ + sc=-1; + fillchar(scard,sizeof(tsoundcard),0); + scard->id=soundcards[select-1]; /* set correct ID */ + } + + /* Query I/O address */ + if (scard->id==id_dac) scard->ioport=0x378; + + /* Read user input */ + val(paramstr(15),i,e); + + if (i!=0) scard->ioport=i; + if (sc!=1) /* Not autodetected */ + switch (scard->id) { + case id_sb16: + case id_pas16: + case id_wss: + case id_aria: + case id_gus : scard->samplesize=2; + break; /* 16-bit card */ + case id_sbpro: + case id_pas: + case id_pasplus: scard->stereo=true; + break; /* enable stereo */ + default: { + scard->samplesize=1; + scard->stereo=false; + } + } + + if (scard->id!=id_dac) { + val(paramstr(17),i,e); + + if (i!=0) scard->dmairq=i; + + val(paramstr(16),i,e); + + if (i!=0) scard->dmachannel=i; + } else { + /* Select correct DAC */ + scard->maxrate=44100; + if (select==11) { + scard->stereo=true; + scard->dmachannel=1; /* Special 'mark' */ + scard->maxrate=60000; + } else + if (select==12) { + scard->stereo=true; + scard->dmachannel=2; + scard->maxrate=60000; + if (scard->ioport==0) scard->ioport=0x378; + } else + if (select==13) { + scard->dmachannel=0; + scard->ioport=0x42; /* Special 'mark' */ + scard->maxrate=44100; + } + } + +/* writeln('Your selection: ',select,' at ',scard^.ioPort, + ' using IRQ ',scard^.dmaIRQ,' and DMA channel ',scard^.dmaChannel); + readln;*/ + + getsoundhardware_result=0; +return getsoundhardware_result; +} + +tsoundcard scard; +tmcpstruct mcpstrc; +tdds dds; +pmodule module; +tsdi_init sdi; +integer e, +bufsize; +char ch; +boolean v86, +vdsok; +longint a,rate, +tempseg; +string answer; +pointer temp; +word flags; +word curch; +byte modulevolume; +array<0,4,tsampleinfo> sample; +array<0,31,word> voltable; + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + parse_cline(); + + nomusic=paramstr(13)=='0'; + + if (! nomusic) + { + /* Read sound card information */ + if (getsoundhardware(&scard)==-1) exit(1); + + + /* Initialize Timer Service */ + tsinit; + atexit(&tsclose); + if (scard.id==id_gus) { + /* Initialize GUS player */ + #ifndef DPMI + scard.extrafield[2]=1; /* GUS DMA transfer does not work in V86 */ + #endif + gusinit(&scard); + atexit(&gusclose); + + /* Initialize GUS heap manager */ + gushminit; + + /* Init CDI */ + cdiinit; + + /* Register GUS into CDI */ + cdiregister(&cdi_gus,0,31); + + /* Add GUS event player engine into Timer Service */ + tsaddroutine(&gusinterrupt,gus_timer); + } else { + /* Initialize Virtual DMA Specification */ + #ifndef DPMI + vdsok=vdsinit==0; + #else + vdsok=false; + #endif + + fillchar(mcpstrc,sizeof(tmcpstruct),0); + + /* Query for sampling rate */ + val(paramstr(14),a,e); + if (a>4000) rate=a; else rate=21000; + + /* Query for quality */ + mcpstrc.options=mcp_quality; + + switch (scard.id) { + case id_sb : { + sdi=sdi_sb; + scard.maxrate=22000; + } + break; + case id_sbpro : { + sdi=sdi_sbpro; + scard.maxrate=22000; + } + break; + case id_pas: + case id_pasplus: + case id_pas16 : { + sdi=sdi_pas; + scard.maxrate=44100; + } + break; + case id_sb16 : { + sdi=sdi_sb16; + scard.maxrate=44100; + } + break; + case id_aria : { + sdi=sdi_aria; + scard.maxrate=44100; + } + break; + case id_wss : { + sdi=sdi_wss; + scard.maxrate=48000; + } + break; + #ifndef DPMI + case id_dac : sdi=sdi_dac; break; /* Only available in real mode */ + #endif + } + + mcpinitsounddevice(sdi,&scard); + a=mcp_tablesize; + mcpstrc.reqsize=0; + + /* Calculate mixing buffer size */ + bufsize=(longint)(2800*(integer)(scard.samplesize) << (byte)(scard.stereo))* + (longint)(rate) / (longint)(22000); + mcpstrc.reqsize=0; + if ((mcpstrc.options & mcp_quality)>0) + if (scard.samplesize==1) a += mcp_qualitysize; else + a=mcp_tablesize16+mcp_qualitysize16; + if ((longint)(bufsize)+(longint)(a)>65500) bufsize=longint(65500)-a; + + #ifdef DPMI + dpmiversion((byte)(e),(byte)(e),(byte)(e),flags); + v86=(flags & 2)==0; + #endif + + /* Allocate volume table + mixing buffer */ + #ifdef DPMI + + /* In the V86 mode, the buffer must be allocated below 1M */ + if (v86) { + tempseg=0; + dpmiallocdos((a+longint(bufsize)) / longint(16)+longint(1),flags,(word)(tempseg)); + } else { + #endif + getmem(temp,a+longint(bufsize)); + if (temp==nil) exit(2); + #ifdef DPMI + tempseg=seg(temp); + } + #else + tempseg=seg(temp)+ofs(temp) / 16+1; + #endif + mcpstrc.bufferseg=tempseg; + mcpstrc.bufferphysical=-1; + + if (vdsok && (scard.id!=id_dac)) { + dds.size=bufsize; + dds.segment=tempseg; + dds.offset=0; + + /* Lock DMA buffer if VDS present */ + if (vdslockdma(&dds)==0) mcpstrc.bufferphysical=dds.address; + } + if (mcpstrc.bufferphysical==-1) + #ifdef DPMI + mcpstrc.bufferphysical=dpmigetlinearaddr(tempseg); + #else + mcpstrc.bufferphysical=(longint)(tempseg) << 4; + #endif + + mcpstrc.buffersize=bufsize; + mcpstrc.samplingrate=rate; + /* Initialize Multi Channel Player */ + if (mcpinit(&mcpstrc)!=0) exit(3); + atexit(&mcpclose); + + /* Initialize Channel Distributor */ + cdiinit; + + /* Register MCP into CDI*/ + cdiregister(&cdi_mcp,0,31); + } + + /* Try to initialize AMP */ + if (ampinit(0)!=0) exit(3); + atexit(&close); + + /* Hook AMP player routine into Timer Service */ + tsaddroutine(&interrupt,amp_timer); + + #ifndef DPMI + /* If using DAC, then adjust DAC timer */ + if (scard.id==id_dac) setdactimer(tsgettimerrate); + #endif + + if (scard.id!=id_gus) mcpstartvoice; else gusstartvoice; + + /* Load an example AMF */ + module=amploadmod("avalot2.mod",0); + if (module==nil) exit(4); + + /* Is it MCP, Quality mode and 16-bit card? */ + if ((scard.id!=id_gus) && ((mcpstrc.options & mcp_quality)>0) + && (scard.samplesize==2)) { + /* Open module+2 channels with amplified volumetable (4.7 gain) */ + for( a=1; a <= 32; a ++) voltable[a-longint(1)]=a*longint(150) / longint(32); + cdisetupchannels(0,module->channelcount+2,&voltable); + } else { + /* Open module+2 channels with regular volumetable */ + cdisetupchannels(0,module->channelcount+2,nil); + } + + curch=module->channelcount; + modulevolume=64; + + /***/ ampplaymodule(module,0); + } + + gd=3; gm=1; initgraph(gd,gm,""); + assign(ff,"avalot.fnt"); reset(ff); ff >> f[0]; close(ff); + assign(ff,"avitalic.fnt"); reset(ff); ff >> f[1]; close(ff); + + c=addr(credits()); c -= 1; + + fillchar(strip,sizeof(strip),'\0'); + reverse=false; spinnum=0; across=7; charnum=1; cfont=0; + bigo2("1189"); /* 1189? 79? 2345? 1967? */ + bigo2go(); + + if (! nomusic) ampstopmodule; + closegraph(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/status.cpp b/engines/avalanche/status.cpp new file mode 100644 index 0000000000..1e046fcc0c --- /dev/null +++ b/engines/avalanche/status.cpp @@ -0,0 +1,34 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer gd,gm; + +void data(integer y, string a,string b) +{; + setcolor(1); settextjustify(2,0); outtextxy(315,y,a+':'); + setcolor(0); settextjustify(0,0); outtextxy(325,y,b); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\turbo"); + setcolor(1); setfillstyle(1,7); bar(0,0,640,200); + settextstyle(1,0,0); setusercharsize(10,4,8,6); settextjustify(1,1); + outtextxy(317,20,"Status Screen"); + settextstyle(0,0,1); + data( 60,"Current game","NoName.ASG"); + data( 70,"Saved?","Yes"); + data( 90,"Current town","Thurringham"); + data(100,"Score","177"); + data(110,"Cash","1/-"); + data(130,"Game","Lord Avalot D'Argent"); + data(140,"Version","1.00 (beta)"); + data(150,"Registered to","Unregistered!"); + data(160,"Number","nix"); + data(177,"Bios/keyboard","AT (enhanced)"); /* or XT (bog standard) */ + data(187,"Display","VGA"); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/sticks.cpp b/engines/avalanche/sticks.cpp new file mode 100644 index 0000000000..1fc11cd313 --- /dev/null +++ b/engines/avalanche/sticks.cpp @@ -0,0 +1,90 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + STICKS The joystick handler. */ + +#define __sticks_implementation__ + + +#include "sticks.h" + + +enum lmc {l,m,r, last_lmc}; /* Left, middle & right */ + +file<joysetup> jf; + +byte joyway(); + + +static lmc getlmc(word n,word max,word min) +{lmc getlmc_result; +; + if (n<min) getlmc_result=l; else + if (n>max) getlmc_result=r; else + getlmc_result=m; +return getlmc_result; +} + +byte joyway() +{ + word x,y; + lmc xx,yy; +byte joyway_result; +; + if (~ dna.user_moves_avvy) return joyway_result; + if (use_joy_a) readjoya(x,y); else readjoyb(x,y); + + {; + xx=getlmc(x,cxmax,cxmin); + yy=getlmc(y,cymax,cymin); + } + + switch (xx) { + case l: switch (yy) { + case l: joyway_result=ul; break; + case m: joyway_result=left; break; + case r: joyway_result=dl; break; + } + break; + case m: switch (yy) { + case l: joyway_result=up; break; + case m: joyway_result=stopped; break; + case r: joyway_result=down; break; + } + break; + case r: switch (yy) { + case l: joyway_result=ur; break; + case m: joyway_result=right; break; + case r: joyway_result=dr; break; + } + break; + } +return joyway_result; +} + +void joykeys() + /* The 2 joystick keys may be reprogrammed. This parses them. */ +{ + byte v; +; + if (use_joy_a) + { + v=(byte)(buttona1); v += (byte)(buttona2)*2; + } else + { + v=(byte)(buttonb1); v += (byte)(buttonb2)*2; + } + + switch (v) { + case 0: return; break; /* No buttons pressed. */ + case 1: opendoor; break; /* Button 1 pressed: open door. */ +/* 2: blip; { Button 2 pressed: nothing (joylock?). }*/ + case 2:case 3: lookaround; break; /* Both buttons pressed: look around. */ + } +} + + /* No init code. */
\ No newline at end of file diff --git a/engines/avalanche/sticks.h b/engines/avalanche/sticks.h new file mode 100644 index 0000000000..5a54cd44bc --- /dev/null +++ b/engines/avalanche/sticks.h @@ -0,0 +1,13 @@ +#ifndef __sticks_h__ +#define __sticks_h__ + + +/*#include "Joystick.h"*/ +/*#include "Acci.h"*/ +/*#include "Gyro.h"*/ + /* for solidarity */ + +byte joyway(); +void joykeys(); + +#endif diff --git a/engines/avalanche/sunrise.cpp b/engines/avalanche/sunrise.cpp new file mode 100644 index 0000000000..1ed894a46e --- /dev/null +++ b/engines/avalanche/sunrise.cpp @@ -0,0 +1,57 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +integer gd,gm; +longint tskellern /*absolute $0:244*/; /* Over int $61 */ + +void hold() +{; + do {; } while (!(tskellern>=1)); + tskellern=0; +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=1; initgraph(gd,gm,"c:\\bp\\bgi"); + + setvisualpage(1); + setfillstyle(1,1); + for( gd=1; gd <= 640; gd ++) + bar(gd,177+trunc(20*sin((real)(gd)/39)),gd,350); + setfillstyle(1,3); setcolor(3); + fillellipse(320,277,60,50); + settextjustify(1,1); settextstyle(0,0,2); setcolor(9); + outtextxy(320,50,"The sun rises over Hertfordshire..."); + settextjustify(2,0); settextstyle(0,0,1); setcolor(0); + outtextxy(635,350,"Press any key..."); + + setpalette(0,egablue); + setpalette(1,egagreen); + setpalette(2,egayellow); + setpalette(3,egagreen); + setpalette(9,egalightblue); + setpalette(11,egalightblue); + setvisualpage(0); + + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << 1; port[0x3cf]=1; + + for( gm=227; gm >= 1; gm --) /* <<< try running this loop the other way round! */ + {; + move(mem[0xa000*gm*80+80],mem[0xa000*gm*80],8042); + hold(); + if (keypressed()) return 0; + } + + for( gm=101; gm >= 1; gm --) + {; + move(mem[0xa000*80],mem[0xa000*0],gm*80); + hold(); + if (keypressed()) return 0; + } +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/tempo.cpp b/engines/avalanche/tempo.cpp new file mode 100644 index 0000000000..634f3214b6 --- /dev/null +++ b/engines/avalanche/tempo.cpp @@ -0,0 +1,77 @@ +#include "ptoc.h" + + +#include "graph.h" + + +enum flavourtype {ch_ega,ch_bgi,ch_natural,ch_two,ch_one, last_flavourtype}; + +struct chunkblocktype { + union { + struct {flavourtype flavour; + integer x,y; + integer xl,yl; + longint size;} s_true; + array<1,14,byte> all; + }; +}; + + +byte screennum; +untyped_file f; + +string strf(longint x) +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +void load() +{ + byte a /*absolute $A000:1200*/; byte bit; +; + reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a,12080); + } + close(f); + bit=getpixel(0,0); +} + +void init() +{ + integer gd,gm; +; + output << "*** Tempo file creater ***" << NL; + output << "Enter place*.avd number:"; + input >> screennum >> NL; + gd=3; gm=0; + initgraph(gd,gm,"c:\\bp\\bgi"); + assign(f,string("place")+strf(screennum)+".avd"); + load(); + setactivepage(1); + setcolor(10); + outtextxy(0,150,"CHUNK FILE: please don't change these codes! ->"); + setactivepage(0); +} + +void choose() +{ + integer x1,y1,xl,yl; +; + +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + init(); + choose(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/test.cpp b/engines/avalanche/test.cpp new file mode 100644 index 0000000000..6d480843f2 --- /dev/null +++ b/engines/avalanche/test.cpp @@ -0,0 +1,19 @@ +#include "ptoc.h" + + +/*$M 2048,0,0*/ +/*#include "Dos.h"*/ + +const array<1,22,char> signature = string("*AVALOT* v1.00 ±tt± ")+'\3'+'\0'; +pointer saveint1f; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + getintvec(0x1f,saveint1f); + setintvec(0x1f,&signature); + swapvectors; + exec("c:\\command.com",""); + swapvectors; + setintvec(0x1f,saveint1f); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/test2.cpp b/engines/avalanche/test2.cpp new file mode 100644 index 0000000000..a4f678d650 --- /dev/null +++ b/engines/avalanche/test2.cpp @@ -0,0 +1,17 @@ +#include "ptoc.h" + + +/*#include "Dos.h"*/ + +const array<1,22,char> signature = string("*AVALOT* v1.00 ±tt± ")+'\3'+'\0'; +pointer getint1f; +array<1,22,char> x; +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + getintvec(0x1f,getint1f); + move(getint1f,x,22); + if (x==signature) + output << "Signature found." << NL; else output << "Signature NOT found!" << NL; +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/testblit.cpp b/engines/avalanche/testblit.cpp new file mode 100644 index 0000000000..bc00393150 --- /dev/null +++ b/engines/avalanche/testblit.cpp @@ -0,0 +1,49 @@ +#include "ptoc.h" + + +#include "graph.h" + + +const integer ttp = 81920; +const integer borland = xorput; +const integer mb1 = 2; /* 2 */ +const integer mb2 = 4; /* 4 */ + +integer gd,gm; +pointer p; +word s; + +void mblit() +{ + byte bit; longint st; +; + st=ttp; + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=mb1; + portw[0x3ce]=copyput*256+3; + portw[0x3ce]=0x205; + port[0x3ce]=0x8; + port[0x3c5]=1 << bit; + port[0x3cf]=bit; + move(mem[longint(0xa000)*st],mem[0xa000*0],7200); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,""); + settextstyle(1,0,7); + for( gd=0; gd <= 1; gd ++) + {; + setactivepage(gd); setcolor(6*gd+6); + outtextxy(0,0,chr(65+gd)); + } + s=imagesize(0,0,90,90); setactivepage(0); getmem(p,s); + getimage(0,0,90,90,p); putimage(100,100,p,0); + setactivepage(1); getimage(0,0,90,90,p); setactivepage(0); + putimage(100,100,p,borland); + mblit(); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/testcard.cpp b/engines/avalanche/testcard.cpp new file mode 100644 index 0000000000..064b0a10b5 --- /dev/null +++ b/engines/avalanche/testcard.cpp @@ -0,0 +1,56 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Dos.h"*/ + +integer gd,gm; +string filename; + +untyped_file f; byte bit; +byte a /*absolute $A000:800*/; +searchrec r; + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + + for( gd=0; gd <= 14; gd ++) + for( gm=0; gm <= 11; gm ++) + {; + setfillstyle(gm,gd+1); + bar(gd*43,gm*12+10,42+gd*43,gm*12+21); + } + + output << NL; output << NL; output << NL; output << NL; + + output << "Thorsoft testcard." << NL; + output << NL; + output << "Room number? "; input >> filename >> NL; + + findfirst(string("place")+filename+".avd",anyfile,r); + if (doserror==0) + {; + output << "*** ALREADY EXISTS! CANCELLED! ***" << NL; + input >> NL; + exit(0); + } + + output << NL; + output << "*** Until this room is drawn, this screen is standing in for it. ***" << NL; + output << NL; + output << "Any other comments? "; + input >> NL; + + assign(f,string("place")+filename+".avd"); + rewrite(f,1); + blockwrite(f,gd,177); /* just anything */ + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,a,12080); + } + close(f); +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/testenh.cpp b/engines/avalanche/testenh.cpp new file mode 100644 index 0000000000..8077ca33d8 --- /dev/null +++ b/engines/avalanche/testenh.cpp @@ -0,0 +1,18 @@ +#include "ptoc.h" + + +/*#include "Enhanced.h"*/ + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + do { + readkeye; + switch (inchar) { + case '\0': output << string('[')+extd+']'; break; + case '\340': output << string('<')+extd+'>'; break; + default: output << inchar; + } + } while (!(inchar=='\33')); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/timeout.cpp b/engines/avalanche/timeout.cpp new file mode 100644 index 0000000000..26ab44989b --- /dev/null +++ b/engines/avalanche/timeout.cpp @@ -0,0 +1,594 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + TIMEOUT The scheduling unit. */ + +#define __timeout_implementation__ + + +#include "timeout.h" + + +#include "visa.h" +#include "lucerna.h" +#include "trip5.h" +#include "scrolls.h" +#include "sequence.h" +#include "pingo.h" +#include "Acci.h" +#include "enid.h" + + +byte fv; + +void set_up_timer(longint howlong, byte whither,byte why) +{ + fv=1; + while ((fv<8) && (times[fv].time_left!=0)) fv += 1; + if (fv==8) return; /* Oh dear... */ + + { + timetype& with = times[fv]; /* Everything's OK here! */ + + with.time_left=howlong; + with.then_where=whither; + with.what_for=why; + } +} + +void one_tick() +{ + + if (ddmnow) return; + + for( fv=1; fv <= 7; fv ++) + { timetype& with = times[fv]; + if (with.time_left>0) + { + with.time_left -= 1; + + if (with.time_left==0) + switch (with.then_where) { + case procopen_drawbridge : open_drawbridge(); break; + case procavaricius_talks : avaricius_talks(); break; + case procurinate : urinate(); break; + case proctoilet2 : toilet2(); break; + case procbang: bang(); break; + case procbang2: bang2(); break; + case procstairs: stairs(); break; + case proccardiffsurvey: cardiff_survey(); break; + case proccardiff_return: cardiff_return(); break; + case proc_cwytalot_in_herts: cwytalot_in_herts(); break; + case procget_tied_up: get_tied_up(); break; + case procget_tied_up2: get_tied_up2(); break; + case prochang_around: hang_around(); break; + case prochang_around2: hang_around2(); break; + case procafter_the_shootemup: after_the_shootemup(); break; + case procjacques_wakes_up: jacques_wakes_up(); break; + case procnaughty_duke: naughty_duke(); break; + case procnaughty_duke2: naughty_duke2(); break; + case procnaughty_duke3: naughty_duke3(); break; + case procjump: jump(); break; + case procsequence: call_sequencer(); break; + case proccrapulus_splud_out: crapulus_says_splud_out(); break; + case procdawn_delay: dawn(); break; + case procbuydrinks: buydrinks(); break; + case procbuywine: buywine(); break; + case proccallsguards: callsguards(); break; + case procgreetsmonk: greetsmonk(); break; + case procfall_down_oubliette: fall_down_oubliette(); break; + case procmeet_avaroid: meet_avaroid(); break; + case procrise_up_oubliette: rise_up_oubliette(); break; + case procrobin_hood_and_geida: robin_hood_and_geida(); break; + case procrobin_hood_and_geida_talk: robin_hood_and_geida_talk(); break; + case procavalot_returns: avalot_returns(); break; + case procavvy_sit_down: avvy_sit_down(); break; + case procghost_room_phew: ghost_room_phew(); break; + case procarkata_shouts: arkata_shouts(); break; + case procwinning: winning(); break; + case procavalot_falls: avalot_falls(); break; + case procspludwick_goes_to_cauldron: spludwick_goes_to_cauldron(); break; + case procspludwick_leaves_cauldron: spludwick_leaves_cauldron(); break; + case procgive_lute_to_geida: give_lute_to_geida(); break; + } + }} + roomtime += 1; /* Cycles since you've been in this room. */ + dna.total_time += 1; /* Total amount of time for this game. */ +} + +void lose_timer(byte which) +{ + byte fv; + + for( fv=1; fv <= 7; fv ++) + { timetype& with = times[fv]; + if (with.what_for==which) + with.time_left=0;} /* Cancel this one! */ +} + +/*function timer_is_on(which:byte):boolean; +var fv:byte; +begin + for fv:=1 to 7 do + with times[fv] do + if (what_for=which) and (time_left>0) then + begin + timer_is_on:=true; + exit; + end; + timer_is_on:=false; +end;*/ + +/* Timeout procedures: */ + +void open_drawbridge() +{ + { + dnatype& with = dna; + + with.drawbridge_open += 1; + show_one(with.drawbridge_open-1); + + if (with.drawbridge_open==4) + magics[2].op=nix; /* You may enter the drawbridge. */ + else set_up_timer(7,procopen_drawbridge,reason_drawbridgefalls); + } +} + +/* --- */ + +void avaricius_talks() +{ + { + dnatype& with = dna; + + dixi('q',with.avaricius_talk); + with.avaricius_talk += 1; + + if (with.avaricius_talk<17) + set_up_timer(177,procavaricius_talks,reason_avariciustalks); + else points(3); + + } +} + +void urinate() +{ + tr[1].turn(up); + stopwalking(); + showrw(); + set_up_timer(14,proctoilet2,reason_gototoilet); +} + +void toilet2() +{ + display("That's better!"); +} + +void bang() +{ + display("\6< BANG! >"); + set_up_timer(30,procbang2,reason_explosion); +} + +void bang2() +{ + display("Hmm... sounds like Spludwick's up to something..."); +} + +void stairs() +{ + blip(); + tr[1].walkto(4); + show_one(2); + dna.brummie_stairs=2; + magics[11].op=special; + magics[11].data=2; /* Reached the bottom of the stairs. */ + magics[4].op=nix; /* Stop them hitting the sides (or the game will hang.) */ +} + +void cardiff_survey() +{ + { + dnatype& with = dna; + + switch (with.cardiff_things) { + case 0: { + with.cardiff_things += 1; + dixi('q',27); + } + break; + } + dixi('z',with.cardiff_things); + } + interrogation=dna.cardiff_things; + set_up_timer(182,proccardiffsurvey,reason_cardiffsurvey); +} + +void cardiff_return() +{ + dixi('q',28); + cardiff_survey(); /* add end of question. */ +} + +void cwytalot_in_herts() +{ + dixi('q',29); +} + +void get_tied_up() +{ + dixi('q',34); /* ...Trouble! */ + dna.user_moves_avvy=false; + dna.been_tied_up=true; + stopwalking(); + tr[2].stopwalk(); tr[2].stophoming(); + tr[2].call_eachstep=true; + tr[2].eachstep=procgrab_avvy; + set_up_timer(70,procget_tied_up2,reason_getting_tied_up); +} + +void get_tied_up2() +{ + tr[1].walkto(4); + tr[2].walkto(5); + magics[4].op=nix; /* No effect when you touch the boundaries. */ + dna.friar_will_tie_you_up=true; +} + +void hang_around() +{ + tr[2].check_me=false; + tr[1].init(7,true); /* Robin Hood */ + whereis[probinhood]=r__robins; + apped(1,2); + dixi('q',39); + tr[1].walkto(7); + set_up_timer(55,prochang_around2,reason_hanging_around); +} + +void hang_around2() +{ + dixi('q',40); + tr[2].vanishifstill=false; + tr[2].walkto(4); + whereis[pfriartuck]=r__robins; + dixi('q',41); + tr[1].done(); tr[2].done(); /* Get rid of Robin Hood and Friar Tuck. */ + + set_up_timer(1,procafter_the_shootemup,reason_hanging_around); /* Immediately + call the following proc (when you have a chance). */ + + dna.tied_up=false; + + back_to_bootstrap(1); /* Call the shoot-'em-up. */ +} + +void after_the_shootemup() +{ + byte shootscore,gain; + + tr[1].init(0,true); /* Avalot. */ + apped(1,2); dna.user_moves_avvy=true; + dna.obj[crossbow]=true; objectlist(); + + shootscore=mem[storage_seg*storage_ofs]; + gain=(shootscore+5) / 10; /* Rounding up. */ + + display(string("\6Your score was ")+strf(shootscore)+'.'+"\r\rYou gain ("+ + strf(shootscore)+" ö 10) = "+strf(gain)+" points."); + + if (gain>20) + { + display("But we won't let you have more than 20 points!"); + points(20); + } else + points(gain); + + dixi('q',70); +} + +void jacques_wakes_up() +{ + dna.jacques_awake += 1; + + switch (dna.jacques_awake) { /* Additional pictures. */ + case 1 : { + show_one(1); /* Eyes open. */ + dixi('Q',45); + } + break; + case 2 : { /* Going through the door. */ + show_one(2); /* Not on the floor. */ + show_one(3); /* But going through the door. */ + magics[6].op=nix; /* You can't wake him up now. */ + } + break; + case 3 : { /* Gone through the door. */ + show_one(2); /* Not on the floor, either. */ + show_one(4); /* He's gone... so the door's open. */ + whereis[pjacques]=0; /* Gone! */ + } + break; + } + + + if (dna.jacques_awake==5) + { + dna.ringing_bells=true; + dna.ayles_is_awake=true; + points(2); + } + + switch (dna.jacques_awake) { + case RANGE_3(1,3): set_up_timer(12,procjacques_wakes_up,reason_jacques_waking_up); + break; + case 4: set_up_timer(24,procjacques_wakes_up,reason_jacques_waking_up); break; + } + +} + +void naughty_duke() + /* This is when the Duke comes in and takes your money. */ +{ + tr[2].init(9,false); /* Here comes the Duke. */ + apped(2,1); /* He starts at the door... */ + tr[2].walkto(3); /* He walks over to you. */ + + /* Let's get the door opening. */ + + show_one(1); first_show(2); start_to_close(); + + set_up_timer(50,procnaughty_duke2,reason_naughty_duke); +} + +void naughty_duke2() +{ + dixi('q',48); /* Ha ha, it worked again! */ + tr[2].walkto(1); /* Walk to the door. */ + tr[2].vanishifstill=true; /* Then go away! */ + set_up_timer(32,procnaughty_duke3,reason_naughty_duke); +} + +void naughty_duke3() +{ + show_one(1); first_show(2); start_to_close(); +} + +void jump() +{ + { + dnatype& with = dna; + + with.jumpstatus += 1; + + { triptype& with1 = tr[1]; + switch (with.jumpstatus) { + case 1:case 2:case 3:case 5:case 7:case 9: with1.y -= 1; break; + case 12:case 13:case 14:case 16:case 18:case 19: with1.y += 1; break; + }} + + if (with.jumpstatus==20) + { /* End of jump. */ + dna.user_moves_avvy=true; + dna.jumpstatus=0; + } else + { /* Still jumping. */ + set_up_timer(1,procjump,reason_jumping); + } + + if ((with.jumpstatus==10) /* You're at the highest point of your jump. */ + && (dna.room==r__insidecardiffcastle) + && (dna.arrow_in_the_door==true) + && (infield(3))) /* beside the wall*/ + { /* Grab the arrow! */ + if (dna.carrying>=maxobjs) + display("You fail to grab it, because your hands are full."); + else + { + show_one(2); + dna.arrow_in_the_door=false; /* You've got it. */ + dna.obj[bolt]=true; + objectlist(); + dixi('q',50); + points(3); + } + } + } +} + +void crapulus_says_splud_out() +{ + dixi('q',56); + dna.crapulus_will_tell=false; +} + +void buydrinks() +{ + show_one(11); /* Malagauche gets up again. */ + dna.malagauche=0; + + dixi('D',ord(dna.drinking)); /* Display message about it. */ + wobble(); /* Do the special effects. */ + dixi('D',1); /* That'll be thruppence. */ + if (pennycheck(3)) /* Pay 3d. */ + dixi('D',3); /* Tell 'em you paid up. */ + have_a_drink(); +} + +void buywine() +{ + show_one(11); /* Malagauche gets up again. */ + dna.malagauche=0; + + dixi('D',50); /* You buy the wine. */ + dixi('D',1); /* It'll be thruppence. */ + if (pennycheck(3)) + { + dixi('D',4); /* You paid up. */ + dna.obj[wine]=true; + objectlist(); + dna.winestate=1; /* OK Wine */ + } +} + +void callsguards() +{ + dixi('Q',58); /* GUARDS!!! */ + gameover(); +} + +void greetsmonk() +{ + dixi('Q',59); dna.entered_lusties_room_as_monk=true; +} + +void fall_down_oubliette() +{ + magics[9].op=nix; + tr[1].iy += 1; /* increments dx/dy! */ + tr[1].y += tr[1].iy; /* Dowwwn we go... */ + set_up_timer(3,procfall_down_oubliette,reason_falling_down_oubliette); +} + +void meet_avaroid() +{ + if (dna.met_avaroid) + { + display("You can't expect to be \6that\22 lucky twice in a row!"); + gameover(); + } else + { + dixi('Q',60); dna.met_avaroid=true; + set_up_timer(1,procrise_up_oubliette,reason_rising_up_oubliette); + { + triptype& with = tr[1]; with.face=left; with.x=151; with.ix=-3; with.iy=-5; } + background(2); + } +} + +void rise_up_oubliette() +{ + { + triptype& with = tr[1]; + + with.visible=true; + with.iy += 1; /* decrements dx/dy! */ + with.y -= with.iy; /* Uuuupppp we go... */ + if (with.iy>0) + set_up_timer(3,procrise_up_oubliette,reason_rising_up_oubliette); + else + dna.user_moves_avvy=true; + } +} + +void robin_hood_and_geida() +{ + tr[1].init(7,true); + apped(1,7); + tr[1].walkto(6); + tr[2].stopwalk(); + tr[2].face=left; + set_up_timer(20,procrobin_hood_and_geida_talk,reason_robin_hood_and_geida); + dna.geida_follows=false; +} + +void robin_hood_and_geida_talk() +{ + dixi('q',66); tr[1].walkto(2); tr[2].walkto(2); + tr[1].vanishifstill=true; tr[2].vanishifstill=true; + set_up_timer(162,procavalot_returns,reason_robin_hood_and_geida); +} + +void avalot_returns() +{ + tr[1].done(); tr[2].done(); + tr[1].init(0,true); + apped(1,1); + dixi('q',67); + dna.user_moves_avvy=true; +} + +void avvy_sit_down() + /* This is used when you sit down in the pub in Notts. It loops around so + that it will happen when Avvy stops walking. */ +{ + if (tr[1].homing) /* Still walking */ + set_up_timer(1,procavvy_sit_down,reason_sitting_down); + else + { + show_one(3); + dna.sitting_in_pub=true; + dna.user_moves_avvy=false; + tr[1].visible=false; + } +} + +void ghost_room_phew() +{ + display("\6PHEW!\22 You're glad to get out of \6there!"); +} + +void arkata_shouts() +{ + if (dna.teetotal) return; + dixi('q',76); + set_up_timer(160,procarkata_shouts,reason_arkata_shouts); +} + +void winning() +{ + dixi('q',79); + winning_pic(); + do { checkclick(); } while (!(mrelease==0)); + callverb(vb_score); + display(" T H E E N D "); + lmo=true; +} + +void avalot_falls() +{ + if (tr[1].step<5) + { + tr[1].step += 1; + set_up_timer(3,procavalot_falls,reason_falling_over); + } else + display("\r\r\r\r\r\r\n\n\n\n\n\n\23Z\26"); +} + +void spludwick_goes_to_cauldron() +{ + if (tr[2].homing) + set_up_timer(1,procspludwick_goes_to_cauldron,reason_spludwalk); + else + set_up_timer(17,procspludwick_leaves_cauldron,reason_spludwalk); +} + +void spludwick_leaves_cauldron() +{ + tr[2].call_eachstep=true; /* So that normal procs will continue. */ +} + +void give_lute_to_geida() /* Moved here from Acci. */ +{ + dixi('Q',86); + points(4); + dna.lustie_is_asleep=true; + first_show(5); then_show(6); /* He falls asleep... */ + start_to_close(); /* Not really closing, but we're using the same procedure. */ +} + +/* "This is all!" */ + +class unit_timeout_initialize { + public: unit_timeout_initialize(); +}; +static unit_timeout_initialize timeout_constructor; + +unit_timeout_initialize::unit_timeout_initialize() { + fillchar(times,sizeof(times),'\0'); +} diff --git a/engines/avalanche/timeout.h b/engines/avalanche/timeout.h new file mode 100644 index 0000000000..5fa9800388 --- /dev/null +++ b/engines/avalanche/timeout.h @@ -0,0 +1,229 @@ +#ifndef __timeout_h__ +#define __timeout_h__ + + +#include "gyro.h" +#include "celer.h" + + +/* reason_ now runs between 1 and 28. */ + +const integer reason_drawbridgefalls = 2; +const integer reason_avariciustalks = 3; +const integer reason_gototoilet = 4; +const integer reason_explosion = 5; +const integer reason_brummiestairs = 6; +const integer reason_cardiffsurvey = 7; +const integer reason_cwytalot_in_herts = 8; +const integer reason_getting_tied_up = 9; +const integer reason_hanging_around = 10; /* Tied to the tree in Nottingham. */ +const integer reason_jacques_waking_up = 11; +const integer reason_naughty_duke = 12; +const integer reason_jumping = 13; +const integer reason_sequencer = 14; +const integer reason_crapulus_says_spludwick_out = 15; +const integer reason_dawndelay = 16; +const integer reason_drinks = 17; +const integer reason_du_lustie_talks = 18; +const integer reason_falling_down_oubliette = 19; +const integer reason_meeting_avaroid = 20; +const integer reason_rising_up_oubliette = 21; +const integer reason_robin_hood_and_geida = 22; +const integer reason_sitting_down = 23; +const integer reason_ghost_room_phew = 1; +const integer reason_arkata_shouts = 24; +const integer reason_winning = 25; +const integer reason_falling_over = 26; +const integer reason_spludwalk = 27; +const integer reason_geida_sings = 28; + +/* PROCx now runs between 1 and 41. */ + +const integer procopen_drawbridge = 3; + +const integer procavaricius_talks = 4; + +const integer procurinate = 5; + +const integer proctoilet2 = 6; + +const integer procbang = 7; + +const integer procbang2 = 8; + +const integer procstairs = 9; + +const integer proccardiffsurvey = 10; + +const integer proccardiff_return = 11; + +const integer proc_cwytalot_in_herts = 12; + +const integer procget_tied_up = 13; + +const integer procget_tied_up2 = 1; + +const integer prochang_around = 14; + +const integer prochang_around2 = 15; + +const integer procafter_the_shootemup = 32; + +const integer procjacques_wakes_up = 16; + +const integer procnaughty_duke = 17; + +const integer procnaughty_duke2 = 18; + +const integer procnaughty_duke3 = 38; + +const integer procjump = 19; + +const integer procsequence = 20; + +const integer proccrapulus_splud_out = 21; + +const integer procdawn_delay = 22; + +const integer procbuydrinks = 23; + +const integer procbuywine = 24; + +const integer proccallsguards = 25; + +const integer procgreetsmonk = 26; + +const integer procfall_down_oubliette = 27; + +const integer procmeet_avaroid = 28; + +const integer procrise_up_oubliette = 29; + +const integer procrobin_hood_and_geida = 2; + +const integer procrobin_hood_and_geida_talk = 30; + +const integer procavalot_returns = 31; + +const integer procavvy_sit_down = 33; /* In Nottingham. */ + +const integer procghost_room_phew = 34; + +const integer procarkata_shouts = 35; + +const integer procwinning = 36; + +const integer procavalot_falls = 37; + +const integer procspludwick_goes_to_cauldron = 39; + +const integer procspludwick_leaves_cauldron = 40; + +const integer procgive_lute_to_geida = 41; + +struct timetype { + longint time_left; + byte then_where; + byte what_for; +}; + + +#ifdef __timeout_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN array<1,7,timetype> times; +#undef EXTERN +#define EXTERN extern + + +void set_up_timer(longint howlong, byte whither,byte why); + +void one_tick(); + +void lose_timer(byte which); + +/*function timer_is_on(which:byte):boolean;*/ + + /* Procedures to do things at the end of amounts of time: */ + + void open_drawbridge(); + + void avaricius_talks(); + + void urinate(); + + void toilet2(); + + void bang(); + + void bang2(); + + void stairs(); + + void cardiff_survey(); + + void cardiff_return(); + + void cwytalot_in_herts(); + + void get_tied_up(); + + void get_tied_up2(); + + void hang_around(); + + void hang_around2(); + + void after_the_shootemup(); + + void jacques_wakes_up(); + + void naughty_duke(); + + void naughty_duke2(); + + void naughty_duke3(); + + void jump(); + + void crapulus_says_splud_out(); + + void buydrinks(); + + void buywine(); + + void callsguards(); + + void greetsmonk(); + + void fall_down_oubliette(); + + void meet_avaroid(); + + void rise_up_oubliette(); + + void robin_hood_and_geida(); + + void robin_hood_and_geida_talk(); + + void avalot_returns(); + + void avvy_sit_down(); + + void ghost_room_phew(); + + void arkata_shouts(); + + void winning(); + + void avalot_falls(); + + void spludwick_goes_to_cauldron(); + + void spludwick_leaves_cauldron(); + + void give_lute_to_geida(); + +#endif diff --git a/engines/avalanche/travel.cpp b/engines/avalanche/travel.cpp new file mode 100644 index 0000000000..b7597670d6 --- /dev/null +++ b/engines/avalanche/travel.cpp @@ -0,0 +1,64 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +integer gd,gm; + +void zoomout(integer x,integer y) +{ + integer x1,y1,x2,y2; + byte fv; +; + setcolor(white); setwritemode(xorput); + setlinestyle(dottedln,0,1); + + for( fv=1; fv <= 20; fv ++) + {; + x1=x-(x / 20)*fv; + y1=y-((y-10) / 20)*fv; + x2=x+(((639-x) / 20)*fv); + y2=y+(((161-y) / 20)*fv); + + rectangle(x1,y1,x2,y2); + delay(17); + rectangle(x1,y1,x2,y2); + } +} + +void zoomin(integer x,integer y) +{ + integer x1,y1,x2,y2; + byte fv; +; + setcolor(white); setwritemode(xorput); + setlinestyle(dottedln,0,1); + + for( fv=20; fv >= 1; fv --) + {; + x1=x-(x / 20)*fv; + y1=y-((y-10) / 20)*fv; + x2=x+(((639-x) / 20)*fv); + y2=y+(((161-y) / 20)*fv); + + rectangle(x1,y1,x2,y2); + delay(17); + rectangle(x1,y1,x2,y2); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + zoomout(177,77); + zoomout(7,31); + zoomout(577,124); + zoomout(320,85); + zoomin(177,77); + zoomin(7,31); + zoomin(577,124); + zoomin(320,85); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/trip.cpp b/engines/avalanche/trip.cpp new file mode 100644 index 0000000000..3dc89ac9ec --- /dev/null +++ b/engines/avalanche/trip.cpp @@ -0,0 +1,139 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + TRIP The trippancy handler. (Trippancy 2) */ + +#define __trip_implementation__ + + +#include "trip.h" + + +#include "graph.h" +#include "gyro.h" +/*#include "Dos.h"*/ + + +/* */ +/* EGA Graphic Primitive for Turbo Pascal 3.01A, Version 01FEB86. */ +/* (C) 1986 by Kent Cedola, 2015 Meadow Lake Ct., Norfolk, VA, 23518 */ +/* */ +/* Description: Write a array of colors in a vertical line. The current */ +/* merge setting is used to control the combining of bits. */ +/* */ + void gpwtcol(void* buf, integer n) /* Cedola */ + {; /* + inline + ($1E/$A1/GDCUR_Y/$D1/$E0/$D1/$E0/$03/$06/GDCUR_Y/$05/$A000/$8E/$C0/$8B/$3E/ + GDCUR_X/$8B/$CF/$D1/$EF/$D1/$EF/$D1/$EF/$BA/$03CE/$8A/$26/GDMERGE/$B0/$03/ + $EF/$B8/$0205/$EF/$B0/$08/$EE/$42/$B0/$80/$80/$E1/$07/$D2/$C8/$EE/$8B/$4E/ + $04/$C5/$76/$06/$8A/$24/$46/$26/$8A/$1D/$26/$88/$25/$83/$C7/$50/$E2/$F2/ + $B0/$FF/$EE/$4A/$B8/>$05/$EF/$B8/>$03/$EF/$1F); */ + } + + +void loadtrip() +{ + untyped_file inf; +; + assign(inf,"t:avvy.trp"); reset(inf,1); + seek(inf,0x27); + blockread(inf,pozzes,sizeof(pozzes)); + blockread(inf,blue3,sizeof(blue3)); close(inf); +} + +void plot(word count, integer ox,integer oy) /* orig x & y. Page is always 1. */ +{ + byte x,y,len; +; + do { + len=blue3[count]; if (len==177) return; + x=blue3[count+1]; y=blue3[count+2]; count += 3; + {; + gdcur_x=x+ox; gdcur_y=y+oy; + /* fiddle xy coords to match page 1 */ + gdcur_y += 205; /* 203 */ gdcur_x -= 128; /* 114 */ + if (gdcur_x<0) + {; gdcur_x += 640; gdcur_y -= 1; } + gpwtcol(&blue3[count],len); count += len; + } + } while (!false); +} + +void boundscheck() +{; + if (dna.uy>123) dna.uy=123; + if (dna.uy<10) dna.uy=10; + if (dna.ux<5) dna.ux=5; + if (dna.ux>600) dna.ux=600; +} + +void budge() +{; + if (set::of(up,ul,ur, eos).has(dna.rw)) dna.uy -= 3; + if (set::of(down,dl,dr, eos).has(dna.rw)) dna.uy += 3; + if (set::of(left,ul,dl, eos).has(dna.rw)) dna.ux -= 5; + if (set::of(right,ur,dr, eos).has(dna.rw)) dna.ux += 5; + + boundscheck(); + + if (dna.rw>0) + {; + anim += 1; if (anim==7) anim=1; + } +} + +void tripkey(char dir) +{; + if (cw!=177) return; + { + dnatype& with = dna; + ; + switch (dir) { + case 'H': if (with.rw!=up) {; with.rw=up; ww=up; } else with.rw=0; break; + case 'P': if (with.rw!=down) {; with.rw=down; ww=down; } else with.rw=0; break; + case 'K': if (with.rw!=left) {; with.rw=left; ww=left; } else with.rw=0; break; + case 'M': if (with.rw!=right) {; with.rw=right; ww=right; } else with.rw=0; break; + case 'I': if (with.rw!=ur) {; with.rw=ur; ww=right; } else with.rw=0; break; + case 'Q': if (with.rw!=dr) {; with.rw=dr; ww=right; } else with.rw=0; break; + case 'O': if (with.rw!=dl) {; with.rw=dl; ww=left; } else with.rw=0; break; + case 'G': if (with.rw!=ul) {; with.rw=ul; ww=left; } else with.rw=0; break; + } + if (with.rw==0) + {; + ux=ppos[0][0]; uy=ppos[0][1]; anim -= 1; + if (anim==0) anim=6; + } + } +} + +void trippancy() +{; + if ((dna.rw==0) || (cw!=177) || (! dropsok)) return; + r.ax=11; intr(0x33,r); + setactivepage(1); off(); + if (ppos[0][1]!=-177) + {; + putimage(ppos[0][0],ppos[0][1],replace[0],0); + } + + getimage(dna.ux,dna.uy,dna.ux+xw,dna.uy+yw,replace[0]); + ppos[0][0]=dna.ux; ppos[0][1]=dna.uy; + + plot(pozzes[anim*4+dna.ww-4],dna.ux,dna.uy); + + { void& with = r; if ((cx==0) && (dx==0)) on();} + getimage(dna.ux-margin,dna.uy-margin,dna.ux+xw+margin,dna.uy+yw+margin,copier); + setactivepage(0); off(); putimage(dna.ux-margin,dna.uy-margin,copier,0); on(); + + { + void& with = mouths[0]; ; x=dna.ux+20; y=dna.uy; } + + budge(); +} + + diff --git a/engines/avalanche/trip.h b/engines/avalanche/trip.h new file mode 100644 index 0000000000..520e323fe8 --- /dev/null +++ b/engines/avalanche/trip.h @@ -0,0 +1,17 @@ +#ifndef __trip_h__ +#define __trip_h__ + + + void loadtrip(); + + void plot(word count, integer ox,integer oy); + + void boundscheck(); + + void budge(); + + void tripkey(char dir); + + void trippancy(); + +#endif diff --git a/engines/avalanche/trip3.cpp b/engines/avalanche/trip3.cpp new file mode 100644 index 0000000000..c67f6e1f51 --- /dev/null +++ b/engines/avalanche/trip3.cpp @@ -0,0 +1,231 @@ +#include "ptoc.h" + +#define __trip3_implementation__ + /* Project Minstrel- Trippancy routines */ + +#include "trip3.h" + + +#include "Graph.h" +/*#include "Crt.h"*/ + +/*$S+*/ + +const integer avvy = 1; +const integer test = 177; + +struct triprec { + byte handle; /* who is it? */ + integer x,y; /* current x&y */ + byte xm,ym; /* x&y margins */ + shortint ix,iy; /* inc x&y */ + byte stage; /* animation */ + integer xl,yl; /* x&y length */ + boolean prime; /* true on first move */ + boolean alive; /* true if it moves */ +}; + +array<1,10,triprec> tr; +byte tramt; +array<1,20000,byte> blue3; +array<1,24,word> pozzes; + +const integer up = 1; const integer right = 2; const integer down = 3; const integer left = 4; const integer ur = 5; const integer dr = 6; const integer dl = 7; const integer ul = 8; + +/* */ +/* EGA Graphic Primitive for Turbo Pascal 3.01A, Version 01FEB86. */ +/* (C) 1986 by Kent Cedola, 2015 Meadow Lake Ct., Norfolk, VA, 23518 */ +/* */ +/* Description: Write a array of colors in a vertical line. The current */ +/* merge setting is used to control the combining of bits. */ +/* */ + void gpwtcol(void* buf, integer n) /* Cedola */ + {; + /* inline + ($1E/$A1/GDCUR_Y/$D1/$E0/$D1/$E0/$03/$06/GDCUR_Y/$05/$A000/$8E/$C0/$8B/$3E/ + GDCUR_X/$8B/$CF/$D1/$EF/$D1/$EF/$D1/$EF/$BA/$03CE/$8A/$26/GDMERGE/$B0/$03/ + $EF/$B8/$0205/$EF/$B0/$08/$EE/$42/$B0/$80/$80/$E1/$07/$D2/$C8/$EE/$8B/$4E/ + $04/$C5/$76/$06/$8A/$24/$46/$26/$8A/$1D/$26/$88/$25/$83/$C7/$50/$E2/$F2/ + $B0/$FF/$EE/$4A/$B8/>$05/$EF/$B8/>$03/$EF/$1F); */ + } + + +void loadtrip() +{ + untyped_file inf; +; + assign(inf,"t:avvy.trp"); reset(inf,1); + seek(inf,0x27); + blockread(inf,pozzes,sizeof(pozzes)); + blockread(inf,blue3,sizeof(blue3)); close(inf); +} + +void enter(byte what_handle, integer xx,integer yy,integer lx,integer ly, byte mmx,byte mmy,byte st) +{; + tramt += 1; + { + triprec& with = tr[tramt]; + ; + with.handle=what_handle; + with.ix=0; with.iy=0; + with.x=xx; with.y=yy; + with.xl=lx; with.yl=ly; + with.xm=mmx; with.ym=mmy; with.stage=st; + with.prime=true; with.alive=true; + } +} + +void plot(byte stage, integer ox,integer oy) /* orig x & y. Page is always 1/UNSEEN. */ +{ + byte x,y,len; word count; +; + count=pozzes[stage]; + do { + len=blue3[count]; if (len==177) return; + x=blue3[count+1]; y=blue3[count+2]; count += 3; + {; + gdcur_x=x+ox; gdcur_y=y+oy; + /* fiddle xy coords to match page 1 */ + gdcur_y += 205; /* 203 */ gdcur_x -= 128; /* 114 */ + if (gdcur_x<0) + {; gdcur_x += 640; gdcur_y -= 1; } + gpwtcol(&blue3[count],len); count += len; + } + } while (!false); +} + +void trippancy() +{ + byte fv; pointer p,saved1,saved2; word s; array<1,10,pointer> q; + boolean allstill; +; + if ((cw!=177) || (! dropsok) || keypressed()) return; + + /* Do the Avvy Walk */ + + switch (dna.rw) { + case up: budge(avvy, 0,-3,anim*4-3); break; + case down: budge(avvy, 0, 3,anim*4-1); break; + case right: budge(avvy, 5, 0,anim*4-2); break; + case left: budge(avvy,-5, 0,anim*4 ); break; + case ul: budge(avvy,-5,-3,anim*4 ); break; + case dl: budge(avvy,-5, 3,anim*4 ); break; + case ur: budge(avvy, 5,-3,anim*4-2); break; + case dr: budge(avvy, 5, 3,anim*4-2); break; + } + + for( fv=1; fv <= tramt; fv ++) { triprec& with = tr[fv]; boundscheck(with.x,with.y,with.xm,with.ym);} + + allstill=true; + for( fv=1; fv <= tramt; fv ++) + { triprec& with = tr[fv]; + if (((with.alive) && (! ((with.ix==0) && (with.iy==0)))) || with.prime) allstill=false;} + if (allstill) return; + + if (dna.rw>0) + {; + anim += 1; if (anim==7) anim=1; + } + + /* Trippancy Step 1 - Grab moon array of unmargined sprites (phew) */ + mark(saved1); + setactivepage(1); off(); + for( fv=1; fv <= tramt; fv ++) + { + triprec& with = tr[fv]; + ; + s=imagesize(with.x-with.xm,with.y-with.ym,with.x+with.xl+with.xm,with.y+with.yl+with.ym); + getmem(q[fv],s); getimage(with.x-with.xm,with.y-with.ym,with.x+with.xl+with.xm,with.y+with.yl+with.ym,q[fv]); + } + /* Step 2 - Plot sprites on 1/UNSEEN */ + for( fv=1; fv <= tramt; fv ++) + { + triprec& with = tr[fv]; + ; + plot(with.stage,with.x,with.y); + } + /* Step 3 - Copy all eligible from 1/UNSEEN to 0/SEEN */ + mark(saved2); + for( fv=1; fv <= tramt; fv ++) + { triprec& with = tr[fv]; + if (((with.alive) && (! ((with.ix==0) && (with.iy==0)))) || with.prime) + {; + s=imagesize(with.x-with.xm,with.y-with.ym,with.x+with.xl+with.xm,with.y+with.yl+with.ym); + getmem(p,s); + setactivepage(1); getimage(with.x-with.xm,with.y-with.ym,with.x+with.xl+with.xm,with.y+with.yl+with.ym,p); + setactivepage(0); putimage(with.x-with.xm,with.y-with.ym,p,0); + release(saved2); with.prime=false; + }} + /* Step 4 - Unplot sprites from 1/UNSEEN */ + setactivepage(1); + for( fv=1; fv <= tramt; fv ++) + { + triprec& with = tr[fv]; + ; + putimage(with.x-with.xm,with.y-with.ym,q[fv],0); + if (with.ix!=0) with.x=with.x+with.ix; + if (with.iy!=0) with.y=with.y+with.iy; + with.ix=0; with.iy=0; + if (with.handle==avvy) { + dnatype& with1 = dna; ; ux=with.x; uy=with.y; } + } + on(); release(saved1); + for( fv=1; fv <= tramt; fv ++) /* synch xy coords of mouths */ + { + triprec& with = tr[fv]; + ; mouths[fv].x=with.x+20; mouths[fv].y=with.y; } + + setactivepage(0); +} + +void budge(byte who, shortint xx,shortint yy, byte frame) /* Moving & animation controller */ +{ + byte fv; +; + for( fv=1; fv <= tramt; fv ++) + { triprec& with = tr[fv]; + if (with.handle==who) + {; + with.ix=xx; with.iy=yy; + with.stage=frame; + }} +} + +void tripkey(char dir) +{; + if (cw!=177) return; + { + dnatype& with = dna; + ; + switch (dir) { + case 'H': if (with.rw!=up) {; with.rw=up; ww=up; } else with.rw=0; break; + case 'P': if (with.rw!=down) {; with.rw=down; ww=down; } else with.rw=0; break; + case 'K': if (with.rw!=left) {; with.rw=left; ww=left; } else with.rw=0; break; + case 'M': if (with.rw!=right) {; with.rw=right; ww=right; } else with.rw=0; break; + case 'I': if (with.rw!=ur) {; with.rw=ur; ww=right; } else with.rw=0; break; + case 'Q': if (with.rw!=dr) {; with.rw=dr; ww=right; } else with.rw=0; break; + case 'O': if (with.rw!=dl) {; with.rw=dl; ww=left; } else with.rw=0; break; + case 'G': if (with.rw!=ul) {; with.rw=ul; ww=left; } else with.rw=0; break; + } + if (with.rw==0) + {; + ux=ppos[0][0]; uy=ppos[0][1]; anim -= 1; + if (anim==0) anim=6; + } + } +} + +void boundscheck(integer& x,integer& y, byte xm,byte ym) +{; + if (y>127-ym) y=127-ym; if (y<ym+10) y=ym+10; + if (x<xm) x=xm; if (x>640-xm) x=640-xm; +} + +class unit_trip3_initialize { + public: unit_trip3_initialize(); +}; +static unit_trip3_initialize trip3_constructor; + +unit_trip3_initialize::unit_trip3_initialize() {; /* init portion of Trip3 */ + tramt=0; +} diff --git a/engines/avalanche/trip3.h b/engines/avalanche/trip3.h new file mode 100644 index 0000000000..ccad15346b --- /dev/null +++ b/engines/avalanche/trip3.h @@ -0,0 +1,20 @@ +#ifndef __trip3_h__ +#define __trip3_h__ + + +#include "gyro.h" + + + void loadtrip(); + + void boundscheck(integer& x,integer& y, byte xm,byte ym); + + void budge(byte who, shortint xx,shortint yy, byte frame); /* Moving & animation controller */ + + void tripkey(char dir); + + void trippancy(); + + void enter(byte what_handle, integer xx,integer yy,integer lx,integer ly, byte mmx,byte mmy,byte st); + +#endif diff --git a/engines/avalanche/trip42.cpp b/engines/avalanche/trip42.cpp new file mode 100644 index 0000000000..b55b209d13 --- /dev/null +++ b/engines/avalanche/trip42.cpp @@ -0,0 +1,450 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + TRIP42 Trippancy IV point 2 - "Trip Oop 2" */ + +#define __trip42_implementation__ + /* Trippancy IV.2 (Trip Oop) */ +#include "trip42.h" + + +/*#include "Scrolls.h"*/ +/*#include "Lucerna.h"*/ +/*#include "Dropdown.h"*/ +/*#include "Access.h"*/ + + +/*procedure copier(x1,y1,x2,y2,x3,y3,x4,y4:integer); + + function dropin(xc,yc,x1,y1,x2,y2:integer):boolean; + { Dropin returns True if the point xc,yc falls within the 1-2 rectangle. } + begin; + dropin:=((xc>=x1) and (xc<=x2) and (yc>=y1) and (yc<=y2)); + end; + + function lesser(a,b:integer):integer; + begin; + if a<b then lesser:=a else lesser:=b; + end; + + function greater(a,b:integer):integer; + begin; + if a>b then greater:=a else greater:=b; + end; + +begin; + if dropin(x3,y3,x1,y1,x2,y2) + or dropin(x3,y4,x1,y1,x2,y2) + or dropin(x4,y3,x1,y1,x2,y2) + or dropin(x4,y4,x1,y1,x2,y2) then + begin; { Overlaps } + mblit(lesser(x1,x3),lesser(y1,y3),greater(x2,x4),greater(y2,y4),1,0); + end else + begin; { Doesn't overlap- copy both of them seperately } + mblit(x3,y3,x4,y4,1,0); { backwards- why not...? } + mblit(x1,y1,x2,y2,1,0); + end; +end; */ + +void loadtrip() +{ + byte gm; +; + for( gm=1; gm <= numtr; gm ++) tr[gm].original(); + tr[1].init(0); +} + +byte checkfeet(integer x1,integer x2,integer oy,integer y, byte yl) +{ + byte a,c; integer fv,ff; +byte checkfeet_result; +; + a=0; setactivepage(2); if (x1<0) x1=0; if (x2>639) x2=639; + if (oy<y) + for( fv=x1; fv <= x2; fv ++) + for( ff=oy+yl; ff <= y+yl; ff ++) + {; + c=getpixel(fv,ff); + if (c>a) a=c; + } else + for( fv=x1; fv <= x2; fv ++) + for( ff=y+yl; ff <= oy+yl; ff ++) + {; + c=getpixel(fv,ff); + if (c>a) a=c; + } + checkfeet_result=a; setactivepage(1-cp); +return checkfeet_result; +} + +void touchcol(byte tc); +static boolean bug; + +static void fr(byte a,byte b) {; fliproom(a,b); bug=false; } + +void touchcol(byte tc) +{; + bug=true; /* j.i.c. */ + switch (dna.room) { + case 1: fr(2,3); break; + case 2: {; /* main corridor */ + switch (tc) { + case 1: fr(3,1); break; /* to the other corridor */ + case 2: fr(2,1); break; /* to this corridor! Fix this later... */ + } + } + break; + case 3: {; /* turn corridor */ + switch (tc) { + case 1: fr(2,1); break; /* to the other corridor */ + case 2: fr(12,1); break; /* through Spludwick's door */ + } + } + break; + case 12: fr(3,2); break; + } + if (bug) + {; + display(string('\7')+"Unknown touchcolour ("+strf(tc)+')'+" in "+strf(dna.room) + +'.'); tr[1].bounce(); + } +} + +triptype* triptype::init(byte spritenum) +{ + integer gd,gm; word s; untyped_file f; varying_string<2> xx; byte sort,n; + word bigsize; pointer p,q; +; + str(spritenum,xx); assign(f,string("c:\\avalot\\sprite")+xx+".avd"); + reset(f,1); seek(f,59); + blockread(f,a,sizeof(a)); blockread(f,bigsize,2); + setactivepage(3); + for( sort=0; sort <= 1; sort ++) + {; + mark(q); getmem(p,bigsize); + blockread(f,p,bigsize); + off; putimage(0,0,p,0); release(q); n=1; + { adxtype& with = a; + for( gm=0; gm <= (with.num / with.seq)-1; gm ++) /* directions */ + for( gd=0; gd <= with.seq-1; gd ++) /* steps */ + {; + getmem(pic[n][sort],a.size); /* grab the memory */ + getimage((gm / 2)*(with.xl*6)+gd*with.xl,(gm % 2)*with.yl, + (gm / 2)*(with.xl*6)+gd*with.xl+with.xl-1,(gm % 2)*with.yl+with.yl-1, + pic[n][sort]); /* grab the pic */ + n += 1; + }} /*on;*/ + } + close(f); setactivepage(1-cp); + + x=0; y=0; quick=true; visible=false; +/* for x:=0 to 1 do getmem(behind[x],a.size);*/ + homing=false; ix=0; iy=0; step=0; check_me=a.name=="Avalot"; + count=0; +return this; +} + +void triptype::original() +{; + quick=false; +} + +void triptype::andexor() +{ + byte picnum; /* Picnum, Picnic, what ye heck */ +; + picnum=face*a.seq+step+1; off; + putimage(x,y,pic[picnum][0],andput); + putimage(x,y,pic[picnum][1],xorput); /*on;*/ +} + +void triptype::turn(byte whichway) +{; + if (whichway==8) face=0; else face=whichway; +} + +void triptype::appear(integer wx,integer wy, byte wf) +{; + x=(wx / 8)*8; y=wy; ox[cp]=wx; oy[cp]=wy; turn(wf); + visible=true; ix=0; iy=0; +} + +void triptype::walk() +{ + byte tc; fieldtype r; +; + {; + x1=x-1; y1=y-2; x2=x+a.xl+1; y2=y+a.yl+2; + } + getset[1-cp].remember(r); + ox[cp]=x; oy[cp]=y; + if (homing) homestep(); + x=x+ix; y=y+iy; + if (check_me) {; + tc=checkfeet(x,x+a.xl,oy[cp],y,a.yl); + if (tc!=0) + { void& with = magics[tc]; + switch (op) { + case exclaim: {; bounce(); dixi('x',data); } break; + case bounces: bounce(); break; + case transport: fliproom(hi(data),lo(data)); break; + case unfinished: {; + bounce(); + display("\7Sorry.\3\rThis place is not avaliable yet!"); + } + break; + }} + } + count += 1; + if (((ix!=0) || (iy!=0)) && (count>1)) + {; + step += 1; if (step==a.seq) step=0; count=0; + } +} + +void triptype::bounce() +{; x=ox[cp]; y=oy[cp]; stopwalk(); return; } + +void triptype::walkto(integer xx,integer yy) +{; + speed(xx-x,yy-y); hx=xx; hy=yy; homing=true; +} + +void triptype::stophoming() +{; + homing=false; +} + +void triptype::homestep() +{ + integer temp; +; + if ((hx==x) && (hy==y)) + {; /* touching the target */ + homing=false; return; + } + ix=0; iy=0; + if (hy!=y) + {; + temp=hy-y; if (temp>4) iy=4; else if (temp<-4) iy=-4; else iy=temp; + } + if (hx!=x) + {; + temp=hx-x; if (temp>4) ix=4; else if (temp<-4) ix=-4; else ix=temp; + } +} + +void triptype::speed(shortint xx,shortint yy) +{; + ix=xx; iy=yy; + if ((ix==0) && (iy==0)) return; /* no movement */ + if (ix==0) + {; /* No horz movement */ + if (iy<0) turn(up); else turn(down); + } else + {; + if (ix<0) turn(left); else turn(right); + } +} + +void triptype::stopwalk() +{; + ix=0; iy=0; homing=false; +} + +void triptype::chatter() +{; + talkx=x+a.xl / 2; talky=y; talkf=a.fgc; talkb=a.bgc; +} + +getsettype* getsettype::init() +{; + numleft=0; /* initialise array pointer */ + return this; +} + +void getsettype::remember(fieldtype r) +{; + numleft += 1; + gs[numleft]=r; +} + +void getsettype::recall(fieldtype& r) +{; + r=gs[numleft]; + numleft -= 1; +} + +void rwsp(byte t,byte r) +{ + const integer xs = 3; const integer ys = 1; +; + { triptype& with = tr[t]; switch (r) { + case up: speed( 0,-ys); break; case down: speed( 0, ys); break; case left: speed(-xs, 0); break; + case right: speed( xs, 0); break; case ul: speed(-xs,-ys); break; case ur: speed( xs,-ys); break; + case dl: speed(-xs, ys); break; case dr: speed( xs, ys); break; + }} +} + +void apped(byte trn,byte np) +{; + { + triptype& with = tr[trn]; + ; { void& with1 = peds[np]; appear(with.x-with.a.xl / 2,with.y-with.a.yl,dir);} + rwsp(trn,tr[trn].face); } +} + +void getback() +{ + byte fv; + fieldtype r; +; + { getsettype& with = getset[1-cp]; + while (with.numleft>0) + {; + recall(r); + mblit(x1,y1,x2,y2,3,1-cp); + }} +} + +void trippancy_link() +{ + byte fv; +; + if ((ddm_o.menunow) | ontoolbar | seescroll | (~ alive)) return; + for( fv=1; fv <= numtr; fv ++) { triptype& with = tr[fv]; if (with.quick) getback();} + for( fv=1; fv <= numtr; fv ++) { triptype& with = tr[fv]; if (with.quick) walk();} + for( fv=1; fv <= numtr; fv ++) { triptype& with = tr[fv]; if (with.quick && with.visible) andexor();} +} + +void stopwalking() +{; + tr[1].stopwalk(); dna.rw=stopped; +} + +void tripkey(char dir) +{; + if (ctrl==cjoy) return; + + { triptype& with = tr[1]; + {; + switch (dir) { + case 'H': if (rw!=up) + {; rw=up; rwsp(1,rw); } else stopwalking(); + break; + case 'P': if (rw!=down) + {; rw=down; rwsp(1,rw); } else stopwalking(); + break; + case 'K': if (rw!=left) + {; rw=left; rwsp(1,rw); } else stopwalking(); + break; + case 'M': if (rw!=right) + {; rw=right; rwsp(1,rw); } else stopwalking(); + break; + case 'I': if (rw!=ur) + {; rw=ur; rwsp(1,rw); } else stopwalking(); + break; + case 'Q': if (rw!=dr) + {; rw=dr; rwsp(1,rw); } else stopwalking(); + break; + case 'O': if (rw!=dl) + {; rw=dl; rwsp(1,rw); } else stopwalking(); + break; + case 'G': if (rw!=ul) + {; rw=ul; rwsp(1,rw); } else stopwalking(); + break; + case 'L': stopwalking(); break; + } + }} +} + +void getsetclear() +{ + byte fv; +; + for( fv=0; fv <= 1; fv ++) getset[fv].init(); +} + +void fliproom(byte room,byte ped) +{; + dusk; getsetclear(); enterroom(room); apped(1,ped); + oldrw=dna.rw; dna.rw=tr[1].face; showrw; dawn; +} + +boolean infield(byte x) /* returns True if you're within field "x" */ +{ + integer yy; +boolean infield_result; +; + { void& with = fields[x]; { + triptype& with = tr[1]; + ; + yy=with.y+with.a.yl; + infield_result=(with.x>=x1) && (with.x<=x2) && (yy>=y1) && (yy<=y2); + }} +return infield_result; +} + +boolean neardoor() /* returns True if you're near a door! */ +{ + integer ux,uy; byte fv; boolean nd; +boolean neardoor_result; +; + if (numfields<9) + {; /* there ARE no doors here! */ + neardoor_result=false; + return neardoor_result; + } + { + triptype& with = tr[1]; + ; + ux=with.x; + uy=with.y+with.a.yl; + } nd=false; + for( fv=9; fv <= numfields; fv ++) + { + void& with = fields[fv]; + ; + if ((ux>=x1) && (ux<=x2) && (uy>=y1) && (uy<=y2)) nd=true; + } + neardoor_result=nd; +return neardoor_result; +} + +void readstick() +{ + byte jw; +; + if (ctrl==ckey) return; + + jw=joyway; + + { + triptype& with = tr[1]; + ; + if (jw==stopped) stopwalking(); else + {; + dna.rw=jw; rwsp(1,dna.rw); + } + } + + if (jw!=oldjw) + {; + showrw; + oldjw=jw; + } + +} + +class unit_trip42_initialize { + public: unit_trip42_initialize(); +}; +static unit_trip42_initialize trip42_constructor; + +unit_trip42_initialize::unit_trip42_initialize() {; + getsetclear(); +} diff --git a/engines/avalanche/trip42.h b/engines/avalanche/trip42.h new file mode 100644 index 0000000000..b5e4f13614 --- /dev/null +++ b/engines/avalanche/trip42.h @@ -0,0 +1,90 @@ +#ifndef __trip42_h__ +#define __trip42_h__ + +/* {$R+ but switch it off soon...} */ + +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Gyro.h"*/ +/*#include "Sticks.h"*/ + + +const integer maxgetset = 10; + +struct adxtype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +class triptype { +public: + adxtype a; /* vital statistics */ + byte face,step; + integer x,y; /* current xy coords */ + array<0,1,integer> ox,oy; /* last xy coords */ + shortint ix,iy; /* amount to move sprite by, each step */ + matrix<1,24,0,1,pointer> pic; /* the pictures themselves */ + boolean quick,visible,homing,check_me; + integer hx,hy; /* homing x & y coords */ + byte count; /* counts before changing step */ + + triptype* init(byte spritenum); /* loads & sets up the sprite */ + void original(); /* just sets Quick to false */ + void andexor(); /* drops sprite onto screen */ + void turn(byte whichway); /* turns him round */ + void appear(integer wx,integer wy, byte wf); /* switches him on */ + void bounce(); /* bounces off walls. */ + void walk(); /* prepares for andexor, etc. */ + void walkto(integer xx,integer yy); /* home in on a point */ + void stophoming(); /* self-explanatory */ + void homestep(); /* calculates ix & iy for one homing step */ + void speed(shortint xx,shortint yy); /* sets ix & iy, non-homing, etc */ + void stopwalk(); /* Stops the sprite from moving */ + void chatter(); /* Sets up talk vars */ +}; + +class getsettype { +public: + array<1,maxgetset,fieldtype> gs; + byte numleft; + + getsettype* init(); + void remember(fieldtype r); + void recall(fieldtype& r); +}; + +const integer numtr = 5; /* current max no. of sprites */ + +void trippancy_link(); + +void loadtrip(); + +void tripkey(char dir); + +void apped(byte trn,byte np); + +void fliproom(byte room,byte ped); + +boolean infield(byte x); /* returns True if you're within field "x" */ + +boolean neardoor(); /* returns True if you're near a door! */ + +void readstick(); + + +#ifdef __trip42_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN array<1,numtr,triptype> tr; +EXTERN array<0,1,getsettype> getset; +#undef EXTERN +#define EXTERN extern + + +#endif diff --git a/engines/avalanche/trip5.cpp b/engines/avalanche/trip5.cpp new file mode 100644 index 0000000000..3674b1ffd7 --- /dev/null +++ b/engines/avalanche/trip5.cpp @@ -0,0 +1,1888 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + TRIP5 Trippancy V */ + +#define __trip5_implementation__ + /* Trippancy V */ /* Define NOASM to use Pascal instead of asm. */ +/*$S- Fast!*/ +#include "trip5.h" + + +/*#include "Scrolls.h"*/ +/*#include "Lucerna.h"*/ +/*#include "Dropdown.h"*/ +/*#include "Visa.h"*/ +/*#include "Celer.h"*/ +/*#include "Timeout.h"*/ +/*#include "Sequence.h"*/ +/*#include "Enid.h"*/ + + +void loadtrip() +{ + byte gm; + + for( gm=1; gm <= numtr; gm ++) tr[gm].original(); + fillchar(aa,sizeof(aa),'\0'); +} + +byte checkfeet(integer x1,integer x2,integer oy,integer y, byte yl) +{ + byte a,c; integer fv,ff; + +/* if not alive then begin checkfeet:=0; exit; end;*/ + byte checkfeet_result; + a=0; setactivepage(2); if (x1<0) x1=0; if (x2>639) x2=639; + if (oy<y) + for( fv=x1; fv <= x2; fv ++) + for( ff=oy+yl; ff <= y+yl; ff ++) + { + c=getpixel(fv,ff); + if (c>a) a=c; + } else + for( fv=x1; fv <= x2; fv ++) + for( ff=y+yl; ff <= oy+yl; ff ++) + { + c=getpixel(fv,ff); + if (c>a) a=c; + } + checkfeet_result=a; setactivepage(1-cp); + return checkfeet_result; +} + +byte geida_ped(byte which) +{ + byte geida_ped_result; + switch (which) { + case 1: geida_ped_result= 7; break; + case 2:case 6: geida_ped_result= 8; break; + case 3:case 5: geida_ped_result= 9; break; + case 4: geida_ped_result=10; break; + } + return geida_ped_result; +} + +void catamove(byte ped) + /* When you enter a new position in the catacombs, this procedure should + be called. It changes the Also codes so that they may match the picture + on the screen. (Coming soon: It draws up the screen, too.) */ +{ + longint here; + word xy_word; + byte fv,ff; + +/* XY_word is cat_x+cat_y*256. Thus, every room in the + catacombs has a different number for it. */ + + + { + xy_word=cat_x+cat_y*256; + geida_spin=0; + } + switch (xy_word) { + case 1801: { /* Exit catacombs */ + fliproom(r__lustiesroom,4); + display("Phew! Nice to be out of there!"); + return; + } + break; + case 1033: { /* Oubliette */ + fliproom(r__oubliette,1); + display("Oh, NO!\231\2"); + return; + } + break; + case 4: { + fliproom(r__geidas,1); + return; + } + break; + case 2307: { + fliproom(r__lusties,5); + display("Oh no... here we go again..."); + dna.user_moves_avvy=false; + tr[1].iy=1; tr[1].ix=0; + return; + } + break; + } + + if (~ dna.enter_catacombs_from_lusties_room) load(29); + here=catamap[cat_y][cat_x]; + + switch (here & 0xf) { /* West. */ + case 0: { /* no connection (wall) */ + magics[2].op=bounces; /* Sloping wall. */ + magics[3].op=nix; /* Straight wall. */ + portals[13].op=nix; /* Door. */ + show_one(28); + } + break; + case 0x1: { /* no connection (wall + shield), */ + magics[2].op=bounces; /* Sloping wall. */ + magics[3].op=nix; /* Straight wall. */ + portals[13].op=nix; /* Door. */ + show_one(28); /* Wall, plus... */ + show_one(29); /* ...shield. */ + } + break; + case 0x2: { /* wall with door */ + magics[2].op=bounces; /* Sloping wall. */ + magics[3].op=nix; /* Straight wall. */ + portals[13].op=special; /* Door. */ + show_one(28); /* Wall, plus... */ + show_one(30); /* ...door. */ + } + break; + case 0x3: { /* wall with door and shield */ + magics[2].op=bounces; /* Sloping wall. */ + magics[3].op=nix; /* Straight wall. */ + portals[13].op=special; /* Door. */ + show_one(28); /* Wall, plus... */ + show_one(30); /* ...door, and... */ + show_one(29); /* ...shield. */ + } + break; + case 0x4: { /* no connection (wall + window), */ + magics[2].op=bounces; /* Sloping wall. */ + magics[3].op=nix; /* Straight wall. */ + portals[13].op=nix; /* Door. */ + show_one(28); /* Wall, plus... */ + show_one(5); /* ...window. */ + } + break; + case 0x5: { /* wall with door and window */ + magics[2].op=bounces; /* Sloping wall. */ + magics[3].op=nix; /* Straight wall. */ + portals[13].op=special; /* Door. */ + show_one(28); /* Wall, plus... */ + show_one(30); /* ...door, and... */ + show_one(5); /* ...window. */ + } + break; + case 0x6: { /* no connection (wall + torches), */ + magics[2].op=bounces; /* Sloping wall. */ + magics[3].op=nix; /* Straight wall. */ + portals[13].op=nix; /* No door. */ + show_one(28); /* Wall, plus... */ + show_one(7); /* ...torches. */ + } + break; + case 0x7: { /* wall with door and torches */ + magics[2].op=bounces; /* Sloping wall. */ + magics[3].op=nix; /* Straight wall. */ + portals[13].op=special; /* Door. */ + show_one(28); /* Wall, plus... */ + show_one(30); /* ...door, and... */ + show_one(7); /* ...torches. */ + } + break; + case 0xf: { /* straight-through corridor. */ + magics[2].op=nix; /* Sloping wall. */ + magics[3].op=special; /* Straight wall. */ + } + break; + } + + /* ---- */ + + switch ((cardinal)(here & 0xf0) >> 4) { /* East */ + case 0: { /* no connection (wall) */ + magics[5].op=bounces; /* Sloping wall. */ + magics[6].op=nix; /* Straight wall. */ + portals[15].op=nix; /* Door. */ + show_one(19); + } + break; + case 0x1: { /* no connection (wall + window), */ + magics[5].op=bounces; /* Sloping wall. */ + magics[6].op=nix; /* Straight wall. */ + portals[15].op=nix; /* Door. */ + show_one(19); /* Wall, plus... */ + show_one(20); /* ...window. */ + } + break; + case 0x2: { /* wall with door */ + magics[5].op=bounces; /* Sloping wall. */ + magics[6].op=nix; /* Straight wall. */ + portals[15].op=special; /* Door. */ + show_one(19); /* Wall, plus... */ + show_one(21); /* ...door. */ + } + break; + case 0x3: { /* wall with door and window */ + magics[5].op=bounces; /* Sloping wall. */ + magics[6].op=nix; /* Straight wall. */ + portals[15].op=special; /* Door. */ + show_one(19); /* Wall, plus... */ + show_one(20); /* ...door, and... */ + show_one(21); /* ...window. */ + } + break; + case 0x6: { /* no connection (wall + torches), */ + magics[5].op=bounces; /* Sloping wall. */ + magics[6].op=nix; /* Straight wall. */ + portals[15].op=nix; /* No door. */ + show_one(19); /* Wall, plus... */ + show_one(18); /* ...torches. */ + } + break; + case 0x7: { /* wall with door and torches */ + magics[5].op=bounces; /* Sloping wall. */ + magics[6].op=nix; /* Straight wall. */ + portals[15].op=special; /* Door. */ + show_one(19); /* Wall, plus... */ + show_one(21); /* ...door, and... */ + show_one(18); /* ...torches. */ + } + break; + case 0xf: { /* straight-through corridor. */ + magics[5].op=nix; /* Sloping wall. */ + magics[6].op=special; /* Straight wall. */ + portals[15].op=nix; /* Door. */ + } + break; + } + + /* ---- */ + + switch ((cardinal)(here & 0xf00) >> 8) { /* South */ + case 0: { /* No connection. */ + magics[7].op=bounces; + magics[12].op=bounces; + magics[13].op=bounces; + } + break; + case 0x1: { + show_one(22); + { void& with = magics[13]; + if ((xy_word==2051) & (dna.geida_follows)) + op=exclaim; + else op=special;} /* Right exit south. */ + magics[7].op=bounces; + magics[12].op=bounces; + } + break; + case 0x2: { + show_one(23); + magics[7].op=special; /* Middle exit south. */ + magics[12].op=bounces; + magics[13].op=bounces; + } + break; + case 0x3: { + show_one(24); + magics[12].op=special; /* Left exit south. */ + magics[7].op=bounces; + magics[13].op=bounces; + } + break; + } + + switch ((cardinal)(here & 0xf000) >> 12) { /* North */ + case 0: { /* No connection */ + magics[1].op=bounces; + portals[12].op=nix; /* Door. */ + } + break; + /* LEFT handles: */ +/* $1: begin + show_one(4); + magics[1].op:=bounces; { Left exit north. } { Change magic number! } + portals[12].op:=special; { Door. } + end;*/ + case 0x2: { + show_one(4); + magics[1].op=bounces; /* Middle exit north. */ + portals[12].op=special; /* Door. */ + } + break; +/* $3: begin + show_one(4); + magics[1].op:=bounces; { Right exit north. } { Change magic number! } + portals[12].op:=special; { Door. } + end; + { RIGHT handles: } + $4: begin + show_one(3); + magics[1].op:=bounces; { Left exit north. } { Change magic number! } + portals[12].op:=special; { Door. } + end;*/ + case 0x5: { + show_one(3); + magics[1].op=bounces; /* Middle exit north. */ + portals[12].op=special; /* Door. */ + } + break; +/* $6: begin + show_one(3); + magics[1].op:=bounces; { Right exit north. } + portals[12].op:=special; { Door. } + end;*/ + /* ARCHWAYS: */ + case 0x7:case 0x8:case 0x9: { + show_one(6); + + if (((cardinal)(here & 0xf000) >> 12)>0x7) show_one(31); + if (((cardinal)(here & 0xf000) >> 12)==0x9) show_one(32); + + magics[1].op=special; /* Middle arch north. */ + portals[12].op=nix; /* Door. */ + } + break; + /* DECORATIONS: */ + case 0xd: { /* No connection + WINDOW */ + magics[1].op=bounces; + portals[12].op=nix; /* Door. */ + show_one(14); + } + break; + case 0xe: { /* No connection + TORCH */ + magics[1].op=bounces; + portals[12].op=nix; /* Door. */ + show_one(8); + } + break; + /* Recessed door: */ + case 0xf: { + magics[1].op=nix; /* Door to Geida's room. */ + show_one(1); + portals[12].op=special; /* Door. */ + } + break; + } + + switch (xy_word) { + case 514: show_one(17); break; /* [2,2] : "Art Gallery" sign over door. */ + case 264: show_one(9); break; /* [8,1] : "The Wrong Way!" sign. */ + case 1797: show_one(2); break; /* [5,7] : "Ite Mingite" sign. */ + case 258: for( fv=0; fv <= 2; fv ++) /* [2,1] : Art gallery - pictures */ + { + show_one_at(15,130+fv*120,70); + show_one_at(16,184+fv*120,78); + } + break; + case 1287: for( fv=10; fv <= 13; fv ++) show_one(fv); break; /* [7,5] : 4 candles. */ + case 776: show_one(10); break; /* [8,3] : 1 candle. */ + case 2049: show_one(11); break; /* [1,8] : another candle. */ + case 257: { show_one(12); show_one(13); } break; /* [1,1] : the other two. */ + } + + if ((dna.geida_follows) & (ped>0)) + { + triptype& with = tr[2]; + + if (! with.quick) /* If we don't already have her... */ + tr[2].init(5,true); /* ...Load Geida. */ + apped(2,geida_ped(ped)); + tr[2].call_eachstep =true; + tr[2].eachstep=procgeida_procs; + } +} + +void call_special(word which); + + /* This proc gets called whenever you touch a line defined as Special. */ +static void dawndelay() + { set_up_timer(2,procdawn_delay,reason_dawndelay); } + +void call_special(word which) +{ + switch (which) { + case 1: { /* Special 1: Room 22: top of stairs. */ + show_one(1); + dna.brummie_stairs=1; + magics[10].op=nix; + set_up_timer(10,procstairs,reason_brummiestairs); + stopwalking(); + dna.user_moves_avvy=false; + } + break; + case 2: { /* Special 2: Room 22: bottom of stairs. */ + dna.brummie_stairs=3; + magics[11].op=nix; + magics[12].op=exclaim; + magics[12].data=5; + magics[4].op=bounces; /* Now works as planned! */ + stopwalking(); + dixi('q',26); + dna.user_moves_avvy=true; + } + break; + case 3: { /* Special 3: Room 71: triggers dart. */ + tr[1].bounce(); /* Must include that. */ + + if (~ dna.arrow_triggered) + { + dna.arrow_triggered=true; + apped(2,4); /* The dart starts at ped 4, and... */ + tr[2].walkto(5); /* flies to ped 5. */ + tr[2].face=0; /* Only face. */ + /* Should call some kind of Eachstep procedure which will deallocate + the sprite when it hits the wall, and replace it with the chunk + graphic of the arrow buried in the plaster. */ + /* OK! */ + tr[2].call_eachstep=true; + tr[2].eachstep=procarrow_procs; + } + } + break; + + case 4: { /* This is the ghost room link. */ + dusk; + tr[1].turn(right); /* you'll see this after we get back from bootstrap */ + set_up_timer(1,procghost_room_phew,reason_ghost_room_phew); + back_to_bootstrap(3); + } + break; + + case 5: if (dna.friar_will_tie_you_up) + { /* Special 5: Room 42: touched tree, and get tied up. */ + magics[4].op=bounces; /* Boundary effect is now working again. */ + dixi('q',35); + tr[1].done(); + /*tr[1].vanishifstill:=true;*/ + show_one(2); + dixi('q',36); + dna.tied_up=true; + dna.friar_will_tie_you_up=false; + tr[2].walkto(3); + tr[2].vanishifstill=true; + tr[2].check_me=true; /* One of them must have Check_Me switched on. */ + whereis[pfriartuck]=177; /* Not here, then. */ + set_up_timer(364,prochang_around,reason_hanging_around); + } + break; + + case 6: { /* Special 6: fall down oubliette. */ + dna.user_moves_avvy=false; + tr[1].ix=3; + tr[1].iy=0; + tr[1].face=right; + set_up_timer(1,procfall_down_oubliette,reason_falling_down_oubliette); + } + break; + + case 7: { /* Special 7: stop falling down oubliette. */ + tr[1].visible=false; + magics[10].op=nix; + stopwalking(); + lose_timer(reason_falling_down_oubliette); + mblit(12,80,38,160,3,0); + mblit(12,80,38,160,3,1); + display("Oh dear, you seem to be down the bottom of an oubliette."); + set_up_timer(200,procmeet_avaroid,reason_meeting_avaroid); + } + break; + + case 8: /* Special 8: leave du Lustie's room. */ + if ((geida_follows) & (~ lustie_is_asleep)) + { + dixi('q',63); + tr[2].turn(down); tr[2].stopwalk(); tr[2].call_eachstep=false; /* Geida */ + gameover; + } + break; + + case 9: { /* Special 9: lose Geida to Robin Hood... */ + if (~ dna.geida_follows) return; /* DOESN'T COUNT: no Geida. */ + tr[2].call_eachstep=false; /* She no longer follows Avvy around. */ + tr[2].walkto(4); /* She walks to somewhere... */ + tr[1].done(); /* Lose Avvy. */ + dna.user_moves_avvy=false; + set_up_timer(40,procrobin_hood_and_geida,reason_robin_hood_and_geida); + } + break; + + case 10: { /* Special 10: transfer north in catacombs. */ + if ((dna.cat_x==4) && (dna.cat_y==1)) + { /* Into Geida's room. */ + if (dna.obj[key]) dixi('q',62); else + { + dixi('q',61); + return; + } + } + dusk; + dna.cat_y -= 1; + catamove(4); if (dna.room!=r__catacombs) return; + delavvy; + switch ((cardinal)(catamap[cat_y][cat_x] & 0xf00) >> 8) { + case 0x1: apped(1,12); break; + case 0x3: apped(1,11); break; + default: apped(1,4); + } + getback(); + dawndelay(); + } + break; + case 11: { /* Special 11: transfer east in catacombs. */ + dusk; + dna.cat_x += 1; + catamove(1); if (dna.room!=r__catacombs) return; + delavvy; + apped(1,1); + getback(); + dawndelay(); + } + break; + case 12: { /* Special 12: transfer south in catacombs. */ + dusk; + dna.cat_y += 1; + catamove(2); if (dna.room!=r__catacombs) return; + delavvy; + apped(1,2); + getback(); + dawndelay(); + } + break; + case 13: { /* Special 13: transfer west in catacombs. */ + dusk; + dna.cat_x -= 1; + catamove(3); if (dna.room!=r__catacombs) return; + delavvy; + apped(1,3); + getback(); + dawndelay(); + } + break; + } +} + +void hide_in_the_cupboard(); + +void open_the_door(byte whither,byte ped,byte magicnum) + /* This slides the door open. (The data really ought to be saved in + the Also file, and will be next time. However, for now, they're + here.) */ +{ + switch (dna.room) { + case r__outsideyours:case r__outsidenottspub:case r__outsideducks: + { + first_show(1); + then_show(2); + then_show(3); + } + break; + case r__insidecardiffcastle: + { + first_show(1); + then_show(5); + } + break; + case r__avvysgarden:case r__entrancehall:case r__insideabbey: + { + first_show(1); + then_show(2); + } + break; + case r__musicroom:case r__outsideargentpub: + { + first_show(5); + then_show(6); + } + break; + case r__lusties: + switch (magicnum) { + case 14: if (dna.avvys_in_the_cupboard) + { + hide_in_the_cupboard(); + first_show(8); then_show(7); + start_to_close; + return; + } else + { + apped(1,6); + tr[1].face=right; /* added by TT 12/3/1995 */ + first_show(8); then_show(9); + } + break; + case 12: { + first_show(4); then_show(5); then_show(6); + } + break; + } + break; + } + + then_flip(whither,ped); + start_to_open; +} + +void newspeed() + /* Given that you've just changed the speed in triptype.xs, this adjusts + ix. */ +{ + const bytefield lightspace = {40, 199, 47, 199}; + byte page_; + + { + triptype& with = tr[1]; + + with.ix=(with.ix / 3)*with.xs; + setactivepage(3); + + setfillstyle(1,14); + if (with.xs==run) bar(371,199,373,199); else bar(336,199,338,199); + setfillstyle(1,9); + if (with.xs==run) bar(336,199,338,199); else bar(371,199,373,199); + + setactivepage(1-cp); + for( page_=0; page_ <= 1; page_ ++) getset[page_].remember(lightspace); + } +} + +triptype* triptype::init(byte spritenum, boolean do_check) +{ + const integer idshould = -1317732048; + integer gd,gm; varying_string<2> xx; + byte fv/*,nds*/; + byte aa,bb; + longint id; word soa; + untyped_file inf; + + if (spritenum==177) return; /* Already running! */ + str(spritenum,xx); assign(inf,string("sprite")+xx+".avd"); + reset(inf,1); + seek(inf,177); + blockread(inf,id,4); + if (id!=idshould) + { + output << '\7'; + close(inf); + exit(0); + } + + blockread(inf,soa,2); + blockread(inf,a,soa); + + { + adxtype& with = a; + + /*nds:=num div seq;*/ totalnum=1; + xw=with.xl / 8; if ((with.xl % 8)>0) xw += 1; + for( aa=1; aa <= /*nds*seq*/with.num; aa ++) + { + getmem(sil[totalnum],11*(with.yl+1)); + getmem(mani[totalnum],with.size-6); + for( fv=0; fv <= with.yl; fv ++) + { + blockread(inf,(*sil[totalnum])[fv],xw); + } + blockread(inf,*mani[totalnum],with.size-6); + totalnum += 1; + } + } + + /* on; */ + x=0; y=0; quick=true; visible=false; xs=3; ys=1; +/* if spritenum=1 then newspeed; { Just for the lights. }*/ + + homing=false; ix=0; iy=0; step=0; check_me=do_check; + count=0; whichsprite=spritenum; vanishifstill=false; + call_eachstep=false; + close(inf); + return this; +} + +void triptype::original() +{ + quick=false; whichsprite=177; +} + +void triptype::andexor() +{ + byte picnum; /* Picnum, Picnic, what ye heck */ + byte lay,laz; /* Limits for Qaz and Qay or equivs. (Laz always = 3). */ +#ifdef NOASM + word offs,fv; + byte qax,qay,qaz; +#else + word segmani,ofsmani; + word ofsaa,realofsaa; + word segsil,ofssil; + word z; byte xwidth; + +#endif + + if ((vanishifstill) && (ix==0) && (iy==0)) return; + picnum=face*a.seq+step+1; + + { + adxtype& with = a; + + getimage(x,y,x+with.xl,y+with.yl,aa); /* Now loaded into our local buffer. */ + + /* Now we've got to modify it! */ + + /* Qaz ranges over the width of the sprite/8. + Qay " " the height. + Qax " " 1 to 4 (the planes). */ + + { + adxtype& with1 = a; + + #ifdef NOASM + laz=xw-1; lay=with1.yl; /* -1's only for Pascal. */ + #else + laz=xw; lay=with1.yl+1; /* +1's only for ASM! */ + #endif + } + + /* ASSEMBLERISED: */ +#ifdef NOASM + for( qax=0; qax <= 3; qax ++) /* 3 */ + for( qay=0; qay <= lay; qay ++) /* 35 */ + for( qaz=0; qaz <= laz; qaz ++) /* 4 */ + { + offs=5+qay*xw*4+xw*qax+qaz; + aa[offs]=aa[offs] & (*sil[picnum])[qay][qaz]; + } + + for( fv=5; fv <= with.size-2; fv ++) + aa[fv]=aa[fv] ^ (*mani[picnum])[fv]; + +#else + /* OK, here's the same thing in assembler... + + AL is Qax, + BL is Qay, + CL is Qaz, + DX is Offs */ + + /* For the first part: */ + xwidth=xw; + segsil=seg(*sil[picnum]); + ofssil=ofs(*sil[picnum]); + + /* For the first and second parts: */ + segmani=seg(*mani[picnum]); /* It's easier to do this in Pascal, and */ + ofsmani=ofs(*mani[picnum])+1; /* besides it only goes round once here. */ + /* Segment of AA is always the current data segment. */ + ofsaa=ofs(aa)+5; + realofsaa=ofs(aa)-1; /* We may not need this. */ + z=with.size-7; +/* + asm + + xor ax,ax; { Initialise ax, bx, and cx, using a rather } + @QAXloop: { AL } + + xor bx,bx; { nifty speed trick. } + @QAYloop: { BL } + + xor cx,cx; + @QAZloop: { CL } + + { Right, well, here we are. We have to do some rather nifty array + manipulation, stuff like that. We're trying to assemblerise: + DX:= 5 + BX * xw * 4 + xw * AX + CX; + aa[DX]:=aa[DX] and sil[picnum]^[BL,CL]; } + + push ax; {AXcdx} { OK, we're going to do some strange things } + { with ax, so we'd better save it. } + mov dx,5; { First of all... set dx to 5. } + add dx,cx; { DX now = 5+CX } + mul xwidth; { Multiply ax by xw (the Pascal variable.) } + add dx,ax; { DX now = 5+CX+xw*AX } + + { Right. Mul only works on ax. Don't ask me why. Ask Intel. Anyway, + since ax is saved on the stack, we can move bx over it. Note that + if xw was a word, using mul would have destroyed the contents of + dx. NOT a good idea! } + + push cx; {CXmul} { We must just borrow cx for a second. } + mov ax,bx; { Make ax = bx. } + mul xwidth; { Do the same to it as we did to ax before. } + mov cl,2; + shl ax,cl; { And multiply it by 4 (i.e., shl it by 2.) } + add dx,ax; { DX now = 5+CX+xw*AX+xw*BX*4. That's OK. } + + pop cx; {CXmul} + pop ax; {AXcdx} { Now we have to get ax and cx back again. } + + { Registers are now returned to original status. } + + { Righto. DX is now all worked out OK. We must now find out the + contents of: 1) aa[dx], and 2) (harder) sil[picnum]^[BL,CL]. Gulp. } + + { DS already points to the segment of AA. So... let's use CL to + put aa[dx] in, and use BX for the offset. Looks like we're going + to have to push a few registers! } + + push ax; { AXaa. Saving loop value of AX. } + { Let's use ax to do our dirty work with. } + push dx; { Saving Offs(DX.) } + + push bx; { BXaa. Saving loop value of BX. } + + mov bx,realofsaa; { aa is now pointed to by [ds:bx]. } + add bx,dx; { Offset is dx bytes. } + mov dl,[bx]; { cl now holds the contents of aa[dx]. } + + pop bx; { BXaa. Restoring loop value of BX. } + + { Stack now holds: Offs(DX). } + + { ^^^ That works. Now to find sil[picnum]^[BL,CL]. Our first task is + to find the address of sil[picnum]^. Since it's dynamic, we must + push and pop ds. } + + push ds; { DXaa. Saving value of Trip5's data segment. } + { Push ds. Now we can put the segment of sil[picnum]^... } + mov ds,segsil; { ...into ds, and... } + mov ax,ofssil; { ...its offset into ax. } + { Addr of sil[picnum]^ is now in [ds:ax]. BUT we want a particular + offset: to wit, [BL,CL]. Now, siltype is defined so that this offset + will be at an offset of (BL*11)+CL. } + + push bx; { Saving loop value of BX. } + push cx; { Saving loop value of CX. } + push ax; { Saving offset of sil[picnum]^. } + { Save them for a bit (!) } + mov al,bl; { Put bl into al. } + mov bl,11; { ... } + mul bl; { ...times it by 11. } + mov bx,ax; { Put it back into bx (now = bx*11) } + pop ax; { Restoring offset of sil[picnum]^. } + { Get ax back again. } + add ax,bx; { Add (original bl)*11 to al. } + add ax,cx; { Add cl to al. } + { AX now holds the offset of sil[picnum]^[bx,cl]. } + + { Stack now holds: loop value of AX, Trip5's DS, lv of BX, lv of CX. } + + { Right. Now the address of sil[picnum]^[bl,cl] is in [ds:ax]. Let's + get the elusive byte itself, and put it into ax. Firstly, we must + swap ax and bx. } + + xchg ax,bx; + mov al,[bx]; { AX now contains sil[picnum]^[bl,cl], AT LAST!! } + + { So now AL contains the sil stuff, and DL holds aa[offs]. } + + and al,dl; { aa[offs]:=aa[offs] and sil[picnum]^[Qay,Qaz]. } + + pop cx; { Restoring loop value of CX. } + pop bx; { Restoring loop value of BX. } + pop ds; { Restore value of Trip5's data segment. } + + { Right. AL contains the byte we need to replace aa[offs] with. + All that's left to do is to put it back. Remember that we already + have the segment of aa in the current DS, so... } + + pop dx; { Restore Offs(DX). } + + { Stack is now as when we entered the loop. Since this copy of DX + is now being used for the last time, we can muck around with it. } + + { Recap: DX now holds the offset from the start of AA. If we add + the offset of aa to it, we'll get the offset of the byte we want. + DS is already set up. } + + push bx; { I'm just borrowing bx for a sec. I'll put it back in 5 lines.} + mov bx,realofsaa; + add dx,bx; { Now aa[offs] is at aa[ds:dx]. } + mov bx,dx; { But we can't address memory with dx, so use bx. } + mov [bx],al; { Shove it into the memory! } + pop bx; { See! I said I would. } + + pop ax; { Restore loop value of AX. } + + { Right, the fancy stuff's all done now. Finish off the loop code. } + + inc cl; + cmp cl,laz; { CL must not reach 5. Does it? } + jnz @QAZloop; { no, keep going around the QAZloop. } + + inc bl; + cmp bl,lay; { BL must not reach 36. Does it? } + jnz @QAYloop; { no, keep going around the QAYloop. } + + inc al; + cmp al,4; { AL must not reach 4. Does it? } + jnz @QAXloop; { no, keep going around the QAXloop. } + + { al, bl and cl are now at their maxima, so we can stop the loops. } + + { *** SECOND ASSEMBLER BIT. *** } + + mov cx,z; { Find the size of the array, -7. } + mov bx,ofsmani; { Now find the offset and put that into bx. } + mov dx,ofsaa; { We'll use dx to be the same as fv, +5. } + + { DS should already hold the segment of aa. } + + @nextbyte: { Main loop... } + + { Firstly, we must get hold of aa[fv] (here called aa[dx].)} + push bx; { We need to "borrow" bx for a second... } + mov bx,dx; { Wrong register- shove it into bx. } + mov al,[bx]; { Get aa[fv] and put it into al. } + pop bx; { Right, you can have bx back again. } + + { Secondly, we must get hold of mani[picnum]^[fv]. } + push cx; { Let's borrow cx for this one. } + push ds; { we must use ds to point to segmani. } + mov ds,segmani; { Find the segment of mani[picnum]^, } + mov cl,[bx]; { now get the byte at [ds:bx] and put it into cl. } + pop ds; { Put ds back to being the current data segment. } + + { Right: now we can do what we came here for in the first place. + AL contains aa[fv], CL contains mani[picnum]^[fv]. } + + xor al,cl; { Xor al with bl. That's it! } + + pop cx; { We don't need cx any more for this now. } + + push bx; { Borrow bx... } + mov bx,dx; { Put dx into bx. } + mov [bx],al; { Put the changed al back into [ds:bx] (ie, [ds:dx].} + pop bx; { Get it back. } + + inc bx; { Add one to bx, for the next char. } + inc dx; { And dx, for the same reason. } + + loop @nextbyte; { Keep going round until cx=0. } +*/ +{; +} +#endif + + /* Now.. let's try pasting it back again! */ + + putimage(x,y,aa,0); + } +} + +void triptype::turn(byte whichway) +{ + if (whichway==8) face=0; else face=whichway; +} + +void triptype::appear(integer wx,integer wy, byte wf) +{ + x=(wx / 8)*8; y=wy; ox[cp]=wx; oy[cp]=wy; turn(wf); + visible=true; ix=0; iy=0; +} + + + + +static boolean collision_check() +{ + byte fv; + + boolean collision_check_result; + for( fv=1; fv <= numtr; fv ++) + if (tr[fv].quick && (tr[fv].whichsprite!=whichsprite) && + ((x+a.xl)>tr[fv].x) && + (x<(tr[fv].x+tr[fv].a.xl)) && + (tr[fv].y==y)) + { + collision_check_result=true; + return collision_check_result; + } + collision_check_result=false; + return collision_check_result; +} + +void triptype::walk() +{ + byte tc; bytefield r; + + + if (visible) + { + { + x1=(x / 8)-1; + if (x1==255) x1=0; + y1=y-2; + x2=((x+a.xl) / 8)+1; + y2=y+a.yl+2; + } + getset[1-cp].remember(r); + } + + if (~ doing_sprite_run) + { + ox[cp]=x; oy[cp]=y; + if (homing) homestep(); + x=x+ix; y=y+iy; + } + + if (check_me) + { + if (collision_check()) + { + bounce(); + return; + } + + tc=checkfeet(x,x+a.xl,oy[cp],y,a.yl); + + if ((tc!=0) & (~ doing_sprite_run)) + { void& with = magics[tc]; + switch (op) { + case exclaim: { + bounce(); mustexclaim=true; saywhat=data; + } + break; + case bounces: bounce(); break; + case transport: fliproom(hi(data),lo(data)); break; + case unfinished: { + bounce(); + display("\7Sorry.\3\rThis place is not available yet!"); + } + break; + case special: call_special(data); break; + case mopendoor: open_the_door(hi(data),lo(data),tc); break; + }} + } + + if (~ doing_sprite_run) + { + count += 1; + if (((ix!=0) || (iy!=0)) && (count>1)) + { + step += 1; if (step==a.seq) step=0; count=0; + } + } + +} + +void triptype::bounce() +{ + x=ox[cp]; y=oy[cp]; + if (check_me) stopwalking(); else stopwalk(); + oncandopageswap=false; + showrw; + oncandopageswap=true; +} + +shortint sgn(integer x) +{ + shortint sgn_result; + if (x>0) sgn_result=1; else + if (x<0) sgn_result=-1; else + sgn_result=0; /* x=0 */ + return sgn_result; +} + +void triptype::walkto(byte pednum) +{ + speed(sgn(peds[pednum].x-x)*4,sgn(peds[pednum].y-y)); + hx=peds[pednum].x-a.xl / 2; + hy=peds[pednum].y-a.yl; homing=true; +} + +void triptype::stophoming() +{ + homing=false; +} + +void triptype::homestep() +{ + integer temp; + + if ((hx==x) && (hy==y)) + { /* touching the target */ + stopwalk(); + return; + } + ix=0; iy=0; + if (hy!=y) + { + temp=hy-y; if (temp>4) iy=4; else if (temp<-4) iy=-4; else iy=temp; + } + if (hx!=x) + { + temp=hx-x; if (temp>4) ix=4; else if (temp<-4) ix=-4; else ix=temp; + } +} + +void triptype::speed(shortint xx,shortint yy) +{ + ix=xx; iy=yy; + if ((ix==0) && (iy==0)) return; /* no movement */ + if (ix==0) + { /* No horz movement */ + if (iy<0) turn(up); else turn(down); + } else + { + if (ix<0) turn(left); else turn(right); + } +} + +void triptype::stopwalk() +{ + ix=0; iy=0; homing=false; +} + +void triptype::chatter() +{ + talkx=x+a.xl / 2; talky=y; talkf=a.fgc; talkb=a.bgc; +} + +void triptype::set_up_saver(trip_saver_type& v) +{ + v.whichsprite=whichsprite; + v.face=face; + v.step=step; + v.x=x; + v.y=y; + v.ix=ix; + v.iy=iy; + v.visible=visible; + v.homing=homing; + v.check_me=check_me; + v.count=count; + v.xw=xw; + v.xs=xs; + v.ys=ys; + v.totalnum=totalnum; + v.hx=hx; + v.hy=hy; + v.call_eachstep=call_eachstep; + v.eachstep=eachstep; + v.vanishifstill=vanishifstill; +} + +void triptype::unload_saver(trip_saver_type v) +{ + whichsprite=v.whichsprite; + face=v.face; + step=v.step; + x=v.x; + y=v.y; + ix=v.ix; + iy=v.iy; + visible=v.visible; + homing=v.homing; + check_me=v.check_me; + count=v.count; + xw=v.xw; + xs=v.xs; + ys=v.ys; + totalnum=v.totalnum; + hx=v.hx; + hy=v.hy; + call_eachstep=v.call_eachstep; + eachstep=v.eachstep; + vanishifstill=v.vanishifstill; +} + +void triptype::savedata(untyped_file& f) +{ + trip_saver_type tripsaver; + + set_up_saver(tripsaver); + + { + blockwrite(f,tripsaver.whichsprite,1); + blockwrite(f,tripsaver.face,1); blockwrite(f,tripsaver.step,1); + blockwrite(f,tripsaver.x,2); blockwrite(f,tripsaver.y,2); + blockwrite(f,tripsaver.ix,1); blockwrite(f,tripsaver.iy,1); + blockwrite(f,tripsaver.visible,1); + blockwrite(f,tripsaver.homing,1); + blockwrite(f,tripsaver.check_me,1); + blockwrite(f,tripsaver.count,1); + blockwrite(f,tripsaver.xw,1); + blockwrite(f,tripsaver.xs,1); blockwrite(f,tripsaver.ys,1); + blockwrite(f,tripsaver.totalnum,1); + blockwrite(f,tripsaver.hx,2); blockwrite(f,tripsaver.hy,2); + blockwrite(f,tripsaver.call_eachstep,1); + blockwrite(f,tripsaver.eachstep,1); + blockwrite(f,tripsaver.vanishifstill,1); + } +} + +void triptype::loaddata(untyped_file& f) +{ + word spritewas,spriteis,saveface,savex,savey,savestep; + boolean wasquick; + trip_saver_type tripsaver; + + + wasquick=quick; + quick=true; spritewas=whichsprite; + + { + blockread(f,tripsaver.whichsprite,1); + blockread(f,tripsaver.face,1); blockread(f,tripsaver.step,1); + blockread(f,tripsaver.x,2); blockread(f,tripsaver.y,2); + blockread(f,tripsaver.ix,1); blockread(f,tripsaver.iy,1); + + if ((! wasquick) || ((unsigned char)tripsaver.whichsprite!=spritewas)) + { + spriteis=tripsaver.whichsprite; + savex=tripsaver.x; savey=tripsaver.y; saveface=tripsaver.face; savestep=tripsaver.step; + + if (wasquick) done(); + + init(spriteis,tripsaver.check_me); + + appear(savex,savey,saveface); tripsaver.step=savestep; + } + + blockread(f,tripsaver.visible,1); + blockread(f,tripsaver.homing,1); + blockread(f,tripsaver.check_me,1); + blockread(f,tripsaver.count,1); + blockread(f,tripsaver.xw,1); + blockread(f,tripsaver.xs,1); blockread(f,tripsaver.ys,1); + blockread(f,tripsaver.totalnum,1); + blockread(f,tripsaver.hx,2); blockread(f,tripsaver.hy,2); + blockread(f,tripsaver.call_eachstep,1); + blockread(f,tripsaver.eachstep,1); + blockread(f,tripsaver.vanishifstill,1); + } + + unload_saver(tripsaver); +} + +triptype* triptype::done() +{ + integer gd,gm; varying_string<2> xx; + byte fv/*,nds*/; + byte aa,bb; + longint id; word soa; + + { + adxtype& with = a; + +/* nds:=num div seq;*/ + xw=with.xl / 8; if ((with.xl % 8)>0) xw += 1; + for( aa=1; aa <= /*nds*seq*/ with.num; aa ++) + { + totalnum -= 1; + freemem(mani[totalnum],with.size-6); + freemem(sil[totalnum],11*(with.yl+1)); /* <<- Width of a siltype. */ + } + } + + quick=false; whichsprite=177; + return this; +} + +getsettype* getsettype::init() +{ + numleft=0; /* initialise array pointer */ + return this; +} + +void getsettype::remember(bytefield r) +{ + numleft += 1; + if (numleft>maxgetset) runerror(runerr_getset_overflow); + gs[numleft]=r; +} + +void getsettype::recall(bytefield& r) +{ + r=gs[numleft]; + numleft -= 1; +} + +void rwsp(byte t,byte r) +{ + { triptype& with = tr[t]; switch (r) { + case up: speed( 0,-with.ys); break; case down: speed( 0, with.ys); break; case left: speed(-with.xs, 0); break; + case right: speed( with.xs, 0); break; case ul: speed(-with.xs,-with.ys); break; case ur: speed( with.xs,-with.ys); break; + case dl: speed(-with.xs, with.ys); break; case dr: speed( with.xs, with.ys); break; + }} +} + +void apped(byte trn,byte np) +{ + { triptype& with = tr[trn]; + { + void& with1 = peds[np]; + + appear(with.x-with.a.xl / 2,with.y-with.a.yl,dir); + rwsp(trn,dir); + }} +} + +void getback(); + +static bytefield r; + + +/* function overlap(x1,y1,x2,y2,x3,y3,x4,y4:word):boolean; + begin { By De Morgan's law: } + overlap:=(x2>=x3) and (x4>=x1) and (y2>=y3) and (y4>=y1); + end;*/ + /* x1,x2 - as bytefield, but *8. y1,y2 - as bytefield. + x3,y3 = mx,my. x4,y4 = mx+16,my+16. */ +static boolean overlaps_with_mouse() +{ + boolean overlaps_with_mouse_result; + overlaps_with_mouse_result= + (x2*8>=mx) && (mx+16>=x1*8) && (y2>=my) && (my+16>=y1); + return overlaps_with_mouse_result; +} + +void getback() +{ + byte fv; + boolean endangered; + + + endangered=false; +/* Super_Off;*/ + + { getsettype& with = getset[1-cp]; + while (with.numleft>0) + { + recall(r); + +/* if overlaps_with_mouse and not endangered then + begin + endangered:=true; + blitfix; + Super_Off; + end;*/ + + mblit(x1,y1,x2,y2,3,1-cp); + }} + + blitfix; + /*if endangered then*/ /*Super_On;*/ +} + +/* Eachstep procedures: */ +void follow_avvy_y(byte tripnum) +{ + { + triptype& with = tr[tripnum]; + + if (tr[1].face==left) return; + if (with.homing) with.hy=tr[1].y; else + { + if (with.y<tr[1].y) + with.y += 1; else + if (with.y>tr[1].y) + with.y -= 1; else + return; + if (with.ix==0) { with.step += 1; if (with.step==with.a.seq) with.step=0; with.count=0; } + } + } +} + +void back_and_forth(byte tripnum) +{ + { triptype& with = tr[tripnum]; + if (! with.homing) + { + if (with.face==right) walkto(4); else walkto(5); + }} +} + +void face_avvy(byte tripnum) +{ + { triptype& with = tr[tripnum]; + if (! with.homing) + { + if (tr[1].x>=with.x) with.face=right; + else with.face=left; + }} +} + +void arrow_procs(byte tripnum) +{ + byte fv; + + { triptype& with = tr[tripnum]; + if (with.homing) + { /* Arrow is still in flight. */ + /* We must check whether or not the arrow has collided with Avvy's head. + This is so if: a) the bottom of the arrow is below Avvy's head, + b) the left of the arrow is left of the right of Avvy's head, and + c) the right of the arrow is right of the left of Avvy's head. */ + if (((with.y+with.a.yl)>=tr[1].y) /* A */ + && (with.x<=(tr[1].x+tr[1].a.xl)) /* B */ + && ((with.x+with.a.xl)>=tr[1].x)) /* C */ + { /* OK, it's hit him... what now? */ + + tr[2].call_eachstep=false; /* prevent recursion. */ + dixi('Q',47); /* Complaint! */ + done(); /* Deallocate the arrow. */ +/* tr[1].done; { Deallocate normal pic of Avvy. } + + off; + for fv:=0 to 1 do + begin + cp:=1-cp; + getback; + end; + on;*/ + + gameover; + + dna.user_moves_avvy=false; /* Stop the user from moving him. */ + set_up_timer(55,procnaughty_duke,reason_naughty_duke); + } + } else /* Arrow has hit the wall! */ + { + done(); /* Deallocate the arrow. */ + show_one(3); /* Show pic of arrow stuck into the door. */ + dna.arrow_in_the_door=true; /* So that we can pick it up. */ + }} +} + +/*procedure Spludwick_procs(tripnum:byte); +var fv:byte; +begin + with tr[tripnum] do + if not homing then { We only need to do anything if Spludwick *stops* + walking. } + with dna do + begin + inc(DogfoodPos); + if DogfoodPos=8 then DogfoodPos:=1; + walkto(DogfoodPos); + end; +end;*/ + +void grab_avvy(byte tripnum) /* For Friar Tuck, in Nottingham. */ +{ + byte fv; integer tox,toy; + + { triptype& with = tr[tripnum]; + { + tox=tr[1].x + 17; + toy=tr[1].y - 1; + if ((with.x==tox) && (with.y==toy)) + { + with.call_eachstep=false; + with.face=left; + stopwalk(); + /* ... whatever ... */ + } else + { /* Still some way to go. */ + if (with.x<tox) + { + with.x += 5; + if (with.x>tox) with.x=tox; + } + if (with.y<toy) with.y += 1; + with.step += 1; if (with.step==with.a.seq) with.step=0; + } + }} +} + +void geida_procs(byte tripnum); + +static void take_a_step(byte& tripnum) +{ + { triptype& with = tr[tripnum]; + if (with.ix==0) + { with.step += 1; if (with.step==with.a.seq) with.step=0; with.count=0; }} +} + + + +static void spin(byte whichway, byte& tripnum) +{ + { triptype& with = tr[tripnum]; + if (with.face!=whichway) + { + with.face=whichway; + if (with.whichsprite==2) return; /* Not for Spludwick */ + + dna.geida_spin += 1; + dna.geida_time=20; + if (dna.geida_spin==5) + { + display("Steady on, Avvy, you'll make the poor girl dizzy!"); + dna.geida_spin=0; dna.geida_time=0; /* knock out records */ + } + }} +} + +void geida_procs(byte tripnum) +{ + { + triptype& with = tr[tripnum]; + + if (dna.geida_time>0) + { + dna.geida_time -= 1; + if (dna.geida_time==0) dna.geida_spin=0; + } + + if (with.y<(tr[1].y-2)) + { /* Geida is further from the screen than Avvy. */ + spin(down, tripnum); + with.iy=1; with.ix=0; + take_a_step(tripnum); + return; + } else + if (with.y>(tr[1].y+2)) + { /* Avvy is further from the screen than Geida. */ + spin(up, tripnum); + with.iy=-1; with.ix=0; + take_a_step(tripnum); + return; + } + + with.iy=0; + if (with.x<tr[1].x-tr[1].xs*8) + { + with.ix=tr[1].xs; + spin(right, tripnum); + take_a_step(tripnum); + } else + if (with.x>tr[1].x+tr[1].xs*8) + { + with.ix=-tr[1].xs; + spin(left, tripnum); + take_a_step(tripnum); + } else with.ix=0; + } +} + +/* That's all... */ + +void call_andexors() +{ + array<1,5,byte> order; + byte fv,temp; + boolean ok; + + fillchar(order,5,'\0'); + for( fv=1; fv <= numtr; fv ++) { triptype& with = tr[fv]; + if (with.quick && with.visible) + order[fv]=fv;} + + do { + ok=true; + for( fv=1; fv <= 4; fv ++) + if (((order[fv]!=0) && (order[fv+1]!=0)) + && (tr[order[fv]].y>tr[order[fv+1]].y)) + { /* Swap them! */ + temp=order[fv]; + order[fv]=order[fv+1]; + order[fv+1]=temp; + ok=false; + } + } while (!ok); + + for( fv=1; fv <= 5; fv ++) + if (order[fv]>0) + tr[order[fv]].andexor(); +} + +void trippancy_link() +{ + byte fv; + + if (ddmnow | ontoolbar | seescroll) return; + for( fv=1; fv <= numtr; fv ++) { triptype& with = tr[fv]; if (with.quick) walk();} + call_andexors(); + for( fv=1; fv <= numtr; fv ++) { triptype& with = tr[fv]; + if (with.quick && with.call_eachstep) + { + switch (tr[fv].eachstep) { + case procfollow_avvy_y : follow_avvy_y(fv); break; + case procback_and_forth : back_and_forth(fv); break; + case procface_avvy : face_avvy(fv); break; + case procarrow_procs : arrow_procs(fv); break; +/* PROCSpludwick_procs : spludwick_procs(fv);*/ + case procgrab_avvy : grab_avvy(fv); break; + case procgeida_procs : geida_procs(fv); break; + } + }} + if (mustexclaim) + { + mustexclaim=false; + dixi('x',saywhat); + } +} + +void get_back_loretta() +{ + byte fv; + +/* for fv:=1 to numtr do with tr[fv] do if quick then getback;*/ + for( fv=1; fv <= numtr; fv ++) if (tr[fv].quick) + { + getback(); + return; + } +/* for fv:=0 to 1 do begin cp:=1-cp; getback; end;*/ +} + +void stopwalking() +{ + tr[1].stopwalk(); dna.rw=stopped; if (alive) tr[1].step=1; +} + +void tripkey(char dir) +{ + if ((ctrl==cjoy) | (~ dna.user_moves_avvy)) return; + + { triptype& with = tr[1]; + { + switch (dir) { + case 'H': if (rw!=up) + { rw=up; rwsp(1,rw); } else stopwalking(); + break; + case 'P': if (rw!=down) + { rw=down; rwsp(1,rw); } else stopwalking(); + break; + case 'K': if (rw!=left) + { rw=left; rwsp(1,rw); } else stopwalking(); + break; + case 'M': if (rw!=right) + { rw=right; rwsp(1,rw); } else stopwalking(); + break; + case 'I': if (rw!=ur) + { rw=ur; rwsp(1,rw); } else stopwalking(); + break; + case 'Q': if (rw!=dr) + { rw=dr; rwsp(1,rw); } else stopwalking(); + break; + case 'O': if (rw!=dl) + { rw=dl; rwsp(1,rw); } else stopwalking(); + break; + case 'G': if (rw!=ul) + { rw=ul; rwsp(1,rw); } else stopwalking(); + break; + case 'L': stopwalking(); break; + } + }} +} + +void readstick() +{ + byte jw; + + if (ctrl==ckey) return; + + jw=joyway; + + { + triptype& with = tr[1]; + + if (jw==stopped) stopwalking(); else + { + dna.rw=jw; rwsp(1,dna.rw); + } + } + + if (jw!=oldjw) + { + showrw; + oldjw=jw; + } + +} + +void getsetclear() +{ + byte fv; + + for( fv=0; fv <= 1; fv ++) getset[fv].init(); +} + +void hide_in_the_cupboard() +{ + const char nowt = '\372'; /* As in Acci. */ + + { + if (avvys_in_the_cupboard) + { + if (wearing==nowt) + display("\6AVVY!\22 Get dressed first!"); + else + { + tr[1].visible=true; + user_moves_avvy=true; + apped(1,3); /* Walk out of the cupboard. */ + display("You leave the cupboard. Nice to be out of there!"); + avvys_in_the_cupboard=false; + first_show(8); then_show(7); start_to_close; + } + } else + { /* Not hiding in the cupboard */ + tr[1].visible=false; + user_moves_avvy=false; + display(string("You walk into the room...\20It seems to be an empty, ")+ + "but dusty, cupboard. Hmmmm... you leave the door slightly open to "+ + "avoid suffocation."); + avvys_in_the_cupboard=true; + show_one(8); + } + } +} + +void fliproom(byte room,byte ped); +static integer beforex,beforey; +static void tidy_after_mouse(); + + +static void tidy_up(integer a,integer b,integer c,integer d) +{ + bytefield bf; + + { + x1=a / 8; + y1=b; + x2=(c+7) / 8; + y2=d; + setactivepage(0); + rectangle(x1*8,y1,x2*8+7,y2); + } + getset[0].remember(bf); + getset[1].remember(bf); +} + + + +static void tidy_after_mouse() +{ + tidy_up(beforex,beforey,beforex+15,beforey+15); + xycheck; + tidy_up(mx,my,mx+15,my+15); +} + +void fliproom(byte room,byte ped) +{ + byte fv; + + + if (~ alive) + { /* You can't leave the room if you're dead. */ + tr[1].ix=0; tr[1].iy=0; /* Stop him from moving. */ + return; + } + + if ((ped==177) && (dna.room==r__lusties)) + { + hide_in_the_cupboard(); + return; + } + + if ((dna.jumpstatus>0) && (dna.room==r__insidecardiffcastle)) + { /* You can't *jump* out of Cardiff Castle! */ + tr[1].ix=0; + return; + } + + xycheck; beforex=mx; beforey=my; + + exitroom(dna.room); + dusk; getsetclear(); + + + for( fv=2; fv <= numtr; fv ++) + { triptype& with = tr[fv]; + if (with.quick) done();} /* Deallocate sprite */ + + if (dna.room==r__lustiesroom) + dna.enter_catacombs_from_lusties_room=true; + + enterroom(room,ped); apped(1,ped); + dna.enter_catacombs_from_lusties_room=false; + oldrw=dna.rw; dna.rw=tr[1].face; showrw; + + for( fv=0; fv <= 1; fv ++) + { + cp=1-cp; + getback(); + } + dawn; + + /* Tidy up after mouse. I know it's a kludge... */ +/* tidy_after_mouse;*/ +} + +boolean infield(byte which) + /* returns True if you're within field "which" */ +{ + integer yy; + + boolean infield_result; + { void& with = fields[which]; { + triptype& with = tr[1]; + + yy=with.y+with.a.yl; + infield_result=(with.x>=x1) && (with.x<=x2) && (yy>=y1) && (yy<=y2); + }} + return infield_result; +} + +boolean neardoor() /* returns True if you're near a door! */ +{ + integer ux,uy; byte fv; boolean nd; + + boolean neardoor_result; + if (numfields<9) + { /* there ARE no doors here! */ + neardoor_result=false; + return neardoor_result; + } + { + triptype& with = tr[1]; + + ux=with.x; + uy=with.y+with.a.yl; + } nd=false; + for( fv=9; fv <= numfields; fv ++) + { + void& with = fields[fv]; + + if ((ux>=x1) && (ux<=x2) && (uy>=y1) && (uy<=y2)) nd=true; + } + neardoor_result=nd; + return neardoor_result; +} + +void new_game_for_trippancy() /* Called by gyro.newgame */ +{ + tr[1].visible=false; +} + +void triptype::save_data_to_mem(word& where) +{ + trip_saver_type tripsaver; + + set_up_saver(tripsaver); + move(tripsaver,mem[storage_seg*where],sizeof(tripsaver)); + where += sizeof(tripsaver); +} + +void triptype::load_data_from_mem(word& where) +{ + word spritewas,spriteis,saveface,savex,savey,savestep; + boolean wasquick; + trip_saver_type tripsaver; + + move(mem[storage_seg*where],tripsaver,sizeof(tripsaver)); + where += sizeof(tripsaver); + unload_saver(tripsaver); + + spriteis=whichsprite; + savex=x; savey=y; saveface=face; savestep=step; + + init(spriteis,check_me); + + appear(savex,savey,saveface); unload_saver(tripsaver); + step=savestep; +} + +class unit_trip5_initialize { + public: unit_trip5_initialize(); +}; +static unit_trip5_initialize trip5_constructor; + +unit_trip5_initialize::unit_trip5_initialize() { + getsetclear(); mustexclaim=false; +} diff --git a/engines/avalanche/trip5.h b/engines/avalanche/trip5.h new file mode 100644 index 0000000000..9e7b3a33bc --- /dev/null +++ b/engines/avalanche/trip5.h @@ -0,0 +1,175 @@ +#ifndef __trip5_h__ +#define __trip5_h__ + + +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Gyro.h"*/ +/*#include "Sticks.h"*/ + + +const integer maxgetset = 35; + +typedef array<5,2053,byte> manitype; + +typedef matrix<0,50,0,10,byte> siltype; /* 35, 4 */ + +struct adxtype { /* Second revision of ADX type */ + varying_string<12> name; /* name of character */ + varying_string<16> comment; /* comment */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ + byte accinum; /* the number according to Acci (1=Avvy, etc.) */ +}; + +struct trip_saver_type { + byte whichsprite; + byte face; byte step; + integer x; integer y; + shortint ix; shortint iy; + boolean visible; + boolean homing; + boolean check_me; + byte count; + byte xw,xs,ys; + byte totalnum; + integer hx; integer hy; + boolean call_eachstep; + byte eachstep; + boolean vanishifstill; +}; + +class triptype { +public: + adxtype a; /* vital statistics */ + byte face,step; + integer x,y; /* current xy coords */ + array<0,1,integer> ox,oy; /* last xy coords */ + shortint ix,iy; /* amount to move sprite by, each step */ + array<1,24,manitype*> mani; + array<1,24,siltype*> sil; + byte whichsprite; + boolean quick,visible,homing,check_me; + integer hx,hy; /* homing x & y coords */ + byte count; /* counts before changing step */ + byte xw; /* x-width in bytes */ + byte xs,ys; /* x & y speed */ + byte totalnum; /* total number of sprites */ + boolean vanishifstill; /* Do we show this sprite if it's still? */ + + boolean call_eachstep; /* Do we call the eachstep procedure? */ + byte eachstep; + + triptype* init(byte spritenum, boolean do_check); + /* loads & sets up the sprite */ + void original(); /* just sets Quick to false */ + void andexor(); /* drops sprite onto screen */ + void turn(byte whichway); /* turns him round */ + void appear(integer wx,integer wy, byte wf); /* switches him on */ + void bounce(); /* bounces off walls. */ + void walk(); /* prepares for andexor, etc. */ + void walkto(byte pednum); /* home in on a point */ + void stophoming(); /* self-explanatory */ + void homestep(); /* calculates ix & iy for one homing step */ + void speed(shortint xx,shortint yy); /* sets ix & iy, non-homing, etc */ + void stopwalk(); /* Stops the sprite from moving */ + void chatter(); /* Sets up talk vars */ + void set_up_saver(trip_saver_type& v); + void unload_saver(trip_saver_type v); + void savedata(untyped_file& f); /* Self-explanatory, */ + void loaddata(untyped_file& f); /* really. */ + void save_data_to_mem(word& where); + void load_data_from_mem(word& where); + triptype* done(); +}; + +class getsettype { +public: + array<1,maxgetset,bytefield> gs; + byte numleft; + + getsettype* init(); + void remember(bytefield r); + void recall(bytefield& r); +}; + + +const integer up = 0; +const integer right = 1; +const integer down = 2; +const integer left = 3; +const integer ur = 4; const integer dr = 5; const integer dl = 6; const integer ul = 7; +const integer stopped = 8; + +const integer numtr = 5; /* current max no. of sprites */ + + + +const integer procfollow_avvy_y = 1; + +const integer procback_and_forth = 2; + +const integer procface_avvy = 3; + +const integer procarrow_procs = 4; + +const integer procspludwick_procs = 5; + +const integer procgrab_avvy = 6; + +const integer procgeida_procs = 7; + + +void trippancy_link(); + +void get_back_loretta(); + +void loadtrip(); + +void call_special(word which); + +void open_the_door(byte whither,byte ped,byte magicnum); /* Handles slidey-open doors. */ + +void catamove(byte ped); + +void stopwalking(); + +void tripkey(char dir); + +void rwsp(byte t,byte r); + +void apped(byte trn,byte np); + +void getback(); + +void fliproom(byte room,byte ped); + +boolean infield(byte which); /* returns True if you're within field "which" */ + +boolean neardoor(); /* returns True if you're near a door! */ + +void readstick(); + +void newspeed(); + +void new_game_for_trippancy(); + + +#ifdef __trip5_implementation__ +#undef EXTERN +#define EXTERN +#endif + +EXTERN array<1,numtr,triptype> tr; +EXTERN array<0,1,getsettype> getset; +EXTERN array<1,16000,byte> aa; + +EXTERN boolean mustexclaim; EXTERN word saywhat; +#undef EXTERN +#define EXTERN extern + + +#endif diff --git a/engines/avalanche/trip5tst.cpp b/engines/avalanche/trip5tst.cpp new file mode 100644 index 0000000000..4b95ff4437 --- /dev/null +++ b/engines/avalanche/trip5tst.cpp @@ -0,0 +1,135 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + +/*$R+*/ + +struct adxtype { + varying_string<12> name; /* name of character */ + varying_string<16> comment; /* comment */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +integer gd,gm; +untyped_file inf; +adxtype a; +array<1,16000,byte> aa; +array<5,2053,byte> mani; +matrix<0,35,0,4,byte> sil; +byte xw; + +void filesetup() +{ + const integer idshould = -1317732048; + longint id; + word soa; +; + assign(inf,"v:sprite2.avd"); + reset(inf,1); + seek(inf,177); + blockread(inf,id,4); + if (id!=idshould) + {; + output << '\7'; + close(inf); + exit(0); + } + + blockread(inf,soa,2); + blockread(inf,a,soa); +} + +void loadpic() +{ + byte fv,ff; +; + {; + xw=a.xl / 8; if ((a.xl % 8)>0) xw += 1; + +/* aa[1]:=xl; aa[2]:=0; aa[3]:=yl; aa[4]:=0;*/ + /* The putimage x&y codes are words but xl & yl are bytes, hence the #0s. */ +/* seek(inf,filepos(inf)+xw*(yl+1));*/ + for( fv=0; fv <= a.yl; fv ++) + blockread(inf,sil[fv],xw); + blockread(inf,mani,a.size-6); +/* blockread(inf,aa[5+fv*xw*4+xw*ff],xw);*/ + aa[a.size-1]=0; aa[a.size]=0; /* footer */ + } +/* putimage(0,0,aa,0);*/ +} + +void plotone(integer xx,integer yy) +{ + word s; + word ofs,fv; + byte x,y,z; +; + {; + s=imagesize(x,y,xx+a.xl,yy+a.yl); + getimage(xx,yy,xx+a.xl,yy+a.yl,aa); /* Now loaded into our local buffer. */ + + /* Now we've got to modify it! */ + + for( x=0; x <= 3; x ++) + for( y=0; y <= 35; y ++) + for( z=0; z <= 4; z ++) + {; + ofs=5+y*xw*4+xw*x+z; + aa[ofs]=aa[ofs] & sil[y][z]; + } + + /* mov ax,5 ; AX = ofs + mov bx,xw ; wherever we get xw from + mov cx,x ; ditto + mov dx,y ; ditto + mul cx,bx ; x*xw + mul dx,bx ; y*yw + add ax,cx ; now add 'em all up + add ax,dx ; ... + mov bx,z ; get z (we don't need x any more) + mov cx,syz ; get silyz (where from??!) + add ax,bx ; add on the last part of the addition + and ax,cx ; AND ax with cx. That's it! */ + +/* + for x:=1 to 4 do + begin; + for y:=0 to 35 do + for z:=0 to 4 do + begin; + ofs:=5+y*xw*4+xw*x+z; + aa[ofs]:=aa[ofs] xor pic[x,y,z]; + end; + end; +*/ + + for( fv=5; fv <= a.size-2; fv ++) + aa[fv]=aa[fv] ^ mani[fv]; + + /* Now.. let's try pasting it back again! */ + + putimage(xx,yy,aa,0); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + initgraph(gd,gm,""); + setfillstyle(6,1); bar(0,0,640,200); + filesetup(); + for( gd=1; gd <= 9; gd ++) loadpic(); + do { + plotone(Random(500),Random(150)); + } while (!keypressed()); + plotone(0,0); + close(inf); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/trip5xf.cpp b/engines/avalanche/trip5xf.cpp new file mode 100644 index 0000000000..0aa5f32ae2 --- /dev/null +++ b/engines/avalanche/trip5xf.cpp @@ -0,0 +1,172 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + + +const string crlf = string('\15')+'\12'; const char eof_ = '\32'; +const array<1,177,char> trip5head = + string("Sprite*.AVD ... data file for Trippancy Five")+crlf+crlf+ + "[Thorsoft relocatable fiveplane sprite image format]"+crlf+crlf+ + "Thomas Thurman was here. ... Have fun!"+crlf+crlf+eof_+ + "±±±±±±± * G. I. E. D. ! * "; + +const array<1,4,char> tripid = string('\x30')+'\x1'+'\x75'+'\261'; + +const array<1,50,char> trip5foot = crlf+crlf+ + " and that's it! Enjoy the game. "+'\3'+crlf+crlf+ + "\n\n\n\n\n\n\n"+"tt"; + +struct adxotype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +struct adxtype { + varying_string<12> name; /* name of character */ + varying_string<16> comment; /* comment */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +varying_string<2> sn; +adxotype oa; +adxtype a; +matrix<1,24,0,1,pointer> pic; /* the pictures themselves */ +array<1,16000,byte> aa; +untyped_file out; +integer bigsize; + +void copyaoa() +{; + {; + a.name=oa.name; + a.comment="Transferred"; + a.num=oa.num; + a.xl=oa.xl; + a.yl=oa.yl; + a.seq=oa.seq; + a.size=oa.size; + a.fgc=oa.fgc; + a.bgc=oa.bgc; + } +} + +void load() +{ + untyped_file f; byte gd,gm,sort,n; pointer p,q; + pointer xf; +; + assign(f,string("v:osprte")+sn+".avd"); reset(f,1); seek(f,59); + blockread(f,oa,sizeof(oa)); blockread(f,bigsize,2); + copyaoa(); + + getmem(xf,a.size); + + for( sort=0; sort <= 1; sort ++) + {; + mark(q); getmem(p,bigsize); + blockread(f,p,bigsize); + putimage(0,0,p,0); release(q); n=1; + + if (sort==0) setfillstyle(1,15); else setfillstyle(1,0); + bar(177,125,300,200); + + for( gm=0; gm <= (a.num / a.seq)-1; gm ++) /* directions */ + for( gd=0; gd <= a.seq-1; gd ++) /* steps */ + {; + getmem(pic[n][sort],a.size); /* grab the memory */ + getimage((gm / 2)*(a.xl*6)+gd*a.xl,(gm % 2)*a.yl, + (gm / 2)*(a.xl*6)+gd*a.xl+a.xl-1,(gm % 2)*a.yl+a.yl-1, + xf); + putimage(177,125,xf,0); + getimage(177,125,177+a.xl,125+a.yl,pic[n][sort]); /* grab the pic */ + n += 1; + } + } + close(f); + freemem(xf,a.size); + cleardevice(); + for( gm=0; gm <= 1; gm ++) + for( gd=1; gd <= a.num; gd ++) + putimage(gd*15,gm*40,pic[gd][gm],0); +} + +void setup() +{ + integer gd,gm; +; + output << "TRIP5XF (c) 1992, Thomas Thurman." << NL; output << NL; + output << "Enter number of SPRITE*.AVD file to convert:"; input >> sn >> NL; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + load(); +} + +string strf(longint x) +{ + string q; +string strf_result; +; + str(x,q); strf_result=q; +return strf_result; +} + +void save() +{ + byte sort,n; + word fv,ff; char r; byte xw; + byte nxl,nyl; + word soa; +; + cleardevice(); + {; + a.size=imagesize(0,0,a.xl,a.yl); + soa=sizeof(a); + + assign(out,string("v:sprite")+sn+".avd"); rewrite(out,1); + blockwrite(out,trip5head,177); + blockwrite(out,tripid,4); + blockwrite(out,soa,2); + blockwrite(out,a,soa); + + nxl=a.xl; nyl=a.yl; + xw=nxl / 8; + if ((nxl % 8)>0) xw += 1; + + for( n=1; n <= a.num; n ++) + {; + putimage( 0,0,pic[n][0],0); + getimage( 0,0,a.xl,a.yl,aa); + for( fv=0; fv <= nyl; fv ++) + blockwrite(out,aa[5+fv*xw*4],xw); + + putimage(100,0,pic[n][1],0); + getimage(100,0,100+a.xl,a.yl,aa); + putimage(100,100,aa,4); +/* for ff:=1 to 4 do { actually 2 to 5, but it doesn't matter here } + for fv:=0 to nyl do*/ +/* for ff:=5 to size-2 do + blockwrite(out,aa[ff],1);*/ + blockwrite(out,aa[5],a.size-6); + } + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + setup(); + save(); + + blockwrite(out,trip5foot,50); + close(out); +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/tripoop.cpp b/engines/avalanche/tripoop.cpp new file mode 100644 index 0000000000..15035c864d --- /dev/null +++ b/engines/avalanche/tripoop.cpp @@ -0,0 +1,290 @@ +#include "ptoc.h" + + /* Trip Oop (Trippancy 4 Andexor */ +#include "graph.h" +/*#include "Crt.h"*/ + + +const integer up = 0; +const integer right = 1; +const integer down = 2; +const integer left = 3; + +const integer numtr = 1; /* current max no. of sprites */ + +struct adxtype { + varying_string<12> name; /* name of character */ + byte num; /* number of pictures */ + byte xl,yl; /* x & y lengths of pictures */ + byte seq; /* how many in one stride */ + word size; /* the size of one picture */ + byte fgc,bgc; /* foreground & background bubble colours */ +}; + +class triptype { +public: + adxtype a; /* vital statistics */ + byte face,step; + integer x,y; /* current xy coords */ + integer ox,oy; /* last xy coords */ + integer tax,tay; /* "behind" taken at... */ + shortint ix,iy; /* amount to move sprite by, each step */ + matrix<1,24,0,1,pointer> pic; /* the pictures themselves */ + boolean quick,visible,homing; + pointer behind; /* what's behind you */ + integer hx,hy; /* homing x & y coords */ + + triptype* init(byte spritenum); /* loads & sets up the sprite */ + void original(); /* just sets Quick to false */ + void andexor(); /* drops sprite onto screen 1 */ + void turn(byte whichway); /* turns him round */ + void appear(integer wx,integer wy, byte wf); /* switches him on */ + void walk(); /* prepares for do_it, andexor, etc. */ + void do_it(); /* Actually copies the picture over */ + void getback(); /* gets background before sprite is drawn */ + void putback(); /* ...and wipes sprite from screen 1 */ + void walkto(integer xx,integer yy); /* home in on a point */ + void stophoming(); /* self-explanatory */ + void homestep(); /* calculates ix & iy for one homing step */ + void speed(shortint xx,shortint yy); /* sets ix & iy, non-homing, etc */ + void halt(); /* Stops the sprite from moving */ +}; + +integer gd,gm; +array<1,1,triptype> tr; + +void copier(integer x1,integer y1,integer x2,integer y2,integer x3,integer y3,integer x4,integer y4); + + +static boolean dropin(integer xc,integer yc,integer x1,integer y1,integer x2,integer y2) +/* Dropin returns True if the point xc,yc falls within the 1-2 rectangle. */ +{boolean dropin_result; +; + dropin_result=((xc>=x1) && (xc<=x2) && (yc>=y1) && (yc<=y2)); +return dropin_result; +} + + + +static void transfer(integer x1,integer y1,integer x2,integer y2) +{ + pointer p,q; word s; +; + s=imagesize(x1,y1,x2,y2); setfillstyle(1,0); + mark(q); getmem(p,s); + setactivepage(1); getimage(x1,y1,x2,y2,p); + setactivepage(0); putimage(x1,y1,p,copyput); + setactivepage(1); release(q); +} + + + +static integer lesser(integer a,integer b) +{integer lesser_result; +; + if (a<b) lesser_result=a; else lesser_result=b; +return lesser_result; +} + + + +static integer greater(integer a,integer b) +{integer greater_result; +; + if (a>b) greater_result=a; else greater_result=b; +return greater_result; +} + +void copier(integer x1,integer y1,integer x2,integer y2,integer x3,integer y3,integer x4,integer y4) + +{; + if (dropin(x3,y3,x1,y1,x2,y2) + || dropin(x3,y4,x1,y1,x2,y2) + || dropin(x4,y3,x1,y1,x2,y2) + || dropin(x4,y4,x1,y1,x2,y2)) + {; /* Overlaps */ + transfer(lesser(x1,x3),lesser(y1,y3),greater(x2,x4),greater(y2,y4)); + } else + {; /* Doesn't overlap- copy both of them seperately */ + transfer(x3,y3,x4,y4); /* backwards- why not...? */ + transfer(x1,y1,x2,y2); + } +} + +void setup() +{ + integer gd,gm; +; + gd=3; gm=0; initgraph(gd,gm,""); + for( gd=0; gd <= 1; gd ++) + {; + setactivepage(gd); + setfillstyle(9,1); bar(0,0,640,200); + } + for( gm=1; gm <= numtr; gm ++) tr[gm].original(); +} + +triptype* triptype::init(byte spritenum) +{ + integer gd,gm; word s; untyped_file f; varying_string<2> xx; pointer p,q; word bigsize; + byte sort,n; +; + str(spritenum,xx); assign(f,string("v:sprite")+xx+".avd"); + reset(f,1); seek(f,59); + blockread(f,a,sizeof(a)); blockread(f,bigsize,2); + setvisualpage(3); setactivepage(3); + for( sort=0; sort <= 1; sort ++) + {; + mark(q); getmem(p,bigsize); + blockread(f,p,bigsize); + putimage(0,0,p,0); release(q); n=1; + { adxtype& with = a; + for( gm=0; gm <= (with.num / with.seq)-1; gm ++) /* directions */ + for( gd=0; gd <= with.seq-1; gd ++) /* steps */ + {; + getmem(pic[n][sort],a.size); /* grab the memory */ + getimage((gm / 2)*(with.xl*6)+gd*with.xl,(gm % 2)*with.yl, + (gm / 2)*(with.xl*6)+gd*with.xl+with.xl-1,(gm % 2)*with.yl+with.yl-1, + pic[n][sort]); /* grab the pic */ + putimage((gm / 2)*(with.xl*6)+gd*with.xl,(gm % 2)*with.yl, + pic[n][sort],notput); /* test the pic */ + n += 1; + }} + } + close(f); setactivepage(0); setvisualpage(0); + x=0; y=0; quick=true; visible=false; getmem(behind,a.size); + homing=false; ix=0; iy=0; +return this; +} + +void triptype::original() +{; + quick=false; +} + +void triptype::getback() +{; + tax=x; tay=y; + getimage(x,y,x+a.xl,y+a.yl,behind); +} + +void triptype::andexor() +{ + byte picnum; /* Picnum, Picnic, what ye heck */ +; + picnum=face*a.seq+step+1; + putimage(x,y,pic[picnum][0],andput); + putimage(x,y,pic[picnum][1],xorput); +} + +void triptype::turn(byte whichway) +{; + face=whichway; step=0; +} + +void triptype::appear(integer wx,integer wy, byte wf) +{; + x=wx; y=wy; ox=wx; oy=wy; turn(wf); visible=true; +} + +void triptype::walk() +{; + ox=x; oy=y; + if (homing) homestep(); + x=x+ix; y=y+iy; + step += 1; if (step==a.seq) step=0; getback(); +} + +void triptype::do_it() +{; + copier(ox,oy,ox+a.xl,oy+a.yl,x,y,x+a.xl,y+a.yl); +} + +void triptype::putback() +{; + putimage(tax,tay,behind,0); +} + +void triptype::walkto(integer xx,integer yy) +{; + speed(xx-x,yy-y); hx=xx; hy=yy; homing=true; +} + +void triptype::stophoming() +{; + homing=false; +} + +void triptype::homestep() +{ + integer temp; +; + if ((hx==x) && (hy==y)) + {; /* touching the target */ + homing=false; return; + } + ix=0; iy=0; + if (hy!=y) + {; + temp=hy-y; if (temp>4) iy=4; else if (temp<-4) iy=-4; else iy=temp; + } + if (hx!=x) + {; + temp=hx-x; if (temp>4) ix=4; else if (temp<-4) ix=-4; else ix=temp; + } +} + +void triptype::speed(shortint xx,shortint yy) +{; + ix=xx; iy=yy; + if ((ix==0) && (iy==0)) return; /* no movement */ + if (ix==0) + {; /* No horz movement */ + if (iy<0) turn(up); else turn(down); + } else + {; + if (ix<0) turn(left); else turn(right); + } +} + +void triptype::halt() +{; + ix=0; iy=0; homing=false; +} + +void trip() +{ + byte fv; +; + for( fv=1; fv <= numtr; fv ++) + { + triptype& with = tr[fv]; + ; + walk(); + if (with.quick && with.visible) andexor(); + do_it(); + putback(); + } +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + setup(); + { + triptype& with = tr[1]; + ; + init(1); + appear(600,100,left); + do { + /* + speed(-5,0); repeat trip until keypressed or (x= 0); + speed( 5,0); repeat trip until keypressed or (x=600); + */ + walkto( 10, 10); do { trip(); } while (!(keypressed() || ! with.homing)); + walkto( 70,150); do { trip(); } while (!(keypressed() || ! with.homing)); + walkto(600, 77); do { trip(); } while (!(keypressed() || ! with.homing)); + } while (!keypressed()); + } +return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/ttmenuxf.cpp b/engines/avalanche/ttmenuxf.cpp new file mode 100644 index 0000000000..51903e948b --- /dev/null +++ b/engines/avalanche/ttmenuxf.cpp @@ -0,0 +1,112 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Tommys.h"*/ +/*#include "Crt.h"*/ + +integer gd,gm; +word s; pointer p; +file<byte> f; +byte bit; + +void load() /* Load2, actually */ +{ + byte a0; /*absolute $A000:800;*/ + byte a1; /*absolute $A000:17184;*/ + byte bit; + untyped_file f; varying_string<2> xx; + boolean was_virtual; + + assign(f,"v:ttmenu.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + bit=getpixel(0,0); +} + +void finder() +{ + char r; integer x,y; +; + setfillstyle(0,0); setcolor(14); + x=320; y=100; setwritemode(xorput); + do { + bar(0,0,200,10); + outtextxy(0,0,strf(x)+','+strf(y)); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + do {; } while (!keypressed()); + line(x-20,y,x+20,y); line(x,y-20,x,y+20); + switch (readkey()) { + case '\15': return; break; + case '8': y -= 10; break; + case '4': x -= 10; break; + case '6': x += 10; break; + case '2': y += 10; break; + case '\0': switch (readkey()) { + case cup: y -= 1; break; + case cdown: y += 1; break; + case cleft: x -= 1; break; + case cright: x += 1; break; + } + break; + } + } while (!false); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + gd=3; gm=1; initgraph(gd,gm,""); + load(); + finder(); + s=imagesize(342,21,407,119); + getmem(p,s); + getimage(342,21,407,119,p); + putimage(342,21,p,4); + input >> NL; + putimage(264,120,p,0); + input >> NL; + freemem(p,s); + + s=imagesize(264,12,329,217); + getmem(p,s); + getimage(264,21,329,218,p); + putimage(264,21,p,4); + putimage(0,0,p,0); + freemem(p,s); + input >> NL; + + s=imagesize(180,103,188,135); + getmem(p,s); + getimage(180,103,188,135,p); + putimage(0,200,p,0); + input >> NL; + + assign(f,"v:menu.avd"); + rewrite(f); + + for( bit=0; bit <= 3; bit ++) + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( gd=0; gd <= 196; gd ++) + for( gm=0; gm <= 8; gm ++) + { + f << mem[0xa000*gd*80+gm]; + mem[0xa000*gd*80+gm]=~ mem[0xa000*gd*80+gm]; + } + + for( gd=200; gd <= 232; gd ++) + { + f << mem[0xa000*gd*80]; + mem[0xa000*gd*80]=~ mem[0xa000*gd*80]; + } + } + + close(f); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/unsquish.cpp b/engines/avalanche/unsquish.cpp new file mode 100644 index 0000000000..ad8bd58ace --- /dev/null +++ b/engines/avalanche/unsquish.cpp @@ -0,0 +1,524 @@ +#include "ptoc.h" + + /*$S-*/ +#include "graph.h" + + +typedef array<1,50000,byte> buffertype; + +integer gd,gm; +varying_string<29> describe; +byte method; +shortint bit; +word offset; +byte a0; /*absolute $A000:800;*/ +array<1,12080,byte> a7; /*absolute $A000:800;*/ +buffertype* buffer; +word bufsize; + +void putup(byte what) +{; + if (offset>12080) + {; + bit += 1; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + offset=1; + } + + a7[offset]=what; + offset += 1; +} + +void load_uncomp(string xx) /* Load2, actually */ +/* a1:byte absolute $A000:17184;*/ +{ + byte this_; + untyped_file f; + word place; +; + assign(f,string("v:place")+xx+".avd"); reset(f,1); seek(f,146); + blockread(f,describe,30); blockread(f,method,1); + bufsize=filesize(f)-177; blockread(f,*buffer,bufsize); + close(f); + + bit=-1; offset=12081; place=1; + + while (place<=bufsize) + {; + this_=(*buffer)[place]; + place += 1; + putup(this_); + } + + output << method << " : \"" << describe << '"' << NL; +} + +void load_comp(string xx); + +const integer maxtab = 4095 /* Table size - 1 ==> 2**10-1 ==> 12 bits */; + +const integer no_prev = -1 /* Special code for no previous character */; + +const integer end_list = -1 /* Marks end of a list */; + +const integer maxstack = 4096 /* Decompression stack size */; + + + + + /* One node in parsing table. */ +struct string_table_entry { + boolean unused /* Is this node *NOT* used yet?*/; + integer prevchar /* Code for preceding string */; + integer follchar /* Code for current character */; + integer next /* Next dupl in collision list */; +}; + + + +typedef array<0,maxtab,string_table_entry> sttype; + + + /* String table */ + +static sttype* string_table; + + +static integer table_used /* # string table entries used */; + +static byte input_code /* Input compressed code */; + +static boolean inempty,popempty; + + /* Decompression stack */ + +static array<1,maxstack,byte> stack; + + +static integer stack_pointer /* Decompression stack depth */; + +static word place; + + +static integer get_hash_code( integer& prevc, integer& follc ) + +{ + integer index; + integer index2; + + /* Get_Hash_Code */ + /* Get initial index using hashing */ + + integer get_hash_code_result; + index = ( ( prevc << 5 ) ^ follc ) & maxtab; + + /* If entry not already used, return */ + /* its index as hash code for <w>C. */ + + if ( (*string_table)[index].unused ) + get_hash_code_result = index; + else + /* If entry already used, search to */ + /* end of list of hash collision */ + /* entries for this hash code. */ + /* Do linear probe to find an */ + /* available slot. */ + { + + /* Skip to end of collision list ... */ + + while ( (*string_table)[index].next != end_list ) + index = (*string_table)[index].next; + + /* Begin linear probe down a bit from */ + /* last entry in collision list ... */ + + index2 = ( index + 101 ) & maxtab; + + /* Look for unused entry using linear */ + /* probing ... */ + + while ( ! (*string_table)[index2].unused ) + index2 = succ(integer, index2 ) & maxtab; + + /* Point prior end of collision list */ + /* to this new node. */ + + (*string_table)[index].next = index2; + + /* Return hash code for <w>C */ + + get_hash_code_result = index2; + + } + + return get_hash_code_result; +} /* Get_Hash_Code */ + + + + /*--------------------------------------------------------------------------*/ + /* Make_Table_Entry --- Enter <w>C string in string table */ + /*--------------------------------------------------------------------------*/ + +static void make_table_entry( integer& prevc, integer& follc ) + +{ /* Make_Table_Entry */ + /* Only enter string if there is room left */ + + if ( table_used <= maxtab ) + { + { + string_table_entry& with = (*string_table)[ get_hash_code( prevc , follc ) ]; + + with.unused = false; + with.next = end_list; + with.prevchar = prevc; + with.follchar = follc; + } + /* Increment count of items used */ + + table_used += 1; +/* + IF ( Table_Used > ( MaxTab + 1 ) ) THEN + BEGIN + WRITELN('Hash table full.'); + END; + */ + } + +} /* Make_Table_Entry */ + + + +static void firstentries() +/* This is just a fast version of the above, when PrevC = No_Prev. TT. */ + +{ + integer i,j; + + + /* There MUST be room- we've only just started! */ + + j=no_prev; + + for( i=0; i <= 255; i ++) + { + string_table_entry& with = (*string_table)[ ((no_prev << 5 ) ^ i) & maxtab]; + + with.unused = false; + with.next = end_list; + with.prevchar = no_prev; + with.follchar = i; + } + + table_used += 256; /* Increment count of items used */ + +} + + + + /*--------------------------------------------------------------------------*/ + /* Initialize_String_Table --- Initialize string table */ + /*--------------------------------------------------------------------------*/ + +static void initialize_string_table() + +{ + integer i; + + /* Initialize_String_Table */ + + /* No entries used in table yet */ + table_used = 0; + + fillchar(*string_table,(maxtab+1)*sizeof((*string_table)[1]),'\377'); + /* Enter all single characters into */ + /* table */ + firstentries(); + +} /* Initialize_String_Table */ + + + + /*--------------------------------------------------------------------------*/ + /* Lookup_String --- Look for string <w>C in string table */ + /*--------------------------------------------------------------------------*/ + +static integer lookup_string( integer prevc, integer follc ) + +{ + integer index; + integer index2; + boolean found; + + /* Lookup_String */ + /* Initialize index to check from hash */ + + integer lookup_string_result; + index = ( ( prevc << 5 ) ^ follc ) & maxtab; + + /* Assume we won't find string */ + lookup_string_result = end_list; + /* Search through list of hash collision */ + /* entries for one that matches <w>C */ + do { + + found = ( (*string_table)[index].prevchar == prevc ) && + ( (*string_table)[index].follchar == follc ); + + if ( ! found ) + index = (*string_table)[index].next; + + } while (!(found || ( index == end_list ))); + + /* Return index if <w>C found in table. */ + if (found) + lookup_string_result = index; + + return lookup_string_result; +} /* Lookup_String */ + + + + /*--------------------------------------------------------------------------*/ + /* Push --- Push character onto stack */ + /*--------------------------------------------------------------------------*/ + +static void push( byte c) + +{ /* Push */ + + stack_pointer += 1; + stack[ stack_pointer ] = c; + + if ( stack_pointer >= maxstack ) + { + output << "Stack overflow!" << NL; + exit(0); + } + +} /* Push */ + + + + /*--------------------------------------------------------------------------*/ + /* Pop --- Pop character from stack */ + /*--------------------------------------------------------------------------*/ + +static void pop( integer& c ) + +{ /* Pop */ + + popempty=stack_pointer==0; + + if (! popempty) + { + c = stack[stack_pointer]; + stack_pointer -= 1; + } + +} /* Pop */ + + + + /*--------------------------------------------------------------------------*/ + /* Get_Code --- Get compression code from input file */ + /*--------------------------------------------------------------------------*/ + +static void get_code( integer& hash_code ) + +{ + byte local_buf; + + /* Get_Code */ + + if (inempty) + { + + if (place>bufsize) return; else + {; + local_buf=(*buffer)[place]; + place += 1; + } + + if (place>bufsize) return; else + {; + input_code=(*buffer)[place]; + place += 1; + } + + hash_code = ( ( local_buf << 4 ) & 0xff0 ) + + ( ( (cardinal)input_code >> 4 ) & 0xf ); + + input_code = input_code & 0xf; + inempty=false; + + } + else + { + + if (place>bufsize) return; else + {; + local_buf=(*buffer)[place]; + place += 1; + } + + hash_code = local_buf + ( ( input_code << 8 ) & 0xf00 ); + inempty=true; + + } + +} /* Get_Code */ + + + + /*--------------------------------------------------------------------------*/ + /* Do_Decompression --- Perform decompression */ + /*--------------------------------------------------------------------------*/ + +static void do_decompression() + +{ + integer c /* Current input character */; + integer code /* Current code string */; + integer old_code /* Previous code string */; + integer fin_char /* Final input character */; + integer in_code /* Current input code */; + integer last_char /* Previous character */; + boolean unknown /* TRUE if code not found */; + integer temp_c /* Char popped off stack */; + + /* Do_Decompression */ + + stack_pointer = 0; /* Decompression stack is empty */ + unknown = false; /* First string is always known */ + get_code( old_code ); /* Get first string == Step 1 */ + code = old_code; + + c=(*string_table)[code].follchar; /* Output corresponding character */ + putup( c ); + fin_char = c; /* Remember this character -- it */ + /* is final character of next string */ + + get_code( in_code ); /* Get next code == Step 2 */ + + while (place<=bufsize) + { + code = in_code; /* Set code to this input code */ + + /* If code not in table, do special */ + /* case ==> Step 3 */ + + if ( (*string_table)[code].unused ) + { + last_char = fin_char; + code = old_code; + unknown = true; + } + /* Run through code extracting single */ + /* characters from code string until */ + /* no more characters can be removed. */ + /* Push these onto stack. They will */ + /* be entered in reverse order, and */ + /* will come out in forwards order */ + /* when popped off. */ + /* */ + /* ==> Step 4 */ + + while( (*string_table)[code].prevchar != no_prev ) + { + string_table_entry& with = (*string_table)[code]; + + push( with.follchar ); + code = with.prevchar; + } + /* We now have the first character in */ + /* the string. */ + + fin_char = (*string_table)[code].follchar; + + /* Output first character ==> Step 5 */ + putup( fin_char ); + /* While the stack is not empty, remove */ + /* and output all characters from stack */ + /* which are rest of characters in the */ + /* string. */ + /* */ + /* ==> Step 6 */ + pop( temp_c ); + + while (! popempty) + { + putup( temp_c ); + pop( temp_c ); + } + /* If code isn't known, output the */ + /* follower character of last character */ + /* of string. */ + if (unknown) + { + fin_char = last_char; + putup( fin_char ); + unknown = false; + } + /* Enter code into table ==> Step 7 */ + + make_table_entry( old_code , fin_char ); + + /* Make current code the previous code */ + old_code = in_code; + + /* Get next code == Step 2 */ + get_code( in_code ); + + } + +} /* Do_Decompression */ + +void load_comp(string xx){ + + /* This loads in the compressed file. */ + +const integer maxbuff = 8192 /* Buffer size for input and output files */; + +integer output_code /* Output compressed code */; +boolean if_compressing /* TRUE if compressing file */; + +byte this_; +untyped_file f; + +; +string_table = new sttype; +inempty=true; +initialize_string_table(); + +assign(f,string("v:compr")+xx+".avd"); reset(f,1); seek(f,146); +blockread(f,describe,30); blockread(f,method,1); +bufsize=filesize(f)-177; blockread(f,*buffer,bufsize); +close(f); + +bit=-1; offset=12081; place=1; + +do_decompression(); + +output << method << " : \"" << describe << '"' << NL; + +delete string_table; + } + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; +gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); +buffer = new buffertype; +#ifdef uncomp +load_uncomp("21"); +#else +load_comp("21"); +#endif +delete buffer; +return EXIT_SUCCESS; +} + + diff --git a/engines/avalanche/viewdocs.cpp b/engines/avalanche/viewdocs.cpp new file mode 100644 index 0000000000..effb1c5474 --- /dev/null +++ b/engines/avalanche/viewdocs.cpp @@ -0,0 +1,522 @@ +#include "ptoc.h" + + /*$S-*/ +/*#include "dos.h"*/ +/*#include "crt.h"*/ +/*#include "tommys.h"*/ + + +typedef array<0,49999,byte> bigtextarray; +struct chaptertype { + varying_string<60> headername; + word headeroffset; +}; +typedef array<1,1120,byte> sbtype; + +const integer contsize = 29; /*number of headers in AVALOT.DOC*/ +const varying_string<80> contentsheader = " -=- The contents of the Lord AVALOT D'Argent (version 1.3) documentation -=-"; +const array<0,15,byte> listpal = {{1,0,3,0,7,0,7,7,0,0,0,0,0,0,0,0}}; +const array<0,15,byte> blankpal = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}; +const integer tabstop = 8; /*length of tab stops*/ + +/*NOTE: Tabs are not properly implemented. The program just interprets them*/ +/*as a number of spaces.*/ + +matrix<1,256, 0,15,byte> textvar,textvar8; +array<0,1500,word> posof13; +array<1,65535,byte> scvar; /*absolute $A000:$0000;*/ +sbtype stbar,stbar2; +pointer dpt; +word sot,nol,bat,bab,tlab,nosl,bfseg,bfofs,useless; +bigtextarray* textmem; +boolean atsof,fast,regimode; +byte hol; +varying_string<80> stline; +array<1,contsize,chaptertype> contlist; +integer lat; + +void wipeit(longint pos, word count) /*Like fillchar, but wraps*/ +{ + longint wpos; + + wpos=(word)(pos); + fillchar(mem[longint(0xa000)+wpos / longint(16)*wpos % longint(16)],count,0); +} + +void wrapcopy(sbtype fromarr, longint pos) /*Like fillchar, but wraps*/ +{ + longint wpos; + + wpos=(word)(pos); + move(fromarr,mem[longint(0xa000)+wpos / longint(16)*wpos % longint(16)],1120); +} + +void blankscreen() /*blanks the screen (!)*/ +{ + registers r; + + r.ax=0x1002; + r.es=seg(blankpal); + r.dx=ofs(blankpal); + intr(0x10,r); +} + +void showscreen() /*shows the screen (!)*/ +{ + registers r; + + r.ax=0x1002; + r.es=seg(listpal); + r.dx=ofs(listpal); + intr(0x10,r); +} + +void wipesb(word wheretop) +{ + byte plane; + + for( plane=2; plane <= 3; plane ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << plane; port[0x3cf]=plane; + fillchar(scvar[(wheretop+336)*80+1],1120,0); + } + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=2; port[0x3cf]=1; +} + +void displstat(byte wipepos) /*displays the status bar*/ +{ + byte plane; + + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=4; port[0x3cf]=2; + wrapcopy(stbar,(lat+336)*80); + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=8; port[0x3cf]=3; + wrapcopy(stbar2,(lat+336)*80); + for( plane=2; plane <= 3; plane ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << plane; port[0x3cf]=plane; + switch (wipepos) { + case 0: wipeit((lat+335)*80-1,80); break; + case 1: wipeit(lat*80-1,80); break; + } + } + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=2; port[0x3cf]=1; +} + +void udstat() /*updates the status bar*/ +{ + varying_string<3> pt; + byte fv,fv2; + + fillchar(pt,4,'\0'); + str(round((real)((tlab-21))/(nol-21)*100),pt); + for( fv=1; fv <= 3; fv ++) + for( fv2=0; fv2 <= 13; fv2 ++) + {; + stbar[fv2*80+fv+68]=~ textvar[ord(pt[fv])+1][fv2]; + stbar2[fv2*80+fv+68]=textvar[ord(pt[fv])+1][fv2]; + } +} + +void finddocinfo() /*finds the line breaks in AVALOT.DOC & finds the +headers by searching for '"""'*/ +{ + word wv,oldwv,varpos,varpos2,contlpos; + boolean thisaheader; + varying_string<60> headerstring; + + thisaheader=false; + posof13[0]=65535; /*this +2 will wrap around to 1*/ + wv=1; + oldwv=1; + varpos=1; + contlist[1].headername="Start of documentation"; + contlist[1].headeroffset=0; + contlpos=2; + while (wv<sot) + { + while (((*textmem)[wv]!=13) && ((*textmem)[wv]!=34) && (wv-oldwv<80)) wv += 1; + switch ((*textmem)[wv]) { + case 13: { + posof13[varpos]=wv; + varpos += 1; + oldwv=wv+1; + thisaheader=false; + } + break; + case 34: if (((*textmem)[wv-1]==34) && ((*textmem)[wv-2]==34) && (varpos>12) + && (thisaheader==false)) + { + thisaheader=true; + headerstring[0]='\0'; + varpos2=posof13[varpos-2]+2; + while (((*textmem)[varpos2]==32) || ((*textmem)[varpos2]==9)) varpos2 += 1; + while (varpos2!=posof13[varpos-1]) + {; + headerstring=headerstring+chr((*textmem)[varpos2]); + varpos2 += 1; + } + contlist[contlpos].headername=headerstring; + contlist[contlpos].headeroffset=varpos-2; + contlpos += 1; + } + break; + } + wv += 1; + } + nol=varpos-2; + nosl=nol*14; +} + +void graphmode(byte gm) /*puts the display adaptor into a specified mode*/ +{ + registers regs; + + regs.ax=gm; + intr(0x10,regs); +} + +void setoffset(word where_on_screen) {; /*assembler; {for scrolling the screen*/ +/*asm + mov bx, where_on_screen + mov dx, $03D4 + mov ah, bh + mov al, $C + out dx, ax + + mov ah, bl + inc al + out dx, ax*/ + } + +void setupsb(byte sbtype) /*sets up the status bar in several styles*/ +{ + integer fv; + + switch (sbtype) { + case 1: if (regimode==false) stline=string("Doc lister: PgUp, PgDn, Home & End to move. Esc exits. C=") + +'\32'+"contents "+'\263'+" % through "; else + stline=string("Doc lister: PgUp, PgDn, Home & End to move. Esc exits to main menu.") + +'\263'+" % through"; + break; + case 2: stline=string("Esc=to doc lister ")+'\263'+" Press the key listed next to the section you wish to jump to"; break; + } + for( fv=0; fv <= 1118; fv ++) {; + stbar[fv+1]=~ textvar[ord(stline[fv % 80+1])+1][fv / 80]; + stbar2[fv+1]=textvar[ord(stline[fv % 80+1])+1][fv / 80]; + } +} + +void setup() /*sets up graphics, variables, etc.*/ +{ + untyped_file f; + integer fv; + registers r; + + if ((paramstr(1)!="REGI") && (paramstr(1)!="ELMPOYTEN")) + + { + clrscr; + output << "This program cannot be run on its own. Run AVALOT.EXE." << NL; + exit(123); + } + val(paramstr(2),bfseg,useless); + val(paramstr(3),bfofs,useless); + bfofs += 1; + atsof=true; + fast=false; + assign(f,"avalot.fnt"); + reset(f,1); + blockread(f,textvar,4096); + close(f); + assign(f,"ttsmall.fnt"); + reset(f,1); + blockread(f,textvar8,4096); + close(f); + assign(f,"avalot.doc"); + reset(f,1); + sot=filesize(f); + mark(dpt); + textmem = new bigtextarray; + blockread(f,*textmem,sot); + close(f); + finddocinfo(); + if (paramstr(1)=="REGI") + {; + regimode=true; + tlab=contlist[contsize].headeroffset+24; + lat=contlist[contsize].headeroffset*14; + } + else + {; + lat=0; tlab=24; + regimode=false; + } + setupsb(1); + graphmode(16); + directvideo=false; + showscreen(); + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=2; port[0x3cf]=1; +} + +void drawscreenf(integer tl) /*draws a screen from a line forwards*/ +/*N.B. tl>1*/ +{ + word fv,fv2,curbyte,plane; + byte xpos; + + blankscreen(); + wipesb(lat); + if (tl>nol-24) tl=nol-24; + if (tl<0) tl=0; + lat=tl*14; + for( plane=2; plane <= 3; plane ++) /*wipe sb off*/ + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << plane; port[0x3cf]=plane; + /*fillchar(mem [$A000:((lat-1)*80) mod 65536],26800,0);*/ + wipeit(lat*80,26800); + } + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=2; port[0x3cf]=1; /*back to normal*/ + if (tl>0) curbyte=posof13[tl-1]+2; else curbyte=0; + bat=curbyte; + for( fv=lat; fv <= lat+335; fv ++) + { + fv2=curbyte; + xpos=1; + while (xpos<=80) + { + if (fv2<posof13[tl]) + { + if ((*textmem)[fv2]==9) + { + wipeit(fv*80+xpos,tabstop); + xpos += tabstop; + } else + { + mem[0xa000*(word)(fv*80+xpos-1)]= + textvar[(*textmem)[fv2]+1][fv % 14]; + xpos += 1; + } + } else + { + wipeit(fv*80+xpos-1,82-xpos); + xpos=81; + } + fv2 += 1; + } + if (fv % 14==0) + { + tl += 1; + curbyte=posof13[tl-1]+2; + } + } + bab=curbyte; + tlab=tl; + udstat(); + displstat(2); + setoffset((word)(lat*80)); + if (tl-23>1) atsof=false; + showscreen(); +} + +void displcont() /*displays the contents*/ +{ + byte fv,fv2,fv3,keyon,jumppos,plane; + word olat; + varying_string<62> curstr; + char rkv; + + blankscreen(); + olat=lat; lat=0; keyon=1; jumppos=0; + setoffset(0); + for( plane=1; plane <= 3; plane ++) /*wipe sb off*/ + { + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << plane; port[0x3cf]=plane; + fillchar(scvar,26800,0); + } + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=2; port[0x3cf]=1; /*back to normal*/ + setupsb(2); + displstat(2); + for( fv=1; fv <= 80; fv ++) + for( fv2=0; fv2 <= 27; fv2 ++) + { + scvar[fv2*80+fv]=textvar[ord(contentsheader[fv-1])+1][fv2 / 2]; + } + for( fv=1; fv <= contsize; fv ++) + { + if (keyon<10) curstr=strf(keyon)+". "+contlist[fv].headername; else + curstr=string(chr(keyon+55))+". "+contlist[fv].headername; + for( fv2=1; fv2 <= length(curstr); fv2 ++) + for( fv3=0; fv3 <= 7; fv3 ++) + scvar[(fv+3)*640+fv3*80+fv2]=textvar8[ord(curstr[fv2])+1][fv3]; + keyon += 1; + } + showscreen(); + do {; } while (!keypressed()); + rkv=readkey(); + switch (rkv) { + case RANGE_9('\61','\71'): jumppos=ord(rkv)-48; + break; + case RANGE_26('\101','\132'): jumppos=ord(rkv)-55; + break; + case RANGE_26('\141','\172'): jumppos=ord(rkv)-87; + break; + default: lat=olat; + } + if (jumppos>0) lat=contlist[jumppos].headeroffset; + setupsb(1); + if (fast==false) wipesb(0); + drawscreenf(lat); +} + +void down() /*scrolls the screen down one line*/ +{ + word fv,xpos,wpos,lab; + + lat += 1; + lab=lat+335; + setoffset((word)(lat*80)); + if (lab % 14==0) { + bat=posof13[tlab-24]+2; bab=posof13[tlab]+2; tlab += 1; udstat(); } + fv=bab; + xpos=1; + while (xpos<=80) + { + if (fv<posof13[tlab]) + { + if ((*textmem)[fv]==9) + { + wipeit(lab*80+xpos-1,tabstop); + xpos += tabstop; + } else + { + wpos=(lab*80+xpos) % 65536; + /*fillchar(mem[$A000+wpos div 16*wpos mod 16],count,0)*/ + mem[0xa000*wpos-1]=textvar[(*textmem)[fv]+1][lab % 14]; + xpos += 1; + } + } else + { + wipeit(lab*80+xpos-1,81-xpos); + xpos=81; + } + fv += 1; + } + atsof=false; + if (fast==true) displstat(0); +} + +void up() /*scrolls the screen up one line*/ +{ + word fv,xpos,wpos; + + if (lat==0) { atsof=true; return; } + if (lat % 14==0) + if (tlab>24) + { + tlab -= 1; bat=posof13[tlab-24]+2; bab=posof13[tlab-1]+2; udstat(); } else + { atsof=true; udstat(); return; } + lat -= 1; + setoffset((word)(lat*80)); + fv=bat; + xpos=1; + while (xpos<=80) + { + if (fv<posof13[tlab-23]) + { + if ((*textmem)[fv]==9) + { + wipeit(lat*80+xpos-1,tabstop); + xpos += tabstop; + } else + { + wpos=(word)((lat*80+xpos) % 65536); + mem[0xa000*wpos-1]=textvar[(*textmem)[fv]+1][lat % 14]; + xpos += 1; + } + } else + { + wipeit(lat*80+xpos-1,81-xpos); + xpos=81; + } + fv += 1; + } + if (fast==true) displstat(1); + /*ateof:=false;*/ +} + +void endit() /*Ends the program*/ +{ + release(dpt); + graphmode(2); +} + +void control() /*User control*/ +{ + char rkv,rkv2/*the sequel*/,rkv3; + integer fv; + boolean first; + + if (regimode==false) displcont(); else drawscreenf(tlab-24); + first=true; + do {; + rkv=readkey(); + switch (rkv) { + case '\0': { + rkv2=readkey(); + switch (rkv2) { + case chome:drawscreenf(0); break; + case cend: drawscreenf(nol-24); break; + case cpgdn: + {; + memw[bfseg*bfofs]=0; + if (fast==false) wipesb(lat); + fv=1; + while (((cardinal)lat+336<nosl) && (fv<337)) + { + fv += 1; + down(); + } + if ((first==true) && (memw[bfseg*bfofs]<=2)) fast=true; + if ((fast==false) || (first==true)) displstat(0); + } + break; + case cpgup: + {; + memw[bfseg*bfofs]=0; + if (fast==false) wipesb(lat); + fv=1; + while ((atsof==false) && (fv<337)) + { + fv += 1; + up(); + } + if ((first==true) && (memw[bfseg*bfofs]<=2)) fast=true; + if ((fast==false) || (first==true)) displstat(0); + } + break; +/* cUp:repeat; + up; + readkey; + until (readkey<>cUp) or (atsof=true); + cDown: repeat; + down; + readkey; + until (readkey<>cDown) or (ateof=true);*/ + } + first=false; + } + break; + case '\33': return; break; + case '\103':case '\143': if (regimode==false) { wipesb(lat); displcont(); } break; + } + } while (!false); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + setup(); + control(); + endit(); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/visa.cpp b/engines/avalanche/visa.cpp new file mode 100644 index 0000000000..f5bd51131e --- /dev/null +++ b/engines/avalanche/visa.cpp @@ -0,0 +1,264 @@ +#include "ptoc.h" + +/* + ÛßÜ ÛßÜ ÜßßÜ ßÛß Ûßß Üß ßÛß ÜßÛßÜ ßÛß ÛÜ Û ÜÛßß ßÛß ÛßÜ Ûßß Û + Ûß ÛÛ Û Û Ü Û Ûßß ßÜ Û Û Û Û Û Û ÛÜÛ ßßßÜ Û ÛÛ Ûßß Û + ß ß ß ßß ßß ßßß ß ß ß ß ß ßßß ß ßß ßßß ß ß ß ßßß ßßß + + VISA The new Sez handler. (Replaces Access.) */ + +#define __visa_implementation__ + + +#include "visa.h" + + +/*#include "Gyro.h"*/ +/*#include "Scrolls.h"*/ +/*#include "Acci.h"*/ +/*#include "Trip5.h"*/ +/*#include "Lucerna.h"*/ + + +const boolean bubbling = false; +const boolean report_dixi_errors = true; + +boolean went_ok; + +void unskrimble() +{ + word fv; + + for( fv=1; fv <= bufsize; fv ++) buffer[fv]=(char)((~(ord(buffer[fv])-fv)) % 256); +} + +void do_the_bubble() +{ + bufsize += 1; + buffer[bufsize]='\2'; +} + +void dixi(char block, byte point) +{ + untyped_file indexfile,sezfile; + word idx_offset,sez_offset; + boolean error; + + error=false; + + assign(indexfile,"avalot.idx"); assign(sezfile,"avalot.sez"); + + reset(indexfile,1); + seek(indexfile,(ord(upcase(block))-65)*2); + blockread(indexfile,idx_offset,2); + if (idx_offset==0) error=true; + seek(indexfile,idx_offset+point*2); + blockread(indexfile,sez_offset,2); + if (sez_offset==0) error=true; + close(indexfile); + + went_ok=! error; + + if (error) + { + if (report_dixi_errors) + display(string('\7')+"Error accessing scroll "+block+strf(point)); + return; + } + + reset(sezfile,1); + seek(sezfile,sez_offset); + blockread(sezfile,bufsize,2); + blockread(sezfile,buffer,bufsize); + close(sezfile); + unskrimble(); + + if (bubbling) do_the_bubble(); + + calldrivers; +} + +void speech(byte who, byte subject) +{ + untyped_file indexfile,sezfile; + word idx_offset,sez_offset,next_idx_offset; + + if (subject==0) + { /* No subject. */ + bubbling=true; report_dixi_errors=false; + dixi('s',who); + bubbling=false; report_dixi_errors=true; + } else + { /* Subject given. */ + assign(indexfile,"converse.avd"); assign(sezfile,"avalot.sez"); + + went_ok=false; /* Assume that until we know otherwise. */ + reset(indexfile,1); + seek(indexfile,who*2-2); + blockread(indexfile,idx_offset,2); + blockread(indexfile,next_idx_offset,2); + + if ((idx_offset==0) || + ((((next_idx_offset-idx_offset) / 2)-1) < subject)) return; + + seek(indexfile,idx_offset+subject*2); + /*$I-*/ + blockread(indexfile,sez_offset,2); + if ((sez_offset==0) || (ioresult!=0)) return; + /*$I+*/ + close(indexfile); + + reset(sezfile,1); + seek(sezfile,sez_offset); + blockread(sezfile,bufsize,2); + blockread(sezfile,buffer,bufsize); + close(sezfile); + + unskrimble(); + do_the_bubble(); + + calldrivers; + went_ok=true; + } +} + +void talkto(byte whom) +{ + byte fv; + boolean no_matches; + + if (person==pardon) + { + person=chr(subjnumber); + subjnumber=0; + } + + if (subjnumber==0) + switch (chr(whom)) { + case pspludwick: + + if ((dna.lustie_is_asleep) & (~ dna.obj[potion])) + { + dixi('q',68); + dna.obj[potion]=true; + objectlist; points(3); return; + } else + { + if (dna.talked_to_crapulus) + switch (dna.given2spludwick) { /* Spludwick - what does he need? */ + /* 0 - let it through to use normal routine. */ + case RANGE_2(1,2): { + display(string("Can you get me ")+ + get_better(spludwick_order[dna.given2spludwick])+", please?"+ + "\232\2"); + return; + } + break; + case 3: { + dixi('q',30); /* need any help with the game? */ + return; + } + break; + } + else { + dixi('q',42); /* Haven't talked to Crapulus. Go and talk to him. */ + return; + } + } + break; + + case pibythneth: if (dna.givenbadgetoiby) + { + dixi('q',33); /* Thanks a lot! */ + return; /* And leave the proc. */ + } + break; /* Or... just continue, 'cos he hasn't got it. */ + case pdogfood: if (dna.wonnim) + { /* We've won the game. */ + dixi('q',6); /* "I'm Not Playing!" */ + return; /* Zap back. */ + } else dna.asked_dogfood_about_nim=true; + break; + case payles: if (~ dna.ayles_is_awake) + { + dixi('q',43); /* He's fast asleep! */ + return; + } else + if (~ dna.given_pen_to_ayles) + { + dixi('q',44); /* Can you get me a pen, Avvy? */ + return; + } + break; + + case pjacques: { dixi('q',43); return; } break; + case pgeida: if (dna.geida_given_potion) + dna.geida_follows=true; else + { + dixi('u',17); + return; + } + break; + case pspurge: if (~ dna.sitting_in_pub) + { + dixi('q',71); /* Try going over and sitting down. */ + return; + } else + { + if (spurge_talk<5) spurge_talk += 1; + if (spurge_talk>1) + { /* no. 1 falls through */ + dixi('q',70+spurge_talk); + return; + } + } + break; + } else /* On a subject. Is there any reason to block it? */ + switch (chr(whom)) { + case payles: if (~ dna.ayles_is_awake) + { + dixi('q',43); /* He's fast asleep! */ + return; + } + break; + } + + if (whom>149) whom -= 149; + + no_matches=true; + for( fv=1; fv <= numtr; fv ++) + if (tr[fv].a.accinum==whom) + { + display(string('\23')+chr(fv+48)+'\4'); + no_matches=false; + flush(); + } + + if (no_matches) display("\23\23\4"); + + speech(whom,subjnumber); + if (! went_ok) /* File not found! */ + dixi('n',whom); + + if (subjnumber==0) + switch (chr(whom+149)) { + case pcrapulus: + { /* Crapulus: get the badge - first time only */ + dna.obj[badge]=true; + objectlist; + dixi('q',1); /* Circular from Cardiff. */ + dna.talked_to_crapulus=true; + + whereis[pcrapulus]=177; /* Crapulus walks off. */ + + tr[2].vanishifstill=true; + tr[2].walkto(4); /* Walks away. */ + + points(2); + } + break; + + } +} + + diff --git a/engines/avalanche/visa.h b/engines/avalanche/visa.h new file mode 100644 index 0000000000..8b79d6be18 --- /dev/null +++ b/engines/avalanche/visa.h @@ -0,0 +1,9 @@ +#ifndef __visa_h__ +#define __visa_h__ + + +void dixi(char block, byte point); + +void talkto(byte whom); + +#endif diff --git a/engines/avalanche/visatest.cpp b/engines/avalanche/visatest.cpp new file mode 100644 index 0000000000..52970adacb --- /dev/null +++ b/engines/avalanche/visatest.cpp @@ -0,0 +1,84 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ + + +char block; +word point; + +array<1,2000,char> result; +word result_len; + +void unskrimble() +{ + word fv; + + for( fv=1; fv <= 2000; fv ++) result[fv]=(char)((~(ord(result[fv])-fv)) % 256); +} + +void visa_get_scroll(char block, word point) +{ + untyped_file indexfile,sezfile; + word idx_offset,sez_offset; + + assign(indexfile,"avalot.idx"); assign(sezfile,"avalot.sez"); + + reset(indexfile,1); + seek(indexfile,(ord(upcase(block))-65)*2); + blockread(indexfile,idx_offset,2); + seek(indexfile,idx_offset+point*2); + blockread(indexfile,sez_offset,2); + close(indexfile); + + reset(sezfile,1); + seek(sezfile,sez_offset); + blockread(sezfile,result_len,2); + blockread(sezfile,result,result_len); + close(sezfile); + unskrimble(); +} + +void access_get_scroll(char block, word point) +{ + string x; + untyped_file f; + + str(point,x); + x=string('S')+block+x+".RAW"; + assign(f,x); + reset(f,1); + result_len=filesize(f); + blockread(f,result,result_len); + close(f); +} + +void display_it() +{ + word fv; + + for( fv=1; fv <= result_len; fv ++) output << result[fv]; +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + do { + output << NL; + output << NL; + output << "Block?"; input >> block >> NL; + output << "Point?"; input >> point >> NL; + + output << "ACCESS reports (this one is always correct):" << NL; + output << NL; + access_get_scroll(block,point); + display_it(); + + output << NL; output << NL; + output << "VISA reports:" << NL; + output << NL; + visa_get_scroll(block,point); + display_it(); + } while (!false); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/waver.cpp b/engines/avalanche/waver.cpp new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/engines/avalanche/waver.cpp diff --git a/engines/avalanche/xf_gover.cpp b/engines/avalanche/xf_gover.cpp new file mode 100644 index 0000000000..67bb5ff561 --- /dev/null +++ b/engines/avalanche/xf_gover.cpp @@ -0,0 +1,95 @@ +#include "ptoc.h" + + +#include "graph.h" + + +void load() +{ + byte a; /*absolute $A000:1200;*/ byte bit; untyped_file f; +; + assign(f,"avagame.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a,12080); + } + close(f); + bit=getpixel(0,0); +} + +void gfx() +{ + integer gd,gm; + + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); +} + +void blit(integer x1,integer y1,integer x2,integer y2,integer x3,integer y3) +{ + pointer p,q; word s; + + mark(q); + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + putimage(x3,y3,p,0); + + release(q); +} + +void copy_hammer() +{ + blit(274,47,311,67,92,10); +} + +void do_text() +{ + settextjustify(1,1); setcolor(0); + settextstyle(2,0,4); + setusercharsize(120,100,100,100); + outtextxy(112,32,"Thorsoft of Letchworth presents"); + blit(3,30,218,31,4,30); + blit(4,35,219,38,3,35); +} + +void dump_to_file(byte x1,byte y1,byte x2,byte y2, string fn) +{ + byte y,bit; + untyped_file f; + + assign(f,fn); + rewrite(f,1); + + for( y=y1; y <= y2; y ++) + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(f,mem[0xa000*y*80+x1],x2-x1); + } + + close(f); + +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + gfx(); + load(); + + setfillstyle(1,7); + bar(2,10,219,37); + bar(0,0,1,200); + bar(220,0,250, 88); + bar(0,88,213,147); + bar(622,88,640,147); + copy_hammer(); + do_text(); + + dump_to_file( 0,10,28,86,"about.avd"); + dump_to_file(26,88,78,147,"gameover.avd"); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/xf_help.cpp b/engines/avalanche/xf_help.cpp new file mode 100644 index 0000000000..1f8063952e --- /dev/null +++ b/engines/avalanche/xf_help.cpp @@ -0,0 +1,86 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ +/*#include "Tommys.h"*/ + + +const integer max_pages = 34; + +byte fv; +text i; +untyped_file o; +string x; +char t; +byte p,w; + +array<0,max_pages,word> where; + +void out(string x) +{ + byte fz; + + for( fz=1; fz <= length(x); fz ++) + x[fz]=chr(ord(x[fz]) ^ 177); + blockwrite(o,x[0],1); + blockwrite(o,x[1],length(x)); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + assign(o,"help.avd"); + rewrite(o,1); + + blockwrite(o,where,sizeof(where)); + + for( fv=0; fv <= max_pages; fv ++) + { + where[fv]=filepos(o); + + assign(i,string('h')+strf(fv)+".raw"); + reset(i); + + i >> x >> NL; /* Title. */ + out(x); + + i >> p >> NL; /* Picture. */ + blockwrite(o,p,1); + + do { + i >> x >> NL; + out(x); + } while (!(x=='!')); + + while (! eof(i)) + { + i >> x >> NL; + if (x=='-') + { /* Null point */ + t='\0'; p=0; w=177; + } else + { /* Has a point. */ + i >> t >> NL; + i >> p >> NL; + i >> w >> NL; + } + + blockwrite(o,t,1); + blockwrite(o,p,1); + blockwrite(o,w,1); + } + + t='\261'; + blockwrite(o,t,1); + blockwrite(o,p,1); + blockwrite(o,w,1); + + close(i); + + } + + seek(o,0); blockwrite(o,where,sizeof(where)); + + close(o); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/xf_visa.cpp b/engines/avalanche/xf_visa.cpp new file mode 100644 index 0000000000..888df55d4e --- /dev/null +++ b/engines/avalanche/xf_visa.cpp @@ -0,0 +1,178 @@ +#include "ptoc.h" + + +/*#include "Crt.h"*/ +/*#include "Dos.h"*/ + +/*$R+*/ + +const varying_string<9> used = "DNPQSTUXZ"; + +const varying_string<12> header = string("Avalot Sez:")+'\32'; + +untyped_file sez,infile; +searchrec s; + +matrix<'A','Z',0,99,word> positions; +array<'A','Z',word> maxlen; + +matrix<1,50,0,255,word> speak_positions; +array<1,50,word> speak_maxlen; + +array<1,2000,char> data; +word data_length; + +byte fv; + +byte numeric_bit() +{ + varying_string<5> x; integer e; byte result; + + byte numeric_bit_result; + x=copy(s.name,3,pos(".",s.name)-3); + val(x,result,e); + if (e!=0) + { + output << "NUMERIC ERROR: " << s.name << '/' << x << NL; + exit(255); + } + numeric_bit_result=result; + return numeric_bit_result; +} + +byte speak_left() +{ + string x; integer e; byte result; + + byte speak_left_result; + x=copy(s.name,3,pos(".",s.name)-3); + x=copy(x,1,pos("-",x)-1); + val(x,result,e); + if (e!=0) + { + output << "NUMERIC ERROR (left): " << s.name << '/' << x << NL; + exit(255); + } + speak_left_result=result; + return speak_left_result; +} + +byte speak_right() +{ + string x; integer e; byte result; + + byte speak_right_result; + x=copy(s.name,3,pos(".",s.name)-3); + x=copy(x,pos("-",x)+1,255); + val(x,result,e); + if (e!=0) + { + output << "NUMERIC ERROR (right): " << s.name << '/' << x << NL; + exit(255); + } + speak_right_result=result; + return speak_right_result; +} + +void write_out() +{ + array<'A','Z',word> points; + array<1,50,word> speak_points; + untyped_file outf; + byte fv; + + fillchar(points,sizeof(points),'\0'); + fillchar(speak_points,sizeof(speak_points),'\0'); + + assign(outf,"v:avalot.idx"); + rewrite(outf,1); + blockwrite(outf,points,sizeof(points)); + + for( fv=1; fv <= length(used); fv ++) + { + points[used[fv-1]]=filepos(outf); + blockwrite(outf,positions[used[fv-1]],maxlen[used[fv-1]]*2+2); + } + + seek(outf,0); + blockwrite(outf,points,sizeof(points)); + + close(outf); + + /* --- now the speech records --- */ + + assign(outf,"v:converse.avd"); + rewrite(outf,1); + blockwrite(outf,speak_points,sizeof(speak_points)); + + for( fv=1; fv <= 15; fv ++) + { + speak_points[fv]=filepos(outf); + + blockwrite(outf,speak_positions[fv],speak_maxlen[fv]*2+2); + } + + seek(outf,0); + blockwrite(outf,speak_points,sizeof(speak_points)); + + close(outf); +} + +void skrimble() +{ + word fv; + + for( fv=1; fv <= 2000; fv ++) data[fv]=(char)((~(ord(data[fv]))+fv) % 256); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + fillchar(positions,sizeof(positions),'\0'); + fillchar(maxlen,sizeof(maxlen),'\0'); + + clrscr; + + assign(sez,"v:avalot.sez"); + rewrite(sez,1); + blockwrite(sez,header[1],12); + + findfirst("s*.raw",anyfile,s); + while (doserror==0) + { + assign(infile,s.name); + reset(infile,1); + blockread(infile,data,2000,data_length); + close(infile); + + clrscr; + if (pos("-",s.name)==0) + { /* Not a speech record. */ + output << s.name << format(numeric_bit(),10) << NL; + + positions[s.name[2]][numeric_bit()]=filepos(sez); + if (maxlen[s.name[2]]<(unsigned char)numeric_bit()) maxlen[s.name[2]]=numeric_bit(); + + } else + { /* A speech record. */ + output << s.name << format(speak_left(),10) << format(speak_right(),10) << " SR" << NL; + + speak_positions[speak_left()][speak_right()]=filepos(sez); + if (speak_maxlen[speak_left()]<(unsigned char)speak_right()) + speak_maxlen[speak_left()]=speak_right(); + } + + skrimble(); + + blockwrite(sez,data_length,2); + blockwrite(sez,data,data_length); + + findnext(s); + clreol; + } + + close(sez); + + write_out(); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/engines/avalanche/xfbutton.cpp b/engines/avalanche/xfbutton.cpp new file mode 100644 index 0000000000..dfbaf5e559 --- /dev/null +++ b/engines/avalanche/xfbutton.cpp @@ -0,0 +1,62 @@ +#include "ptoc.h" + + +#include "graph.h" + +integer x,y; +untyped_file f,out; + +void load() /* Load2, actually */ +{ + byte a0; /*absolute $A000:800;*/ + byte bit; + untyped_file f; + integer gd,gm; + + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + + assign(f,"d:butnraw.avd"); reset(f,1); + seek(f,177); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a0,12080); + } + close(f); + bit=getpixel(0,0); +} + +void grab(integer x1,integer y1,integer x2,integer y2) /* s=930 */ +{ + word s; pointer p; + + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + putimage(0,0,p,0); + blockwrite(out,p,s); + freemem(p,s); + rectangle(x1,y1,x2,y2); +} + +int main(int argc, const char* argv[]) +{ + pio_initialize(argc, argv); + assign(f,"d:butnraw.avd"); + assign(out,"v:buttons.avd"); rewrite(out,1); + load(); + for( x=0; x <= 5; x ++) + for( y=0; y <= 3; y ++) + { + if (! + (((x==1) && (y==0)) + || ((x==4) && (y==2)) + || ((y==3) && (x>2) && (x<5)))) + { + input >> NL; + grab(100+x*83,51+y*22,180+x*83,71+y*22); + } + } + close(out); + return EXIT_SUCCESS; +} diff --git a/engines/avalanche/xfghost.cpp b/engines/avalanche/xfghost.cpp new file mode 100644 index 0000000000..8809bb58a3 --- /dev/null +++ b/engines/avalanche/xfghost.cpp @@ -0,0 +1,246 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ + + +const array<1,44,char> chunkheader = +string("Spooky file! Nearly a Chunk... (c) MT.")+'\32'+'\261'+'\x30'+'\x1'+'\x75'+'\261'; + +const integer n = -1; /* "No change" in new-whatever */ + +const integer aa = -2; /* This is an aargh. */ + +const integer aargh_x_ofs = -177; const integer aargh_y_ofs = 52; + +enum flavourtype {ch_ega,ch_bgi,ch_natural,ch_two,ch_one, last_flavourtype}; + +struct chunkblocktype { + flavourtype flavour; + integer x,y; + integer xl,yl; + longint size; +}; + +integer gd,gm,x,y; +untyped_file f; byte bit; +byte a; /*absolute $A000:0;*/ +palettetype cc; +char r; text t; +word s; pointer p; + +untyped_file chunkfile; +chunkblocktype cb; + +pointer a_p; word a_s; + +void open_chunk() +{; + assign(chunkfile,"v:spooky.avd"); + rewrite(chunkfile,1); + blockwrite(chunkfile,chunkheader,sizeof(chunkheader)); +} + +void close_chunk() +{; + close(chunkfile); +} + +void grab(integer x1,integer y1,integer x2,integer y2, flavourtype how, integer newx,integer newy) +{ + pointer p; + word s; + integer y; + byte bit; + +; +#ifndef DRYRUN + {; + cb.flavour=how; + switch (newx) { + case n: cb.x=x1; break; + case aa: cb.x=x1+aargh_x_ofs; break; + default: cb.x=newx; + } + + switch (newy) { + case n: cb.y=y1; break; + case aa: cb.y=y1+aargh_y_ofs; break; + default: cb.y=newy; + } + + cb.xl=x2-x1; + if (set_of_enum(flavourtype)::of(ch_ega,ch_one,ch_two, eos).has(how)) cb.xl=((cb.xl+7) / 8)*8; + cb.yl=y2-y1; + } + + if (how!=ch_natural) + {; + s=imagesize(x1,y1,x2,y2); + getmem(p,s); + getimage(x1,y1,x2,y2,p); + } + + rectangle(x1,y1,x2,y2); + + switch (how) { + case ch_bgi: cb.size=s; break; + } + + blockwrite(chunkfile,cb,sizeof(cb)); + + switch (how) { + case ch_bgi: blockwrite(chunkfile,p,s); break; + case ch_ega: {; + setactivepage(1); + cleardevice(); + putimage(0,0,p,0); + setactivepage(0); + + for( bit=0; bit <= 3; bit ++) + for( y=0; y <= cb.yl; y ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(chunkfile,mem[0xa400*y*80],cb.xl / 8); + } + + y=getpixel(0,0); + } + break; + case ch_two: {; /* Same as EGA, but with only 2 planes. */ + setactivepage(1); + cleardevice(); + putimage(0,0,p,0); + setactivepage(0); + + for( bit=2; bit <= 3; bit ++) /* << Bit to grab? */ + for( y=0; y <= cb.yl; y ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(chunkfile,mem[0xa400*y*80],cb.xl / 8); + } + + y=getpixel(0,0); + } + break; + case ch_one: {; /* ...but with only one plane! */ + setactivepage(1); + cleardevice(); + putimage(0,0,p,0); + setactivepage(0); + + for( bit=3; bit <= 3; bit ++) + for( y=0; y <= cb.yl; y ++) + {; + port[0x3c4]=2; port[0x3ce]=4; + port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockwrite(chunkfile,mem[0xa400*y*80],cb.xl / 8); + } + + y=getpixel(0,0); + } + break; + } + + freemem(p,s); #endif + rectangle(x1,y1,x2,y2); + +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; +#ifndef DRYRUN + open_chunk(); +#endif + + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + assign(f,"c:\\sleep4\\colour.ptx"); reset(f,1); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + blockread(f,a,16000); /* 28000 */ + } + close(f); + + setwritemode(xorput); + + /* Grab the big ghost. */ + + grab( 0, 0,160, 65,ch_two,n,n); /* First column, */ + grab( 0, 67,172,127,ch_two,n,n); + grab( 0,132,158,190,ch_two,n,n); + + a_s=imagesize(349,36,361,43); getmem(a_p,a_s); + getimage(349,36,361,43,a_p); + setfillstyle(1,0); bar(349,36,361,43); + + grab(173, 66,347,124,ch_two,n,n); /* Second column. */ + grab(173, 6,352, 64,ch_two,n,n); + + putimage(349,36,a_p,0); + + /* Grab Avvy's eyes and the exclamation mark. */ + + grab(605, 10,620, 12,ch_bgi,n,n); /* Eyes looking left */ + grab(622, 10,638, 12,ch_bgi,n,n); /* Ditto looking right (eye eye, sir) */ + grab(611, 0,616, 5,ch_bgi,n,n); /* ! */ + + /* Grab the cobweb. */ + + grab(535, 25,639, 75,ch_one,n,0); + /* ^^^ Interesting point here: the ch_EGA save routine pads with black + space to the RIGHT of the object. Since this cobweb needs to be right- + justified, we must decrease x1 until xl is a multiple of 8. */ + + /* Grab Mark's signature. */ + + grab(462, 61,525, 65,ch_ega,576,195); + + /* Grab the open door. */ + + grab(180,132,294,180,ch_ega,520,127); + + /* Grab the bat. */ + + grab(354, 0,474, 28,ch_bgi,n,n); + grab(484, 0,526, 23,ch_bgi,n,n); + grab(542, 2,564, 22,ch_bgi,n,n); + + /* Grab the big fade-in face. */ + + grab(350, 71,420,105,ch_ega,n,n); /* Top line. */ + grab(421, 71,491,105,ch_ega,n,n); + + grab(350,107,419,141,ch_ega,n,n); /* Second line. */ + grab(421,107,490,141,ch_ega,n,n); + + grab(350,143,420,177,ch_ega,n,n); /* Third line. */ + grab(422,143,489,177,ch_ega,n,n); + + /* Grab the "AARGH!" */ + + grab(349, 36,361, 43,ch_bgi,aa,aa); /* A */ + grab(366, 31,385, 46,ch_bgi,aa,aa); /* Aa */ + grab(394, 34,415, 52,ch_bgi,aa,aa); /* Aar */ + grab(428, 33,457, 57,ch_bgi,aa,aa); /* Aarg */ + grab(471, 30,508, 59,ch_bgi,aa,aa); /* Aargh */ + grab(524, 30,524, 58,ch_bgi,aa,aa); /* Aargh! */ + + for( gd=0; gd <= 4; gd ++) + grab(509, 76+gd*22,551, 96+gd*22,ch_bgi,n,n); /* The big green eyes. */ + + for( gd=5; gd >= 0; gd --) + grab(181+gd*34,186,214+gd*34,199,ch_bgi,n,n); /* The red greldet. */ + + for( gd=0; gd <= 5; gd ++) + grab(390+gd*34,186,423+gd*34,199,ch_bgi,n,n); /* The blue greldet. */ + +#ifndef DRYRUN + close_chunk(); +#endif +return EXIT_SUCCESS; +} diff --git a/engines/avalanche/zapdraw.cpp b/engines/avalanche/zapdraw.cpp new file mode 100644 index 0000000000..5645fa9330 --- /dev/null +++ b/engines/avalanche/zapdraw.cpp @@ -0,0 +1,38 @@ +#include "ptoc.h" + + +#include "graph.h" +/*#include "Crt.h"*/ +/*#include "Dos.h"*/ + + +untyped_file f; +byte bit; +byte a; /*absolute $A000:0; */ +integer gd,gm; + +void graphmode(integer mode) +{ + registers regs; +; + regs.ax=(mode % 0x100); + intr(0x10,regs); +} + +int main(int argc, const char* argv[]) +{pio_initialize(argc, argv); +; + gd=3; gm=0; initgraph(gd,gm,"c:\\bp\\bgi"); + assign(f,"d:avltzap.raw"); reset(f,1); + for( bit=0; bit <= 3; bit ++) + {; + port[0x3c4]=2; port[0x3ce]=4; port[0x3c5]=1 << bit; port[0x3cf]=bit; + for( gd=0; gd <= 199; gd ++) + blockread(f,mem[0xa000*gd*80],40); /* 28000 */ + } + close(f); + setwritemode(xorput); + rectangle( 0, 0, 5, 8); + rectangle( 0, 10, 27, 19); +return EXIT_SUCCESS; +} |