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˙