Decoded: Rogue (1980) by Toy, Arnold, Wichman
DOS version (1983) by Mel Sibony and Jon Lane
Source file: RIP.C
Beginner friendly, line-by-line code walkthrough by MaiZure

RIP.C displays the end game statistics screen for both victory and defeat

Original code:
https://britzl.github.io/roguearchive/

Original code with line numbers
http://www.maizure.org/projects/decoded-rogue/RIP_linenum.txt



1     COMMENT
2     COMMENT
3     COMMENT
4     COMMENT
5     COMMENT
6     COMMENT
7     BLANK
8     Include game header
9     Include console management header
10    BLANK
11    Declares a file descriptor for the score file
12    COMMENT
13    COMMENT
14    COMMENT
15    Imports the screen mode from CURSES.C
16    BLANK
17    COMMENT
18    COMMENT
19    COMMENT
20    COMMENT
21    COMMENT
22    BLANK
23    BLANK

CALCULATE AND SAVE SCORE

24    Define score with three arguments
25    Arguments 1 and 2 are the score amount and the ending flags
26    Argument 3 is the monster that caused player death
27    BLOCK START - score, calculates end of game stats
28    Check if this is NOT the demo version
29    Check if we're NOT in wizard mode
30    Declare score entry structs for this game and for the high score list
31    Initialize score file to null and ranking to null
32    Initialize player input character to space
33    BLANK
34    BLANK
35    Set the screen saved state to true
36    BLANK
37    If any of the input arguments have entries...
38    BLOCK START - Prompt to show end game scores
39    Move the cursor to the bottom left  
40    Enable the flashing cursor display
41    BLANK
42    Print a message for player input
43    Clear the keyboard buffer
44    Wait for player to input a carriage return
45    BLANK
46    Move cursor to the bottom left again
47    BLOCK END - Prompt to show end game scores
48    Open the high score file if it fails to open...
49    BLOCK START - Retry opening high score file
50    Print a newline character
51    If there isn't a score file or the input score is 0...
52    Return - nothing to score
53    Output failure to open high scores
54    Label to retry user input
55    SWITCH on user input
56    BLOCK START - Switch on user input
57    CASE create lowercase (fallthrough)
58    CASE create uppercare
59    Create a new score file and immediate close it (will reopen on next try)
60    CASE retry lowercase (fallthrough)
61    CASE retry uppercase
62    Break - Go around the open attempt loop again
63    CASE abort lowercase (fallthrough)
64    CASE abort uppercase
65    Return to stop open attempt
66    For all other input...
67    Jump back to line 54 to retry input
68    BLOCK END - Switch on user input
69    BLOCK END - Retry opening high score file
70    Print newline
71    Get the scores in to the score array
72    BLANK
73    If we're saving this score...
74    BLOCK START - Save scores
75    Copy the player name to the current score
76    Copy the player's gold amount to the current score
77    Copy the end game condition to the current score
78    Copy the player's max dungeon level to the current score
79    Copy the player's experience level to the current score
80    Add the new score to the high scores and get the final rank
81    BLOCK END - Save scores
82    Close the high score file
83    If we have a positive rank...
84    Attempt to reopen score file
85    Add the new score
86    Close the file
87    End file open attempt
88    End check for positive rank
89    Print the high scores
90    End check for wizard mode
91    End check for demo mode
92    BLOCK END - score
93    BLANK
94    If demo mode is NOT enabled...
95    If wizard mode is NOT enabled...

GET THE SCORE HISTORY

96    Define get_scores with one argument
97    Argument 1 is the high score entry struct array
98    BLOCK START - get_scores, get the score history
99    Declare an iterator and initialize a return value
100   BLANK
101   Loop through all the scores
102   If there is a positive return code (should be if successful)...
103   Read from the file
104   If there was an unsuccessful read..
105   Set that entry to 0 gold (no record, end of list)
106   End loop through scores
107   BLOCK END - get_scores
108   BLANK
109   BLANK

SAVE THE SCORE HISTORY

110   Define put_scores with one argument
111   Argument 1 is a pointer to the high score table
112   BLOCK START - put_scores, save the score history
113   Declare an integer iterator
114   BLANK
115   Loop through all the cores
116   BLOCK START - Save scores 
117   Write score entry to the file but if there is a failure...
118   Return from writing scores
119   BLOCK END - Save scores
120   BLOCK END - put_scores
121   BLANK

PRINT THE SCORE HISTORY

