Copy Link
Add to Bookmark
Report

Doom Editing Digest Vol. 01 Nr. 478

eZine's profile picture
Published in 
Doom editing
 · 6 months ago

From:      owner-doom-editing-digest 
To: doom-editing-digest@nvg.unit.no
Subject: doom-editing-digest V1 #478
Reply-To: doom-editing
Errors-To: owner-doom-editing-digest
Precedence: bulk


doom-editing-digest Sunday, 12 November 1995 Volume 01 : Number 478

Quake Scripting Language
Hexen scripting language
script decompiler
Re: Quake Scripting Language
Re: Stand Alone Node builder
Re: Hexen scripting language
Re: Hexen scripting language
Re: Hexen scripting language
Quake Scripting Language

----------------------------------------------------------------------

From: Romero <johnr@idtokay.idsoftware.com>
Date: Fri, 10 Nov 95 18:52:04 -0600
Subject: Quake Scripting Language

Hexen has a scripting language, Quake has a programming language. There is no
"scripting" per se in Quake, it's all programming.

Hence, there is NO similarity. And yes, Quake will not make Christmas.

Have lots of fun with Hexen!

- ---
+-----------------------------+
| John Romero |
| id Software, inc. |
| johnr@idsoftware.com |
| 214.613.3589.11 |
+-----------------------------+

------------------------------

From: Romero <johnr@idtokay.idsoftware.com>
Date: Fri, 10 Nov 95 18:57:27 -0600
Subject: Hexen scripting language

> Gosh, and I thought John had better things to do. Like writing
> QuakeEd. So he can write a quake editor and an hexen editor at
> the same time, while playing deathmatch half of the day?
>
> However, that confirms the impression that the hexen script language
> may be real close to .QP, and that the intermediary form of .QP might
> be that strange 'compiled' form of hexen behavior.
>
> Another reason for Luc to build a hexen script decompiler.
>

Nope. HexenEd is an extension of DoomEd, which i wrote. Chris Rhinehart and
Ben Gokey wrote the extensions to it and created HereticEd, then extended it
more into HexenEd (all versions are NEXTSTEP only). John Carmack and I
created QuakeEd which has nothing to do with our previous editors. I also
don't deathmatch 1/2 the day -- i'm making Quake all day! I'm the Lead
Designer!

Quake's programming language is called Quake C, which makes our filename
extension .QC. It USED to be .QP but i changed it.

Again, there is NO similarity between Hexen's scripting language and QC.

- ---
+-----------------------------+
| John Romero |
| id Software, inc. |
| johnr@idsoftware.com |
| 214.613.3589.11 |
+-----------------------------+

------------------------------

From: Robert Forsman <thoth@cis.ufl.edu>
Date: Fri, 10 Nov 1995 19:36:02 EST
Subject: script decompiler

OK. I had this done about 2pm, but took a nap. Now it's time for dinner
and I figure I shouldn't keep you waiting any more.

Caveats: This does not properly decompile all of the Hexen wads. There are
some branching constructs I seem to have fucked up. I know for a fact that I
don't do the do-while or do-until, and I'm getting diagnostics that say I'm
misinterpreting some branching spaghetti. I'll fix it eventually.

Caveat 2: You certainly can't turn around and recompile the output. I'm
sure there are semicolons out of place. I also don't do anything with
strings. I need to add argument recognition to the function opcode
recognizer. This will enable me to put strings in their proper place in the
arguments.

One good thing about me doing this first. Nobody has to cough up an ounce
of bud or a kilo, just a case of beer (which is much less illegal). I think
I'm going to go drinking.

Maybe I'll install my new ethernet card first (WOOHOO, my pentium is wired
in 30 minutes!)

#!/usr/bin/perl

@opeqnames = ("+=", "-=", "*=", "/=", "%=", "++", "--" );
@vartypes = ("lvar", "mvar", "gvar");
@opnames = ("+", "-", "*", "/", "%",
"==", "!=", "<", ">", "<=", ">=");

