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