xref: /titanic_53/usr/src/cmd/ast/libshell/common/scripts/gnaw.sh (revision 906afcb89d0412cc073b95c2d701a804a8cdb62c)
1*906afcb8SAndy Fiddaman#!/usr/bin/ksh93
2*906afcb8SAndy Fiddaman
3*906afcb8SAndy Fiddaman#
4*906afcb8SAndy Fiddaman# CDDL HEADER START
5*906afcb8SAndy Fiddaman#
6*906afcb8SAndy Fiddaman# The contents of this file are subject to the terms of the
7*906afcb8SAndy Fiddaman# Common Development and Distribution License (the "License").
8*906afcb8SAndy Fiddaman# You may not use this file except in compliance with the License.
9*906afcb8SAndy Fiddaman#
10*906afcb8SAndy Fiddaman# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*906afcb8SAndy Fiddaman# or http://www.opensolaris.org/os/licensing.
12*906afcb8SAndy Fiddaman# See the License for the specific language governing permissions
13*906afcb8SAndy Fiddaman# and limitations under the License.
14*906afcb8SAndy Fiddaman#
15*906afcb8SAndy Fiddaman# When distributing Covered Code, include this CDDL HEADER in each
16*906afcb8SAndy Fiddaman# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*906afcb8SAndy Fiddaman# If applicable, add the following below this CDDL HEADER, with the
18*906afcb8SAndy Fiddaman# fields enclosed by brackets "[]" replaced with your own identifying
19*906afcb8SAndy Fiddaman# information: Portions Copyright [yyyy] [name of copyright owner]
20*906afcb8SAndy Fiddaman#
21*906afcb8SAndy Fiddaman# CDDL HEADER END
22*906afcb8SAndy Fiddaman#
23*906afcb8SAndy Fiddaman
24*906afcb8SAndy Fiddaman#
25*906afcb8SAndy Fiddaman# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
26*906afcb8SAndy Fiddaman#
27*906afcb8SAndy Fiddaman
28*906afcb8SAndy Fiddaman#
29*906afcb8SAndy Fiddaman# gnaw - a simple ksh93 technology demo
30*906afcb8SAndy Fiddaman#
31*906afcb8SAndy Fiddaman# Note that this script has been written with the main idea to show
32*906afcb8SAndy Fiddaman# many of ksh93's new features (comparing to ksh88/bash) and not
33*906afcb8SAndy Fiddaman# as an example of efficient&&clean script code (much of the code
34*906afcb8SAndy Fiddaman# could be done more efficient using compound variables, this script
35*906afcb8SAndy Fiddaman# focus is the usage of associative arrays).
36*906afcb8SAndy Fiddaman#
37*906afcb8SAndy Fiddaman
38*906afcb8SAndy Fiddaman# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
39*906afcb8SAndy Fiddamanexport PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin
40*906afcb8SAndy Fiddaman
41*906afcb8SAndy Fiddaman# Make sure all math stuff runs in the "C" locale to avoid problems
42*906afcb8SAndy Fiddaman# with alternative # radix point representations (e.g. ',' instead of
43*906afcb8SAndy Fiddaman# '.' in de_DE.*-locales). This needs to be set _before_ any
44*906afcb8SAndy Fiddaman# floating-point constants are defined in this script).
45*906afcb8SAndy Fiddamanif [[ "${LC_ALL}" != "" ]] ; then
46*906afcb8SAndy Fiddaman    export \
47*906afcb8SAndy Fiddaman        LC_MONETARY="${LC_ALL}" \
48*906afcb8SAndy Fiddaman        LC_MESSAGES="${LC_ALL}" \
49*906afcb8SAndy Fiddaman        LC_COLLATE="${LC_ALL}" \
50*906afcb8SAndy Fiddaman        LC_CTYPE="${LC_ALL}"
51*906afcb8SAndy Fiddaman        unset LC_ALL
52*906afcb8SAndy Fiddamanfi
53*906afcb8SAndy Fiddamanexport LC_NUMERIC=C
54*906afcb8SAndy Fiddaman
55*906afcb8SAndy Fiddamanfunction print_setcursorpos
56*906afcb8SAndy Fiddaman{
57*906afcb8SAndy Fiddaman    print -n -- "${vtcode[cup_${1}_${2}]}"
58*906afcb8SAndy Fiddaman}
59*906afcb8SAndy Fiddaman
60*906afcb8SAndy Fiddamanfunction beep
61*906afcb8SAndy Fiddaman{
62*906afcb8SAndy Fiddaman    ${quiet} || print -n -- "${vtcode["bel"]}"
63*906afcb8SAndy Fiddaman}
64*906afcb8SAndy Fiddaman
65*906afcb8SAndy Fiddamanfunction fatal_error
66*906afcb8SAndy Fiddaman{
67*906afcb8SAndy Fiddaman    print -u2 "${progname}: $*"
68*906afcb8SAndy Fiddaman    exit 1
69*906afcb8SAndy Fiddaman}
70*906afcb8SAndy Fiddaman
71*906afcb8SAndy Fiddaman# Get terminal size and put values into a compound variable with the integer
72*906afcb8SAndy Fiddaman# members "columns" and "lines"
73*906afcb8SAndy Fiddamanfunction get_term_size
74*906afcb8SAndy Fiddaman{
75*906afcb8SAndy Fiddaman	nameref rect=$1
76*906afcb8SAndy Fiddaman
77*906afcb8SAndy Fiddaman	rect.columns=${ tput cols ; } || return 1
78*906afcb8SAndy Fiddaman	rect.lines=${ tput lines ; }  || return 1
79*906afcb8SAndy Fiddaman
80*906afcb8SAndy Fiddaman	return 0
81*906afcb8SAndy Fiddaman}
82*906afcb8SAndy Fiddaman
83*906afcb8SAndy Fiddamanfunction print_levelmap
84*906afcb8SAndy Fiddaman{
85*906afcb8SAndy Fiddaman    integer screen_y_offset=$1
86*906afcb8SAndy Fiddaman    integer start_y_pos=$2 # start at this line in the map
87*906afcb8SAndy Fiddaman    integer max_numlines=$3 # maximum lines we're allowed to render
88*906afcb8SAndy Fiddaman    integer x
89*906afcb8SAndy Fiddaman    integer y
90*906afcb8SAndy Fiddaman    typeset line=""
91*906afcb8SAndy Fiddaman
92*906afcb8SAndy Fiddaman    print_setcursorpos 0 ${screen_y_offset}
93*906afcb8SAndy Fiddaman
94*906afcb8SAndy Fiddaman    for (( y=start_y_pos; (y-start_y_pos) < max_numlines && y < levelmap["max_y"] ; y++ )) ; do
95*906afcb8SAndy Fiddaman        line=""
96*906afcb8SAndy Fiddaman        for (( x=0 ; x < levelmap["max_x"] ; x++ )) ; do
97*906afcb8SAndy Fiddaman            line+="${levelmap["${x}_${y}"]}"
98*906afcb8SAndy Fiddaman        done
99*906afcb8SAndy Fiddaman
100*906afcb8SAndy Fiddaman        print -- "${line} "
101*906afcb8SAndy Fiddaman    done
102*906afcb8SAndy Fiddaman
103*906afcb8SAndy Fiddaman    # print lines filled with spaces for each line not filled
104*906afcb8SAndy Fiddaman    # by the level map
105*906afcb8SAndy Fiddaman    line="${vtcode["spaceline"]:0:${levelmap["max_x"]}}"
106*906afcb8SAndy Fiddaman    for (( ; (y-start_y_pos) < max_numlines ; y++ )) ; do
107*906afcb8SAndy Fiddaman        print -- "${line} "
108*906afcb8SAndy Fiddaman    done
109*906afcb8SAndy Fiddaman    return 0
110*906afcb8SAndy Fiddaman}
111*906afcb8SAndy Fiddaman
112*906afcb8SAndy Fiddamanfunction level_completed
113*906afcb8SAndy Fiddaman{
114*906afcb8SAndy Fiddaman    integer i
115*906afcb8SAndy Fiddaman    typeset dummy
116*906afcb8SAndy Fiddaman    typeset render_buffer="$(
117*906afcb8SAndy Fiddaman    print -n -- "${vtcode["clear"]}"
118*906afcb8SAndy Fiddaman    cat <<ENDOFTEXT
119*906afcb8SAndy Fiddaman
120*906afcb8SAndy Fiddaman #       ######  #    #  ######  #
121*906afcb8SAndy Fiddaman #       #       #    #  #       #
122*906afcb8SAndy Fiddaman #       #####   #    #  #####   #
123*906afcb8SAndy Fiddaman #       #       #    #  #       #
124*906afcb8SAndy Fiddaman #       #        #  #   #       #
125*906afcb8SAndy Fiddaman ######  ######    ##    ######  ######
126*906afcb8SAndy Fiddaman
127*906afcb8SAndy Fiddaman             (Good job)
128*906afcb8SAndy Fiddaman
129*906afcb8SAndy Fiddaman     #####    ####   #    #  ######
130*906afcb8SAndy Fiddaman     #    #  #    #  ##   #  #
131*906afcb8SAndy Fiddaman     #    #  #    #  # #  #  #####
132*906afcb8SAndy Fiddaman     #    #  #    #  #  # #  #
133*906afcb8SAndy Fiddaman     #    #  #    #  #   ##  #
134*906afcb8SAndy Fiddaman     #####    ####   #    #  ######
135*906afcb8SAndy Fiddaman
136*906afcb8SAndy Fiddaman
137*906afcb8SAndy FiddamanENDOFTEXT
138*906afcb8SAndy Fiddaman
139*906afcb8SAndy Fiddaman    printf "    SCORE: --> %s <--\n" "${player["score"]}"
140*906afcb8SAndy Fiddaman    printf "    LIVES: --> %s <--\n" "${player["lives"]}"
141*906afcb8SAndy Fiddaman    )"
142*906afcb8SAndy Fiddaman    print -- "${render_buffer}${end_of_frame}"
143*906afcb8SAndy Fiddaman
144*906afcb8SAndy Fiddaman    # wait five seconds and swallow any user input
145*906afcb8SAndy Fiddaman    for (( i=0 ; i < 50 ; i++ )) ; do
146*906afcb8SAndy Fiddaman        read -r -t 0.1 -n 1 dummy
147*906afcb8SAndy Fiddaman    done
148*906afcb8SAndy Fiddaman
149*906afcb8SAndy Fiddaman    print "Press any key to continue...${end_of_frame}"
150*906afcb8SAndy Fiddaman    # wait five secs or for a key
151*906afcb8SAndy Fiddaman    read -r -t 5 -n 1 dummy
152*906afcb8SAndy Fiddaman    return 0
153*906afcb8SAndy Fiddaman}
154*906afcb8SAndy Fiddaman
155*906afcb8SAndy Fiddamanfunction game_over
156*906afcb8SAndy Fiddaman{
157*906afcb8SAndy Fiddaman    typeset dummy
158*906afcb8SAndy Fiddaman    typeset render_buffer="$(
159*906afcb8SAndy Fiddaman    print -n -- "${vtcode["clear"]}"
160*906afcb8SAndy Fiddaman    cat <<ENDOFTEXT
161*906afcb8SAndy Fiddaman
162*906afcb8SAndy Fiddaman  ####     ##    #    #  ######
163*906afcb8SAndy Fiddaman #    #   #  #   ##  ##  #
164*906afcb8SAndy Fiddaman #       #    #  # ## #  #####
165*906afcb8SAndy Fiddaman #  ###  ######  #    #  #
166*906afcb8SAndy Fiddaman #    #  #    #  #    #  #
167*906afcb8SAndy Fiddaman  ####   #    #  #    #  ######
168*906afcb8SAndy Fiddaman
169*906afcb8SAndy Fiddaman            (LOSER!)
170*906afcb8SAndy Fiddaman
171*906afcb8SAndy Fiddaman  ####   #    #  ######  #####
172*906afcb8SAndy Fiddaman #    #  #    #  #       #    #
173*906afcb8SAndy Fiddaman #    #  #    #  #####   #    #
174*906afcb8SAndy Fiddaman #    #  #    #  #       #####
175*906afcb8SAndy Fiddaman #    #   #  #   #       #   #
176*906afcb8SAndy Fiddaman  ####     ##    ######  #    #
177*906afcb8SAndy Fiddaman
178*906afcb8SAndy FiddamanENDOFTEXT
179*906afcb8SAndy Fiddaman
180*906afcb8SAndy Fiddaman    printf "\n    SCORE: --> %s <--\n" "${player["score"]}"
181*906afcb8SAndy Fiddaman    )"
182*906afcb8SAndy Fiddaman    print -r -- "${render_buffer}${end_of_frame}"
183*906afcb8SAndy Fiddaman
184*906afcb8SAndy Fiddaman    # wait five seconds and swallow any user input
185*906afcb8SAndy Fiddaman    for (( i=0 ; i < 50 ; i++ )) ; do
186*906afcb8SAndy Fiddaman        read -r -t 0.1 -n 1 dummy
187*906afcb8SAndy Fiddaman    done
188*906afcb8SAndy Fiddaman
189*906afcb8SAndy Fiddaman    print "Press any key to continue...${end_of_frame}"
190*906afcb8SAndy Fiddaman    # wait five secs or for a key
191*906afcb8SAndy Fiddaman    read -r -t 5 -n 1 dummy
192*906afcb8SAndy Fiddaman    return 0
193*906afcb8SAndy Fiddaman}
194*906afcb8SAndy Fiddaman
195*906afcb8SAndy Fiddamanfunction run_logo
196*906afcb8SAndy Fiddaman{
197*906afcb8SAndy Fiddaman    typeset render_buffer="$(
198*906afcb8SAndy Fiddaman    cat <<ENDOFTEXT
199*906afcb8SAndy Fiddaman
200*906afcb8SAndy Fiddaman #####  #     #    #    #     #   ###
201*906afcb8SAndy Fiddaman#     # ##    #   # #   #  #  #   ###
202*906afcb8SAndy Fiddaman#       # #   #  #   #  #  #  #   ###
203*906afcb8SAndy Fiddaman#  #### #  #  # #     # #  #  #    #
204*906afcb8SAndy Fiddaman#     # #   # # ####### #  #  #
205*906afcb8SAndy Fiddaman#     # #    ## #     # #  #  #   ###
206*906afcb8SAndy Fiddaman #####  #     # #     #  ## ##    ###
207*906afcb8SAndy FiddamanENDOFTEXT
208*906afcb8SAndy Fiddaman    )"
209*906afcb8SAndy Fiddaman    print -- "${vtcode["clear"]}${render_buffer}"
210*906afcb8SAndy Fiddaman
211*906afcb8SAndy Fiddaman    # wait two seconds and swallow any user input
212*906afcb8SAndy Fiddaman    for (( i=0 ; i < 20 ; i++ )) ; do
213*906afcb8SAndy Fiddaman        read -r -t 0.1 -n 1 dummy
214*906afcb8SAndy Fiddaman    done
215*906afcb8SAndy Fiddaman
216*906afcb8SAndy Fiddaman    print "\n   (The KornShell 93 maze game)"
217*906afcb8SAndy Fiddaman
218*906afcb8SAndy Fiddaman    attract_mode
219*906afcb8SAndy Fiddaman    return 0
220*906afcb8SAndy Fiddaman}
221*906afcb8SAndy Fiddaman
222*906afcb8SAndy Fiddamanfunction attract_mode
223*906afcb8SAndy Fiddaman{
224*906afcb8SAndy Fiddaman(
225*906afcb8SAndy Fiddaman    # Now present some info, line-by-line in an endless loop
226*906afcb8SAndy Fiddaman    # until the user presses a key (we turn the "magic" return
227*906afcb8SAndy Fiddaman    # code for that)
228*906afcb8SAndy Fiddaman    integer -r magic_return_code=69
229*906afcb8SAndy Fiddaman    typeset line
230*906afcb8SAndy Fiddaman    IFS='' ; # Make sure we do not swallow whitespaces
231*906afcb8SAndy Fiddaman
232*906afcb8SAndy Fiddaman    while true ; do
233*906afcb8SAndy Fiddaman        (
234*906afcb8SAndy Fiddaman            redirect 5<&0
235*906afcb8SAndy Fiddaman
236*906afcb8SAndy Fiddaman        (cat <<ENDOFTEXT
237*906afcb8SAndy Fiddaman
238*906afcb8SAndy Fiddaman
239*906afcb8SAndy Fiddaman
240*906afcb8SAndy Fiddaman
241*906afcb8SAndy Fiddaman
242*906afcb8SAndy Fiddaman         ################
243*906afcb8SAndy Fiddaman     ########################
244*906afcb8SAndy Fiddaman   ############################
245*906afcb8SAndy Fiddaman  #######     ######     #######
246*906afcb8SAndy Fiddaman  ######     ######     ########
247*906afcb8SAndy Fiddaman  #######     ######     #######
248*906afcb8SAndy Fiddaman  ##############################
249*906afcb8SAndy Fiddaman  ##############################
250*906afcb8SAndy Fiddaman  ##############################
251*906afcb8SAndy Fiddaman  ##############################
252*906afcb8SAndy Fiddaman  ##############################
253*906afcb8SAndy Fiddaman  #########  ########  #########
254*906afcb8SAndy Fiddaman  #  ####      ####      ####  #
255*906afcb8SAndy Fiddaman
256*906afcb8SAndy Fiddaman
257*906afcb8SAndy Fiddaman
258*906afcb8SAndy Fiddaman
259*906afcb8SAndy Fiddaman
260*906afcb8SAndy Fiddaman
261*906afcb8SAndy Fiddaman           Written by
262*906afcb8SAndy Fiddaman
263*906afcb8SAndy Fiddaman          Roland Mainz
264*906afcb8SAndy Fiddaman    (roland.mainz@nrubsig.org)
265*906afcb8SAndy Fiddaman
266*906afcb8SAndy Fiddaman
267*906afcb8SAndy Fiddaman
268*906afcb8SAndy Fiddaman
269*906afcb8SAndy Fiddaman
270*906afcb8SAndy Fiddaman
271*906afcb8SAndy Fiddaman           ##############
272*906afcb8SAndy Fiddaman      ########################
273*906afcb8SAndy Fiddaman   #################**############
274*906afcb8SAndy Fiddaman  ################################
275*906afcb8SAndy Fiddaman ############################
276*906afcb8SAndy Fiddaman ######################
277*906afcb8SAndy Fiddaman ################
278*906afcb8SAndy Fiddaman ######################
279*906afcb8SAndy Fiddaman ############################
280*906afcb8SAndy Fiddaman  ################################
281*906afcb8SAndy Fiddaman   ##############################
282*906afcb8SAndy Fiddaman      ########################
283*906afcb8SAndy Fiddaman           ##############
284*906afcb8SAndy Fiddaman
285*906afcb8SAndy Fiddaman
286*906afcb8SAndy Fiddaman
287*906afcb8SAndy Fiddaman
288*906afcb8SAndy Fiddaman
289*906afcb8SAndy Fiddaman
290*906afcb8SAndy Fiddaman
291*906afcb8SAndy Fiddaman             High scores:
292*906afcb8SAndy Fiddaman
293*906afcb8SAndy Fiddaman        * 'chin'      8200 pt
294*906afcb8SAndy Fiddaman        * 'gisburn'   7900 pt
295*906afcb8SAndy Fiddaman        * 'tpenta'    5520 pt
296*906afcb8SAndy Fiddaman        * 'kupfer'    5510 pt
297*906afcb8SAndy Fiddaman        * 'noname'    5000 pt
298*906afcb8SAndy Fiddaman        * 'noname'    4000 pt
299*906afcb8SAndy Fiddaman        * 'livad'     3120 pt
300*906afcb8SAndy Fiddaman        * 'noname'    3000 pt
301*906afcb8SAndy Fiddaman        * 'noname'    2000 pt
302*906afcb8SAndy Fiddaman        * 'noname'    1000 pt
303*906afcb8SAndy Fiddaman
304*906afcb8SAndy FiddamanENDOFTEXT
305*906afcb8SAndy Fiddaman
306*906afcb8SAndy Fiddaman        # clear screen, line-by-line
307*906afcb8SAndy Fiddaman        for (( i=0 ; i < termsize.lines ; i++ )) ; do print "" ; done
308*906afcb8SAndy Fiddaman        ) | (while read -r line ; do
309*906afcb8SAndy Fiddaman                read -r -t 0.3 -n 1 c <&5
310*906afcb8SAndy Fiddaman                [[ "$c" != "" ]] && exit ${magic_return_code}
311*906afcb8SAndy Fiddaman                print -- "${line}"
312*906afcb8SAndy Fiddaman            done)
313*906afcb8SAndy Fiddaman        (( $? == magic_return_code )) && exit ${magic_return_code}
314*906afcb8SAndy Fiddaman        )
315*906afcb8SAndy Fiddaman        (( $? == magic_return_code )) && return 0
316*906afcb8SAndy Fiddaman
317*906afcb8SAndy Fiddaman        sleep 2
318*906afcb8SAndy Fiddaman    done
319*906afcb8SAndy Fiddaman)
320*906afcb8SAndy Fiddaman}
321*906afcb8SAndy Fiddaman
322*906afcb8SAndy Fiddamanfunction run_menu
323*906afcb8SAndy Fiddaman{
324*906afcb8SAndy Fiddaman    integer numlevels=0
325*906afcb8SAndy Fiddaman    integer selected_level=0
326*906afcb8SAndy Fiddaman    typeset l
327*906afcb8SAndy Fiddaman
328*906afcb8SAndy Fiddaman    # built list of available levels based on the "function levelmap_.*"
329*906afcb8SAndy Fiddaman    # built into this script
330*906afcb8SAndy Fiddaman    typeset -f | egrep "^function.*levelmap_.*" | sed 's/^function //' |
331*906afcb8SAndy Fiddaman    while read -r l ; do
332*906afcb8SAndy Fiddaman        levellist[numlevels]="$l"
333*906afcb8SAndy Fiddaman        numlevels+=1
334*906afcb8SAndy Fiddaman    done
335*906afcb8SAndy Fiddaman
336*906afcb8SAndy Fiddaman    # swallow any queued user input (e.g. drain stdin)
337*906afcb8SAndy Fiddaman    read -r -t 0.1 -n 100 dummy
338*906afcb8SAndy Fiddaman
339*906afcb8SAndy Fiddaman    while true ; do
340*906afcb8SAndy Fiddaman        # menu loop with timeout (which switches to "attract mode")
341*906afcb8SAndy Fiddaman        while true ; do
342*906afcb8SAndy Fiddaman            print -n -- "${vtcode["clear"]}"
343*906afcb8SAndy Fiddaman
344*906afcb8SAndy Fiddaman    cat <<ENDOFTEXT
345*906afcb8SAndy Fiddaman>======================================\
346*906afcb8SAndy Fiddaman>  /-\     .--.                        |
347*906afcb8SAndy Fiddaman> | OO|   / _.-' .-.   .-.  .-.   .-.  |
348*906afcb8SAndy Fiddaman> |   |   \  '-. '-'   '-'  '-'   '-'  |
349*906afcb8SAndy Fiddaman> ^^^^^    '--'                        |
350*906afcb8SAndy Fiddaman>======\       /================\  .-. |
351*906afcb8SAndy Fiddaman>      |       |                |  '-' |
352*906afcb8SAndy Fiddaman ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
353*906afcb8SAndy FiddamanENDOFTEXT
354*906afcb8SAndy Fiddaman            print "    GNAW - the ksh93 maze game"
355*906afcb8SAndy Fiddaman            print "\n\tMenu:"
356*906afcb8SAndy Fiddaman
357*906afcb8SAndy Fiddaman            print "\t - [L]evels:"
358*906afcb8SAndy Fiddaman            for (( i=0 ; i < numlevels ; i++ )) ; do
359*906afcb8SAndy Fiddaman                printf "\t    %s %s \n" "$( (( i == selected_level )) && print -n "*" || print -n " ")" "${levellist[i]##levelmap_}"
360*906afcb8SAndy Fiddaman            done
361*906afcb8SAndy Fiddaman
362*906afcb8SAndy Fiddaman            print  "\t - Rendering options:"
363*906afcb8SAndy Fiddaman            printf "\t    [%s] Use [U]nicode\n" "$( (( game_use_unicode == 1 )) && print -n "x" || print -n "_" )"
364*906afcb8SAndy Fiddaman            printf "\t    [%s] Use [C]olors\n"  "$( (( game_use_colors  == 1 )) && print -n "x" || print -n "_" )"
365*906afcb8SAndy Fiddaman
366*906afcb8SAndy Fiddaman            print "\t - [S]tart - [Q]uit"
367*906afcb8SAndy Fiddaman
368*906afcb8SAndy Fiddaman            # wait 30 secs (before we switch to "attract mode")
369*906afcb8SAndy Fiddaman            c="" ; read -r -t 30 -n 1 c
370*906afcb8SAndy Fiddaman            case "$c" in
371*906afcb8SAndy Fiddaman                'l') (( selected_level=(selected_level+numlevels+1) % numlevels )) ;;
372*906afcb8SAndy Fiddaman                'L') (( selected_level=(selected_level+numlevels-1) % numlevels )) ;;
373*906afcb8SAndy Fiddaman                ~(Fi)s)
374*906afcb8SAndy Fiddaman                    (( game_use_colors == 1 )) && print -- "${vtcode["bg_black"]}"
375*906afcb8SAndy Fiddaman                    case "${game_use_colors}${game_use_unicode}" in
376*906afcb8SAndy Fiddaman                        "00") main_loop "${levellist[selected_level]}" ;;
377*906afcb8SAndy Fiddaman                        "01") main_loop "${levellist[selected_level]}" | map_filter 0 1 ;;
378*906afcb8SAndy Fiddaman                        "10") main_loop "${levellist[selected_level]}" | map_filter 1 0 ;;
379*906afcb8SAndy Fiddaman                        "11") main_loop "${levellist[selected_level]}" | map_filter 1 1 ;;
380*906afcb8SAndy Fiddaman                    esac
381*906afcb8SAndy Fiddaman                    print -- "${vtcode["vtreset"]}"
382*906afcb8SAndy Fiddaman                    ;;
383*906afcb8SAndy Fiddaman                ~(Fi)q | $'\E')
384*906afcb8SAndy Fiddaman                    # make sure we do not exit on a cursor key (e.g. <esc>[A,B,C,D)
385*906afcb8SAndy Fiddaman                    read -r -t 0.01 -n 1 c
386*906afcb8SAndy Fiddaman                    if [[ "$c" == "[" ]] ; then
387*906afcb8SAndy Fiddaman                        # this was a cursor key sequence, just eat the 3rd charcater
388*906afcb8SAndy Fiddaman                        read -r -t 0.01 -n 1 c
389*906afcb8SAndy Fiddaman                    else
390*906afcb8SAndy Fiddaman                        exit 0
391*906afcb8SAndy Fiddaman                    fi
392*906afcb8SAndy Fiddaman                    ;;
393*906afcb8SAndy Fiddaman                ~(Fi)u) (( game_use_unicode=(game_use_unicode+2+1) % 2)) ;;
394*906afcb8SAndy Fiddaman                ~(Fi)c) (( game_use_colors=(game_use_colors+2+1) % 2))   ;;
395*906afcb8SAndy Fiddaman                "") break ;; # timeout, switch to attract mode
396*906afcb8SAndy Fiddaman                *) beep ;;
397*906afcb8SAndy Fiddaman            esac
398*906afcb8SAndy Fiddaman        done
399*906afcb8SAndy Fiddaman
400*906afcb8SAndy Fiddaman        print -n -- "${vtcode["clear"]}"
401*906afcb8SAndy Fiddaman        attract_mode
402*906afcb8SAndy Fiddaman    done
403*906afcb8SAndy Fiddaman    return 0
404*906afcb8SAndy Fiddaman}
405*906afcb8SAndy Fiddaman
406*906afcb8SAndy Fiddamanfunction levelmap_stripes
407*906afcb8SAndy Fiddaman{
408*906afcb8SAndy Fiddamancat <<ENDOFLEVEL
409*906afcb8SAndy Fiddaman###################################
410*906afcb8SAndy Fiddaman#.......    ...............    P  #
411*906afcb8SAndy Fiddaman#########..#################..### #
412*906afcb8SAndy Fiddaman#########..#################..### #
413*906afcb8SAndy Fiddaman#.......    ..    ..............# #
414*906afcb8SAndy Fiddaman###############  ################ #
415*906afcb8SAndy Fiddaman###############  ################ #
416*906afcb8SAndy Fiddaman#............. M  ..............# #
417*906afcb8SAndy Fiddaman##..#####################  ###### #
418*906afcb8SAndy Fiddaman##..#####################  ###### #
419*906afcb8SAndy Fiddaman#.......  ...........    .......# #
420*906afcb8SAndy Fiddaman########  ############  ######### #
421*906afcb8SAndy Fiddaman#   ####  ############  ######### #
422*906afcb8SAndy Fiddaman# #..................     ......# #
423*906afcb8SAndy Fiddaman# ############################### #
424*906afcb8SAndy Fiddaman#                                 #
425*906afcb8SAndy Fiddaman###################################
426*906afcb8SAndy FiddamanENDOFLEVEL
427*906afcb8SAndy Fiddaman    return 0
428*906afcb8SAndy Fiddaman}
429*906afcb8SAndy Fiddaman
430*906afcb8SAndy Fiddamanfunction levelmap_livad
431*906afcb8SAndy Fiddaman{
432*906afcb8SAndy Fiddamancat <<ENDOFLEVEL
433*906afcb8SAndy Fiddaman#####################################################
434*906afcb8SAndy Fiddaman#                                                   #
435*906afcb8SAndy Fiddaman# ##############  ###############  ################ #
436*906afcb8SAndy Fiddaman# #............       P             ..............# #
437*906afcb8SAndy Fiddaman#  .#############################################.# #
438*906afcb8SAndy Fiddaman# #.#..........                     ............#.  #
439*906afcb8SAndy Fiddaman# #.#.##########  ###############  ############.#.# #
440*906afcb8SAndy Fiddaman# #...#........                     ..........#...# #
441*906afcb8SAndy Fiddaman# #...#.#####################################.#.#.# #
442*906afcb8SAndy Fiddaman# #...#.#......                     ........#...#.# #
443*906afcb8SAndy Fiddaman# #.#.#...######  #########################.#.#.#.# #
444*906afcb8SAndy Fiddaman#  .#.....#....          M          ......#...#.#.# #
445*906afcb8SAndy Fiddaman# #.#.#...#######################  ########.#.#.#.# #
446*906afcb8SAndy Fiddaman# #...#.#......                     ........#...#.# #
447*906afcb8SAndy Fiddaman# #...#.########  ###############  ##########.#.#.# #
448*906afcb8SAndy Fiddaman# #...#........                     ..........#...# #
449*906afcb8SAndy Fiddaman# #.#.#########################################.#.# #
450*906afcb8SAndy Fiddaman# #.#..........                     ............#.  #
451*906afcb8SAndy Fiddaman#  .############  ###############  ##############.# #
452*906afcb8SAndy Fiddaman# #............                     ..............# #
453*906afcb8SAndy Fiddaman# ################################################# #
454*906afcb8SAndy Fiddaman#                                                   #
455*906afcb8SAndy Fiddaman#####################################################
456*906afcb8SAndy FiddamanENDOFLEVEL
457*906afcb8SAndy Fiddaman    return 0
458*906afcb8SAndy Fiddaman}
459*906afcb8SAndy Fiddaman
460*906afcb8SAndy Fiddamanfunction levelmap_classic1
461*906afcb8SAndy Fiddaman{
462*906afcb8SAndy Fiddamancat <<ENDOFLEVEL
463*906afcb8SAndy Fiddaman#########################
464*906afcb8SAndy Fiddaman#.P.........#...........#
465*906afcb8SAndy Fiddaman#.####.####.#.####.####.#
466*906afcb8SAndy Fiddaman#.#  #.#  #.#.#  #.#  #.#
467*906afcb8SAndy Fiddaman#.#  #.#  #.#.#  #.#  #.#
468*906afcb8SAndy Fiddaman#.####.####.#.####.####.#
469*906afcb8SAndy Fiddaman#.......................#
470*906afcb8SAndy Fiddaman#.####.#.#######.#.####.#
471*906afcb8SAndy Fiddaman#.#  #.#.#     #.#.#  #.#
472*906afcb8SAndy Fiddaman#.####.#.#######.#.####.#
473*906afcb8SAndy Fiddaman#......#....#....#......#
474*906afcb8SAndy Fiddaman######.####.#.####.######
475*906afcb8SAndy Fiddaman###### #         # ######
476*906afcb8SAndy Fiddaman###### # ##   ## # ######
477*906afcb8SAndy Fiddaman###### # #     # # ######
478*906afcb8SAndy Fiddaman#        #  M  #        #
479*906afcb8SAndy Fiddaman###### # ####### # ######
480*906afcb8SAndy Fiddaman###### #         # ######
481*906afcb8SAndy Fiddaman###### # ####### # ######
482*906afcb8SAndy Fiddaman###### # #     # # ######
483*906afcb8SAndy Fiddaman######.#.#######.#.######
484*906afcb8SAndy Fiddaman#...........#...........#
485*906afcb8SAndy Fiddaman#.###.###...#...###.###.#
486*906afcb8SAndy Fiddaman#...#...............#...#
487*906afcb8SAndy Fiddaman###.#....#######....#.###
488*906afcb8SAndy Fiddaman# #.#..#.#     #.#..#.# #
489*906afcb8SAndy Fiddaman###....#.#######.#....###
490*906afcb8SAndy Fiddaman#......#....#....#......#
491*906afcb8SAndy Fiddaman#.#########.#.#########.#
492*906afcb8SAndy Fiddaman#.......................#
493*906afcb8SAndy Fiddaman#########################
494*906afcb8SAndy FiddamanENDOFLEVEL
495*906afcb8SAndy Fiddaman    return 0
496*906afcb8SAndy Fiddaman}
497*906afcb8SAndy Fiddaman
498*906afcb8SAndy Fiddamanfunction levelmap_classic2
499*906afcb8SAndy Fiddaman{
500*906afcb8SAndy Fiddamancat <<ENDOFLEVEL
501*906afcb8SAndy Fiddaman#######################
502*906afcb8SAndy Fiddaman#.P...#.........#.....#
503*906afcb8SAndy Fiddaman#.###.#.#######.#.###.#
504*906afcb8SAndy Fiddaman#.....................#
505*906afcb8SAndy Fiddaman###.#.####.#.####.#.###
506*906afcb8SAndy Fiddaman###.#......#......#.###
507*906afcb8SAndy Fiddaman###.###.#######.###.###
508*906afcb8SAndy Fiddaman###.................###
509*906afcb8SAndy Fiddaman###.###.### ###.###.###
510*906afcb8SAndy Fiddaman###.#...#M    #...#.###
511*906afcb8SAndy Fiddaman###.#.#.#######.#.#.###
512*906afcb8SAndy Fiddaman#.....#.........#.....#
513*906afcb8SAndy Fiddaman###.#####..#..#####.###
514*906afcb8SAndy Fiddaman###........#........###
515*906afcb8SAndy Fiddaman###.###.#######.###.###
516*906afcb8SAndy Fiddaman#.....................#
517*906afcb8SAndy Fiddaman#.###.####.#.####.###.#
518*906afcb8SAndy Fiddaman#.###.#....#....#.###.#
519*906afcb8SAndy Fiddaman#.###.#.#######.#.###.#
520*906afcb8SAndy Fiddaman#.....................#
521*906afcb8SAndy Fiddaman#######################
522*906afcb8SAndy FiddamanENDOFLEVEL
523*906afcb8SAndy Fiddaman    return 0
524*906afcb8SAndy Fiddaman}
525*906afcb8SAndy Fiddaman
526*906afcb8SAndy Fiddamanfunction levelmap_easy
527*906afcb8SAndy Fiddaman{
528*906afcb8SAndy Fiddamancat <<ENDOFLEVEL
529*906afcb8SAndy Fiddaman##################
530*906afcb8SAndy Fiddaman# .............. #
531*906afcb8SAndy Fiddaman# . ######       #
532*906afcb8SAndy Fiddaman# . #  M #       #
533*906afcb8SAndy Fiddaman# . #    #       #
534*906afcb8SAndy Fiddaman# . ### ##       #
535*906afcb8SAndy Fiddaman# .   #          #
536*906afcb8SAndy Fiddaman# .   ###        #
537*906afcb8SAndy Fiddaman# .              #
538*906afcb8SAndy Fiddaman# ..........     #
539*906afcb8SAndy Fiddaman# .......... P   #
540*906afcb8SAndy Fiddaman##################
541*906afcb8SAndy FiddamanENDOFLEVEL
542*906afcb8SAndy Fiddaman    return 0
543*906afcb8SAndy Fiddaman}
544*906afcb8SAndy Fiddaman
545*906afcb8SAndy Fiddamanfunction levelmap_sunsolaristext
546*906afcb8SAndy Fiddaman{
547*906afcb8SAndy Fiddamancat <<ENDOFLEVEL
548*906afcb8SAndy Fiddaman################################################
549*906afcb8SAndy Fiddaman# .####   .    #  #....#                       #
550*906afcb8SAndy Fiddaman# #       #    #  #....#                       #
551*906afcb8SAndy Fiddaman#  ####   #    #  #.#..#          M            #
552*906afcb8SAndy Fiddaman#      #  #    #  #..#.#                       #
553*906afcb8SAndy Fiddaman# #    #  #    #  #...##                       #
554*906afcb8SAndy Fiddaman#  ####    ####   #....#                       #
555*906afcb8SAndy Fiddaman#                                              #
556*906afcb8SAndy Fiddaman#  ####    ####  #       ##    #####  #  ####  #
557*906afcb8SAndy Fiddaman# #       #.  .# #      #  #   #....# # #      #
558*906afcb8SAndy Fiddaman#  ####   #    # #      # P #  #....# #  ####  #
559*906afcb8SAndy Fiddaman#      #  #    ###      #.#### #.###  #      # #
560*906afcb8SAndy Fiddaman# #   .#  #.  ..        #    # #...#  # #    # #
561*906afcb8SAndy Fiddaman#  ####    ####  ###### .    #  ....# #  ####. #
562*906afcb8SAndy Fiddaman################################################
563*906afcb8SAndy FiddamanENDOFLEVEL
564*906afcb8SAndy Fiddaman    return 0
565*906afcb8SAndy Fiddaman}
566*906afcb8SAndy Fiddaman
567*906afcb8SAndy Fiddamanfunction read_levelmap
568*906afcb8SAndy Fiddaman{
569*906afcb8SAndy Fiddaman    typeset map="$( $1 )"
570*906afcb8SAndy Fiddaman
571*906afcb8SAndy Fiddaman    integer y=0
572*906afcb8SAndy Fiddaman    integer x=0
573*906afcb8SAndy Fiddaman    integer maxx=0
574*906afcb8SAndy Fiddaman    integer numdots=0
575*906afcb8SAndy Fiddaman    typeset line
576*906afcb8SAndy Fiddaman    typeset c
577*906afcb8SAndy Fiddaman
578*906afcb8SAndy Fiddaman    while read -r line ; do
579*906afcb8SAndy Fiddaman        for (( x=0 ; x < ${#line} ; x++ )) ; do
580*906afcb8SAndy Fiddaman            c="${line:x:1}"
581*906afcb8SAndy Fiddaman
582*906afcb8SAndy Fiddaman            case $c in
583*906afcb8SAndy Fiddaman                ".") numdots+=1 ;;
584*906afcb8SAndy Fiddaman                "M")
585*906afcb8SAndy Fiddaman		    # log start position of monsters
586*906afcb8SAndy Fiddaman                    levelmap["monsterstartpos_x"]="$x"
587*906afcb8SAndy Fiddaman                    levelmap["monsterstartpos_y"]="$y"
588*906afcb8SAndy Fiddaman                    c=" "
589*906afcb8SAndy Fiddaman                    ;;
590*906afcb8SAndy Fiddaman                "P")
591*906afcb8SAndy Fiddaman		    # log start position of player
592*906afcb8SAndy Fiddaman                    levelmap["playerstartpos_x"]="$x"
593*906afcb8SAndy Fiddaman                    levelmap["playerstartpos_y"]="$y"
594*906afcb8SAndy Fiddaman                    c=" "
595*906afcb8SAndy Fiddaman                    ;;
596*906afcb8SAndy Fiddaman            esac
597*906afcb8SAndy Fiddaman
598*906afcb8SAndy Fiddaman            levelmap["${x}_${y}"]="$c"
599*906afcb8SAndy Fiddaman        done
600*906afcb8SAndy Fiddaman        (( maxx=x , y++ ))
601*906afcb8SAndy Fiddaman    done <<<"${map}"
602*906afcb8SAndy Fiddaman
603*906afcb8SAndy Fiddaman    levelmap["max_x"]=${maxx}
604*906afcb8SAndy Fiddaman    levelmap["max_y"]=${y}
605*906afcb8SAndy Fiddaman    levelmap["numdots"]=${numdots}
606*906afcb8SAndy Fiddaman
607*906afcb8SAndy Fiddaman    # consistency checks
608*906afcb8SAndy Fiddaman    if [[ "${levelmap["monsterstartpos_x"]}" == "" ]] ; then
609*906afcb8SAndy Fiddaman        fatal_error "read_levelmap: monsterstartpos_x is empty."
610*906afcb8SAndy Fiddaman    fi
611*906afcb8SAndy Fiddaman    if [[ "${levelmap["playerstartpos_x"]}" == "" ]] ; then
612*906afcb8SAndy Fiddaman        fatal_error "read_levelmap: playerstartpos_x is empty."
613*906afcb8SAndy Fiddaman    fi
614*906afcb8SAndy Fiddaman
615*906afcb8SAndy Fiddaman    return 0
616*906afcb8SAndy Fiddaman}
617*906afcb8SAndy Fiddaman
618*906afcb8SAndy Fiddamanfunction player.set
619*906afcb8SAndy Fiddaman{
620*906afcb8SAndy Fiddaman    case "${.sh.subscript}" in
621*906afcb8SAndy Fiddaman        pos_y)
622*906afcb8SAndy Fiddaman            if [[ "${levelmap["${player["pos_x"]}_${.sh.value}"]}" == "#" ]] ; then
623*906afcb8SAndy Fiddaman                .sh.value=${player["pos_y"]}
624*906afcb8SAndy Fiddaman                beep
625*906afcb8SAndy Fiddaman            fi
626*906afcb8SAndy Fiddaman            ;;
627*906afcb8SAndy Fiddaman
628*906afcb8SAndy Fiddaman        pos_x)
629*906afcb8SAndy Fiddaman            if [[ "${levelmap["${.sh.value}_${player["pos_y"]}"]}" == "#" ]] ; then
630*906afcb8SAndy Fiddaman                .sh.value=${player["pos_x"]}
631*906afcb8SAndy Fiddaman                beep
632*906afcb8SAndy Fiddaman            fi
633*906afcb8SAndy Fiddaman            ;;
634*906afcb8SAndy Fiddaman    esac
635*906afcb8SAndy Fiddaman    return 0
636*906afcb8SAndy Fiddaman}
637*906afcb8SAndy Fiddaman
638*906afcb8SAndy Fiddamanfunction monster.set
639*906afcb8SAndy Fiddaman{
640*906afcb8SAndy Fiddaman    case "${.sh.subscript}" in
641*906afcb8SAndy Fiddaman        *_pos_y)
642*906afcb8SAndy Fiddaman            if [[ "${levelmap["${monster[${currmonster}_"pos_x"]}_${.sh.value}"]}" == "#" ]] ; then
643*906afcb8SAndy Fiddaman                .sh.value=${monster[${currmonster}_"pos_y"]}
644*906afcb8SAndy Fiddaman                # turn homing off when the monster hit a wall
645*906afcb8SAndy Fiddaman                monster[${currmonster}_"homing"]=0
646*906afcb8SAndy Fiddaman            fi
647*906afcb8SAndy Fiddaman            ;;
648*906afcb8SAndy Fiddaman
649*906afcb8SAndy Fiddaman        *_pos_x)
650*906afcb8SAndy Fiddaman            if [[ "${levelmap["${.sh.value}_${monster[${currmonster}_"pos_y"]}"]}" == "#" ]] ; then
651*906afcb8SAndy Fiddaman                .sh.value=${monster[${currmonster}_"pos_x"]}
652*906afcb8SAndy Fiddaman                # turn homing off when the monster hit a wall
653*906afcb8SAndy Fiddaman                monster[${currmonster}_"homing"]=0
654*906afcb8SAndy Fiddaman            fi
655*906afcb8SAndy Fiddaman            ;;
656*906afcb8SAndy Fiddaman    esac
657*906afcb8SAndy Fiddaman    return 0
658*906afcb8SAndy Fiddaman}
659*906afcb8SAndy Fiddaman
660*906afcb8SAndy Fiddamanfunction render_game
661*906afcb8SAndy Fiddaman{
662*906afcb8SAndy Fiddaman    # render_buffer is some kind of "background buffer" to "double buffer"
663*906afcb8SAndy Fiddaman    # all output and combine it in one write to reduce flickering in the
664*906afcb8SAndy Fiddaman    # terminal
665*906afcb8SAndy Fiddaman    typeset render_buffer="$(
666*906afcb8SAndy Fiddaman        integer screen_y_offset=1
667*906afcb8SAndy Fiddaman        integer start_y_pos=0
668*906afcb8SAndy Fiddaman        integer render_num_lines=${levelmap["max_y"]}
669*906afcb8SAndy Fiddaman
670*906afcb8SAndy Fiddaman        if (( (termsize.lines-3) < levelmap["max_y"] )) ; then
671*906afcb8SAndy Fiddaman            (( start_y_pos=player["pos_y"] / 2))
672*906afcb8SAndy Fiddaman            (( render_num_lines=termsize.lines-5))
673*906afcb8SAndy Fiddaman        fi
674*906afcb8SAndy Fiddaman
675*906afcb8SAndy Fiddaman        #print -n -- "${vtcode["clear"]}"
676*906afcb8SAndy Fiddaman        print_setcursorpos 0 0
677*906afcb8SAndy Fiddaman
678*906afcb8SAndy Fiddaman        # print score (note the " " around "%d" are neccesary to clean up cruft
679*906afcb8SAndy Fiddaman        # when we overwrite the level
680*906afcb8SAndy Fiddaman        printf "SCORE: %05d  DOTS: %.3d  LIVES: %2.d " "${player["score"]}" "${levelmap["numdots"]}" "${player["lives"]}"
681*906afcb8SAndy Fiddaman        print_levelmap ${screen_y_offset} ${start_y_pos} ${render_num_lines}
682*906afcb8SAndy Fiddaman
683*906afcb8SAndy Fiddaman        # render player
684*906afcb8SAndy Fiddaman        print_setcursorpos ${player["pos_x"]} $((player["pos_y"]+screen_y_offset-start_y_pos))
685*906afcb8SAndy Fiddaman        print -n "@"
686*906afcb8SAndy Fiddaman
687*906afcb8SAndy Fiddaman        # render monsters
688*906afcb8SAndy Fiddaman        for currmonster in ${monsterlist} ; do
689*906afcb8SAndy Fiddaman            (( m_pos_x=monster[${currmonster}_"pos_x"] ))
690*906afcb8SAndy Fiddaman            (( m_pos_y=monster[${currmonster}_"pos_y"]+screen_y_offset-start_y_pos ))
691*906afcb8SAndy Fiddaman
692*906afcb8SAndy Fiddaman            if (( m_pos_y >= screen_y_offset && m_pos_y < render_num_lines )) ; then
693*906afcb8SAndy Fiddaman                print_setcursorpos ${m_pos_x} ${m_pos_y}
694*906afcb8SAndy Fiddaman                print -n "x"
695*906afcb8SAndy Fiddaman            fi
696*906afcb8SAndy Fiddaman        done
697*906afcb8SAndy Fiddaman
698*906afcb8SAndy Fiddaman        # status block
699*906afcb8SAndy Fiddaman        print_setcursorpos 0 $((render_num_lines+screen_y_offset))
700*906afcb8SAndy Fiddaman        emptyline="                                                            "
701*906afcb8SAndy Fiddaman        print -n " >> ${player["message"]} <<${emptyline:0:${#emptyline}-${#player["message"]}}"
702*906afcb8SAndy Fiddaman    )"
703*906afcb8SAndy Fiddaman    print -r -- "${render_buffer}${end_of_frame}"
704*906afcb8SAndy Fiddaman#    print "renderbuffersize=$(print "${render_buffer}" | wc -c) ${end_of_frame}"
705*906afcb8SAndy Fiddaman    return 0
706*906afcb8SAndy Fiddaman}
707*906afcb8SAndy Fiddaman
708*906afcb8SAndy Fiddamanfunction main_loop
709*906afcb8SAndy Fiddaman{
710*906afcb8SAndy Fiddaman    float   sleep_per_cycle=0.2
711*906afcb8SAndy Fiddaman    float   seconds_before_read
712*906afcb8SAndy Fiddaman    integer num_cycles=0
713*906afcb8SAndy Fiddaman    float   rs
714*906afcb8SAndy Fiddaman
715*906afcb8SAndy Fiddaman    print -n -- "${vtcode["clear"]}"
716*906afcb8SAndy Fiddaman
717*906afcb8SAndy Fiddaman    read_levelmap "$1"
718*906afcb8SAndy Fiddaman
719*906afcb8SAndy Fiddaman    # player init
720*906afcb8SAndy Fiddaman    player["pos_x"]=${levelmap["playerstartpos_x"]}
721*906afcb8SAndy Fiddaman    player["pos_y"]=${levelmap["playerstartpos_y"]}
722*906afcb8SAndy Fiddaman    player["score"]=0         # player score
723*906afcb8SAndy Fiddaman    player["lives"]=5         # number of lives
724*906afcb8SAndy Fiddaman    player["invulnerable"]=10 # cycles how long the player remains invulnerable
725*906afcb8SAndy Fiddaman    player["message"]="Go..."
726*906afcb8SAndy Fiddaman
727*906afcb8SAndy Fiddaman    monsterlist="maw claw jitterbug tentacle grendel"
728*906afcb8SAndy Fiddaman
729*906afcb8SAndy Fiddaman    for currmonster in ${monsterlist} ; do
730*906afcb8SAndy Fiddaman        monster[${currmonster}_"pos_x"]=${levelmap["monsterstartpos_x"]}
731*906afcb8SAndy Fiddaman        monster[${currmonster}_"pos_y"]=${levelmap["monsterstartpos_y"]}
732*906afcb8SAndy Fiddaman        monster[${currmonster}_"xstep"]=0
733*906afcb8SAndy Fiddaman        monster[${currmonster}_"ystep"]=0
734*906afcb8SAndy Fiddaman        monster[${currmonster}_"homing"]=0
735*906afcb8SAndy Fiddaman    done
736*906afcb8SAndy Fiddaman
737*906afcb8SAndy Fiddaman    # main game cycle loop
738*906afcb8SAndy Fiddaman    while true ; do
739*906afcb8SAndy Fiddaman        num_cycles+=1
740*906afcb8SAndy Fiddaman        seconds_before_read=${SECONDS}
741*906afcb8SAndy Fiddaman        c="" ; read -r -t ${sleep_per_cycle} -n 1 c
742*906afcb8SAndy Fiddaman
743*906afcb8SAndy Fiddaman        if [[ "$c" != "" ]] ; then
744*906afcb8SAndy Fiddaman            # special case handling for cursor keys which are usually composed
745*906afcb8SAndy Fiddaman            # of three characters (e.g. "<ESC>[D"). If only <ESC> is hit we
746*906afcb8SAndy Fiddaman            # quicky exit
747*906afcb8SAndy Fiddaman            if [[ "$c" == $'\E' ]] ; then
748*906afcb8SAndy Fiddaman                read -r -t 0.1 -n 1 c
749*906afcb8SAndy Fiddaman                if [[ "$c" != "[" ]] ; then
750*906afcb8SAndy Fiddaman                    return 0
751*906afcb8SAndy Fiddaman                fi
752*906afcb8SAndy Fiddaman
753*906afcb8SAndy Fiddaman                # we assume the user is using the cursor keys, this |read|
754*906afcb8SAndy Fiddaman                # should fetch the 3rd byte of the three-character sequence
755*906afcb8SAndy Fiddaman                # for the cursor keys
756*906afcb8SAndy Fiddaman                read -r -t 0.1 -n 1 c
757*906afcb8SAndy Fiddaman            fi
758*906afcb8SAndy Fiddaman
759*906afcb8SAndy Fiddaman            # if the user hit a key the "read" above was interrupted
760*906afcb8SAndy Fiddaman            # and didn't wait exactly |sleep_per_cycle| seconds.
761*906afcb8SAndy Fiddaman            # We wait here some moments (|rs|="remaining seconds") to
762*906afcb8SAndy Fiddaman            # avoid that the game gets "faster" when more user input
763*906afcb8SAndy Fiddaman            # is given.
764*906afcb8SAndy Fiddaman            (( rs=sleep_per_cycle-(SECONDS-seconds_before_read) ))
765*906afcb8SAndy Fiddaman            (( rs > 0.001 )) && sleep ${rs}
766*906afcb8SAndy Fiddaman
767*906afcb8SAndy Fiddaman            player["message"]=""
768*906afcb8SAndy Fiddaman
769*906afcb8SAndy Fiddaman            case "$c" in
770*906afcb8SAndy Fiddaman                j|D|4) (( player["pos_x"]-=1 )) ;;
771*906afcb8SAndy Fiddaman                k|C|6) (( player["pos_x"]+=1 )) ;;
772*906afcb8SAndy Fiddaman                i|A|8) (( player["pos_y"]-=1 )) ;;
773*906afcb8SAndy Fiddaman                m|B|2) (( player["pos_y"]+=1 )) ;;
774*906afcb8SAndy Fiddaman
775*906afcb8SAndy Fiddaman                q) return 0 ;;
776*906afcb8SAndy Fiddaman            esac
777*906afcb8SAndy Fiddaman
778*906afcb8SAndy Fiddaman            if [[ "${levelmap["${player["pos_x"]}_${player["pos_y"]}"]}" == "." ]] ; then
779*906afcb8SAndy Fiddaman                levelmap["${player["pos_x"]}_${player["pos_y"]}"]=" "
780*906afcb8SAndy Fiddaman                (( levelmap["numdots"]-=1 ))
781*906afcb8SAndy Fiddaman
782*906afcb8SAndy Fiddaman                (( player["score"]+=10 ))
783*906afcb8SAndy Fiddaman                player["message"]='GNAW!!'
784*906afcb8SAndy Fiddaman
785*906afcb8SAndy Fiddaman                if (( levelmap["numdots"] <= 0 )) ; then
786*906afcb8SAndy Fiddaman                    level_completed
787*906afcb8SAndy Fiddaman                    return 0
788*906afcb8SAndy Fiddaman                fi
789*906afcb8SAndy Fiddaman            fi
790*906afcb8SAndy Fiddaman        fi
791*906afcb8SAndy Fiddaman
792*906afcb8SAndy Fiddaman        # generic player status change
793*906afcb8SAndy Fiddaman        if (( player["invulnerable"] > 0 )) ; then
794*906afcb8SAndy Fiddaman            (( player["invulnerable"]-=1 ))
795*906afcb8SAndy Fiddaman        fi
796*906afcb8SAndy Fiddaman        if (( player["lives"] <= 0 )) ; then
797*906afcb8SAndy Fiddaman            game_over
798*906afcb8SAndy Fiddaman            return 0
799*906afcb8SAndy Fiddaman        fi
800*906afcb8SAndy Fiddaman
801*906afcb8SAndy Fiddaman        # move monsters
802*906afcb8SAndy Fiddaman        for currmonster in ${monsterlist} ; do
803*906afcb8SAndy Fiddaman            # make monster as half as slow then the others when it is following the user
804*906afcb8SAndy Fiddaman            if (( monster[${currmonster}_"homing"] > 0 )) ; then
805*906afcb8SAndy Fiddaman                (( (num_cycles%2) > 0 )) && continue
806*906afcb8SAndy Fiddaman            fi
807*906afcb8SAndy Fiddaman
808*906afcb8SAndy Fiddaman            if [[ ${monster[${currmonster}_"pos_x"]} == ${player["pos_x"]} ]] ; then
809*906afcb8SAndy Fiddaman                if (( (monster[${currmonster}_"pos_y"]-player["pos_y"]) > 0 )) ; then
810*906afcb8SAndy Fiddaman                    (( monster[${currmonster}_"xstep"]=+0 , monster[${currmonster}_"ystep"]=-1 ))
811*906afcb8SAndy Fiddaman                else
812*906afcb8SAndy Fiddaman                    (( monster[${currmonster}_"xstep"]=+0 , monster[${currmonster}_"ystep"]=+1 ))
813*906afcb8SAndy Fiddaman                fi
814*906afcb8SAndy Fiddaman                monster[${currmonster}_"homing"]=1
815*906afcb8SAndy Fiddaman                if (( player["invulnerable"] <= 0 )) ; then
816*906afcb8SAndy Fiddaman                    player["message"]="Attention: ${currmonster} is chasing you"
817*906afcb8SAndy Fiddaman                fi
818*906afcb8SAndy Fiddaman            elif (( monster[${currmonster}_"pos_y"] == player["pos_y"] )) ; then
819*906afcb8SAndy Fiddaman                if (( (monster[${currmonster}_"pos_x"]-player["pos_x"]) > 0 )) ; then
820*906afcb8SAndy Fiddaman                    (( monster[${currmonster}_"xstep"]=-1 , monster[${currmonster}_"ystep"]=-0 ))
821*906afcb8SAndy Fiddaman                else
822*906afcb8SAndy Fiddaman                    (( monster[${currmonster}_"xstep"]=+1 , monster[${currmonster}_"ystep"]=+0 ))
823*906afcb8SAndy Fiddaman                fi
824*906afcb8SAndy Fiddaman                monster[${currmonster}_"homing"]=1
825*906afcb8SAndy Fiddaman                if (( player["invulnerable"] <= 0 )) ; then
826*906afcb8SAndy Fiddaman                    player["message"]="Attention: ${currmonster} is chasing you"
827*906afcb8SAndy Fiddaman                fi
828*906afcb8SAndy Fiddaman            else
829*906afcb8SAndy Fiddaman                if (( monster[${currmonster}_"homing"] == 0 )) ; then
830*906afcb8SAndy Fiddaman                    case $((SECONDS % 6 + RANDOM % 4)) in
831*906afcb8SAndy Fiddaman                        0) (( monster[${currmonster}_"xstep"]=+0 , monster[${currmonster}_"ystep"]=+0 )) ;;
832*906afcb8SAndy Fiddaman                        2) (( monster[${currmonster}_"xstep"]=+0 , monster[${currmonster}_"ystep"]=+1 )) ;;
833*906afcb8SAndy Fiddaman                        3) (( monster[${currmonster}_"xstep"]=+1 , monster[${currmonster}_"ystep"]=+0 )) ;;
834*906afcb8SAndy Fiddaman                        5) (( monster[${currmonster}_"xstep"]=+0 , monster[${currmonster}_"ystep"]=-1 )) ;;
835*906afcb8SAndy Fiddaman                        6) (( monster[${currmonster}_"xstep"]=-1 , monster[${currmonster}_"ystep"]=+0 )) ;;
836*906afcb8SAndy Fiddaman                    esac
837*906afcb8SAndy Fiddaman                fi
838*906afcb8SAndy Fiddaman            fi
839*906afcb8SAndy Fiddaman
840*906afcb8SAndy Fiddaman            (( monster[${currmonster}_"pos_x"]=monster[${currmonster}_"pos_x"]+monster[${currmonster}_"xstep"] ))
841*906afcb8SAndy Fiddaman            (( monster[${currmonster}_"pos_y"]=monster[${currmonster}_"pos_y"]+monster[${currmonster}_"ystep"] ))
842*906afcb8SAndy Fiddaman
843*906afcb8SAndy Fiddaman            # check if a monster hit the player
844*906afcb8SAndy Fiddaman            if (( player["invulnerable"] <= 0 )) ; then
845*906afcb8SAndy Fiddaman                if (( monster[${currmonster}_"pos_x"] == player["pos_x"] && \
846*906afcb8SAndy Fiddaman                      monster[${currmonster}_"pos_y"] == player["pos_y"] )) ; then
847*906afcb8SAndy Fiddaman                     # if player was hit by a monster take one life and
848*906afcb8SAndy Fiddaman                     # make him invulnerable for 10 cycles to avoid that
849*906afcb8SAndy Fiddaman                     # the next cycle steals more lives
850*906afcb8SAndy Fiddaman                     player["message"]="Ouuuchhhh"
851*906afcb8SAndy Fiddaman                     player["invulnerable"]=10
852*906afcb8SAndy Fiddaman                     (( player["lives"]-=1 ))
853*906afcb8SAndy Fiddaman
854*906afcb8SAndy Fiddaman                     beep ; beep ; sleep 0.2 ; beep ; beep
855*906afcb8SAndy Fiddaman                fi
856*906afcb8SAndy Fiddaman            fi
857*906afcb8SAndy Fiddaman        done
858*906afcb8SAndy Fiddaman
859*906afcb8SAndy Fiddaman        render_game
860*906afcb8SAndy Fiddaman    done
861*906afcb8SAndy Fiddaman    return 0
862*906afcb8SAndy Fiddaman}
863*906afcb8SAndy Fiddaman
864*906afcb8SAndy Fiddamanfunction map_filter
865*906afcb8SAndy Fiddaman{
866*906afcb8SAndy Fiddaman    typeset ch_player ch_monster ch_wall var
867*906afcb8SAndy Fiddaman
868*906afcb8SAndy Fiddaman    if (( $1 == 1 )) ; then
869*906afcb8SAndy Fiddaman        ch_player="${vtcode["fg_yellow"]}"
870*906afcb8SAndy Fiddaman        ch_monster="${vtcode["fg_red"]}"
871*906afcb8SAndy Fiddaman        ch_wall="${vtcode["fg_blue"]}"
872*906afcb8SAndy Fiddaman    else
873*906afcb8SAndy Fiddaman        ch_player=""
874*906afcb8SAndy Fiddaman        ch_monster=""
875*906afcb8SAndy Fiddaman        ch_wall=""
876*906afcb8SAndy Fiddaman    fi
877*906afcb8SAndy Fiddaman
878*906afcb8SAndy Fiddaman    if (( $2 == 1 )) ; then
879*906afcb8SAndy Fiddaman        # unicode map
880*906afcb8SAndy Fiddaman        ch_player+="$(printf '\u[24d2]')"
881*906afcb8SAndy Fiddaman        ch_monster+="$(printf '\u[2605]')"
882*906afcb8SAndy Fiddaman        ch_wall+="$(printf '\u[25a6]')"
883*906afcb8SAndy Fiddaman    else
884*906afcb8SAndy Fiddaman        # ascii map
885*906afcb8SAndy Fiddaman        ch_player+="@"
886*906afcb8SAndy Fiddaman        ch_monster+="x"
887*906afcb8SAndy Fiddaman        ch_wall+="#"
888*906afcb8SAndy Fiddaman    fi
889*906afcb8SAndy Fiddaman
890*906afcb8SAndy Fiddaman    # note that this filter currently defeats the "double-buffering"
891*906afcb8SAndy Fiddaman    while IFS='' read -r -d "${end_of_frame}" var ; do
892*906afcb8SAndy Fiddaman        var="${var// /${vtcode["fg_grey"]} }"
893*906afcb8SAndy Fiddaman        var="${var//\./${vtcode["fg_lightred"]}.}"
894*906afcb8SAndy Fiddaman        var="${var//@/${ch_player}}"
895*906afcb8SAndy Fiddaman        var="${var//x/${ch_monster}}"
896*906afcb8SAndy Fiddaman        var="${var//#/${ch_wall}}"
897*906afcb8SAndy Fiddaman
898*906afcb8SAndy Fiddaman        print -r -- "${var}"
899*906afcb8SAndy Fiddaman    done
900*906afcb8SAndy Fiddaman    return 0
901*906afcb8SAndy Fiddaman}
902*906afcb8SAndy Fiddaman
903*906afcb8SAndy Fiddamanfunction exit_trap
904*906afcb8SAndy Fiddaman{
905*906afcb8SAndy Fiddaman    # restore stty settings
906*906afcb8SAndy Fiddaman    stty ${saved_stty}
907*906afcb8SAndy Fiddaman
908*906afcb8SAndy Fiddaman    print "bye."
909*906afcb8SAndy Fiddaman    return 0
910*906afcb8SAndy Fiddaman}
911*906afcb8SAndy Fiddaman
912*906afcb8SAndy Fiddamanfunction usage
913*906afcb8SAndy Fiddaman{
914*906afcb8SAndy Fiddaman    OPTIND=0
915*906afcb8SAndy Fiddaman    getopts -a "${progname}" "${gnaw_usage}" OPT '-?'
916*906afcb8SAndy Fiddaman    exit 2
917*906afcb8SAndy Fiddaman}
918*906afcb8SAndy Fiddaman
919*906afcb8SAndy Fiddaman# program start
920*906afcb8SAndy Fiddaman# make sure we use the ksh93 "cat" builtin which supports the "-u" option
921*906afcb8SAndy Fiddamanbuiltin basename
922*906afcb8SAndy Fiddamanbuiltin cat
923*906afcb8SAndy Fiddamanbuiltin wc
924*906afcb8SAndy Fiddaman
925*906afcb8SAndy Fiddamantypeset progname="${ basename "${0}" ; }"
926*906afcb8SAndy Fiddaman
927*906afcb8SAndy Fiddaman# terminal size rect
928*906afcb8SAndy Fiddamancompound termsize=(
929*906afcb8SAndy Fiddaman    integer columns=-1
930*906afcb8SAndy Fiddaman    integer lines=-1
931*906afcb8SAndy Fiddaman)
932*906afcb8SAndy Fiddaman
933*906afcb8SAndy Fiddaman# global variables
934*906afcb8SAndy Fiddamantypeset quiet=false
935*906afcb8SAndy Fiddaman
936*906afcb8SAndy Fiddamantypeset -A levelmap
937*906afcb8SAndy Fiddamantypeset -A player
938*906afcb8SAndy Fiddamantypeset -A monster
939*906afcb8SAndy Fiddaman# global rendering options
940*906afcb8SAndy Fiddamaninteger game_use_colors=0
941*906afcb8SAndy Fiddamaninteger game_use_unicode=0
942*906afcb8SAndy Fiddaman
943*906afcb8SAndy Fiddamantypeset -r gnaw_usage=$'+
944*906afcb8SAndy Fiddaman[-?\n@(#)\$Id: gnaw (Roland Mainz) 2009-05-09 \$\n]
945*906afcb8SAndy Fiddaman[-author?Roland Mainz <roland.mainz@nrubsig.org>]
946*906afcb8SAndy Fiddaman[+NAME?gnaw - maze game written in ksh93]
947*906afcb8SAndy Fiddaman[+DESCRIPTION?\bgnaw\b is a maze game.
948*906afcb8SAndy Fiddaman        The player maneuvers a yellow "@" sign to navigate a maze while eating
949*906afcb8SAndy Fiddaman        small dots. A level is finished when all the dots are eaten. Five monsters
950*906afcb8SAndy Fiddaman        (maw, claw, jitterbug, tentacle and grendel) also wander the maze in an attempt
951*906afcb8SAndy Fiddaman        to catch the "@". Each level begins with all ghosts in their home, and "@" near
952*906afcb8SAndy Fiddaman        the bottom of the maze. The monsters are released from the home one by one at the
953*906afcb8SAndy Fiddaman        start of each level and start their rentless hunt after the player.]
954*906afcb8SAndy Fiddaman[q:quiet?Disable use of terminal bell.]
955*906afcb8SAndy Fiddaman[+SEE ALSO?\bksh93\b(1)]
956*906afcb8SAndy Fiddaman'
957*906afcb8SAndy Fiddaman
958*906afcb8SAndy Fiddamanwhile getopts -a "${progname}" "${gnaw_usage}" OPT ; do
959*906afcb8SAndy Fiddaman#    printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|"
960*906afcb8SAndy Fiddaman    case ${OPT} in
961*906afcb8SAndy Fiddaman        q)    quiet=true  ;;
962*906afcb8SAndy Fiddaman        +q)   quiet=false ;;
963*906afcb8SAndy Fiddaman        *)    usage ;;
964*906afcb8SAndy Fiddaman    esac
965*906afcb8SAndy Fiddamandone
966*906afcb8SAndy Fiddamanshift $((OPTIND-1))
967*906afcb8SAndy Fiddaman
968*906afcb8SAndy Fiddaman# save stty values and register the exit trap which restores these values on exit
969*906afcb8SAndy Fiddamansaved_stty="$(stty -g)"
970*906afcb8SAndy Fiddamantrap exit_trap EXIT
971*906afcb8SAndy Fiddaman
972*906afcb8SAndy Fiddamanprint "Loading..."
973*906afcb8SAndy Fiddaman
974*906afcb8SAndy Fiddaman# set stty values, "-icanon min 1 time 0 -inpck" should improve input latency,
975*906afcb8SAndy Fiddaman# "-echo" turns the terminal echo off
976*906afcb8SAndy Fiddamanstty -icanon min 1 time 0 -inpck -echo
977*906afcb8SAndy Fiddaman
978*906afcb8SAndy Fiddamanget_term_size termsize || fatal_error "Could not get terminal size."
979*906afcb8SAndy Fiddaman
980*906afcb8SAndy Fiddaman# prechecks
981*906afcb8SAndy Fiddaman(( termsize.columns < 60 )) && fatal_error "Terminal width must be larger than 60 columns (currently ${termsize.columns})."
982*906afcb8SAndy Fiddaman
983*906afcb8SAndy Fiddamantypeset -A vtcode
984*906afcb8SAndy Fiddaman# color values taken from http://frexx.de/xterm-256-notes/, other
985*906afcb8SAndy Fiddaman# codes from http://vt100.net/docs/vt100-tm/
986*906afcb8SAndy Fiddamanvtcode=(
987*906afcb8SAndy Fiddaman    ["bg_black"]="$(print -n "\E[40m")"
988*906afcb8SAndy Fiddaman    ["fg_black"]="$(print -n "\E[30m")"
989*906afcb8SAndy Fiddaman    ["fg_red"]="$(print -n "\E[31m")"
990*906afcb8SAndy Fiddaman    ["fg_lightred"]="$(print -n "\E[1;31m")"
991*906afcb8SAndy Fiddaman    ["fg_green"]="$(print -n "\E[32m")"
992*906afcb8SAndy Fiddaman    ["fg_lightgreen"]="$(print -n "\E[1;32m")"
993*906afcb8SAndy Fiddaman    ["fg_yellow"]="$(print -n "\E[33m")"
994*906afcb8SAndy Fiddaman    ["fg_lightyellow"]="$(print -n "\E[1;33m")"
995*906afcb8SAndy Fiddaman    ["fg_blue"]="$(print -n "\E[34m")"
996*906afcb8SAndy Fiddaman    ["fg_lightblue"]="$(print -n "\E[1;34m")"
997*906afcb8SAndy Fiddaman    ["fg_grey"]="$(print -n "\E[1;37m")"
998*906afcb8SAndy Fiddaman    ["fg_white"]="$(print -n "\E[37m")"
999*906afcb8SAndy Fiddaman
1000*906afcb8SAndy Fiddaman    # misc other vt stuff
1001*906afcb8SAndy Fiddaman    ["vtreset"]="$(tput reset)"
1002*906afcb8SAndy Fiddaman    ["clear"]="$(tput clear)"
1003*906afcb8SAndy Fiddaman    ["bel"]="$(tput bel)"
1004*906afcb8SAndy Fiddaman    ["spaceline"]="$(for (( i=0 ; i < termsize.columns ; i++ )) ; do print -n " " ; done)"
1005*906afcb8SAndy Fiddaman)
1006*906afcb8SAndy Fiddaman
1007*906afcb8SAndy Fiddaman# character used to as marker that a single frame ends at this point - this
1008*906afcb8SAndy Fiddaman# is used by the "double buffering" code to make sure the "read" builtin
1009*906afcb8SAndy Fiddaman# can read a whole "frame" instead of reading stuff line-by-line
1010*906afcb8SAndy Fiddamantypeset -r end_of_frame=$'\t'
1011*906afcb8SAndy Fiddaman
1012*906afcb8SAndy Fiddaman# get terminal sequence to move cursor to position x,y
1013*906afcb8SAndy Fiddaman# (see http://vt100.net/docs/vt100-ug/chapter3.html#CPR)
1014*906afcb8SAndy Fiddamancase ${TERM} in
1015*906afcb8SAndy Fiddaman    xterm | xterm-color | vt100 | vt220 | dtterm | sun | sun-color)
1016*906afcb8SAndy Fiddaman        cup="$(infocmp -1 | \
1017*906afcb8SAndy Fiddaman	       egrep '^[[:space:]]*cup=' | \
1018*906afcb8SAndy Fiddaman	       sed -e 's/.*cup=//' \
1019*906afcb8SAndy Fiddaman	           -e 's/%[%id]*p1[%id]*/%2\\\$d/g' \
1020*906afcb8SAndy Fiddaman		   -e 's/%[%id]*p2[%id]*/%1\\\$d/g' \
1021*906afcb8SAndy Fiddaman		   -e 's/,$//')"
1022*906afcb8SAndy Fiddaman        for (( x=0 ; x < termsize.columns ; x++ )) ; do
1023*906afcb8SAndy Fiddaman            for (( y=0 ; y < termsize.lines ; y++ )) ; do
1024*906afcb8SAndy Fiddaman                vtcode[cup_${x}_${y}]="$(printf "${cup}" $((x + 1)) $((y + 1)) )"
1025*906afcb8SAndy Fiddaman            done
1026*906afcb8SAndy Fiddaman        done
1027*906afcb8SAndy Fiddaman        ;;
1028*906afcb8SAndy Fiddaman    *)
1029*906afcb8SAndy Fiddaman        printf "# Unrecognised terminal type '%s', fetching %dx%d items from terminfo database, please wait...\n" "${TERM}" "${termsize.columns}" "${termsize.lines}"
1030*906afcb8SAndy Fiddaman        for (( x=0 ; x < termsize.columns ; x++ )) ; do
1031*906afcb8SAndy Fiddaman            for (( y=0 ; y < termsize.lines ; y++ )) ; do
1032*906afcb8SAndy Fiddaman                vtcode[cup_${x}_${y}]="$(tput cup ${y} ${x})"
1033*906afcb8SAndy Fiddaman            done
1034*906afcb8SAndy Fiddaman        done
1035*906afcb8SAndy Fiddaman        ;;
1036*906afcb8SAndy Fiddamanesac
1037*906afcb8SAndy Fiddaman
1038*906afcb8SAndy Fiddamanprint -- "${vtcode["vtreset"]}"
1039*906afcb8SAndy Fiddaman
1040*906afcb8SAndy Fiddamanrun_logo
1041*906afcb8SAndy Fiddamanrun_menu
1042*906afcb8SAndy Fiddaman
1043*906afcb8SAndy Fiddamanexit 0
1044*906afcb8SAndy Fiddaman# EOF.
1045