122   Defines pr_scores with two arguments
123   Argument 1 is the current game's rank in the high score table
124   Argument 2 is the high score table of entries
125   BLOCK START - pr_scores, prints the top scores
126   Declare an iterator
127   Declare an unused character pointer
128   Declare column position variable
129   Declare a character buffer for a death string
130   Declare an alternate output string
131   BLANK
132   Switch graphics to the base memeory page
133   Clear the screen
134   Set output to high intensity
135   If this is a Monochrome screen...
136   Remove all extended output formatting
137   Print hall of fame message in the upper left
138   End extended formatting
139   Set output color to yellow
140   Print 'Gold'
141   BLANK
142   Loop through all of the high scores
143   BLOCK START - Score printing loop
144   Clear the alternate message
145   Set output color to brown
146   If we've found the current game's position in the high score table
147   BLOCK START - Current game score output
148   If this is a Monochrome monitor...
149   End extended formatting effects
150   Otherwise..
151   Set output color to yellow
152   BLOCK END - Current game score output
153   If the next high score entry has no score (no game)
154   Break from printing all scores -- this is the end of the list
155   Get the column position depending on the monitor size
156   Move the cursor to the new column
157   Print the gold score
158   Move the cursor down 6 lines from last printing start
159   If this entry is not the current game
160   Set output color to red
161   Print the name of the game's entry
162   If this entry is not the current game
163   Set output color to brown
164   If this entry's player reached the final dungeon level...
165   Add an extra message
166   If this entry's player was killed by a monster...
167   BLOCK START - high score monster death message
168   Add the death message to the text buffer...
169   Including the monster responsible
170   If the screen is small and the death message is too large
171   Just say that the player died
172   BLOCK END - high score monster death message
173   Otherwise, the player didn't die from a monster so...
174   BLOCK START - SWITCH on game over condition
175   CASE won the game
176   Copy victory message to buffer
177   End game over check
178   CASE quit the game
179   Copy quit message to buffer
180   End game over check
181   CASE missing in action (unknown ending)
182   Copy message to buffer
183   BLOCK END - SWITCH on game over condition
184   If the current buffer usage...
185   Is less than the screen width if we add more info..
186   BLOCK START - Add player rank to high scores
187   If the player had a meaningful rank...
188   Copy that rank to the buffer
189   BLOCK END - Add player rank to high scores
190   If the screen is small
191   Move the cursor over one space
192   If there is no alternate message
193   Print the ending level information
194   Otherwise there is an extra message
195   Print it
196   BLOCK END - Score printing loop
197   End extended formatting
198   If this is a larger screen
199   Add four lines to the end
200   BLOCK END - pr_scores
201   BLANK

ADD NEW SCORE TO THE HISTORY

202   Defines add_scores with two arguments
203   Argument 1 is this games score entry, Argument 2 is the score list
204   BLOCK START - add_scores, adds this score to the history
205   Declare pointers to two score entries
206   Initialize a return code to the length of the score list
207   BLANK
208   Loop through the high score list from the back
209   If this game's score is better than the current entry (time to swap)
210   Point to the entry
211   Decrement the return code
212   If this entry is valid...
213   Repoint the entry
214   End check for list entry position
215   Break on this position
216   Retry loop through score list
217   If the score isn't good enough for the list...
218   Return with no change
219   The current game score is in the new position
220   Return the new position index
221   BLOCK END - add_scores
222   End check for wizard mode
223   End chec for demo mode
224   BLANK
225   COMMENT
226   COMMENT
227   COMMENT
228   COMMENT

PLAYER DEFEAT

229   Define death with one argument
230   Argument 1 is the monster that killed the player
231   BLOCK START - death, display the loss screen
232   Declare pointer to a character buffer holding the monster's name
233   Declare a generic buffer
234   Declare an integer for the year
235   Check if this is not the demo
236   BLANK
237   Remove 10% of the player's gold
238   BLANK
239   Change video memory to the base page
240   Clear the screen
241   Animate the screen fade out
242   If this is a color monitor
243   Set the output color to brown
244   Draw a box taking up the middle part of the screen
245   Remove extended output formats
246   BLANK
247   Center text on line 10
248   Center text on line 11
249   Center text on line 12
250   Set the output color to red
251   Center text on line 21
252   Set color to green
253   Center text on line 22
254   Remove extended output formats
255   BLANK
256   If this is a monochrome screen
257   Set output format to underline
258   Center character's name on line 14
259   Remove extended output formats
260   BLANK
261   Get the name of the monster that killed the player
262   BLANK
263   Copy text to the general buffer
264   BLANK
265   Center buffer text on line 15
266   Center funny killer name string on line 16
267   BLANK
268   Copy the player's gold amount in to buffer
269   Center gold gained on line 18
270   BLANK
271   Move 0x2a in to AH
272   Invoke DOS software interrupt to get the system date
273   Read the year from CX
274   Copy the year to the text buffer
275   Center the year on line 19
276   Fade in animation
277   Move cursor to the bottom left of the screen
278   Calculate player score
279   If this is the demo version...(ignore above)
280   Display demo end game screen
281   Get the killing monster's name
282   BLANK
283   Copy text to the biffer
284   Copy a space to the buffer
285   Copy the killer's name to the buffer
286   If the above buffer doesn't fit on the screen...
287   Center a basic death message on line 6
288   Otherwise
289   Output the longer death message on line 6
290   Move the cursor to the (almost) bottom left
291   End check for demo
292   End the console
293   Exit the game
294   BLOCK END - death
295   BLANK
296   COMMENT
297   COMMENT
298   COMMENT
299   COMMENT

