Inform - Support - Patches

About Patches  

Compiler  
Library  

DM4 Errata  

Issue L61022

Inform's standard screen effects don't work in V6
Submitted by: Kevin Bracey     Appeared in: Library 6/10 or before     Fixed in: Library 6/11
Problem

The screen handling in the standard library and veneers doesn't work properly in V6. This has been addressed to a large degree by V6Lib, but this really shouldn't be necessary for the basic stuff. The DM4 in particular gives no clue that standard Inform doesn't function correctly in V6.

Given that anyone attempting anything ambitious displaywise with V6 will probably use V6Lib or replace all the standard routines anyway, there's no point in providing anything more than basic functionality, but the standard routines should at least work. It certainly drives me nuts when knocking up simple textual V6 programs.

Here is a V6-compatible version of menus.h, superseding the one available from the Archive.

Solution

The routines affected are KeyboardPrimitive(), DrawStatusLine(), Box__Routine(), VersionSub() and DoMenu().

--- parserm~    Sat Nov 13 11:29:22 1999
+++ parserm     Wed Nov 28 21:35:15 2001
@@ -605,6 +605,14 @@

 [ KeyboardPrimitive  a_buffer a_table;
   read a_buffer a_table;
+#iftrue #version_number == 6;
+  @output_stream -1;
+  @loadb a_buffer 1 -> sp;
+  @add a_buffer 2 -> sp;
+  @print_table sp sp;
+  new_line;
+  @output_stream 1;
+#endif;
 ];
 [ Keyboard  a_buffer a_table  nw i w w2 x1 x2;

@@ -4380,6 +4388,75 @@
 ! ----------------------------------------------------------------------------

 #IFV5;
+#Iftrue #version_number == 6;
+[ DrawStatusLine width charw height wx wy x y scw mvw;
+   ! Split the window. Standard 1.0 interpreters should keep the window 0
+   ! cursor in the same absolute position, but older interpreters,
+   ! including Infocom's don't - they keep the window 0 cursor in the
+   ! same position relative to its origin. We therefore compensate
+   ! manually.
+   @get_wind_prop 0 0 -> wy; @get_wind_prop 0 1 -> wx;
+   @get_wind_prop 0 13 -> height; @log_shift height $FFF8 -> height;
+   @get_wind_prop 0 4 -> y; @get_wind_prop 0 5 -> x;
+   @split_window height;
+   y = y - height + wy - 1;
+   if (y < 1) y = 1;
+   x = x + wx - 1;
+   @set_cursor y x 0;
+   ! Now clear it. This isn't totally trivial. Our approach is to select the
+   ! fixed space font, measure its width, and print an appropriate
+   ! number of spaces. We round up if the screen isn't a whole number
+   ! of characters wide, and rely on window 1 being set to clip by default.
+   @set_window 1;
+   @set_cursor 1 1;
+   @set_font 4 -> x;
+   style reverse;
+   @get_wind_prop 1 3 -> width;
+   @get_wind_prop 1 13 -> charw;
+   charw = charw & $FF;
+   spaces (width+charw-1) / charw;
+   ! Back to standard font for the display. We use output_stream 3 to
+   ! measure the space required, the aim being to get 50 characters
+   ! worth of space for the location name.
+   x = 1+charw;
+   @set_cursor 1 x;
+   @set_font 1 -> x;
+   @get_wind_prop 1 13 -> charw;
+   charw = charw & $FF;
+   if (location == thedark) print (name) location;
+   else
+   {   FindVisibilityLevels();
+       if (visibility_ceiling == location)
+           print (name) location;
+       else print (The) visibility_ceiling;
+   }
+   @output_stream 3 StorageForShortName;
+   print (string) SCORE__TX, "00000";
+   @output_stream -3; scw = 0-->24 + charw;
+   @output_stream 3 StorageForShortName;
+   print (string) MOVES__TX, "00000";
+   @output_stream -3; mvw = 0-->24 + charw;
+   if (width - scw - mvw >= 50*charw)
+   {   x = 1+width-scw-mvw;
+       @set_cursor 1 x; print (string) SCORE__TX, sline1;
+       x = x+scw;
+       @set_cursor 1 x; print (string) MOVES__TX, sline2;
+   }
+   else
+   {   @output_stream 3 StorageForShortName;
+       print "00000/00000";
+       @output_stream -3; scw = 0-->24 + charw;
+       if (width - scw >= 50*charw)
+       {   x = 1+width-scw;
+           @set_cursor 1 x; print sline1, "/", sline2;
+       }
+   }
+   ! Reselect roman, as Infocom's interpreters interpreters go funny
+   ! if reverse is selected twice.
+   style roman;
+   @set_window 0;
+];
+#Ifnot;
 [ DrawStatusLine width posa posb;
    @split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
    width = 0->33; posa = width-26; posb = width-13;
@@ -4408,11 +4485,92 @@
    }
    @set_cursor 1 1; style roman; @set_window 0;
 ];