%codes = (
1, "0 proc terminate",
2, "0 proc suspend",
# 3 literal
# 4..8 special proc
# 9..13 special proc const args
# 14..24 infix operators
# 25..27 assignment
# 28..30 variable load
# 31..51 op-assign
# 52 branch
# 53 branch non-zero?
54, "1 proc ignore",
# 54 pop (endcase)
55, "1 proc delay",
56, "1 constproc delay",
57, "2 func random",
58, "2 constfunc random",
59, "2 func thingcount",
60, "2 constfunc thingcount",
61, "1 proc tagwait",
62, "1 constproc tagwait",
63, "1 proc polywait",
64, "1 constproc polywait",
65, "2 proc changefloor",
66, "2 constproc changefloor",
67, "2 proc changeceiling",
68, "2 constproc changeceiling",

70, "2 infix &&",
71, "2 infix ||",
72, "2 infix &",
73, "2 infix |",
74, "2 infix ^",
75, "2 infix !",
76, "2 infix <<",
77, "2 infix >>",
78, "1 func -",
# 79 branch zero ("unless")
80, "0 func lineside",
81, "1 proc scriptwait",
82, "1 constproc scriptwait",
83, "0 proc clearlinespecial",
# 84 case goto
85, "0 proc printbegin",
86, "0 proc printdispatch",
87, "1 proc printstring",
88, "1 proc printdecimal",
89, "1 proc printconst",
##
90, "0 func playercount",
91, "0 func gametype",
92, "0 func gameskill",
93, "0 func timer",
94, "2 proc sectorsound",
95, "2 proc ambientsound",
96, "1 proc soundsequence",
97, "4 proc setlinetexture",
98, "2 proc setlineblocking",
99, "7 proc setlinespecial",
100, "3 proc thingsound",
101, "0 proc printBOLDdispatch",
);

%functions = (
);


sub int_at
{
local ($offset) = @_;
return unpack("I", substr($behavior, $offset, 4));
}

