Decoded: Rogue (1980) by Toy, Arnold, Wichman DOS version (1983) by Mel Sibony and Jon Lane Source file: MAIN.C Beginner friendly, line-by-line code walkthrough by MaiZure MAIN.C is the game entry point and contains the game loop Original code: https://britzl.github.io/roguearchive/ Original code with line numbers http://www.maizure.org/projects/decoded-rogue/MAIN_linenum.txt 1 COMMENT 2 COMMENT 3 COMMENT 4 COMMENT 5 COMMENT 6 COMMENT 7 COMMENT 8 COMMENT 9 COMMENT 10 COMMENT 11 COMMENT 12 COMMENT 13 COMMENT 14 COMMENT 15 COMMENT 16 BLANK 17 Include main game header (rogue.h) 18 Include curses library header (curses.h) 19 BLANK 20 Unused macro. Returns true if input with hyphen or forward slash 21 Unused macro. Returns true if characters match 22 BLANK 23 Global flag for black and white mode 24 Global flag to disable screen retrace check (no waiting, just go) 25 If we're logging... 26 Then declare integers for the log method 27 End log check 28 BLANK 29 COMMENT 30 COMMENT 31 COMMENT 32 Declares a global structure to hold a register collection 33 BLANK 34 COMMENT 35 COMMENT 36 COMMENT 37 COMMENT 38 BLANK 39 Declares and defines main() with the usual suspects 40 Argument 1 is the count of command line arguments 41 Argument 2 is a pointer to the argument vector THE MAIN ENTRY POINT FOR ROGUE 42 BLOCK START - main, the entry point for Rogue 43 Declare local pointers to the current command line arg and the save file 44 Declare a local temporary register state 45 Declares a 4 byte variable used as a temporary DMA buffer 46 Declares a 2 byte string length integer 47 BLANK 48 Sets our global register pointer to the local main register structure 49 Moves two bytes of DMA buffer to the 4th byte of I/O, (DMA controller) 50 Initializes the real time clock 51 Display the title screen pic 52 Allocate basic heap for game objects 53 BLANK 54 Loads the environment settings in "rogue.opt". 55 Write protects the drive the game disk is on, default drive B 56 COMMENT 57 COMMENT 58 COMMENT 59 COMMENT 60 COMMENT 61 If the screen environment variable is set to "bw" 62 Set the flag for black and white mode 63 If the screen option setting (in rogue.opt) is longer than 4 characters 64 And the first 4 characters include the string "fast" 65 Then assert the force immediate redraw flag (used in ZOOM.ASM) 66 Initializes the dungeon number to zero. This will be randomized later 67 If protected mode is set 68 Loop on decremented argument counter and verify protect setting 69 Otherwise.. 70 Just loop on the decremented argument counter 71 End protection check 72 Increments the current argument pointer, initially skipping program name 73 If we detected a switch as the first character, 74 BLOCK START - Handling a switch 75 SWITCH on switch letter 76 BLOCK START - Switch on command line argument 77 CASE argument is 'R' or 'r' 78 Set save file to default save (rogue.sav) 79 END CASE 80 CASE argument is 'S' or 's' 81 Initialize a curses window 82 Disable scoring 83 Set is_saved to true (flag for screen dump during boss key) 84 Clear score 85 Ends execution immediately with no message 86 END CASE 87 If logging is enabled...(it isn't) 88 CASE argument is 'l' 89 Set log writing to -1 (this is not used) 90 Fix eventual random seed to 100 91 END CASE 92 CASE argument is 'K' or 'k' 93 Set log reading to -1 (this is not used) 94 Fix random seed to 100 95 END CASE 96 End logging enabled 97 BLOCK END - Switch on command line arguments 98 BLOCK END - Handling a switch 99 Check if no save file has been define... 100 Set save file to the current argument 101 End loop on command line arguments 102 If no save file is defined (due to lack of helpful arguments)..new game! 103 Set save file to 0 (redundant code) 104 Initialize a curses window 105 If black and white flag has been asserted 106 Force black and white mode (set attribute table to monochrome) 107 If retrace checking hasn't been set... 108 Set retrace check to desired state (fast draw or not) 109 Display game credits screen 110 If random number seed hasn't been set 111 Randomize the seed 112 Set the seed 113 BLANK 114 BLANK 115 Set up player stats 116 Set up loot tables 117 Set up names 118 Set up color tables 119 Set up other tables 120 Set up wands 121 Set up everything else 122 Animate and clear screen 123 Create a new level 124 COMMENT 125 COMMENT 126 COMMENT 127 Initialize healing over time background function 128 Start countdown for monster wandering trigger 129 Initialize hunger background function 130 Initialize moving monsters 131 Print starting banner message 132 Play start animation 133 End set up for new game 134 Kick off the game loop! Saved game reference is passed in. 135 BLOCK END - main 136 BLANK 137 COMMENT 138 COMMENT 139 COMMENT 140 COMMENT 141 Defines endit with no arguments 142 BLOCK START - endit, abnormal program termination 143 End game with an exit message 144 BLOCK END - endit 145 BLANK 146 Defines a random number incrementing function 147 COMMENT 148 COMMENT 149 COMMENT 150 COMMENT 151 COMMENT 152 COMMENT 153 Defines 154 Defines ran with one argument 155 BLOCK START - ran, random number generator seed incrementation 156 Multuply seed by 125 157 Minus itself (get the remainder) 158 Return the new seed 159 BLOCK END - ran 160 BLANK 161 COMMENT 162 COMMENT 163 COMMENT 164 COMMENT 165 Defines rnd with one argument 166 Argument 1 is the upper bound of the randon number range 167 BLOCK START - rnd, returns a random number from a range 168 Returns a random integer below the input range. Return value is the modular ring of the unsigned masked number seed (31-bit) 169 BLOCK END - rnd 170 BLANK 171 COMMENT 172 COMMENT 173 COMMENT 174 COMMENT 175 Defines roll with 2 arguments 176 Arguments are the number of die and the number of sides 177 BLOCK START - roll, rolls a die using input die configuration 178 Declare a local integer for the die total 179 BLANK 180 For each die... 181 Add a random number between 1 and the number of sides to total 182 Returns die total 183 BLOCK END - roll 184 BLANK 185 COMMENT 186 COMMENT 187 COMMENT 188 COMMENT 189 COMMENT 190 Defines playit with two arguments 191 Argument 1 is the saved game to load 192 Argument 2 is the black and white mode flag THE GAME LOOP (Actually it's one line -- #214) 193 BLOCK START - playit, the main game play loop: read input and execute 194 If there is a saved game to load... 195 Reference an external variable for the cursor state (on/off) 196 Declare two integers (dead code) 197 BLANK 198 Load the game state 199 If we're configued for black and white mode... 200 Then forces the color mode to BW, (see CURSES.C). 201 If screen retrace check isn't set... 202 Then initialize it to the most recent configuration value (do_force) 203 Initialize the default system config, screen size, interrupt override 204 Turn the cursor state to on 205 Turn the cursor itself on. The input is current state. (see CURSES.C) 206 End loading of saved game, but if no saved game was passed... 207 Set the last player x position to the current position. 208 Set the last player y position to the current position. 209 Update the room pointer to the hero's current room 210 End of game init 211 Check if ME is defined (dead code, it's not defined anywhere) 212 Sets a variable for a (presumably) debug user 213 End check for ME 214 Begin Loop while the game is still active 215 Check for user input 216 End the game 217 BLOCK END - playit 218 BLANK 219 COMMENT 220 COMMENT 221 COMMENT 222 COMMENT 223 Define quit with no arguments 224 BLOCK START - quit, graceful program exit 225 Declare two integers for x and y cursor positions 226 Declare single byte to hold player response 227 Declares a quit state flag 228 BLANK 229 COMMENT 230 COMMENT 231 COMMENT 232 COMMENT 233 If qstate is already true... 234 Leave game in a hurry without stats display 235 Set qstate to true 236 Save line tracking variable to top 237 Set cursor ox and oy to the current cursor position 238 Move the cursor to the top left (See ZOOM.ASM for how this works) 239 Clears the line 240 Moves the cursor back to the upper left 241 If the terse flag isn't set (output is not pruned) 242 Then print a string prefix to the screen. 243 Print a formatted quit query to the screen 244 Update the screen with the new text 245 Read in player input 246 If the player answered that they wanted to check 247 Check if this is the demo version (it's not) 248 Display the demo ending 249 Otherwise display the real ending 250 Clear the screen 251 Moves the cursor to the top left 252 Print the final amount of gold 253 Calculate the final score 254 Exit the game 255 Othterwise, the player didn't choose to quit yet 256 Move the cursor to the top left 257 Clear the line 258 Print out the current status 259 Move the cursor to the current position 260 Set the temporary position to 0 261 Set count to zero 262 End case for demo version 263 End case for quitting 264 Set quit state to false 265 BLOCK END - quit 266 BLANK 267 COMMENT 268 COMMENT 269 COMMENT 270 COMMENT 271 Declares and defines leave with no arguments 272 BLOCK START - leave, quick exit from game 273 Update the screen 274 Move the cursor to the last status line 275 Clear it 276 Move it to the second to last line 277 Clear it 278 Move it back to the start of the line 279 End the game with a message (DOS prompt resumes below final game screen) 280 BLOCK END - leave 281 BLANK 282 COMMENT 283 COMMENT 284 COMMENT 285 Declares and defines fatal with two arguments 286 Argument 1 is the message to output 287 Argument 2 is an argument plugged in to the text (similar to printf) 288 BLOCK START - fatal, end process with message 289 Closes the curses session 290 Prints the message and argument to the console 291 Ends program 292 BLOCK END - fatal 293 EOF˙