/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /* * This code is based on the original source code of Lord Avalot d'Argent version 1.3. * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman. */ /*$M 10000,0,1000*/ /*$V-*/ /*#include "Dos.h"*/ /*#include "Tommys.h"*/ namespace Avalanche { 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=""; 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; } } // End of namespace Avalanche.