PLAYER VICTORY

300   Define total_winner with no arguments
301   BLOCK START - total_winner, display the victory screen
302   If this isn't the demo version
303   Declare a pointer to an object
304   Declare an integer for the player's net worth
305   Declare a character
306   Declare an original purse value
307   BLANK
308   Switch video memory to the base page
309   Clear the screen
310   Checks for a defined macro 'MINROG'...? (Not defined, so this is dead)
311   If we're not in terse mode
312   BLOCK START - Big victory ASCII art
313   Remove extended formatting
314   Print 'You Made it!' with big ASCII art
315   Print 'You Made it!' with big ASCII art
316   Print 'You Made it!' with big ASCII art
317   Print 'You Made it!' with big ASCII art
318   Print 'You Made it!' with big ASCII art
319   Print 'You Made it!' with big ASCII art
320   Print 'You Made it!' with big ASCII art
321   Print 'You Made it!' with big ASCII art
322   BLOCK END - Big victory ASCII art
323   Print a victory message
324   Print a victory message
325   Remove extended formatting
326   Print a victory message
327   Print a victory message
328   Print a victory message
329   Otherwise, MINROG is not defined (this is the normal victory screen)
330   Print a victory message
331   Print a victory message
332   Print a victory message
333   Print a victory message
334   End check for MINROG
335   Move cursor to the bottom left and ask player to hit space
336   Wait for the the space
337   Clear the screen
338   Move cursor to the top left and print a header
339   Save the player's base gold amount  
340   Loop through each item in inventory
341   BLOCK START - Final item tally
342   SWITCH on item type
343   BLOCK START - Switch on item type to get value
344   CASE food
345   Food is worth two gold each
346   CASE weapon
347   Switch on weapon type
348   BLOCK START - Switch on weapon type
349   Mace is worth 8
350   Sword is worth 15
351   Crossbow is worth 30
352   Arrows are worth 1
353   Dagger is worth 2
354   Two-Handed sword is worth 75
355   Darts are worth 1
356   Bow is worth 15
357   Bolts are worth 1
358   Spear is worth 5
359   BLOCK END - Switch on weapon type
360   Magic items are worth at least 3x their base value plus power bonus
361   Set weapon to known by player
362   CASE armor
363   Switch on armor type
364   BLOCK START - Switch on armor type
365   Leather is worth 20
366   Ring mail is worth 25
367   Studded Leather is worth 20
368   Scale mail is worth 30
369   Chain mail is worth 75
370   Splint mail is worth 80
371   Banded mail is worth 90
372   Plate mail is worth 150
373   BLOCK END - Switch on armor type
374   Value of armor goes up by 100 for each AC better than 9
375   Worth goes up by 10 times it's AC over base...why?
376   Player knows about the armor
377   CASE scroll
378   Base worth is set by the worth of the magic effect (EXTERN.C)
379   Each scroll adds to the worth
380   If player doesn't know about the scroll...
381   Cut the value in half
382   Set the scroll to known
383   CASE potion
384   Base worth is set by the worth of the magic effect (EXTERN.C)
385   Multiple the worth by the number of potions
386   If the player doesn't know about the potion...
387   Cut the value in half
388   Set the potion to known
389   CASE ring
390   Base worth is set by the worth of the magic effect (EXTERN.C)
391   If the ring has strength or damage effect...
392   Or protection, or hit chance effect...
393   And it has a positive power...
394   Add 100 for each point of power it has
395   Otherwise...
396   It's only worth 10
397   If the player doesn't know about the ring...
398   Cut the value in half
399   Set the ring to known
400   Set the ring known array
401   CASE stick
402   Base worth is set by the worth of the magic effect (EXTERN.C)
403   Each charge remaining adds 20 value
404   If the player doesn't know about the wand/staff...
405   Cut the value in half
406   Set the wand/staff to known
407   Set the wand/staff known array
408   CASE amulet
409   Amulet is worth 1000
410   BLOCK END - Switch on item type to get value
411   If the worth is negative...
412   Set worth to 0
413   Move the cursor to the next line
414   Print the item and it's value
415   Add the total item value to the gold value
416   BLOCK END - Final item tally
417   Move the cursor to the next line
418   Print the player's basic gold amount collected
419   Save the game score using player's total purse value
420   End check for demo
421   End the game
422   BLOCK END - totak_winner
423   BLANK
424   COMMENT
425   COMMENT
426   COMMENT
427   COMMENT

