!! CZECH: Comprehensive Z-machine Emulation CHecker
!!
!! Tests requiring user interaction (input or looking at output)
!!
!! Amir Karger
!! See README.txt for license. (Basically, use/copy/modify, but be nice.)
!! TODO
!! - output_streams using different input streams
!! - exhaust input file OR switch it off manualy
!! - show_status #ifndef V4PLUS
!! - 'read' opcode using either input stream & various output streams
!! - transcript bit set/cleared correctly for stream 2
!! - 'read' word separators and space separation
!! - use set_cursor to print a magic square. Also in upper window.
!! Also, create frame in lower window, fill in in upper
!! - text styles (in different windows (and streams?)
!! - more amusing print strings
! ---- PRINT opcodes ----------------------------------
[ test_print do_this i j;
print "Print opcodes";
@jz do_this ?~skipped;
print " skipped";
rfalse;
.skipped;
print " [", Testnum+1, "]: ";
! Note: pt()'s best location is after you print what should come out
! and before you actually print it. But we may get some off-by-ones
@print "Tests should look like... '[Test] opcode (stuff): stuff'";
@print "^print_num (0, 1, -1, 32767,-32768, -1): "; pt();
@print_num 0; print ", ";
i = 1;
@print_num i; print ", "; pt();
@print_num n1; print ", "; pt();
@print_num 32767; print ", "; pt();
@print_num n32768; print ", "; pt();
i = 65535;
@print_num i; pt();
print "^[", Testnum+1, "] ";
print "print_char (abcd): ";
@print_char 'a'; pt();
@print_char 98; pt();
i = 99;
@print_char i; pt();
@push 100; pt();
@print_char sp;
@print_char 13; pt();
@print "This string should be on its own line.";
print "^[", Testnum+1, "] ";
print "new_line:^"; pt();
@new_line;
@print "There should be an empty line above this line.^";
i = do_print_ret(); pt(); ! test printing AND return
assert0(i, 1);
! TODO Once we have objects, print_addr of first word in dictionary.
! I could also write stuff to globalvars (as long as I knew what
! offset they'd have) then load the address from 0->0c and print_addr.
@print "^print_addr (Hello.): "; pt();
@storew mytable 0 $11aa; ! 4 13 10: Shift-He
@storew mytable 1 $4634; ! 17 17 20: llo
@storew mytable 2 $1645; ! 5 18 5: A2 . A2
@storew mytable 3 $9ca5; ! 7 5 5: \n space-fill
! FYI xyzzy is 77df ffc5
! print mytable->1;
@print_addr mytable;
@print "^print_paddr (A long string that Inform will put in high memory):^";
pt();
print "A long string that Inform will put in high memory";
! Break up print statement to NOT use abbrev in parenthetical part
print "^Abbreviations (I love 'xyz"; print "zy' [two times]): "; pt();
i = "I love 'xyzzy' ";
@print_paddr i;
pt();
@print " I love 'xyzzy'^";
! TODO @print_paddr sp, global vars
! TODO test word wrapping
print "^[", Testnum+1, "] ";
@print "print_obj (Test Object #1Test Object #2): "; pt();
@print_obj Obj1; pt();
@print_obj Obj2;
! TODO long test object name
! Word wrap
pt();
print "^This is an extremely long string which should definitely get wrapped even if you have a whole lot of columns in your particular output device, whatever it may be.^";
! More
i = 0->32;
@je i 255 ?skip_more;
pt();
print "Test paging functionality^";
for (j = 0: j < i * 2 + 5: j++) print j,"^";
.skip_more;
! TODO print many more complicated things, Unicode, whatever
! TODO use unfinished abbreviations.
rtrue;
];
[ do_print_ret;
@print_ret "print_ret (should have newline after this)";
];
! ---- Header ----------------------------------
!Global standard;
[ test_header do_this flags i j;
print "Header";
@jz do_this ?~skipped;
print " skipped";
rfalse;
.skipped;
!print " [", Testnum+1, "]: ";
print " (No tests)";
! standard = 0->50;
@loadb 0 50 -> i;
@loadb 0 51 -> j;
if(i || j)
print "^ standard ", i, ".", j, " ";
!print "interpreter ", 0->30, (char) 0->31;
@loadb 0 30 -> i;
print "^ interpreter ", i, " ";
@loadb 0 31 -> i;
@print_char i;
@loadb 0 30 -> i;
print " ("; say_platform(i); print ")";
for(i = 0: i < 2: i++) {
if(i == 0)
print "^ Flags on: ";
else
print "^ Flags off: ";
@loadb 0 1 -> flags;
#Ifdef V4PLUS;
do_say_flags(i, flags & 1, "color");
do_say_flags(i, flags & 2, "pictures");
do_say_flags(i, flags & 4, "boldface");
do_say_flags(i, flags & 8, "italic");
do_say_flags(i, flags & 16, "fixed-space");
do_say_flags(i, flags & 32, "sound");
do_say_flags(i, flags & 128, "timer");
#Ifnot;
do_say_flags(i, flags & 2, "time game");
do_say_flags(i, flags & 4, "story file split");
do_say_flags(i, flags & 16, "NO status");
do_say_flags(i, flags & 32, "screen-splitting");
do_say_flags(i, flags & 64, "variable-pitch-default");
#Endif;
!flags2
@loadw 0 8 -> flags;
do_say_flags(i, flags & 1, "transcripting on");
do_say_flags(i, flags & 2, "fixed-pitch on");
#Ifdef V5PLUS;
! TODO comment out v6 stuff if #version_number == 5
do_say_flags(i, flags & 4, "redraw pending");
do_say_flags(i, flags & 8, "using pictures");
do_say_flags(i, flags & 16, "using undo");
do_say_flags(i, flags & 32, "using mouse");
do_say_flags(i, flags & 64, "using colors");
do_say_flags(i, flags & 128, "using sound");
do_say_flags(i, flags & 256, "using menus");
#Endif;
}
#Ifdef V4PLUS;
! These are all width x height
print "^ Screen size: ", 0->33, "x", 0->32;
#Endif;
#Ifdef V5PLUS;
print "; in ", 0->38, "x", 0->39, " units: ", 0-->17, "x", 0-->18;
print "^ Default color: ";
say_color(0->45); print " on "; say_color(0->44);
#Endif;
! TODO v6 has font width/height switched
@loadb 0 56 -> i;
if (i) {
print "^ User: ";
for(i = 56: i < 64: i++)
@loadb 0 i -> j;
@print_char j;
}
];
[ do_say_flags i cond text;
if((~~cond) == i) {
@print_paddr text;
print ", ";
}
];
#Ifdef V5PLUS;
[ say_color c;
switch(c) {
0: print "current"; return;
1: print "default"; return;
2: print "black"; return;
3: print "red"; return;
4: print "green"; return;
5: print "yellow"; return;
6: print "blue"; return;
7: print "magenta"; return;
8: print "cyan"; return;
9: print "white"; return;
10: print "light grey"; return;
11: print "medium grey"; return;
12: print "dark grey"; return;
}
print "UNKNOWN";
];
#Endif;
[ say_platform p;
switch(p) {
1: print "DECSystem-20"; return;
2: print "Apple IIe"; return;
3: print "Macintosh"; return;
4: print "Amiga"; return;
5: print "Atari ST"; return;
6: print "IBM PC"; return;
7: print "Commodore 128"; return;
8: print "Commodore 64"; return;
9: print "Apple IIc"; return;
10: print "Apple IIgs"; return;
11: print "Tandy Color"; return;
}
];
! ---- Streams ----------------------------------
[ test_streams do_this;
print "Streams";
@jz do_this ?~skipped;
print " skipped";
rfalse;
.skipped;
print " [", Testnum+1, "]: ";
print "output_stream^";
pt();
@output_stream(-1);
print "This shouldn't print.^"; pt();
@output_stream(1);
print "1 (only). "; pt();
@output_stream(2);
print "1 and 2. "; pt();
! TODO I should be calling other print calls
@output_stream(-1);
print "2 again (only). "; pt();
@output_stream(-2);
print "This shouldn't print.^"; pt();
pt();
@output_stream(1);
print "1 only again.^";
! @output_stream 3 mytable;
! print "...looks ";
! @output_stream 3 mysecond;
! print " to me...";
! @output_stream -3;
! print "good";
! @output_stream -3;
! for(i = 0: i < mytable-->0: i++)
! print (char) mytable->(i+2);
! for(i = 0: i < mysecond-->0: i++)
! print (char) mysecond->(i+2);
rtrue;
];
! Only purpose of this sub is to use vars declared in included files
! so the compiler doesn't complain.
[ make_compiler_happy_io i;
i = n2; i = n3; i = n4; i = n5; i = n500; i = n32768;
i = count;
i = Gtemp;
i = 0; if (i) make_compiler_happy_io();
assert1(1, 1);
assert2(1, 1, "foo", 1, 1);
];
! vim: tw=78 sw=3 ft=Inform