sub decode
{
local ($idx, $base) = @_;
local ($offset) = $idx + $base;
local ($opcode) = &int_at($offset);
local ($arg1) = &int_at($offset + 4);
local ($arg2) = &int_at($offset + 8);
local ($advance, $str); # multiply $advance by 4 before returning
local ($indentadj);

local ($i);
for ($i=0; $i<@curlies; $i++) {
local ($o, $n) = split(" ", $curlies[$i]);
if ($o == $offset) {
if ($o+$n == $breakables[0]) {
shift(@breakables);
shift(@continuables);
}
printf "\t%04d\t%s}\t\n", $offset, " "x($indent-=4);
splice(@curlies, $i, 1);
if ($n) {
return $n;
} else {
$i--;
}
}
}

for ($i=0; $i<@elses; $i++) {
if ($offset == $elses[$i]) {
printf "\t%04d\t%s} else {\t\n", $offset, " "x($indent-4);
# print("} else {\t\n\t");
splice(@elses, $i, 1);
return 8;
}
}

for ($i=0; $i<@cases; $i++) {
local ($o, $n) = split(" ", $cases[$i]);
if ($offset == $o) {
printf "\t%04d\t%scase $n:\t\n", $offset, " "x($indent-4);
splice(@cases, $i, 1);
$i--;
}
}

if (@stack == 0) {
$lastemptystack = $offset;
}

if (defined($codes{$opcode})) {
local ($arity, $fixness, $name) = split(/ /, $codes{$opcode});
$advance = 1;
local (@args);
local ($prefix);
if ($fixness =~ s/^const//) {
$prefix = "const: ";
for ($i=0; $i<$arity; $i++) {
push(@args, &int_at($offset+4+$i*4));
$advance++;
}
} else {
@args = splice(@stack, scalar(@stack)-$arity);
}
if ($fixness eq "proc") {
$str = "$name($prefix".join(", ", @args).");";
} elsif ($fixness eq "func") {
local ($tmp) = "$name($prefix".join(", ", @args).")";
$str = "\t # $tmp";
push(@stack, $tmp);
} elsif ($fixness eq "infix") {
local ($tmp) = "(".join(" $name ", @args).")";
$str = "\t \# $tmp";
push(@stack, $tmp);
} else {
die "bad fixness $fixness for opcode $opcode";
}
} elsif ($opcode == 3) {
$advance = 2;
$str = "\t # literal $arg1";
push(@stack, $arg1);
} elsif ($opcode >= 4 && $opcode < 9) {
$advance =2;
local ($arity) = $opcode-3;
#$str = "special ";
local ($i);
for ($i=0; $i*3<@specials; $i++) {
if ($arity == $specials[$i*3+2] && $arg1==$specials[$i*3]) {
last;
}
}
if ($i*3<@specials) {
$str .= $specials[$i*3+1];
} else {
$str .= "code$arg1";
}
if (@stack >= $arity) {
@args = splice(@stack, @stack-$arity);
$str .= "(".join(", ", @args).");";
} else {
die "Stack is short [@stack]";
}

} elsif ($opcode >= 9 && $opcode < 14) {
local ($arity) = $opcode-8;
$advance =2+$arity;
$str = "";
local ($i, @args);
for ($i=0; $i*3<@specials; $i++) {
if ($arity == $specials[$i*3+2] && $arg1==$specials[$i*3]) {
last;
}
}
if ($i*3<@specials) {
$str .= $specials[$i*3+1];
} else {
$str .= "code$arg1";
}

local (@args);
for ($i=0; $i<$arity; $i++) {
push(@args, &int_at($offset+4+4*$i));
}
$str .= "(const: ".join(", ", @args).");";

} elsif ($opcode >= 14 && $opcode <=24) {
$advance = 1;
$str = "\t # ".$opnames[$opcode-14];
local ($rhs) = pop(@stack);
local ($lhs) = pop(@stack);
push(@stack, "(".$lhs.$opnames[$opcode-14].$rhs.")");
} elsif ($opcode >24 && $opcode<=27) {
$advance = 2;
local ($vartype) = $vartypes[$opcode-25];
#$str = "store $vartype[$arg1]\n";
$str = "$vartype[$arg1] = ".pop(@stack);
} elsif ($opcode >= 28 && $opcode<30) {
$advance = 2;
local ($vartype) = $vartypes[$opcode-28];
$str = "\t # load $vartype[$arg1]";
push(@stack, "$vartype[$arg1]");
} elsif ($opcode>=31 && $opcode <52) {
$advance = 2;
local ($op) = $opeqnames[($opcode-31)/3];
local ($vartype) = $vartypes[($opcode-31)%3];
if ($opcode<50) {
$str = "$vartype[$arg1] $op ". pop(@stack). ";";
} else {
$str = "$vartype[$arg1] $op ;";
}
} elsif ($opcode == 52) {
$advance = 2;
if (&int_at($arg1) == 84) {
$str = "switch (".pop(@stack).") {";
# case statement
for ($i=0; &int_at($arg1+$i*12) == 84; $i++) {
local ($const) = &int_at($arg1+$i*12 + 4);
local ($off) = &int_at($arg1+$i*12 + 8);
push(@cases, "$off $const");
}
local ($breakaddr);
if (&int_at($arg1+$i*12) == 54) {
if (&int_at($arg1+$i*12 +4) == 52) { #
local ($off) = &int_at($arg1+$i*12+8);
push(@cases, "$off default");
$breakaddr = $arg1+ $i*12 +12;
} else {
$breakaddr = $arg1+ $i*12 +4;
}
push(@curlies, "$arg1 ".($breakaddr-$arg1));
} else {
print "//funky, unexpected end of case\n";
push(@curlies, "$arg1 ".($i*12));
$breakaddr = ($arg1+$i*12);
}
unshift(@breakables, $breakaddr);
unshift(@continuables, 0);
# print "# new{break,continu}able $breakaddr, 0\n";
$indentadj = 4;
} elsif ($arg1 == $breakables[0]) {
$str = "break";
} elsif ($arg1 == $continuables[0]) {
$str = "continue";
} else {
$str = "br $arg1";
}
} elsif ($opcode == 53) {
$advance = 2;
$indentadj = 4;
if (&int_at($arg1-8) == 52) {
if (&int_at($arg1-4) == $lastemptystack) {
# a while statement
$str = "until (" . pop(@stack) . ") {";
push(@curlies, ($arg1-8)." 8");
unshift(@breakables, $arg1);
unshift(@continuables, $lastemptystack);
# print "# new{break,continu}able $arg1, $lastemptystack\n";
} else {
# an ifelse
$str = "unless (" . pop(@stack) . ") {";
push(@elses, ($arg1-8));
push(@curlies, &int_at($arg1-4)." 0");
}
} elsif ($arg1 > $offset) {
$str = "if (" . pop(@stack) . ") {";
push(@curlies, $arg1." 0");
} else {
$str = "bnz $arg1 " . pop(@stack);
$indentadj = 0;
}
# $str = "bnz $arg1\n";
} elsif ($opcode == 69) {
$advance = 1;
$str = "restart";
} elsif ($opcode == 79) {
$advance = 2;
$indentadj = 4;
local ($handled) = 0;
if ($arg1 > $offset && &int_at($arg1-8) == 52) {
if (&int_at($arg1-4) == $lastemptystack) {
# a while statement
$str = "while (" . pop(@stack) . ") {";
push(@curlies, ($arg1-8)." 8");
unshift(@breakables, $arg1);
unshift(@continuables, $lastemptystack);
# print "# new{break,continu}able $arg1, $lastemptystack\n";
$handled = 1;
} else {
# an ifelse
$str = "if (" . pop(@stack) . ") {";
push(@elses, ($arg1-8));
push(@curlies, &int_at($arg1-4)." 0");
$handled = 1;
}
}
if (!$handled) {
if ($arg1 > $offset) {
$str = "if (" . pop(@stack) . ") {";
push(@curlies, $arg1." 0");
} else {
$indentadj = 0;
$str = "bz $arg1 " . pop(@stack);
}
}
} elsif ($opcode == 84) {
$advance = 3;
$str = "case ==$arg1 br $arg2";
} else {
$advance = 0;
$str = "unknown";
}
unless ($str =~ /^\s*\#/) {
printf "\t%04d\t%s%s\n", $offset, " "x$indent, $str;
if (@stack!=0) {
warn "// previous statement had stack leftovers ";
}
}
$indent += $indentadj;
return $advance*4;
}

