// // nazghul - an old-school RPG engine // Copyright (C) 2002, 2003 Gordon McNutt // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // // You should have received a copy of the GNU General Public License along with // this program; if not, write to the Free Foundation, Inc., 59 Temple Place, // Suite 330, Boston, MA 02111-1307 USA // // Gordon McNutt // gmcnutt@users.sourceforge.net // #include "ascii.h" #include "images.h" #include "screen.h" #include "common.h" #include "cfg.h" #include "dimensions.h" #include #include #define ASCII_DEF_CLR White /* default printing color is white */ #define ASCII_CLR_STK_SZ 32 /* State machine states for embedded control sequences. */ enum ascii_ctrl_states { ASCII_STATE_DEF = 0, ASCII_STATE_ESC, ASCII_STATE_CLR, ASCII_STATE_CLRPUSH }; /* This is a default character image set in XPM format. For emergency use * only. */ static char * charset_xpm[] = { "128 144 44 1", " c None", ". c #000000", "+ c #004040", "@ c #20FCFC", "# c #E0FCFC", "$ c #000060", "% c #000080", "& c #0000A0", "* c #0000C0", "= c #E8E8E8", "- c #C0C0C0", "; c #808080", "> c #FCFCFC", ", c #B0B0B0", "' c #D4D4D4", ") c #008080", "! c #006060", "~ c #800000", "{ c #FC1000", "] c #404040", "^ c #505050", "/ c #4040FC", "( c #600000", "_ c #400000", ": c #A0A0A0", "< c #C0C0FC", "[ c #C00000", "} c #303030", "| c #909090", "1 c #8080FC", "2 c #000040", "3 c #0000FC", "4 c #6060FC", "5 c #0000E0", "6 c #A00000", "7 c #202020", "8 c #101010", "9 c #606060", "0 c #FCFC80", "a c #FCFCE0", "b c #FCFCA0", "c c #A0A0FC", "d c #FCFC40", "e c #FCFCC0", ".+@##@+.$%%&*&%$=-;-=-;-=-;-=-;-...;>......;-......;>....+@##@+............->>.....->>.............->>..........,-''''-,........", ".+@##@+.$%%&*&%$=-;-=-;-=-;-=-;-...;>......;-......;>....+@##@+............->>.....->>.............->>..........,-''''-,........", ".@#)!#@.%~{{{{~%;.;;;;.;;;;;;;;;..;;->.....;-.....;;->...@#)!#@...];;]....-^^^>...-^^^>......->>..->^->.////////-......-..$&&$..", ".@#)!#@.%~{{{{~%;.;;;;.;;;;;;;;;..;;->.....;-.....;;->...@#)!#@...];;]....-^^^>...-^^^>......->>..->^->.////////-......-..$&&$..", ".@#.+#@.&~(__(~&;-=-;-=-;-=-;-=-.;;-->>....;-....;;-->>..........^:'=:^..-.->>^>.-.-->^>....^^->.^->^->.<<<<<<<<'......'.%*//*%.", ".@#.+#@.&~(__(~&;-=-;-=-;-=-;-=-.;;-->>....;-....;;-->>..........^:'=:^..-.->>^>.-.-->^>....^^->.^->^->.<<<<<<<<'......'.%*//*%.", ".+@##@+.*~[__[~*;;;;;;;;;;;;;;;;...;;......;-......;;....+@##@+.}|'>>'|}^-^-^.^>^-^->^^>..->>-^>.^^->>..11111111'......'2&341/&2", ".+@##@+.*~[__[~*;;;;;;;;;;;;;;;;...;;......;-......;;....+@##@+.}|'>>'|}^-^-^.^>^-^->^^>..->>-^>.^^->>..11111111'......'2&341/&2", "+@####@+&~(__(~&=-;-=-;-=-;-=-;=...;-......;-......;-...........}|--''|}^-^->>^>^-^-^>^>.->^->^...^^>...////////'......'2&55/3&2", "+@####@+&~(__(~&=-;-=-;-=-;-=-;=...;-......;-......;-...........}|--''|}^-^->>^>^-^-^>^>.->^->^...^^>...////////'......'2&55/3&2", "..+@#+..%~6__6~%;;;;;;;;;;;;;;;;.;;-->>..;;-->>....;-.....+@#+...^:--:^.^^-^^.>.^^-^^.>.^->^->.....->>..********'......'.%*55*%.", "..+@#+..%~6__6~%;;;;;;;;;;;;;;;;.;;-->>..;;-->>....;-.....+@#+...^:--:^.^^-^^.>.^^-^^.>.^->^->.....->>..********'......'.%*55*%.", "..+@#+..2%~66~%2;.=-;-.-;-=-;-=-..;;->....;;->.....;-.....+@#+....];;]...^^-->...^^-->..^^->>.....^^-...%%%%%%%%-......-..$&&$..", "..+@#+..2%~66~%2;.=-;-.-;-=-;-=-..;;->....;;->.....;-.....+@#+....];;]...^^-->...^^-->..^^->>.....^^-...%%%%%%%%-......-..$&&$..", "..+@#+...2%~~%2.;;;;;;;;;;;;;;;;...;>......;>......;-.....+@#+............^^^.....^^^....^^^.......^............,-''''-,........", "..+@#+...2%~~%2.;;;;;;;;;;;;;;;;...;>......;>......;-.....+@#+............^^^.....^^^....^^^.......^............,-''''-,........", "..................................;78.....|^8.....|,7.....|,|.....7,|.....8^|.....87;.....888....2%%&&$..%*55*$..%5/5$2..222$$2.", "..................................;78.....|^8.....|,7.....|,|.....7,|.....8^|.....87;.....888....2%%&&$..%*55*$..%5/5$2..222$$2.", "/*%..........%*/.................,9778...,>978...,>0,7...,>a>,...7,>b,...879>,...8779,...87778..2$2$$%*%$*%%%*5%$5*&*5%22%**%2$2", "/*%..........%*/.................,9778...,>978...,>0,7...,>a>,...7,>b,...879>,...8779,...87778..2$2$$%*%$*%%%*5%$5*&*5%22%**%2$2", "<5*$........$*5c................;'77778.;>b^778.;>>>b97.|>00a0|.79b>b>;.877^b>;.87777';.8777778.$2&53&%*&%&3/**5***/%/*2$5//5&2%", "<5*$........$*5c................;'77778.;>b^778.;>>>b97.|>00a0|.79b>b>;.877^b>;.87777';.8777778.$2&53&%*&%&3/**5***/%/*2$5//5&2%", "135%........%531................,=77778.,>a9778.,>bbd;7.,>>>0b,.7;eded-.8779a>,.87777=,.8777778.$%5**3%5&$3**/&/5%/*%/*25*%%*5$%", "135%........%531................,=77778.,>a9778.,>bbd;7.,>>>0b,.7;eded-.8779a>,.87777=,.8777778.$%5**3%5&$3**/&/5%/*%/*25*%%*5$%", "//5%........%5//................;'77778.;>e^778.;>d>097.|>b>ad|.79b>>>;.877^b>;.87777';.8777778.2*/%*/%5%$5*%%*55%3**5%$/&/**3$&", "//5%........%5//................;'77778.;>e^778.;>d>097.|>b>ad|.79b>>>;.877^b>;.87777';.8777778.2*/%*/%5%$5*%%*55%3**5%$/&/**3$&", "**%$........$%**........->.->.->.,9778...,>978...,>b,7...,>>0,...7,b>,...879>,...8779,...87778..2*/%/***%2&5//5$*%&35&2$5**/3&%&", "**%$........$%**........->.->.->.,9778...,>978...,>b,7...,>>0,...7,b>,...879>,...8779,...87778..2*/%/***%2&5//5$*%&35&2$5**/3&%&", "%%$..........$%%........->^->^->..;78.....|^8.....|,7.....|,|.....7,|.....8^|.....87;.....888...2%5*&*5$2$2%**%2%*%$$2$2%5*%%%*$", "%%$..........$%%........->^->^->..;78.....|^8.....|,7.....|,|.....7,|.....8^|.....87;.....888...2%5*&*5$2$2%**%2%*%$$2$2%5*%%%*$", "........................^.^^.^^..................................................................2$5/5%..2$$222..$&&%%2..$*55*%.", "........................^.^^.^^..................................................................2$5/5%..2$$222..$&&%%2..$*55*%.", "...........->.....->.->.............>..............->>....->........->....->..................................................->", "...........->.....->.->.............>..............->>....->........->....->..................................................->", "..........^->....^->^->...->.->...->>>>..->...->..->^->..^->.......->....^^->.....->.->....->................................->.", "..........^->....^->^->...->.->...->>>>..->...->..->^->..^->.......->....^^->.....->.->....->................................->.", "..........^->....^->^->..->>>>>>.->^>^..^->..->..^^->>...->.......->......^^->...^^->>....^->...............................->..", "..........^->....^->^->..->>>>>>.->^>^..^->..->..^^->>...->.......->......^^->...^^->>....^->...............................->..", "..........^->....^^.^^..^^->^->.^^->>>>.^^..->....->>...^^.......^->.......^->...->>>>>>.->>>>>..........->>>>.............->...", "..........^->....^^.^^..^^->^->.^^->>>>.^^..->....->>...^^.......^->.......^->...->>>>>>.->>>>>..........->>>>.............->...", "..........^->............->>>>>>.^^^>^->...->....->^->->.........^->.......^->..^^^->>^.^^^->...........^^^^^.............->....", "..........^->............->>>>>>.^^^>^->...->....->^->->.........^->.......^->..^^^->>^.^^^->...........^^^^^.............->....", "..........^^............^^->^->...->>>>...->..->^->.^->..........^^->......->.....->^->...^->......->..............->....->.....", "..........^^............^^->^->...->>>>...->..->^->.^->..........^^->......->.....->^->...^->......->..............->....->.....", "...........->............^^.^^...^^^>....->..^->^^->>>............^^->....->.....^^.^^....^^......^->.............^->...->......", "...........->............^^.^^...^^^>....->..^->^^->>>............^^->....->.....^^.^^....^^......^->.............^->...->......", "..........^^.......................^....^^...^^..^^^^..............^^....^^.......................->..............^^....^.......", "..........^^.......................^....^^...^^..^^^^..............^^....^^.......................->..............^^....^.......", "...->>.....->.....->>>....->>>...->.^->..->>>>>....->>...->>>>>...->>>....->>>......................->............->......->>>..", "...->>.....->.....->>>....->>>...->.^->..->>>>>....->>...->>>>>...->>>....->>>......................->............->......->>>..", "..->^->...->>....->^^->..->^^->.^->.^->.^->^^^....->^...^^^^^->..->^^->..->^^->....................->............^^->....->^^->.", "..->^->...->>....->^^->..->^^->.^->.^->.^->^^^....->^...^^^^^->..->^^->..->^^->....................->............^^->....->^^->.", ".->.^->..^^->...^^..^->.^^..^->.^->.^->.^->>>>...->.........->..^->.^->.^->.^->....->......->.....->.....->>>>....^^->..^^..^->.", ".->.^->..^^->...^^..^->.^^..^->.^->.^->.^->>>>...->.........->..^->.^->.^->.^->....->......->.....->.....->>>>....^^->..^^..^->.", "^->.^->...^->......->>.....->>..^->>>>>.^^^^^->.^->>>>.....^->..^^->>>..^^->>>>...^->.....^->....->.....^^^^^......^^->.....->..", "^->.^->...^->......->>.....->>..^->>>>>.^^^^^->.^->>>>.....^->..^^->>>..^^->>>>...^->.....^->....->.....^^^^^......^^->.....->..", "^->.^->...^->.....->^.....^^^->.^^^^^->.....^->.^->^^->....->....->^^->..^^^^->...^^......^^....^^->................->.....->...", "^->.^->...^->.....->^.....^^^->.^^^^^->.....^->.^->^^->....->....->^^->..^^^^->...^^......^^....^^->................->.....->...", "^->.^->...^->....->......->.^->.....^->..->.^->.^->.^->...^->...^->.^->.....->.....->......->....^^->....->>>>.....->.....^^....", "^->.^->...^->....->......->.^->.....^->..->.^->.^->.^->...^->...^->.^->.....->.....->......->....^^->....->>>>.....->.....^^....", "^^->>>....->>>..^->>>>>.^^->>>......^->.^^->>>..^^->>>....^->...^^->>>....->>.....^->.....^->.....^^->..^^^^^.....->.......->...", "^^->>>....->>>..^->>>>>.^^->>>......^->.^^->>>..^^->>>....^->...^^->>>....->>.....^->.....^->.....^^->..^^^^^.....->.......->...", ".^^^^....^^^^...^^^^^^...^^^^.......^^...^^^^....^^^^.....^^.....^^^^....^^^......^^......->.......^^............^^.......^^....", ".^^^^....^^^^...^^^^^^...^^^^.......^^...^^^^....^^^^.....^^.....^^^^....^^^......^^......->.......^^............^^.......^^....", "..->>>.....->....->>>>....->>>...->>>>...->>>>>..->>>>>...->>>...->..->...->>>.....->>>..->..->..->......->...->.->..->...->>>..", "..->>>.....->....->>>>....->>>...->>>>...->>>>>..->>>>>...->>>...->..->...->>>.....->>>..->..->..->......->...->.->..->...->>>..", ".->^^->...->>>..^->^^->..->^^->.^->^^->.^->^^^..^->^^^...->^^->.^->.^->..^^->.....^^^->.^->.^->.^->.....^->>.->>^->>^->..->^^->.", ".->^^->...->>>..^->^^->..->^^->.^->^^->.^->^^^..^->^^^...->^^->.^->.^->..^^->.....^^^->.^->.^->.^->.....^->>.->>^->>^->..->^^->.", "^->.->>..->^^->.^->.^->.^->.^^..^->.^->.^->.....^->.....^->.^^..^->.^->...^->.......^->.^->.->..^->.....^->>>>>>^->->->.^->.^->.", "^->.->>..->^^->.^->.^->.^->.^^..^->.^->.^->.....^->.....^->.^^..^->.^->...^->.......^->.^->.->..^->.....^->>>>>>^->->->.^->.^->.", "^->^-^>.^->.^->.^->>>>..^->.....^->.^->.^->>>...^->>>...^->.->>.^->>>>>...^->.......^->.^->>>...^->.....^->^>^->^->^->>.^->.^->.", "^->^-^>.^->.^->.^->>>>..^->.....^->.^->.^->>>...^->>>...^->.->>.^->>>>>...^->.......^->.^->>>...^->.....^->^>^->^->^->>.^->.^->.", "^->^->>.^->>>>>.^->^^->.^->.....^->.^->.^->^....^->^....^->^^->.^->^^->...^->....->.^->.^->^->..^->.....^->^.^->^->^^->.^->.^->.", "^->^->>.^->>>>>.^->^^->.^->.....^->.^->.^->^....^->^....^->^^->.^->^^->...^->....->.^->.^->^->..^->.....^->^.^->^->^^->.^->.^->.", "^->^^^..^->.^->.^->.^->.^->..->.^->.^->.^->.....^->.....^->..->.^->.^->...^->...^->.^->.^->^^->.^->.....^->..^->^->.^->.^->.^->.", "^->^^^..^->.^->.^->.^->.^->..->.^->.^->.^->.....^->.....^->..->.^->.^->...^->...^->.^->.^->^^->.^->.....^->..^->^->.^->.^->.^->.", "^^->>>..^->.^->.^->>>>..^^->>>..^->>>>..^->>>>>.^->.....^^->>>..^->.^->...->>>..^^->>>..^->.^->.^->>>>>.^->..^->^->.^->.^^->>>..", "^^->>>..^->.^->.^->>>>..^^->>>..^->>>>..^->>>>>.^->.....^^->>>..^->.^->...->>>..^^->>>..^->.^->.^->>>>>.^->..^->^->.^->.^^->>>..", ".^^^^...^^..^^..^^^^^....^^^^...^^^^^...^^^^^^..^^.......^^^^...^^..^^...^^^^....^^^^...^^..^^..^^^^^^..^^...^^.^^..^^...^^^^...", ".^^^^...^^..^^..^^^^^....^^^^...^^^^^...^^^^^^..^^.......^^^^...^^..^^...^^^^....^^^^...^^..^^..^^^^^^..^^...^^.^^..^^...^^^^...", ".->>>>....->>>...->>>>....->>>...->>>>>..->..->..->..->..->...->.->..->..->..->..->>>>>..^>-....^>.......^->.......^............", ".->>>>....->>>...->>>>....->>>...->>>>>..->..->..->..->..->...->.->..->..->..->..->>>>>..^>-....^>.......^->.......^............", "^->^^->..->^^->.^->^^->..->^^->.^^^->...^->.^->.^->.^->.^->..^->^->.^->.^->.^->.^^^^^->..^>......^>........>......^->...........", "^->^^->..->^^->.^->^^->..->^^->.^^^->...^->.^->.^->.^->.^->..^->^->.^->.^->.^->.^^^^^->..^>......^>........>......^->...........", "^->.^->.^->.^->.^->.^->.^->.^^....^->...^->.^->.^->.^->.^->..^->^^->->..^->.^->.....->...^>.......^>.......>.....^-.^>..........", "^->.^->.^->.^->.^->.^->.^->.^^....^->...^->.^->.^->.^->.^->..^->^^->->..^->.^->.....->...^>.......^>.......>.....^-.^>..........", "^->>>>..^->.^->.^->>>>..^^->>>....^->...^->.^->.^->.^->.^->.>^->.^^->...^^->>>.....->....^>........^>......>....^-...^>.........", "^->>>>..^->.^->.^->>>>..^^->>>....^->...^->.^->.^->.^->.^->.>^->.^^->...^^->>>.....->....^>........^>......>....^-...^>.........", "^->^^...^->.^->.^->.^->..^^^^->...^->...^->.^->.^->.^->.^->>>>->..->->...^^->.....->.....^>.........^-.....>....................", "^->^^...^->.^->.^->.^->..^^^^->...^->...^->.^->.^->.^->.^->>>>->..->->...^^->.....->.....^>.........^-.....>....................", "^->.....^->.>>>.^->.^->..->.^->...^->...^->.^->.^^->>>..^->>^->>.->^^->...^->....->......^>..........^-....>....................", "^->.....^->.>>>.^->.^->..->.^->...^->...^->.^->.^^->>>..^->>^->>.->^^->...^->....->......^>..........^-....>....................", "^->.....^^->->..^->.^->.^^->>>....^->...^^->>>...^^->...^->.^^->^->.^->...^->...^->>>>>..^>-..........^..^->....................", "^->.....^^->->..^->.^->.^^->>>....^->...^^->>>...^^->...^->.^^->^->.^->...^->...^->>>>>..^>-..........^..^->....................", "^^.......^^^^->.^^..^^...^^^^.....^^.....^^^^.....^^....^^...^^.^^..^^....^^....^^^^^^..................................>>>>>>>>", "^^.......^^^^->.^^..^^...^^^^.....^^.....^^^^.....^^....^^...^^.^^..^^....^^....^^^^^^..................................>>>>>>>>", ".^>..............->..................->............->>...........->........->........->..->.......->>...........................", ".^>..............->..................->............->>...........->........->........->..->.......->>...........................", ".^>^............^->.................^->...........->^->.........^->.......^^........^^..^->......^^->...........................", ".^>^............^->.................^->...........->^->.........^->.......^^........^^..^->......^^->...........................", "..^-......->>>..^->.......->>>......^->...->>>...^->^^....->>>>.^->.......->>.......->>.^->..->...^->....->>.>>..->>>>....->>>..", "..^-......->>>..^->.......->>>......^->...->>>...^->^^....->>>>.^->.......->>.......->>.^->..->...^->....->>.>>..->>>>....->>>..", ".........^^^^->.^->>>>...->^^->...->>>>..->^^->..->>>....->^^->.^->>>>...^^->......^^->.^->.->....^->...^->>>>>>^->^^->..->^^->.", ".........^^^^->.^->>>>...->^^->...->>>>..->^^->..->>>....->^^->.^->>>>...^^->......^^->.^->.->....^->...^->>>>>>^->^^->..->^^->.", "..........->>>>.^->^^->.^->.^^...->^^->.^->>>>>.^^->....^->.^->.^->^^->...^->.......^->.^->>>.....^->...^->^>^->^->.^->.^->.^->.", "..........->>>>.^->^^->.^->.^^...->^^->.^->>>>>.^^->....^->.^->.^->^^->...^->.......^->.^->>>.....^->...^->^>^->^->.^->.^->.^->.", ".........->^^->.^->.^->.^->..->.^->.^->.^->^^^...^->....^^->>>>.^->.^->...^->....->.^->.^->^->....^->...^->^.^->^->.^->.^->.^->.", ".........->^^->.^->.^->.^->..->.^->.^->.^->^^^...^->....^^->>>>.^->.^->...^->....->.^->.^->^->....^->...^->^.^->^->.^->.^->.^->.", "........^^->>>>.^->>>>..^^->>>..^^->>>>.^^->>>...^->.....^^^^->.^->.^->...->>>..^->.^->.^->^^->...->>>..^->..^->^->.^->.^^->>>..", "........^^->>>>.^->>>>..^^->>>..^^->>>>.^^->>>...^->.....^^^^->.^->.^->...->>>..^->.^->.^->^^->...->>>..^->..^->^->.^->.^^->>>..", ".........^^^^^..^^^^^....^^^^....^^^^^...^^^^....^^.......->>>..^^..^^...^^^^...^^->>>..^^..^^...^^^^...^^...^^.^^..^^...^^^^...", ".........^^^^^..^^^^^....^^^^....^^^^^...^^^^....^^.......->>>..^^..^^...^^^^...^^->>>..^^..^^...^^^^...^^...^^.^^..^^...^^^^...", "..................................->........................................................->.....->.....->......->>.->........", "..................................->........................................................->.....->.....->......->>.->........", ".................................^->.......................................................->.....^->....^^->....->^->>....^>...", ".................................^->.......................................................->.....^->....^^->....->^->>....^>...", ".->>>>....->>>>..->>>>....->>>...->>>....->..->..->..->..->...->.->..->..->..->..->>>>>....->.....^->.....^->...^^.^^^....^-->..", ".->>>>....->>>>..->>>>....->>>...->>>....->..->..->..->..->...->.->..->..->..->..->>>>>....->.....^->.....^->...^^.^^^....^-->..", "^->^^->..->^^->.^->^^->..->^^...^^->....^->.^->.^->.^->.^->.>^->^^->->..^->.^->.^^^^->....->......^^......^^->...........^->^->.", "^->^^->..->^^->.^->^^->..->^^...^^->....^->.^->.^->.^->.^->.>^->^^->->..^->.^->.^^^^->....->......^^......^^->...........^->^->.", "^->.^->.^->.^->.^->.^^..^^->>>...^->....^->.^->.^->.^->.^->>>>->.^^->...^->.^->....->....^^->......->......->...........^->..^->", "^->.^->.^->.^->.^->.^^..^^->>>...^->....^->.^->.^->.^->.^->>>>->.^^->...^->.^->....->....^^->......->......->...........^->..^->", "^->>>>..^^->>>>.^->......^^^^->..^->.->.^->.^->.^^->>>..^->>^->>..->->..^^->>>>...->......^->.....^->.....^->...........^->..^->", "^->>>>..^^->>>>.^->......^^^^->..^->.->.^->.^->.^^->>>..^->>^->>..->->..^^->>>>...->......^->.....^->.....^->...........^->..^->", "^->^^....^^^^->.^->.......->>>...^^->>..^^->>>>..^^->...^->.^^->.->^^->..^^^^->..->>>>>...^^->....^->.....->............^------>", "^->^^....^^^^->.^->.......->>>...^^->>..^^->>>>..^^->...^->.^^->.->^^->..^^^^->..->>>>>...^^->....^->.....->............^------>", "^->.........^->.^^.......^^^^.....^^^....^^^^^....^^....^^...^^.^^..^^....->>>..^^^^^^.....^^.....^^.....^^.....................", "^->.........^->.^^.......^^^^.....^^^....^^^^^....^^....^^...^^.^^..^^....->>>..^^^^^^.....^^.....^^.....^^.....................", "................ ", "....>>.......... ", "..>>>>.......... ", ">>---->>>>>>>>>> ", ";;;;--;;;;;;;;;; ", "..;;;;.......... ", "....;;.......... ", "................ ", "................ ", "..........>>.... ", "..........>>>>.. ", ">>>>>>>>------>> ", ";;;;;;;;;;--;;;; ", "..........;;;;.. ", "..........;;.... ", "................ "}; static struct ascii { struct images *images; int offset; ascii_ctrl_states state; Uint32 color_stack[ASCII_CLR_STK_SZ]; int i_color; /* index onto stack */ Uint32 color; /* active color */ } Ascii; static Uint32 asciiDecodeColor(char clr) { switch (clr) { case 'w': return White; case 'B': return Black; case 'r': return TextRed; case 'g': return TextGreen; case 'b': return TextBlue; case 'y': return TextYellow; case 'c': return TextCyan; case 'm': return TextMagenta; case 'G': return Gray; default: warn("Color '%c' unknown\n", clr); return ASCII_DEF_CLR; } } static void asciiPushColor() { /* Check for overrun. */ if (array_sz(Ascii.color_stack) == Ascii.i_color) { warn("Ascii color stack overrun\n"); return; } /* Push the new color. */ Ascii.color_stack[Ascii.i_color] = Ascii.color; Ascii.i_color++; } static void asciiPopColor() { /* Check for underrun. */ if (0 == Ascii.i_color) { warn("Ascii color stack already at bottom\n"); return; } Ascii.i_color--; Ascii.color = Ascii.color_stack[Ascii.i_color]; return; } static void asciiSetColor(char clr) { /* Check for a pop. */ switch (clr) { case '+': asciiPushColor(); break; case '-': asciiPopColor(); break; case '=': /* current color, nop */ break; default: Ascii.color = asciiDecodeColor(clr); break; } } static void asciiBlitColored16(SDL_Surface *dst, SDL_Rect *dstrect, SDL_Surface *src, SDL_Rect *srcrect, Uint32 color) { Uint16 mask = color; Uint16 *srcpix, *dstpix; int x=0, y=0; assert(dst->format->BitsPerPixel==16); for (y=0; yh; y++) { srcpix = (Uint16*)src->pixels + (srcrect->y+y)*src->w + srcrect->x; dstpix = (Uint16*)dst->pixels + (dstrect->y+y)*dst->w + dstrect->x; for (x=0; xw; x++) { *dstpix = *srcpix&mask; srcpix++; dstpix++; } } } static void asciiBlitColored32(SDL_Surface *dst, SDL_Rect *dstrect, SDL_Surface *src, SDL_Rect *srcrect, Uint32 color) { Uint32 mask = color; Uint32 *srcpix, *dstpix; int x=0, y=0; assert(dst->format->BitsPerPixel==32); for (y=0; yh; y++) { srcpix = (Uint32*)src->pixels + (srcrect->y+y)*src->w + srcrect->x; dstpix = (Uint32*)dst->pixels + (dstrect->y+y)*dst->w + dstrect->x; for (x=0; xw; x++) { *dstpix = *srcpix&mask; srcpix++; dstpix++; } } } static void asciiBlitColored(SDL_Surface *dst, SDL_Rect *dstrect, SDL_Surface *src, SDL_Rect *srcrect, Uint32 color) { assert(dst->format->BitsPerPixel==src->format->BitsPerPixel); assert(dstrect->w==srcrect->w); assert(dstrect->h==srcrect->h); switch (dst->format->BitsPerPixel) { case 16: asciiBlitColored16(dst, dstrect, src, srcrect, color); break; case 32: asciiBlitColored32(dst, dstrect, src, srcrect, color); break; default: err("asciiBlitColored: unsupported BitsPerPixel: %d\n", dst->format->BitsPerPixel); break; } } static void asciiPaintColored(unsigned char c, int x, int y, SDL_Surface *surf, Uint32 color) { SDL_Rect dest; SDL_Rect src; int row; int col; assert(Ascii.images); if (c == '\t') c = ' '; assert(c >= ' '); if (c<' ') { warn("c==%d\n", c); c='?'; } /* fixme -- put these calcs in a table or something. Don't need to do * it every time. */ col = c % Ascii.images->cols; row = c / Ascii.images->cols; src.x = (col * ASCII_W) + Ascii.images->offx; src.y = (row * ASCII_H) + Ascii.images->offy; src.w = ASCII_W; src.h = ASCII_H; dest.x = x; dest.y = y; dest.w = ASCII_W; dest.h = ASCII_H; asciiBlitColored(surf, &dest, Ascii.images->images, &src, color); } static void asciiPaintDefault(unsigned char c, int x, int y, SDL_Surface * surf) { SDL_Rect dest; SDL_Rect src; int row; int col; assert(Ascii.images); if (c == '\t') c = ' '; /* fixme -- put these calcs in a table or something. Don't need to do * it every time. */ col = c % Ascii.images->cols; row = c / Ascii.images->cols; src.x = (col * ASCII_W) + Ascii.images->offx; src.y = (row * ASCII_H) + Ascii.images->offy; src.w = ASCII_W; src.h = ASCII_H; dest.x = x; dest.y = y; dest.w = ASCII_W; dest.h = ASCII_H; SDL_BlitSurface(Ascii.images->images, &src, surf, &dest); } /** * Load the emergency ASCII image set from XPM. * * @returns The images struct ready for use, our 0 if there was some kind of * error in loading it. */ static struct images *ascii_load_fixed_charset() { struct images *images; SDL_Surface *tmp; images = new struct images; assert(images); memset(images, 0, sizeof(*images)); images->w = 8; images->h = 16; images->offx = 0; images->offy = 0; images->rows = 9; images->cols = 16; images->images = IMG_ReadXPMFromArray(charset_xpm); if (!images->images) { err("IMG_ReadXPMFromArray() failed: '%s'\n", SDL_GetError() ); goto fail; } /* Images which are saved with a transparency layer will have the * SDL_SRCALPHA flag set. Their alpha layer will be managed * automatically by SDL_BlitSurface(). For images without an alpha * layer, assume that magenta (RGB 0xff00ff) is the special color for * transparency. To correctly support transparent blitting we have to * set their color key to magenta and we have to convert them to match * the display format. */ if (! (images->images->flags & SDL_SRCALPHA)) { /* Convert to video format for faster blitting */ if ((tmp = SDL_DisplayFormat(images->images)) == NULL) { err("SDL_DisplayFormat: %s", SDL_GetError()); goto fail; } SDL_FreeSurface(images->images); images->images = tmp; /* Make magenta the transparent color */ if (SDL_SetColorKey(images->images, SDL_SRCCOLORKEY, SDL_MapRGB(images->images->format, 0xff, 0x00, 0xff)) < 0) { err("SDL_SetColorKey: %s", SDL_GetError()); goto fail; } } /*images_dump_surface(fname, images->images);*/ return images; fail: images_del(images); return 0; } int asciiInit(void) { char *fname = cfg_get("ascii-image-filename"); /* This lib might be unitialized twice: once early in startup so that * error messages can be displayed, and again later after the * configuration file has been found and parsed. */ if (Ascii.images) { images_del(Ascii.images); Ascii.images = 0; } if (fname) { Ascii.images = images_new(0, 8, 16, 9, 16, 0, 0, fname); } else { Ascii.images = ascii_load_fixed_charset(); } assert(Ascii.images); Ascii.offset = 0; Ascii.state = ASCII_STATE_DEF; Ascii.i_color = 0; Ascii.color = ASCII_DEF_CLR; return 0; } int asciiPaint(char c, int x, int y, SDL_Surface * surf) { int ret = 0; switch (Ascii.state) { case ASCII_STATE_CLR: asciiSetColor(c); Ascii.state = ('+'==c?ASCII_STATE_CLRPUSH:ASCII_STATE_DEF); break; case ASCII_STATE_CLRPUSH: asciiSetColor(c); Ascii.state = ASCII_STATE_DEF; break; case ASCII_STATE_ESC: if (c == 'c') { Ascii.state = ASCII_STATE_CLR; } break; case ASCII_STATE_DEF: default: if (c == '^') { Ascii.state = ASCII_STATE_ESC; } else { if (ASCII_DEF_CLR==Ascii.color) { asciiPaintDefault(c, x, y, surf); } else { asciiPaintColored(c, x, y, surf, Ascii.color); } ret = 1; } } return ret; }