the-infocom-files / trinity

Trinity
23 stars 5 forks source link

CTHE-PRINT does not honor the NOARTICLE bit #83

Open eriktorbjorn opened 4 years ago

eriktorbjorn commented 4 years ago

The THE-PRINT routine honors the NOARTICLE bit:

<ROUTINE THE-PRINT ("OPTIONAL" (O <>))
     <COND (<ZERO? .O>
        <SET O ,PRSO>)>
     <COND (<NOT <IS? .O ,NOARTICLE>>
        <TELL "the ">)>
     <TELL D .O>
     <RTRUE>>

The CTHE-PRINT routine does not:

<ROUTINE CTHE-PRINT ("OPTIONAL" (O <>))
     <COND (<ZERO? .O>
        <SET O ,PRSO>)>
     <TELL "The " D .O>
     <RTRUE>>

This can lead to strange replies like this:

>RESCUE HAND
The your hand doesn't need any help.

Of course, for this to work it would have to print the object name to a buffer and manipulate the first character to upper case.

eriktorbjorn commented 4 years ago

Something like this might work:

<ROUTINE CTHE-PRINT ("OPTIONAL" (O <>) "AUX" CHAR LEN (PTR 2))
     <COND (<ZERO? .O>
        <SET O ,PRSO>)>
     <COND (<IS? .O ,NOARTICLE>
        <DIROUT ,D-TABLE-ON ,SL-TABLE>
        <PRINTD .O>
        <DIROUT ,D-TABLE-OFF>
        <SET LEN <GET ,SL-TABLE 0>>
        <INC LEN>
        <SET CHAR <GETB ,SL-TABLE 2>>
        <COND (<AND <G? .CHAR 96>
                <L? .CHAR 123>>
               <PUTB ,SL-TABLE 2 <- .CHAR 32>>)>
        <REPEAT ()
            <PRINTC <GETB ,SL-TABLE .PTR>>
            <COND (<EQUAL? .PTR .LEN>
                   <RETURN>)>
            <INC PTR>>)
           (T
        <TELL "The " D .O>)>
     <RTRUE>>

(With some inspiration from ITALICIZE.)

eriktorbjorn commented 4 years ago

If instead we want to go with a pre-existing solution...

As far as I know, there's no way to handle it in the ZIP games, so we're limited to looking at the larger games. The ones that have a CTHE-PRINT routine are Beyond Zork, Border Zone, Bureaucracy, Shogun and (of course) Trinity. Mind you, it could be in others as well under a different name.

As far as I can tell, neither Beyond Zork, Border Zone nor Shogun handles it. Bureaucracy does, because of course Bureaucracy has to do everything in its own way:

<DEFINE CTHE-PRINT ("OPTIONAL" (O <>))
         <COND (<ZERO? .O>
                <SET O ,PRSO>)>
         <COND (<NOT <IS? .O ,NOARTICLE>>
                <TELL "The " D .O>)
               (T
                <START-CAPS>
                <TELL D .O>
                <END-CAPS>)>>

<DEFINE START-CAPS ()
        <DIROUT ,D-SCREEN-OFF>
        <DIROUT ,D-TABLE-ON ,SL-TABLE>>

<DEFINE END-CAPS EC ("OPT" (ALLWORDS? <>) "AUX" (CNT:FIX 2) LEN:FIX X)
        <DIROUT ,D-TABLE-OFF>
        <DIROUT ,D-SCREEN-ON>
        <SET LEN <ZGET ,SL-TABLE 0>>
        <SET LEN <+ .LEN 1>>
        <ZPUT ,SL-TABLE 0 0>
        <COND (<1? .LEN> <RETURN T .EC>)>
        <REPEAT ((LC %<ASCII !\ >))
                <SET X <GETB ,SL-TABLE .CNT>>
                <COND (<AND <G=? .X %<ASCII !\a>>
                            <L=? .X %<ASCII !\z>>>
                       <COND (<OR <==? .CNT 2>
                                  <AND <T? .ALLWORDS?>
                                       <==? .LC %<ASCII !\ >>>>
                              <SET X <- .X:FIX 32>>)>)>
                <PRINTC .X>
                <SET LC .X>
                <COND (<G? <SET CNT <+ .CNT 1>> .LEN>
                       <RETURN>)>>>

(I don't understand what the EC parameter is here. I just don't.)