while (@ARGV) {
if ($ARGV[0] eq "-specials") {
shift;
local ($fname) = shift;
open(FILE, $fname) || die "Unable to open $fname for read";
while (<FILE>) {
if (/(\d+)\s*:\s*(\w+)\s*\(\s*(\d+)\s*\)\s*[,;]/) {
push(@specials, $1, $2, $3);
}
}
} else {
last;
}
}

undef $/;
$behavior = <>;

$diroff = &int_at(4);

$dirlen = &int_at($diroff);
for ($i=0; $i<$dirlen; $i++) {
local ($idx) = ($i*3+1)*4+$diroff;
print "script ", &int_at($idx), " {\n";
local ($offset) = &int_at($idx+4);
local ($len);
if ($i+1<$dirlen) {
$len = &int_at($idx+16) - $offset;
} elsif (&int_at($idx+12)==0) {
$len = $diroff - $offset;
} else {
# print "length calc. ", &int_at($idx + 16), "\n";
$len = &int_at($idx + 16) - $offset;
}
$j = 0;
while ($j<$len) {
local ($advance) = &decode($j,$offset);
if ($advance > 0 && $advance+$j <= $len) {
#print "$str\n\t";
$j += $advance;
} else {
last;
}
}
while ($j<$len) {
printf "%5d ", &int_at($j+$offset);
if (($j/4+1)%10 == 0) {
print "\n\t";
} else {
# print "\t";
}
$j+=4;
}
print "}\n\n";
if ($indent != 0) {
warn "leftover indentation = $indent\n";
$indent = 0
}
if (@stack) {
warn "leftover stack: [", join(", ", @stack), "]\n";
@stack = ();
}
if (@curlies) {
warn "spare curlies: [", join(", ", @curlies), "]\n";
@curlies = ();
}
if (@elses) {
warn "spare elses: [", join(", ", @elses), "]\n";
@elses = ();
}
if (@cases) {
warn "spare cases: [", join(", ", @cases), "]\n";
@cases = ();
}
if (@breakables) {
warn "spare breakables: [", join(", ", @breakables), "]\n";
@breakables = ();
}
}

