2 * Copyright (c) 2015-2020 Philip Pavlick. See '3rdparty.txt' for other
3 * licenses. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the SwashRL project nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
29 // iomain.d: Defines functions related to program output (graphics, &c)
33 // This interface is the skeleton for all of the different display modes.
35 // The various input/output modules for SwashRL are stored in classes which
36 // inherit from this interface. The interface itself defines certain
37 // functions which are universal to all of the other modules.
41 // SECTION 1: ////////////////////////////////////////////////////////////////
43 //////////////////////////////////////////////////////////////////////////////
45 // Performs final cleanup functions for the input/output module, to close
46 // the display before exiting the program.
49 // Used to determine if the "close window" button has been pressed.
51 // This is only useful for the SDL interfaces, because the curses interface
52 // works in the terminal.
54 // The function is used to instruct the mainloop to close the program in the
55 // event that the player is trapped in an input loop.
58 // SECTION 2: ////////////////////////////////////////////////////////////////
60 //////////////////////////////////////////////////////////////////////////////
62 // Gets a character input from the user and returns it.
65 // Outputs a question to the user and returns a `char` result based on their
67 char ask( string question
, char[] options
= ['y', 'n'],
68 bool assume_lower
= false );
70 // SECTION 3: ////////////////////////////////////////////////////////////////
72 //////////////////////////////////////////////////////////////////////////////
74 // General Output //////////////////////////////////////////////////////////
79 // Refreshes the screen to reflect the changes made by the below `display`
81 void refresh_screen();
83 // Outputs a text character at the given coordinates.
84 void put_char( uint y
, uint x
, char c
,
85 Colors color
= Colors
.Default
);
87 // The central display function: displays a given symbol at the given
88 // coordinates. Equivalent to `mvputch` in curses.
89 void display( uint y
, uint x
, Symbol s
, bool center
= true );
91 // The Message Line ////////////////////////////////////////////////////////
93 // Clears the current message off the message line.
94 void clear_message_line();
96 // Outputs all of the messages in the message queue.
99 // Gives the player a menu containing their message history.
100 void read_message_history();
102 // The Status Bar //////////////////////////////////////////////////////////
104 // Refreshes the status bar.
105 void refresh_status_bar( Player
* u
);
107 // SECTION 4: ////////////////////////////////////////////////////////////////
108 // Global Input Functions //
109 //////////////////////////////////////////////////////////////////////////////
111 // Player Movement / Commands //////////////////////////////////////////////
113 // Takes in a `char` input from the player and returns a movement flag
114 // appropriate to the input.
115 final uint get_command()
119 // First check if `c' is contained in the player's keymap (see `keymap.d')
120 uint* cmd
= (c
in Keymaps
[Current_keymap
]);
122 // If so, return the appropriate command:
124 { return Keymaps
[Current_keymap
].get( c
, MOVE_UNKNOWN
);
127 // If not, check the standard prompts:
151 // If it's not in any of the standard controls or the number pad
152 // controls, check the "admin keys":
156 return MOVE_GETVERSION
;
163 // Handle the default case outside this switch statement
168 // If none of the above command prompts match, default to the "command
169 // not recognized" response.
174 // Inventory / Equipment Screen ////////////////////////////////////////////
176 // Display the inventory screen and allow the user to move items from their
177 // bag into an equipment slot.
178 final bool manage_inventory( Player
* u
)
180 import std
.ascii
: toLower
;
182 // Whether to communicate to the calling function to refresh the screen
183 // after managing the inventory. Depending on what goes down in here, it
184 // may be beneficial to let this function draw the screen itself so it can
185 // display its own error messages.
188 // `grab` and `line` here perform much the same functions they do in
189 // `control_inventory`
196 // Clear the screen and display a new menu with the items in the
198 display_inventory( u
);
200 // `last_i_sym` is the character that comes _after_ the last
201 // item in the inventory. This variable is used to determine
202 // which characters not to accept when the player requests
204 char last_i_sym
= 'a';
205 foreach( size_t slot_temp
; INVENT_BAG
.. u
.inventory
.items
.length
)
208 if( !Item_here( u
.inventory
.items
[slot_temp
] ) )
210 // If the _first_ inventory slot is empty, just exit the inventory
211 // screen and go back to the equipment screen; there's nothing left
213 if( slot_temp
== INVENT_BAG
)
215 display_equipment_screen( u
, -1, "Your bag is empty." );
223 // In the meantime, `grab` will tell us which item has been
227 if( grab
== 'Q' || grab
== ' ' ) return true;
229 // Check the player's grasp; if they do not have an open hand, they can
230 // not take any more items out of their inventory.
231 if( !check_grasp( u
.inventory
) )
233 display_equipment_screen( u
, -1, "You do not have a free grasp." );
237 if( toLower( grab
) >= last_i_sym || grab
< 'a' )
239 display_equipment_screen( u
, -1,
240 "You do not have that item." );
245 line
= (grab
- 'a') + INVENT_BAG
;
247 // Decide which hand to place the item in. As with picking up
248 // items off the floor, weapons will prefer to go into the
249 // weapon-hand, but other objects will favor the off-hand,
250 // except when the favored hand is already taken.
251 if( !Item_here( u
.inventory
.items
[INVENT_WEAPON
] ) &&
252 (u
.inventory
.items
[line
].type
& ITEM_WEAPON
253 ||
Item_here( u
.inventory
.items
[INVENT_OFFHAND
] ))
255 { hand
= INVENT_WEAPON
;
258 { hand
= INVENT_OFFHAND
;
261 // Transfer the item to the hand...
262 u
.inventory
.items
[hand
] = u
.inventory
.items
[line
];
263 u
.inventory
.items
[line
] = No_item
;
264 // Now we shuffle all the items in the inventory up one to
265 // overwrite the item we've just removed from the bag.
267 for( I
= (line
+ 1); I
<= (24 + INVENT_LAST_SLOT
); I
++ )
269 if( !Item_here( u
.inventory
.items
[I
] ) ) break;
272 u
.inventory
.items
[I
- 1] = u
.inventory
.items
[I
];
273 u
.inventory
.items
[I
] = No_item
;
277 // Don't break this do loop just because we were successful in
278 // extracting an item; the player might want to take out more than one
280 // Besides, in future implementations, we might want to allow the
281 // player to remove a certain _number_ of a stacking item, and
282 // breaking here makes it more of a hassle to correct a mistake if
283 // they decide they want more stuff.
285 } /* else from if( toLower( grab ) >= I_sym || grab < 'a' ) */
287 } while( grab
!= 'Q' && grab
!= ' ' );
291 } // final bool manage_inventory( Player* )
293 // Controls the equipment screen and returns the number of turns spent based
294 // on how many items are swapped around.
295 final uint manage_equipment( Player
* u
)
297 import std
.ascii
: toLower
;
298 import std
.format
: format
;
300 // the inventory slot letter the player has selected
302 // `line': the line corresponding to the `grab' slot letter
303 // `grabbed_line': the line corresponding to an item that has been grabbed
304 int line
= -1, grabbed_line
= -1;
305 // `grabbed': an item that has been grabbed
306 Item grabbed
= No_item
;
308 // whether to refresh the inventory screen
311 // the number of turns that have passed...
322 display_equipment_screen( u
, grabbed_line
);
327 if( grab
== 'Q' || grab
== ' ' )
331 // this line is here to clear error messages
332 foreach( count
; 1 .. 79 )
333 { put_char( 21, count
, ' ' );
336 grab
= toLower( grab
);
340 display_equipment_screen( u
, -1, "You do not have a tail." );
345 // The player has chosen to access an item in their bag
346 // If the player already has an item selected, attempt to place that
348 if( grabbed_line
> -1 )
350 // First we need to check if the bag is full.
351 bool bag_full
= true;
353 for( I
= 0; I
< 24; I
++ )
355 if( !Item_here( u
.inventory
.items
[INVENT_BAG
+ I
] ) )
361 // If the bag is full, complain to the user and discard the swap
366 display_equipment_screen( u
, -1,
367 "Your bag can not contain any more items." );
369 // Go back to the start of the loop
372 // If the bag is NOT full, append the item to the end of their bag
373 // and remove it from the equipment slot it came from
376 grabbed
= u
.inventory
.items
[grabbed_line
];
377 u
.inventory
.items
[grabbed_line
] = No_item
;
378 u
.inventory
.items
[INVENT_BAG
+ I
] = grabbed
;
380 // Make a note to refresh the screen, discard all swaps, and go
381 // back to the start of the loop:
383 grabbed_line
= line
= -1;
387 } /* if( grabbed_line != -1 ) */
388 // If the player does NOT have an item already selected, they are
389 // trying to REMOVE an item from their bag...
392 // If the player does not have a free grasp, let them know.
393 if( !check_grasp( u
.inventory
) )
395 display_equipment_screen( u
, grabbed_line
,
396 "You do not have a free grasp to reach into your bag." );
398 // Discard all swaps and go back to the start of the loop...
399 grabbed_line
= line
= -1;
404 // Pass control over to the inventory management function.
405 // Note that we're letting `manage_inventory` decide whether or
406 // not to refresh the equipment screen now. This is because in
407 // some circumstances the function will redraw the equipment
409 refnow
= manage_inventory( u
);
411 // Also reset the `line` and `grabbed_line` variables _after_
412 // managing the inventory so that we don't end up anomalously
413 // grabbing a new item right out the gate
414 grabbed_line
= line
= -1;
416 // Reset `grab` so that a press of 'Q' or SPACE doesn't kick
417 // the user out of the equipment screen as well as the inventory
421 // Go back to the start of the loop
424 } /* else from if( !check_grasp( u.inventory ) ) */
426 } /* else from if( grabbed_line != -1 ) */
428 /* end of case 'i'; there's no `break` statement here because all of
429 * the above `if` statements have `continue` statements that would
430 * render it unreachable and frankly the warnings get on my nerves
433 case 'w': line
= 0; break;
434 case 'o': line
= 1; break;
435 case 'q': line
= 2; break;
436 case 'h': line
= 3; break;
437 case 'c': line
= 4; break;
438 case 'p': line
= 5; break;
439 case 'b': line
= 6; break;
440 case 'l': line
= 7; break;
441 case 'r': line
= 8; break;
442 case 'n': line
= 9; break;
443 case 'g': line
= 10; break;
444 case 'k': line
= 11; break;
445 case 'f': line
= 12; break;
454 // if we haven't grabbed an item yet...
455 if( grabbed
.sym
.ch
== '\0' )
457 // ...confirm the slot is not empty...
458 if( u
.inventory
.items
[line
].sym
.ch
== '\0' )
460 display_equipment_screen( u
, -1, "There is no item there." );
465 // ...grab the item...
466 grabbed
= u
.inventory
.items
[line
];
467 display_equipment_screen( u
, line
);
469 // ...and save that line so we can swap the items later.
472 } /* if( grabbed.sym.ch == '\0' ) */
473 // if we have already grabbed an item...
476 bool confirm_swap
= false;
477 // ...check to see if the player can equip the item in this slot
481 if( grabbed
.type
& ITEM_WEAPON
)
483 // Don't use `display_equipment_screen` here because we need
484 // to be able to format this message and we're going to end up
485 // quitting the equipment screen immediately anyway.
487 "You stab yourself in the head with a %s and die instantly.",
495 goto case INVENT_CUIRASS
;
496 // fall through to next case
498 if( grabbed
.type
& ITEM_WEAPON
)
500 // See above comment at `case INVENT_HELMET` for why we're not
501 // using `display_equipment_screen`
503 "You slice into your gut with a %s and commit seppuku.",
508 // fall through to next case
510 // confirm the player can swap this item to this slot
511 confirm_swap
= check_equip( grabbed
, line
);
513 } /* switch( line ) */
517 // if we can't equip that item here, discard the swap
518 display_equipment_screen( u
, -1,
519 format( "You can not equip a %s there.", grabbed
.name
)
523 grabbed
.sym
.ch
= '\0';
530 // check again in the opposite direction
531 if( !check_equip( u
.inventory
.items
[line
], grabbed_line
) )
533 display_equipment_screen( u
, -1,
534 format( "You can not swap the %s and the %s.",
535 u
.inventory
.items
[line
].name
,
541 // ...swap the inventory items...
542 u
.inventory
.items
[grabbed_line
] = u
.inventory
.items
[line
];
543 // if the new slot is not empty, the player expends a turn moving
545 if( u
.inventory
.items
[line
].sym
.ch
!= '\0' )
548 u
.inventory
.items
[line
] = grabbed
;
549 // ...remove the grabbed item...
550 grabbed
.sym
.ch
= '\0';
551 grabbed_line
= line
= -1;
552 // ...clear the screen...
554 // ...and make a note to refresh the inventory screen.
557 // the player expends a turn moving an inventory item
559 } /* if( grabbed.sym.ch != '\0' ) */
560 } /* if( line != -1 ) */
561 } while( grab
!= 'Q' && grab
!= ' ' );
564 } // uint manage_equipment( Player* )
566 deprecated("control_inventory has been superceded by manage_equipment to prevent ambiguity. Please use this function instead.")
567 final uint control_inventory( Player
* u
)
569 return manage_equipment( u
);
572 // SECTION 5: ////////////////////////////////////////////////////////////////
573 // Global Output Functions //
574 //////////////////////////////////////////////////////////////////////////////
576 // General Output //////////////////////////////////////////////////////////
578 // Prints a string at the given coordinates. Equivalent to `mvprint` in
579 // curses. If `color` is given, the output line will be in the given color.
580 final void put_colored_line( T
... )( uint y
, uint x
, Colors color
, T args
)
582 import std
.string
: format
;
583 string output
= format( args
);
585 foreach( c
; 0 .. cast(uint)output
.length
)
586 { put_char( y
, x
+ c
, output
[c
], color
);
590 final void put_line( T
... )( uint y
, uint x
, T args
)
591 { put_colored_line( y
, x
, Colors
.Default
, args
);
594 // The Help Screen /////////////////////////////////////////////////////////
596 // Displays the "help" screen and waits for the player to clear it.
597 final void help_screen()
601 put_line( 1, 1, "To move: on numpad: on Dvorak:" );
602 put_line( 2, 1, " y k u 7 8 9 f t g" );
603 put_line( 3, 1, " \\|/ \\|/ \\|/" );
604 put_line( 4, 1, " h-*-l 4-*-6 d-*-l" );
605 put_line( 5, 1, " /|\\ /|\\ /|\\" );
606 put_line( 6, 1, " b j n 1 2 3 x h b" );
608 put_line( 8, 1, ". to wait" );
609 put_line( 10, 1, "e to manage equipment" );
610 put_line( 11, 1, "i for inventory" );
611 put_line( 12, 1, ", to pick up an item" );
612 put_line( 13, 1, "d to drop an item (or p to put down an item, on Dvorak)" );
613 put_line( 14, 1, "P to read message history" );
614 put_line( 15, 1, "SPACE clears the message line" );
616 put_line( 17, 1, "? this help screen" );
617 put_line( 18, 1, "Q Quit" );
618 put_line( 19, 1, "v check the version number" );
619 put_line( 20, 1, "@ change keyboard layout" );
621 put_line( 22, 1, "Press any key to continue..." );
625 // wait for the player to clear the screen
627 } // void help_screen()
629 // Map Output //////////////////////////////////////////////////////////////
631 // Uses `display` to draw the player.
632 final void display_player( Player u
)
634 // if the player is wearing a "festive hat," display them in a special
636 if( u
.inventory
.items
[INVENT_HELMET
].name
== "festive hat" )
638 display( u
.y
+ 1, u
.x
, symdata( u
.sym
.ch
, Colors
.Festive_Player
), true );
640 else display( u
.y
+ 1, u
.x
, u
.sym
, true );
643 // Uses `display` to draw the given monster.
644 final void display_mon( Monst m
)
645 { display( m
.y
+ 1, m
.x
, m
.sym
);
648 // Uses `display_mon` to display all monsters on the given map.
649 final void display_map_mons( Map to_display
)
651 size_t d
= to_display
.m
.length
;
655 mn
= to_display
.m
[c
];
657 if( No_shadows || to_display
.v
[mn
.y
][mn
.x
] )
661 } /* foreach( c; 0 .. d ) */
664 // Uses `display` to draw all of the map tiles and items on the given map.
665 final void display_map( Map to_display
)
667 foreach( y
; 0 .. MAP_Y
)
669 foreach( x
; 0 .. MAP_X
)
671 Symbol output
= to_display
.t
[y
][x
].sym
;
672 Color_Pair initial_color
= CLR
[output
.color
];
678 // If there is mold growing on this tile, change the tile's color
679 // to green (unless there's also water)
680 if( to_display
.t
[y
][x
].hazard
& SPECIAL_MOLD
)
682 if( !(to_display
.t
[y
][x
].hazard
& HAZARD_WATER
) )
684 if( initial_color
.get_inverted() )
685 { output
.color
= Colors
.Inverted_Green
;
688 { output
.color
= Colors
.Green
;
695 // If there is blood spattered on this tile, change the tile's
696 // color to red (unless there's also water?)
697 if( to_display
.t
[y
][x
].hazard
& SPECIAL_BLOOD
)
699 if( !(to_display
.t
[y
][x
].hazard
& HAZARD_WATER
) )
701 if( initial_color
.get_inverted() )
702 { output
.color
= Colors
.Inverted_Red
;
705 { output
.color
= Colors
.Red
;
710 } // static if( COLOR )
712 if( to_display
.i
[y
][x
].sym
.ch
!= '\0' )
713 { output
= to_display
.i
[y
][x
].sym
;
716 if( !No_shadows
&& !to_display
.v
[y
][x
] )
722 if( to_display
.t
[y
][x
].seen
)
724 if( initial_color
.get_inverted() )
725 { output
.color
= Colors
.Inverted_Dark_Gray
;
728 { output
.color
= Colors
.Dark_Gray
;
738 display( y
+ 1, x
, output
);
739 } /* foreach( x; 0 .. MAP_X ) */
740 } /* foreach( y; 0 .. MAP_Y ) */
743 // Uses `display_map` and `display_map_mons` to display all map tiles,
744 // items, and monsters.
745 final void display_map_all( Map to_display
)
747 display_map( to_display
);
748 display_map_mons( to_display
);
751 // Uses `display_map_all` and `display_player` to draw the full play area
752 // including the map, items, monsters, and player.
753 final void display_map_and_player( Map to_display
, Player u
)
755 display_map_all( to_display
);
759 // The Inventory / Equipment Screens ///////////////////////////////////////
761 // Displays the equipment screen.
762 final void display_equipment_screen( Player
* u
, int grabbed
= -1,
768 string snam
; // the name of the slot
769 char schr
; // the character that represents the slot
771 foreach( count
; 0 .. INVENT_LAST_SLOT
)
773 // This switch statement of doom sets up the name and selection
774 // button for each inventory slot
777 default: snam
= "bag"; schr
= '\0'; break;
779 case INVENT_WEAPON
: snam
= "Weapon-hand"; schr
= 'w'; break;
780 case INVENT_OFFHAND
: snam
= "Off-hand"; schr
= 'o'; break;
781 case INVENT_QUIVER
: snam
= "Quiver"; schr
= 'q'; break;
782 case INVENT_HELMET
: snam
= "Helmet"; schr
= 'h'; break;
783 case INVENT_CUIRASS
: snam
= "Cuirass"; schr
= 'c'; break;
784 case INVENT_PAULDRONS
: snam
= "Pauldrons"; schr
= 'p'; break;
785 case INVENT_BRACERS
: snam
= "Bracers/gloves"; schr
= 'b'; break;
786 case INVENT_RINGL
: snam
= "Left ring"; schr
= 'l'; break;
787 case INVENT_RINGR
: snam
= "Right ring"; schr
= 'r'; break;
788 case INVENT_NECKLACE
: snam
= "Necklace"; schr
= 'n'; break;
789 case INVENT_GREAVES
: snam
= "Greaves"; schr
= 'g'; break;
790 case INVENT_KILT
: snam
= "Kilt/skirt"; schr
= 'k'; break;
791 case INVENT_FEET
: snam
= "Feet"; schr
= 'f'; break;
792 case INVENT_TAIL
: snam
= "Tailsheath"; schr
= 't'; break;
799 put_line( 1 + count
, 1, " %c) %s: %s", schr
, snam
,
800 u
.inventory
.items
[count
].sym
.ch
== '\0'
801 ?
"EMPTY" : u
.inventory
.items
[count
].name
803 } /* foreach( count; 0 .. INVENT_LAST_SLOT ) */
805 put_line( 16, 1, "i) Bag" );
809 put_line( 18, 1, "Press a letter to \"grab\" that item" );
810 put_line( 19, 1, "or \'i\' to take an item out of your bag" );
814 put_line( grabbed
+ 1, 1, "GRABBED:" );
816 "Press a letter to move the grabbed item into a new equipment slot" );
817 put_line( 19, 1, "or \'i\' to put it in your bag" );
820 put_line( 20, 1, "Press \'Q\' or SPACE to exit this screen" );
822 if( msg
!= "" ) put_line( 22, 1, msg
);
826 } // final void display_equipment_screen( Player*(, int, string) )
828 // Displays the inventory screen.
829 final void display_inventory( Player
* u
)
834 // The symbol of the current item
835 char slot_char
= 'a';
837 foreach( slot_index
; 0 .. 24 )
839 // Inform the player of each item, up to 24 (one per line)
840 if( Item_here( u
.inventory
.items
[INVENT_BAG
+ slot_index
] ) )
842 put_line( slot_index
, 0, "%c) %s", slot_char
,
843 u
.inventory
.items
[INVENT_BAG
+ slot_index
].name
);
851 } // final void display_inventory( Player* )
856 // Section 6: //////////////////////////////////////////////////////////////
858 ////////////////////////////////////////////////////////////////////////////
860 // Output a screen which will display various color pairs for test purposes
861 final void color_test_screen()
865 put_colored_line( 1, 1,
866 Colors
.Default
, "Default" );
867 put_colored_line( 3, 1,
868 Colors
.Black
, "Black" );
869 put_colored_line( 5, 1,
871 put_colored_line( 7, 1,
872 Colors
.Green
, "Green" );
873 put_colored_line( 9, 1,
874 Colors
.Dark_Blue
, "Dark_Blue" );
875 put_colored_line( 11, 1,
876 Colors
.Brown
, "Brown" );
877 put_colored_line( 13, 1,
878 Colors
.Magenta
, "Magenta" );
879 put_colored_line( 15, 1,
880 Colors
.Cyan
, "Cyan" );
881 put_colored_line( 17, 1,
882 Colors
.Gray
, "Gray" );
883 put_colored_line( 19, 1,
884 Colors
.Dark_Gray
, "Dark_Gray" );
885 put_colored_line( 21, 1,
886 Colors
.Lite_Red
, "Lite_Red" );
887 put_colored_line( 23, 1,
888 Colors
.Lite_Green
, "Lite_Green" );
889 put_colored_line( 1, 21,
890 Colors
.Blue
, "Blue" );
891 put_colored_line( 3, 21,
892 Colors
.Yellow
, "Yellow" );
893 put_colored_line( 5, 21,
894 Colors
.Pink
, "Pink" );
895 put_colored_line( 7, 21,
896 Colors
.Lite_Cyan
, "Lite_Cyan" );
897 put_colored_line( 9, 21,
898 Colors
.White
, "White" );
899 put_colored_line( 11, 21,
900 Colors
.Inverted_Black
, "Inverted_Black" );
901 put_colored_line( 13, 21,
902 Colors
.Inverted_Red
, "Inverted_Red" );
903 put_colored_line( 15, 21,
904 Colors
.Inverted_Green
, "Inverted_Green" );
905 put_colored_line( 17, 21,
906 Colors
.Inverted_Dark_Blue
, "Inverted_Dark_Blue" );
907 put_colored_line( 19, 21,
908 Colors
.Inverted_Brown
, "Inverted_Brown" );
909 put_colored_line( 21, 21,
910 Colors
.Inverted_Magenta
, "Inverted_Magenta" );
911 put_colored_line( 23, 21,
912 Colors
.Inverted_Cyan
, "Inverted_Cyan" );
913 put_colored_line( 1, 41,
914 Colors
.Inverted_Gray
, "Inverted_Gray" );
915 put_colored_line( 3, 41,
916 Colors
.Inverted_Dark_Gray
, "Inverted_Dark_Gray" );
917 put_colored_line( 5, 41,
918 Colors
.Inverted_Lite_Red
, "Inverted_Lite_Red" );
919 put_colored_line( 7, 41,
920 Colors
.Inverted_Lite_Green
, "Inverted_Lite_Green" );
921 put_colored_line( 9, 41,
922 Colors
.Inverted_Blue
, "Inverted_Blue" );
923 put_colored_line( 11, 41,
924 Colors
.Inverted_Yellow
, "Inverted_Yellow" );
925 put_colored_line( 13, 41,
926 Colors
.Inverted_Pink
, "Inverted_Pink" );
927 put_colored_line( 15, 41,
928 Colors
.Inverted_Lite_Cyan
, "Inverted_Lite_Cyan" );
929 put_colored_line( 17, 41,
930 Colors
.Inverted_White
, "Inverted_White" );
931 put_colored_line( 19, 41,
932 Colors
.Error
, "Error" );
933 put_colored_line( 21, 41,
934 Colors
.Player
, "Player" );
935 put_colored_line( 23, 41,
936 Colors
.Festive_Player
, "Festive_Player" );
937 put_colored_line( 1, 61,
938 Colors
.Water
, "Water" );
939 put_colored_line( 3, 61,
940 Colors
.Lava
, "Lava" );
941 put_colored_line( 5, 61,
942 Colors
.Acid
, "Acid" );
943 put_colored_line( 7, 61,
944 Colors
.Copper
, "Copper" );
945 put_colored_line( 9, 61,
946 Colors
.Silver
, "Silver" );
947 put_colored_line( 11, 61,
948 Colors
.Gold
, "Gold" );
949 put_colored_line( 13, 61,
950 Colors
.Roentgenium
, "Roentgenium" );
951 put_colored_line( 15, 61,
952 Colors
.Money
, "Money" );
953 put_colored_line( 17, 61,
954 Colors
.Royal
, "Royal" );
955 put_colored_line( 19, 61,
956 Colors
.Holy
, "Holy" );
957 put_colored_line( 21, 61,
958 Colors
.Snow
, "Snow" );
959 put_colored_line( 23, 61,
960 Colors
.Snow_Tree
, "Snow_Tree" );
965 } // color_test_screen()
968 } // interface SwashIO
970 // SECTION 7: ////////////////////////////////////////////////////////////////
971 // Importing Further IO Files //
972 //////////////////////////////////////////////////////////////////////////////
974 // Import the classes which expand on this template depending on what display
975 // outputs have been compiled:
978 { import iocurses
; /* display interface for curses */
982 { import ioterm
; /* display interface for sdl terminal */