+#Endif;
 #ENDIF;

 #ifv5;
 Array StorageForShortName --> 161;
 #endif;
+
+#Iftrue #version_number==6;
+
+! ----------------------------------------------------------------------------
+! Replace the compiler's built-in box handling code, which only works with
+! the V4/V5 screen model.
+! ----------------------------------------------------------------------------
+
+[ Box__Routine maxw table n w w2 lc t y x of cw ch s;
+    n = table --> 0;
+    @set_font 4 -> of;
+    @get_wind_prop 0 0 -> y;
+    @get_wind_prop 0 1 -> x;
+    @get_wind_prop 0 3 -> w;
+    @get_wind_prop 0 13 -> ch;
+    cw = ch & $ff;
+    @log_shift ch $fff8 -> ch;
+    @set_font of -> temp_global;
+    if (maxw < 160)
+    {   maxw = 0; lc = 1;
+        do
+        {   t = table --> lc;
+            if (t~=0)
+            {   @output_stream 3 StorageForShortName;
+                print (string) t;
+                @output_stream -3;
+                t = 0-->24;
+                if (t > maxw) maxw = t;
+            }
+            lc++;
+        } until (lc > n);
+    }
+    else maxw = maxw*cw;
+    s = (maxw + cw - 1) / cw + 4;
+    w2 = s * cw;
+    x = x+(w-w2)/2;
+    y = y+ch*2;
+    @move_window 1 y x;
+    y = (n+2)*ch;
+    @window_size 1 y w2;
+    x = (w2-maxw)/2;
+    @set_window 1;
+    @set_font 4 -> temp_global;
+    style reverse;
+    y = 1+ch;
+    lc = 1;
+    @set_cursor 1 1;
+    spaces s;
+    do
+    {   @set_cursor y 1;
+        spaces s;
+        t = table --> lc;
+        if (t~=0)
+        {  @set_cursor y x;
+           @set_font 1 -> sp;
+           print (string) t;
+           @set_font sp -> temp_global;
+        }
+        y=y+ch; lc++;
+    } until (lc > n);
+    @set_cursor y 1;
+    spaces s;
+    style roman;
+    @set_window 0;
+    @output_stream -1;
+    print "[ ";
+    lc = 1;
+    do
+    {   w = table --> lc;
+        if (w ~= 0) print (string) w;
+        lc++;
+        if (lc > n)
+        {   print "]^^";
+            break;
+        }
+        print "^  ";
+    } until (false);
+    @output_stream 1;
+];
+#Endif;

 [ PrefaceByArticle o acode pluralise  i artform findout;

--- verblibm~   Sat Nov 13 11:29:15 1999
+++ verblibm    Wed Nov 28 19:13:51 2001
@@ -47,10 +47,25 @@
 [ VersionSub;
   Banner();
   if (standard_interpreter > 0)
-      print "Standard interpreter ",
+  {   print "Standard interpreter ",
           standard_interpreter/256, ".", standard_interpreter%256,
-          " (", 0->$1e, (char) 0->$1f, ") / ";
-  else print "Interpreter ", 0->$1e, " Version ", (char) 0->$1f, " / ";
+          " (", 0->$1e;
+#iftrue #version_number == 6;
+      print (char) '.', 0->$1f;
+#ifnot;
+      print (char) 0->$1f;
+#endif;
+      print ") / ";
+  }
+  else
+  {   print "Interpreter ", 0->$1e, " Version ";
+#iftrue #version_number == 6;
+      print 0->$1f;
+#ifnot;
+      print (char)0->$1f;
+#endif;
+      print " / ";
+  }
   print "Library serial number ", (string) LibSerial, "^";
 #IFDEF LanguageVersion;
   print (string) LanguageVersion, "^";
@@ -601,7 +616,7 @@

 #IFV5;
 [ DoMenu menu_choices EntryR ChoiceR
-         lines main_title main_wid cl i j oldcl pkey;
+         lines main_title main_wid cl i j oldcl pkey ch cw y x;

   if (pretty_flag==0)
       return LowKey_Menu(menu_choices,EntryR,ChoiceR);
@@ -615,34 +630,49 @@
   .ReDisplay;
       oldcl=0;
       @erase_window $ffff;
-      i=lines+7;
+      #Iftrue #version_number==6;
+      @set_cursor -1;
+      ch=0->38;
+      #Ifnot;
+      ch=1;
+      #Endif;
+      i=ch*(lines+7);
       @split_window i;
-      i = 0->33;
+      i=0->33;
       if (i==0) i=80;
       @set_window 1;
       @set_cursor 1 1;
+      #Iftrue #version_number==6;
+      @set_font 4 -> cw;
+      cw=0->39;
+      #Ifnot;
+      cw=1;
+      #Endif;
       style reverse;
-      spaces(i); j=i/2-main_wid;
+      spaces(i); j=1+(i/2-main_wid)*cw;
       @set_cursor 1 j;
       print (string) main_title;
-      @set_cursor 2 1; spaces(i);
-      @set_cursor 2 2; print (string) NKEY__TX;
-      j=i-12; @set_cursor 2 j; print (string) PKEY__TX;
-      @set_cursor 3 1; spaces(i);
-      @set_cursor 3 2; print (string) RKEY__TX;
-      j=i-17; @set_cursor 3 j;
+      y=1+ch; @set_cursor y 1; spaces(i);
+      x=1+cw; @set_cursor y x; print (string) NKEY__TX;
+      j=1+(i-13)*cw; @set_cursor y j; print (string) PKEY__TX;
+      y=y+ch; @set_cursor y 1; spaces(i);
+      @set_cursor y x; print (string) RKEY__TX;
+      j=1+(i-18)*cw; @set_cursor y j;
       if (menu_nesting==1) print (string) QKEY1__TX;
                       else print (string) QKEY2__TX;
       style roman;
-      @set_cursor 5 2; font off;
+      y=y+2*ch;
+      @set_cursor y x; font off;

       if (menu_choices ofclass String) print (string) menu_choices;
       else menu_choices.call();

+      x = 1+3*cw;
       for (::)
       {   if (cl ~= oldcl)
-          {   if (oldcl>0) { @set_cursor oldcl 4; print " "; }
-              @set_cursor cl 4; print ">";
+          {   if (oldcl>0)
+              { y=1+(oldcl-1)*ch; @set_cursor y x; print " "; }
+              y=1+(cl-1)*ch; @set_cursor y x; print ">";
           }
           oldcl=cl;
           @read_char 1 -> pkey;
@@ -661,10 +691,10 @@
               EntryR.call();

               @erase_window $ffff;
-              @split_window 1;
+              @split_window ch;
               i = 0->33; if (i==0) { i=80; }
               @set_window 1; @set_cursor 1 1; style reverse; spaces(i);
-              j=i/2-item_width;
+              j=1+(i/2-item_width)*cw;
               @set_cursor 1 j;
               print (string) item_name;
               style roman; @set_window 0; new_line;
@@ -681,6 +711,9 @@
       menu_nesting--; if (menu_nesting>0) rfalse;
       font on; @set_cursor 1 1;
       @erase_window $ffff; @set_window 0;
+      #Iftrue #version_number==6;
+      @set_cursor -2;
+      #Endif;
       new_line; new_line; new_line;
       if (deadflag==0) <<Look>>;
 ];


Last updated 17 April 2013. This site is no longer supported; information may be out of date.
Maintained as a historical archive by the Interactive Fiction Technology Foundation. Copyright 1993-2018 IFTF, CC-BY-SA unless otherwise noted.
This page was originally managed by Roger Firth.