$stroff = $diroff + ($dirlen*12 + 4);

$nstrs = &int_at($stroff);

for ($i=0; $i<$nstrs; $i++) {
local ($offset) = &int_at($stroff+($i+1)*4);
local ($tmp) = substr($behavior, $offset);
if ($tmp =~ /^([^\0]*)/) {
print "String $i: $1\n";
} else {
warn "problem extracting string #$i from offset $offset\n";
}
}

------------------------------

From: Jim Wraith <jim@kildare.demon.co.uk>
Date: Sat, 11 Nov 1995 08:39:59 GMT
Subject: Re: Quake Scripting Language

In your message dated Friday 10, November 1995 you wrote :
> Hence, there is NO similarity. And yes, Quake will not make Christmas.

Bummer.

> Have lots of fun with Hexen!
>

Looks as though I'll have to now :)


<sulk mode on>

------------------------------

From: Michael Deckerd <deckerd@gonzo.wolfenet.com>
Date: Sat, 11 Nov 1995 10:56:14 -0800
Subject: Re: Stand Alone Node builder

At 06:29 PM 11/10/95 EST, you wrote:
>Matt --
>
>You can get ZenNode at ftp.cdrom.com as ZEN095.ZIP. It works in DOS, Win95,
>NT, and OS/2.
>
>- John
>
>-----------------------
>John W. Anderson
>dr_sleep@cis.compuserve.com @ 10-Nov-95 18:24:35 EST
>
>
...Okie, now where can you get HETH-B13? The closes version I can find is
HETH-B11...

------------------------------

From: Walter Meyer <wrmeyer@immd3.informatik.uni-erlangen.de>
Date: Sat, 11 Nov 1995 20:22:22 +0100 (MET)
Subject: Re: Hexen scripting language

>
> > Gosh, and I thought John had better things to do. Like writing
> > QuakeEd. So he can write a quake editor and an hexen editor at
> > the same time, while playing deathmatch half of the day?
> >
> > However, that confirms the impression that the hexen script language
> > may be real close to .QP, and that the intermediary form of .QP might
> > be that strange 'compiled' form of hexen behavior.
> >
> > Another reason for Luc to build a hexen script decompiler.
> >
>
> Nope. HexenEd is an extension of DoomEd, which i wrote. Chris Rhinehart and
> Ben Gokey wrote the extensions to it and created HereticEd, then extended it
> more into HexenEd (all versions are NEXTSTEP only). John Carmack and I
> created QuakeEd which has nothing to do with our previous editors. I also
> don't deathmatch 1/2 the day -- i'm making Quake all day! I'm the Lead
> Designer!

If you have access to all those tools, why did you ask for third party
editors? Missing features like auto-align-textures, consistency check, etc.?
Don't write mails, design! 8)

Bye, Walter

P.S. Did you know that, according to one of our games mags, Carmack has left
ID Software to found a new company called Crack Dot Com, where he is
currently working on a game called Abuse?