GET PLAYER'S KILLER

428   killname returns a character string
429   Define killname with two arguments
430   Argument 1 is the monster's symbol
431   Argument 2 is a flag to print the death info
432   BLOCK START - killname, gets name of the monster that killed the player
433   Delcare a pointer to a string
434   Declare a flag for outputting info
435   BLANK
436   Point to the global print buffer
437   Set output death flag to true
438   SWITCH on monster symbol (could be a non-monster too)
439   BLOCK START - Make death notice
440   CASE arrow
441   Set the print buffer to the cause of death
442   CASE bolt
443   Set the print buffer to the cause of death
444   CASE dart
445   Set the print buffer to the cause of death
446   CASE stavation
447   Set the print buffer to the cause of death
448   Don't print this result
449   CASE falling
450   Set the print buffer to the cause of death
451   CASE everything else (monsters)
452   If death was caused by a monster...
453   Copy the monster's name to the print buffer
454   Otherwise, we dont know
455   BLOCK START - Unknown death
456   Cause of death was God
457   Don't print this
458   BLOCK END - Unknown death
459   BLOCK END - Make death notice
460   If we're outputting death causes
461   Copy the monster to the print buffer
462   Otherwise
463   Clear the print buffer
464   Copy all this to the print buffer
465   Return the print buffer contents
466   BLOCK END - killname
467   BLANK
468   Check for demo flag
469   COMMENT
470   COMMENT
471   COMMENT
472   COMMENT
473   COMMENT

DEMO MODE ENDING

474   Define demo with one argument
475   Argument 1 is the game ending condition (quit, die, etc)
476   BLOCK START - demo, prints the demo ending screen
477   Declare an unused iterator
478   Declare a temporary buffer to hold formatted text
479   BLANK
480   Switch memory page to the base video memory page
481   Clear the screen
482   If this is a color monitor...
483   Set output color to brown
484   Draw a box border around the screen
485   Set text to bold output
486   Print line 2 of centered demo game over text
487   Remove extended formatting from output
488   If this is a color monitor...
489   Set output color to magenta
490   Copy the demo ending message to the buffer
491   If we're in terse mode
492   Copy the shorter demo ending message to the buffer
493   Print line 4 of centered demo game over text
494   If the player quit...
495   BLOCK START - Demo quit condition
496   Copy the quit message to the buffer
497   Print line 6 of centered demo game over text if player quit
498   Otherwise the player time elapsed
499   Copy the time elapsed message to the buffer
500   Print line 6 of centered demo game over text if game time elapsed
501   BLOCK END - Demo quit condition
502   If this is terse output
503   Print line 8 of terse demo game over text
504   Otherwise this is normal output
505   Print line 8 of centered demo game over text
506   Print line 9 of centered demo game over text
507   If this is a color monitor...
508   Set output color to red
509   Print line 11 of centered demo game over text
510   If this is a Monochrome monitor...
511   Set output format to underline
512   Otherwise
513   Remove extended formatting from output
514   Print line 13 of centered demo game over text
515   Print line 14 of centered demo game over text
516   Print line 15 of centered demo game over text
517   IF this is a color monitor...
518   Set output color to red
519   Print line 17 of centered demo game over text
520   If this is a color monitor...
521   Set output color to yellow
522   Otherwise this is Monochrome
523   Remove extended formatting from output
524   Print line 19 of centered demo game over text
525   Set high intensity output
526   Print line 20 of centered demo game over text
527   If this is a color monitor...
528   Set output color to yellow
529   Otherwise this is Monochrome
530   Remove extended formatting from output
531   Print line 21 of centered demo game over text
532   If no exit code was set
533   Return without closing
534   Move cursor to the 2nd to last line
535   Close the terminal instance
536   Exit program success
537   BLOCK END - demo
538   End check for demo flag
539   EOF