- --
email: wrmeyer@cip.informatik.uni-erlangen.de

------------------------------

From: joost schuur <jschuur@jalad.globalnews.com>
Date: Sat, 11 Nov 1995 21:18:44 +0000 (GMT)
Subject: Re: Hexen scripting language

On Sat, 11 Nov 1995, Walter Meyer wrote:

> P.S. Did you know that, according to one of our games mags, Carmack has left
> ID Software to found a new company called Crack Dot Com, where he is
> currently working on a game called Abuse?

not true. dave taylor is funding the company of some friends called
'crack dot com'. they previosly released a cross platform paint programm
called 'satan paint' and just recently a platform game called 'abuse'.
(see http://www.crack.com).

neither dave nor john c left id.

</j>

------------------------------

From: Robert Forsman <thoth@cis.ufl.edu>
Date: Sat, 11 Nov 1995 15:33:24 EST
Subject: Re: Hexen scripting language

Walter Meyer <wrmeyer@immd3.informatik.uni-erlangen.de> ,in message <1995111119
22.UAA18474@faui30v.immd3.informatik.uni-erlangen.de>, wrote:

> P.S. Did you know that, according to one of our games mags, Carmack has lef
>> t
> ID Software to found a new company called Crack Dot Com, where he is
> currently working on a game called Abuse?

I've seen the game. The snareware is distributed in the Y section of
Slackware 3.0. You're this guy who looks like a Predator and you fight
critters that look like Aliens, but have guns and rockets. It's a side-view
hop and shoot. It's cute, but I've spent too much money on hardware
recently.

------------------------------

From: jbrown@odont.com (Morphius)
Date: 11 Nov 1995 15:57:28 PDT
Subject: Quake Scripting Language

What happened?!?! (i know this is off subject) Why isn't Quake making
Christmas?!?! Is it because you forgot to work on it or something?!?!
Since it ain't making Christmas gamers are going to expect a lot more
from it so it better be good.

------------------------------

End of doom-editing-digest V1 #478
**********************************

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

guest's profile picture
@guest
12 Nov 2024
It is very remarkable that the period of Atlantis’s destruction, which occurred due to earthquakes and cataclysms, coincides with what is co ...

guest's profile picture
@guest
12 Nov 2024
Plato learned the legend through his older cousin named Critias, who, in turn, had acquired information about the mythical lost continent fr ...

guest's profile picture
@guest
10 Nov 2024
الاسم : جابر حسين الناصح - السن :٤٢سنه - الموقف من التجنيد : ادي الخدمه - خبره عشرين سنه منهم عشر سنوات في كبرى الشركات بالسعوديه وعشر سنوات ...

lostcivilizations's profile picture
Lost Civilizations (@lostcivilizations)
6 Nov 2024
Thank you! I've corrected the date in the article. However, some websites list January 1980 as the date of death.

guest's profile picture
@guest
5 Nov 2024
Crespi died i april 1982, not january 1980.

guest's profile picture
@guest
4 Nov 2024
In 1955, the explorer Thor Heyerdahl managed to erect a Moai in eighteen days, with the help of twelve natives and using only logs and stone ...

guest's profile picture
@guest
4 Nov 2024
For what unknown reason did our distant ancestors dot much of the surface of the then-known lands with those large stones? Why are such cons ...

guest's profile picture
@guest
4 Nov 2024
The real pyramid mania exploded in 1830. A certain John Taylor, who had never visited them but relied on some measurements made by Colonel H ...

guest's profile picture
@guest
4 Nov 2024
Even with all the modern technologies available to us, structures like the Great Pyramid of Cheops could only be built today with immense di ...

lostcivilizations's profile picture
Lost Civilizations (@lostcivilizations)
2 Nov 2024
In Sardinia, there is a legend known as the Legend of Tirrenide. Thousands of years ago, there was a continent called Tirrenide. It was a l ...
Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT