Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!rutgers!lll-lcc!seismo!munnari!moncskermit!trldeity!trlamct!sunk!richb From: richb@sunk.UUCP Newsgroups: net.sources.games Subject: Sid Tool (Pacman) Part 4 of 5. Message-ID: <125@sunk.oz> Date: Sun, 12-Apr-87 01:12:51 EST Article-I.D.: sunk.125 Posted: Sun Apr 12 01:12:51 1987 Date-Received: Tue, 14-Apr-87 23:36:40 EST Organization: Sun Microsystems Australia Lines: 1417 Keywords: Sun O/S v3.2 or later. ---------CUT HERE----------CUT HERE-------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh sid_blt.c <<'END_OF_sid_blt.c' X X/* sid_blt.c X * X * Various routines that do "rasterop" type graphics used by sidtool. X * X * Written by Rich Burridge - SUN Microsystems Australia (Melbourne). X * X * Version 2.1. - April 1987. X * X * No responsibility is taken for any errors inherent either to the code X * or the comments of this program, but if reported to me then an attempt X * will be made to fix them. X */ X X#include X#include X#include X#include "bltstuff.h" X#include "sidtool.h" X#include X#include X#include X#include X Xextern jmp_buf exception ; Xextern int val ; X Xextern Pixfont *pf ; Xextern Pixwin *pw ; X X/* For descriptions of these variables, see sid_main.c */ X Xextern BOOLEAN autoplay,demomode,remove ; X Xextern char a_name[MAXLINE],buffer[MAXLINE],but_names[7][8],h_name[MAXLINE] ; Xextern char m_name[MAXLINE],maze[XSIZE+2][YSIZE+2],names[4][MAXLINE],sc ; Xextern char titlestring[MAXLINE] ; X Xextern int autoscore,blueblink,blueincblink,boxx,boxy,button,c,circatchup ; Xextern int cirmx,cirmy,cirx,ciry,count,credits,curbluetime[MAXNUMPLAYERS+1] ; Xextern int curdir,dots[MAXNUMPLAYERS+1][XSIZE+4][YSIZE+2],dotx,doty ; Xextern int fruitchances[MAXNUMPLAYERS+1],fruiton,fruittime,fruitx,fruity ; Xextern int fruitmaze[MAXNUMPLAYERS+1],g,gamestate,height,highplayer ; Xextern int highscore,inc,movei,movej,movex,newdir,numcir[MAXNUMPLAYERS+1] ; Xextern int numdots[MAXNUMPLAYERS+1],nx,ny,oldcurdir,oldcx,oldcy,orgx,orgy ; Xextern int pausetime,player,posx,posy,progstate,score[MAXNUMPLAYERS+1] ; Xextern int sfunc,skilllevel,speed,tunnel[XSIZE+4][YSIZE+2],walls[XSIZE+6][YSIZE+1] ; Xextern int width,x,y ; X Xextern Pixrect *load_picture() ; Xextern long random() ; X Xextern Pixrect *bigdot,*bluebug[2],*bluepics[2],*bugpics[4][2],*circleexplode[9] ; Xextern Pixrect *circles[4][4],*corner[4],*curcircle,*eyes[4],*fruitpics[9] ; Xextern Pixrect *smalldot ; X Xextern struct bugrec bugs[4] ; /* The bad guys. */ Xextern struct scorerec allhighscores[11] ; Xextern struct startrec startpos[4] ; X X Xclear_screen() X X{ X BLT_SCRN(orgx,orgy,width,height,RCLR) ; X X/* To get over displaying the last cursor incorrectly after a cleared screen, X * the old cursor position is forced off the screen. X */ X X oldcx = 1000 ; X oldcy = 1000 ; X} X X Xddrawline(mx,my,dir) Xint mx,my,dir ; X X/* Draw a maze line from mx,my in the direction dir. X * Parameters: dir should be d,u,l,r, (or R for a thin line). X */ X X{ X int x,y ; X X TRANSPT(mx,my,x,y) ; X switch (dir) X { X case 'd' : X case 'u' : BLT_SCRN(x+SQUARE/2,y,2,SQUARE,RSET) ; X break ; X case 'l' : X case 'r' : BLT_SCRN(x,y+SQUARE/2,SQUARE,2,RSET) ; X break ; X case 'R' : BLT_SCRN(x,y+SQUARE/2,SQUARE,1,RSET) ; X } X} X X Xdrawbug(g) Xregister struct bugrec *g ; X X{ X int inc,winc ; X X inc = g->scrx - GOFFSET ; X winc = 0 ; X X if (inc < 0) X if (inc <= 45) return ; X else winc = inc ; X else if (inc > SWIDTH-45) X if (inc > SWIDTH - 1) return ; X else X { X winc = SWIDTH-45-inc ; X inc = 0 ; X } X else inc = 0 ; X X if (g->eyesonly) X { X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET, X 45+winc,21,RXOR,eyes[g->dir],-inc,0) ; X/* Fake BLT to get speed same. */ X BLT_MEM(bugpics[GIND(g)][g->pic],0,0,45+winc,21,RRPL, X bugpics[GIND(g)][g->pic],0,0) ; X } X else if (g->bluetime > 0) X { X if ((g->bluetime < blueblink) && X (g->bluetime % blueincblink > blueincblink / 2)) X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET, X 45+winc,45,RXOR,bluepics[g->pic],-inc,0) ; X else X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET, X 45+winc,45,RXOR,bluebug[g->pic],-inc,0) ; X/* Fake BLT to get speed same. */ X BLT_MEM(eyes[g->dir],0,0,45+winc,21,RRPL,eyes[g->dir],0,0) ; X } X else X { X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET, X 45+winc,45,RXOR,bugpics[GIND(g)][g->pic],-inc,0) ; X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET, X 45+winc,21,RXOR,eyes[g->dir],-inc,0) ; X } X} X X Xdrawcir(p,x,y) /* Draw the specified screen on the screen. */ Xint x,y ; XPixrect *p ; X X{ X if (x < 0) return ; /* Fully off left side. */ X else if (x > SWIDTH+1) return ; /* Fully off right side. */ X X if (!(oldcx == x && oldcy == y)) X { X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ; X curcircle = p ; X BLT_MEM_TO_SCRN(x-GOFFSET+5,y-GOFFSET+5,45,45,RXOR,curcircle,0,0) ; X oldcx = x ; X oldcy = y ; X } X} X X Xdrawcorner(mx,my,dir) Xint dir,mx,my ; X X/* Draw a corner at MAZE position mx,my turning the direction dir. */ X X{ X int x,y ; X X TRANSPT(mx,my,x,y) ; X BLT_MEM_TO_SCRN(x,y,SQUARE,SQUARE,RRPL,corner[dir],0,0) ; X} X X Xdrawdot(mx,my,size) /* XORS a dot at the maze position mx,my. */ Xint mx,my,size ; X X{ X TRANSPT(mx,my,mx,my) ; X if (size == BIGDOT) BLT_MEM_TO_SCRN(mx,my,24,24,RXOR,bigdot,0,0) ; X else if (size == SMALLDOT) BLT_MEM_TO_SCRN(mx+9,my+9,7,7,RXOR,smalldot,9,9) ; X} X X Xdrawmaze() /* Draw the maze,the dots,the scores, etc on the screen. */ X X{ X int x,y ; X X clear_screen() ; X for (y = 0; y <= YSIZE+1; y++) X { X walls[1][y] = 1 ; X walls[0][y] = 1 ; X walls[XSIZE+4][y] = 1 ; X walls[XSIZE+5][y] = 1 ; X for (x = 0; x <= XSIZE+1; x++) walls[x+2][y] = 0 ; X } X X for (y = 0; y <= YSIZE+1; y++) X for (x = 0; x <= XSIZE+1; x++) X if ((maze[x][y] == 's') || (maze[x][y] == 'S') || (maze[x][y] == 'T')) X drawbox(x,y) ; X else if (maze[x][y] == 'x') walls[x+2][y] = 1 ; /* Borders. */ X X PPAUSE(pausetime*30) ; X BLT_SCRN(XBASE-(SQUARE/2)-2,YBASE-(SQUARE/2)-2, X SQUARE*(XSIZE+1)+6,SQUARE*(YSIZE+1)+6,RINV) ; X fixexits() ; X X for (y = 1; y <= YSIZE; y++) X for (x = 1; x <= XSIZE; x++) X if (dots[player][x+1][y] == SMALLDOT) X { X PPAUSE(pausetime*5) ; X drawdot(x,y,SMALLDOT) ; X } X else if (dots[player][x+1][y] == BIGDOT) X { X PPAUSE(pausetime*5) ; X drawdot(x,y,BIGDOT) ; X } X X for (x = 1; x <= 4; x++) showplayerscore(x) ; X X SPRINTF(buffer,"High Score (%1d)",skilllevel) ; X WRITELN(310,20,buffer) ; X if (!highscore) WRITELN(348,35,"0") ; X else X { X SPRINTF(buffer,"%1d0",highscore) ; X WRITELN(348,35,buffer) ; X } X X for (x = 1; x <= numcir[player]; x++) X { X PPAUSE(pausetime*30) ; X BLT_MEM_TO_SCRN(30+(x-1)*60,20,50,50,RXOR,circles[RIGHT][0],0,0) ; X } X X BLT_MEM_TO_SCRN(705,25,45,45,RRPL,fruitpics[fruitmaze[player]],0,0) ; X BLT_SCRN(700,20,55,55,RINV) ; X SPRINTF(buffer,"%1d0",fruitscore(fruitmaze[player])) ; X WRITELN(710,15,buffer) ; X X if (autoplay && (!demomode)) X { X SCHRFUNC(RXOR) ; X WRITELN(339,YBASE+SQUARE*16,"GAME OVER!") ; X SCHRFUNC(RRPL) ; X WRITELN(300,65,"Type DEL to begin") ; X WRITELN(480,50,"Auto Score") ; X WRITELN(489,65,"0") ; X } X} X X Xdocredits() X X{ X int g,x,y,i,j ; X X credits = 1 ; X clear_screen() ; X dohelp() ; X WRITELN(5,860,"Type DEL to begin") ; X for (i = 0; i < 100; i++) LONGPAUSE() ; X X newbugs(0) ; X UNTRANSPT(130,350,dotx,doty) ; X UNTRANSPT(860,350,x,y) ; X TRANSPT(x,y,i,ciry) ; X BLT_SCRN(3,ciry-37,762,100,RINV) ; X X for (g = POKEY; g <= SHADOW; g++) X { X bugs[g].mx = x + g * 2 ; X bugs[g].my = doty ; X bugs[g].dir = g ; X TRANSPT(bugs[g].mx,bugs[g].my,bugs[g].scrx,bugs[g].scry) ; X drawbug(&bugs[g]) ; /* Should be invisible. */ X } X drawdot(dotx,doty,BIGDOT) ; X cirx = 720 ; X inc = 0 ; X movei = 1 ; X progstate = MOVELEFT ; X} X X Xmove_left() /* Animate screen and bugs left. */ X X{ X int g ; X X if (movei % 8) cirx-- ; X drawcir(circles[LEFT][inc],cirx,ciry) ; X if (movei % 4 == 0) inc = (inc + 1) % 4 ; X for (g = POKEY; g <= SHADOW; g++) X { X drawbug(&bugs[g]) ; /* Erase old. */ X bugs[g].scrx-- ; X if (movei % 13 == 0) bugs[g].pic = (bugs[g].pic + 1) % 2 ; X if (movei % 18 == 0) bugs[g].dir = (bugs[g].dir + 1) % 4 ; X drawbug(&bugs[g]) ; /* Draw new. */ X } X if (++movei > 662) X { X credits = 2 ; X drawdot(dotx,doty,BIGDOT) ; X for (g = POKEY; g <= SHADOW; g++) X { X drawbug(&bugs[g]) ; /* Erase old. */ X bugs[g].bluetime = 32000 ; X drawbug(&bugs[g]) ; /* Draw new as blue. */ X } X SCHRFUNC(RXOR) ; X movej = 200 ; X movex = 1 ; X movei = 1 ; X progstate = MOVERIGHT ; X } X} X X Xmove_right() /* Animate eating screen and bugs right. */ X X{ X int g,i ; X X PPAUSE(8*movex) ; X if (movei % 26) cirx++ ; X drawcir(circles[RIGHT][inc],cirx,ciry) ; X if (movei % 4 == 0) inc = (inc + 1) % 4 ; X for (g = POKEY; g <= SHADOW; g++) X if (!bugs[g].eyesonly) X { X drawbug(&bugs[g]) ; /* Erase old. */ X if (movei % 2) bugs[g].scrx++ ; X if (movei % 13 == 0) bugs[g].pic = (bugs[g].pic + 1) % 2 ; X if (cirx >= bugs[g].scrx-20) X { X bugs[g].eyesonly = 1 ; X SPRINTF(buffer,"%1d",movej) ; X WRITELN(bugs[g].scrx-20,440,buffer) ; X for (i = 0; i < 60; i++) LONGPAUSE() ; X SPRINTF(buffer,"%1d",movej) ; X WRITELN(bugs[g].scrx-20,440,buffer) ; X movej *= 2 ; X movex++ ; X } X else drawbug(&bugs[g]) ; /* Draw new. */ X } X if (++movei > 665) X { X SCHRFUNC(RRPL) ; X for (i = 0; i < 100; i++) LONGPAUSE() ; X credits = 0 ; X progstate = INITGAME ; X } X} X X Xdohelp() X X{ X int g,i,x,y ; X char line[MAXLINE] ; X FILE *fn ; X X write_bold(105,100,titlestring) ; X WRITELN(105,120,"Original version by Brad A. Myers with pictures of fruit by Terry Vavra.") ; X X for (g = POKEY; g <= SHADOW; g++) X { X if (g > 1) y = YBASE + 130 ; X else y = YBASE + 50 ; X x = (g % 2) ? 384 : 100 ; X X BLT_MEM_TO_SCRN(x,y,45,45,RRPL,bugpics[g][0],0,0) ; X BLT_MEM_TO_SCRN(x,y,45,21,RXOR,eyes[g],0,0) ; X for (i = 0; i < 40; i++) LONGPAUSE() ; X SPRINTF(buffer,"- %s",names[g]) ; X WRITELN(x+60,y+25,buffer) ; X for (i = 0; i < 40; i++) LONGPAUSE() ; X } X X if ((fn = fopen(h_name,"r")) == NULL) X { X FPRINTF(stderr,"\nsidtool: can't open %s\n",h_name) ; X exit(-1) ; X } X x = 105 ; X y = 465 ; X i = 0 ; X while (get_string(fn,line) != -1) X { X WRITELN(x,i*15+y,line) ; X i++ ; X } X if (!autoplay) make_control_panel() ; X if (!autoplay) display_settings() ; X} X X Xdoplay() X X{ X if (remove) /* Jump here if have been eaten or starting new game. */ X { X removecircle() ; X numcir[player]-- ; X } X curdir = LEFT ; /* Jump here if got all dots. */ X fruiton = 0 ; X sc = ' ' ; X inc = 0 ; X count = 1 ; X posx = (SWIDTH / 2) - 11 ; X posy = YBASE + SQUARE * 21 ; X fruittime = randomrange(1000,2500) ; X UNTRANSPT(posx,posy,cirmx,cirmy) ; X drawcir(circles[curdir][inc],posx,posy) ; X newbugs(1) ; X if (demomode || !autoplay) X { X SCHRFUNC(RXOR) ; X WRITELN(357,YBASE+SQUARE*16,"READY!") ; X blinkpause() ; X SCHRFUNC(RXOR) ; X WRITELN(357,YBASE+SQUARE*16,"READY!") ; X SCHRFUNC(RRPL) ; X } X} X X Xmake_play() /* Perform next movement of each sid tool object. */ X X{ X updatebugs() ; X if (checkcollision(cirmx,cirmy,&g)) handlecollision(&bugs[g]) ; X if (fruittime != -1) X { X fruittime-- ; X if (!fruittime) updatefruit() ; X } X newdir = curdir ; X if (GCENTERED(posx,posy)) X { X if (autoplay) X newdir = dorandomdir(curdir,posx,posy,cirmx,cirmy,&x,&y,&nx,&ny,1) ; X else X switch (curdir) X { X case UP : if (sc == 'r' && !walls[cirmx+3][cirmy]) newdir = RIGHT ; X else if (sc == 'l' && !walls[cirmx+1][cirmy]) newdir = LEFT ; X else if (sc == 'd' && !walls[cirmx+2][cirmy+1]) newdir = DOWN ; X break ; X X case DOWN : if (sc == 'r' && !walls[cirmx+3][cirmy]) newdir = RIGHT ; X else if (sc == 'l' && !walls[cirmx+1][cirmy]) newdir = LEFT ; X else if (sc == 'u' && !walls[cirmx+2][cirmy-1]) newdir = UP ; X break ; X X case RIGHT : if (sc == 'l' && !walls[cirmx+1][cirmy]) newdir = LEFT ; X else if (sc == 'u' && !walls[cirmx+2][cirmy-1]) newdir = UP ; X else if (sc == 'd' && !walls[cirmx+2][cirmy+1]) newdir = DOWN ; X break ; X X case LEFT : if (sc == 'r' && !walls[cirmx+3][cirmy]) newdir = RIGHT ; X else if (sc == 'u' && !walls[cirmx+2][cirmy-1]) newdir = UP ; X else if (sc == 'd' && !walls[cirmx+2][cirmy+1]) newdir = DOWN ; X break ; X } X } X if (doinc(newdir,posx,posy,cirmx,cirmy,&x,&y,&nx,&ny)) doupdate() ; X else X { X if (!GCENTERED(posx,posy)) doupdate() ; /* Until centered. */ X else X { X if (oldcurdir != curdir) X { X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5, X 45,45,RXOR,curcircle,0,0) ; X curcircle = circles[curdir][0] ; X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5, X 45,45,RXOR,curcircle,0,0) ; X oldcurdir = curdir ; X } X } X } X if (checkcollision(cirmx,cirmy,&g)) handlecollision(&bugs[g]) ; X} X X Xdoupdate() X X{ X count++ ; X if (count % circatchup == 0) return ; /* Go slower than bugs. */ X drawcir(circles[newdir][inc],x,y) ; X if (count % 4 == 0) inc = (inc + 1) % 4 ; X if (fruiton) X if ((nx == FRUITMX) && (ny == FRUITMY)) destroyfruit() ; X if (dots[player][nx+1][ny] != NODOT) X { X if (dots[player][nx+1][ny] == SMALLDOT) updatescore(1) ; X else X { X changebugs() ; X updatescore(5) ; X } X numdots[player]-- ; X drawdot(nx,ny,dots[player][nx+1][ny]) ; X dots[player][nx+1][ny] = NODOT ; X if (!numdots[player]) X { X resetmaze() ; X gamestate = FALSE ; X progstate = RESETGAME ; X longjmp(exception,val) ; X } X } X curdir = newdir ; X posx = x ; X posy = y ; X cirmx = nx ; X cirmy = ny ; X} X X Xexplodecircle(posx,posy) Xint posx,posy ; X X{ X int i ; X X for (i = 0; i <= 8; i++) X { X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ; X curcircle = circleexplode[i] ; X BLT_MEM_TO_SCRN(posx-GOFFSET+5,posy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ; X oldcx = posx ; X oldcy = posy ; X PPAUSE(pausetime*70) ; X } X for (i = 0; i < 80; i++) LONGPAUSE() ; X} X X Xfixexits() X X/* Look for tunnels on the borders. For each, show the area as black X * on the screen and set the walls and tunnel global variables to X * reflect the presence of the tunnel. X */ X X{ X int x,y,t ; X X PPAUSE(pausetime*30) ; X for (y = 1; y <= YSIZE; y++) X if (maze[0][y] == ' ') X { X walls[1][y] = 0 ; X walls[0][y] = 0 ; X x = -1 ; X do X { X x++ ; X tunnel[x][y] = 1 ; X } X while (maze[x][y] == ' ') ; X TRANSPT(0,y,x,t) ; X BLT_SCRN(3,t-2-SQUARE/2,XBASE-(SQUARE/2)-5,SQUARE*2+6,RINV) ; X } X X PPAUSE(pausetime*30) ; X for (y = 1; y <= YSIZE; y++) X if (maze[XSIZE+1][y] == ' ') X { X walls[XSIZE+4][y] = 0 ; X walls[XSIZE+5][y] = 0 ; X x = XSIZE+1 ; X do X { X x-- ; X tunnel[x][y] = 1 ; X } X while (maze[x][y] == ' ') ; X TRANSPT(0,y,x,t) ; X BLT_SCRN(XBASE-(SQUARE/2)+SQUARE*(XSIZE+1)+4,t-2-SQUARE/2, X XBASE-(SQUARE/2)-5,SQUARE*2+6,RINV) ; X } X} X X Xget_button_option() X X{ X if (!c) return ; X else if (c >= BUT_AUTO+2 && c <= BUT_START+2) X { X BLT_SCRN(SQUARE/2+100*(c-2)+BUTXOFF,SQUARE/2+BUTYOFF,70,SQUARE,RINV) ; X PPAUSE(pausetime*100) ; X BLT_SCRN(SQUARE/2+100*(c-2)+BUTXOFF,SQUARE/2+BUTYOFF,70,SQUARE,RINV) ; X progstate = MAKESEL ; X button = c - 2 ; X c = 0 ; X } X} X X Xinitialize() X X{ X int fd,i,j,g,x,y ; X struct timeb tp ; X FILE *fn ; X X ftime(&tp) ; X for (x = 1; x < tp.millitm % 10; x++) y = (int) random() ; /* Randomize start. */ X X if (!demomode) FPRINTF(stdout," Random") ; X if (!demomode) FPRINTF(stdout," Memory") ; X X if ((fd = open(a_name,0)) == -1) X { X FPRINTF(stderr,"sidtool: unable to open %s.\n",a_name) ; X exit(-1) ; X } X X for (i = UR; i <= LU; i++) corner[i] = load_picture(fd) ; X X bigdot = load_picture(fd) ; X smalldot = load_picture(fd) ; X X for (i = RIGHT; i <= DOWN; i++) X for (j = 0; j <= 3; j++) circles[i][j] = load_picture(fd) ; X for (i = POKEY; i <= SHADOW; i++) X for (j = 0; j <= 1; j++) bugpics[i][j] = load_picture(fd) ; X X for (i = 0; i <= 1; i++) bluebug[i] = load_picture(fd) ; X for (i = 0; i <= 1; i++) bluepics[i] = load_picture(fd) ; X for (i = 0; i <= 3; i++) eyes[i] = load_picture(fd) ; X for (i = 0; i <= 8; i++) circleexplode[i] = load_picture(fd) ; X for (i = 1; i <= 8; i++) fruitpics[i] = load_picture(fd) ; X X CLOSE(fd) ; X X if (!demomode) FPRINTF(stdout," File") ; X X if ((fn = fopen(m_name,"r")) == NULL) X { X FPRINTF(stderr,"\nsidtool: can't open %s\n",m_name) ; X exit(-1) ; X } X X for (y = 0; y <= YSIZE+1; y++) X { X FGETS(buffer,MAXLINE,fn) ; X for (x = 0; x <= XSIZE+1; x++) maze[x][y] = buffer[x] ; X } X FCLOSE(fn) ; X X if (!demomode) FPRINTF(stdout," Maze") ; X X TRANSPT(FRUITMX,FRUITMY,fruitx,fruity) ; X readallhighscores() ; X highscore = allhighscores[skilllevel].score ; X if (!demomode) FPRINTF(stdout," HighScore") ; X X g = POKEY ; X for (y = 1; y <= YSIZE; y++) X for (x = 1; x <= XSIZE; x++) X if ((maze[x][y] >= '0') && (maze[x][y] <= '9')) X { X startpos[g].x = x ; X startpos[g].y = y ; X startpos[g].time = maze[x][y] - '0' ; X if (g < SHADOW) g++ ; X if (maze[x][y] == '0') X { X boxx = x ; X boxy = y ; X } X } X X if (!demomode) FPRINTF(stdout," Starting\n") ; X for (x = 0; x < XSIZE+3; x++) X for (y = 0; y < YSIZE; y++) tunnel[x][y] = 0 ; X} X X Xmake_button(x,y,but_name) Xint x,y ; Xchar but_name[MAXLINE] ; X X{ X int len ; X X len = strlen(but_name) * 10 ; X BLT_MEM_TO_SCRN(x,y,SQUARE,SQUARE,RRPL,corner[UR],0,0) ; X BLT_MEM_TO_SCRN(x,y+SQUARE,SQUARE,SQUARE,RRPL,corner[LU],0,0) ; X X BLT_SCRN(x+SQUARE,y+SQUARE/2,len,2,RSET) ; X BLT_SCRN(x+SQUARE,y+SQUARE*3/2,len,2,RSET) ; X X BLT_MEM_TO_SCRN(x+len,y,SQUARE,SQUARE,RRPL,corner[RD],0,0) ; X BLT_MEM_TO_SCRN(x+len,y+SQUARE,SQUARE,SQUARE,RRPL,corner[DL],0,0) ; X write_bold(x+SQUARE-5,y+SQUARE*3/2-10,but_name) ; X} X X Xmake_control_panel() X X{ X int i ; X X BLT_SCRN(0,0,width,YBASE-20,RCLR) ; /* Clear panel area. */ X for (i = BUT_AUTO; i <= BUT_START; i++) X make_button(100*i+BUTXOFF,BUTYOFF,but_names[i]) ; /* Make option buttons. */ X} X X Xremovecircle() X X{ X BLT_MEM_TO_SCRN(30+(numcir[player]-1)*60,20,50,50,RXOR,circles[RIGHT][0],0,0) ; X} X X Xresetmaze() X X{ X int i,j ; X X erasebugs() ; X LONGPAUSE() ; X for (i = 1; i <= 20; i++) X { X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ; X for (j = 0; j < 10; j++) LONGPAUSE() ; X } X LONGPAUSE() ; X if (fruitmaze[player] < 8) fruitmaze[player]++ ; X fruitchances[player] = 0 ; X setdots(player) ; X drawmaze() ; X if (curbluetime[player] > 1) curbluetime[player] -= 60 ; X} X X Xupdatefruit() X X{ X Pixrect *p ; X X p = fruitpics[fruitmaze[player]] ; X BLT_MEM_TO_SCRN(fruitx-GOFFSET,fruity-GOFFSET,45,45,RXOR,p,0,0) ; X if (fruiton) /* Turning fruit off. */ X { X fruitchances[player]++ ; X if (fruitchances[player] > 2) fruittime = -1 ; /* Already had 2 chances. */ X else fruittime = randomrange(1000,2500) ; X } X else fruittime = randomrange(500,1000) ; /* Turning fruit on. */ X fruiton = !fruiton ; X} X X Xupdatescore(amt) Xint amt ; X X{ X int i,temp,x,y ; X X if (autoplay) X if (!demomode) X { X autoscore += amt ; X SPRINTF(buffer,"%1d0",autoscore) ; X WRITELN(489,65,buffer) ; X return ; X } X temp = score[player] + amt ; X if (temp >= 1000) X if (score[player] < 1000) X { X for (i = 1; i < 7; i++) X { X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ; X for (i = 0; i < 10; i++) LONGPAUSE() ; X } X numcir[player]++ ; X BLT_MEM_TO_SCRN(30+(numcir[player]-1)*60,20,50,50,RXOR,circles[RIGHT][0],0,0) ; X } X score[player] = temp ; X x = (player % 2) ? 217 : 597 ; X y = (player < 3) ? 40 : 80 ; X SPRINTF(buffer,"%1d0",score[player]) ; X WRITELN(x,y,buffer) ; X if (score[player] > highscore) X { X highplayer = player ; X highscore = score[player] ; X SPRINTF(buffer,"%1d0",highscore) ; X WRITELN(348,35,buffer) ; X } X} END_OF_sid_blt.c if test 21194 -ne `wc -c sid_stuff.c <<'END_OF_sid_stuff.c' X X/* sid_stuff.c X * X * Various functions and procedures used by Sid Tool. X * X * Written by Rich Burridge - SUN Microsystems Australia (Melbourne). X * X * Version 2.1. - April 1987. X * X * No responsibility is taken for any errors inherent either to the code X * or the comments of this program, but if reported to me then an attempt X * will be made to fix them. X */ X X#include X#include X#include X#include "bltstuff.h" X#include "sidtool.h" X#include X#include X Xextern Pixfont *pf ; Xextern Pixrect *circles[4][4] ; Xextern Pixwin *pw ; X Xextern jmp_buf exception ; Xextern int val ; X Xextern long random() ; Xextern char *getenv() ; X X/* For descriptions of these external variables, see sid_main.c */ X Xextern BOOLEAN autoplay,changed,demomode,gamestate,remove ; X Xextern char a_name[MAXLINE],buffer[MAXLINE],h_name[MAXLINE] ; Xextern char m_name[MAXLINE], new_key_vals[9][MAXLINE] ; Xextern char old_key_vals[9][MAXLINE],s_name[MAXLINE],titlestring[MAXLINE] ; X Xextern int blueblink,blueincblink,button,c,cirx,ciry,credits ; Xextern int curbluetime[MAXNUMPLAYERS+1],curdir,dotx,doty ; Xextern int fruitmaze[MAXNUMPLAYERS+1],fruiton,fruitsgotten[MAXNUMPLAYERS+1][9] ; Xextern int fruitx,fruity,bugssincedot,height,highscore,inc,key_stations[9] ; Xextern int lastnumplayers,numcir[MAXNUMPLAYERS+1],numplayers ; Xextern int orgx,orgy,player,posx,posy,progstate,redraw,sfunc,skilllevel,speed ; Xextern int started,walls[XSIZE+6][YSIZE+1],width ; X Xextern struct bugrec bugs[4] ; Xextern struct scorerec allhighscores[11] ; Xextern struct startrec startpos[4] ; X X Xchangebugs() X X{ X register struct bugrec *p ; X X bugssincedot = 0 ; X for (p = &bugs[POKEY]; p <= &bugs[SHADOW]; p++) X if (!p->eyesonly) X { X drawbug(p) ; X p->bluetime = curbluetime[player] ; X if ((!p->boxtime) && (!p->inbox)) X p->dir = REVERSEDIR(p->dir) ; X drawbug(p) ; /* Will be blue now. */ X } X} X X Xchangeplayers(startgame) Xint startgame ; X X{ X int cnt,i ; X X if (numplayers == 1) X { X if (fruiton) updatefruit() ; X gamestate = TRUE ; X progstate = RESETGAME ; X longjmp(exception,val) ; X } X cnt = 0 ; X do X { X cnt++ ; X player = 1 + (player % numplayers) ; X if (cnt > 5) /* Game all over. */ X { X progstate = DOLEAVE ; X longjmp(exception,val) ; X } X } X while (!numcir[player]) ; X clear_screen() ; X SPRINTF(buffer,"Player %1d",player) ; X write_bold(348,500,buffer) ; X for (i = 0; i < 100; i++) LONGPAUSE() ; X drawmaze() ; X blinkpause() ; X if (!startgame) X { X gamestate = TRUE ; X progstate = RESETGAME ; X longjmp(exception,val) ; X } X} X X Xcheckcollision(nx,ny,g) Xregister int nx,ny ; Xint *g ; X X{ X register struct bugrec *tg ; X X for (tg = &bugs[POKEY]; tg <= &bugs[SHADOW]; tg++) X if (tg->mx == nx) X if (tg->my == ny) X if (!tg->eyesonly) X { X *g = GIND(tg) ; X return(1) ; X } X return(0) ; X} X X Xcheckinc(dir,mx,my) Xint dir,mx,my ; X X{ X switch (dir) X { X case UP : return(!walls[mx+2][my-1]) ; X case RIGHT : return(!walls[mx+3][my]) ; X case DOWN : return(!walls[mx+2][my+1]) ; X case LEFT : return(!walls[mx+1][my]) ; X } X return(0) ; X} X X Xdestroyblue(g) Xregister struct bugrec *g ; X X{ X int i,inc,x ; X X drawbug(g) ; /* Turn off. */ X g->eyesonly = 1 ; X g->bluetime = 0 ; X inc = 20 ; X for (i = 1; i <= bugssincedot; i++) inc *= 2 ; X bugssincedot++ ; X x = g->scrx + 10 ; X if (x > 740) x = 740 ; X else if (x < 5) x = 5 ; X SCHRFUNC(RXOR) ; X SPRINTF(buffer,"%1d0",inc) ; X WRITELN(x,g->scry+10,buffer) ; X for (i = 0; i < 10; i++) LONGPAUSE() ; X SPRINTF(buffer,"%1d0",inc) ; X WRITELN(x,g->scry+10,buffer) ; X SCHRFUNC(RRPL) ; X drawbug(g) ; /* Turn on as eyesonly. */ X updatescore(inc) ; X} X X Xdestroyfruit() X X{ X int i,inc ; X X fruitsgotten[player][fruitmaze[player]]++ ; X updatefruit() ; /* Turn fruit off. */ X inc = fruitscore(fruitmaze[player]) ; X updatescore(inc) ; X SCHRFUNC(RXOR) ; X SPRINTF(buffer,"%1d0",inc) ; X WRITELN(fruitx+10,fruity+10,buffer) ; X for (i = 0; i < 10; i++) LONGPAUSE() ; X SPRINTF(buffer,"%1d0",inc) ; X WRITELN(fruitx+10,fruity+10,buffer) ; X SCHRFUNC(RRPL) ; X} X X Xdisplay_settings() /* Display current skill level and number of players. */ X X{ X int x,y ; X char buffer[MAXLINE] ; X X x = 50 ; X y = 70 ; X write_bold(x,y,"Current skill level:") ; X SPRINTF(buffer,"%1d ",skilllevel) ; X WRITELN(x+190,y,buffer) ; X X x = 430 ; X write_bold(x,y,"Number of players:") ; X SPRINTF(buffer,"%1d ",numplayers) ; X WRITELN(x+180,y,buffer) ; X} X X Xdohighscores() /* Display high scores on the screen. */ X X{ X char skillc ; X int level ; X X clear_screen() ; X write_bold(334,200,"High Scores") ; X SCHRFUNC(ROR) ; X WRITELN(334,201,"___________") ; X WRITELN(200,300,"Skill level Score Who") ; X WRITELN(200,301,"___________ _____ ___"); X SCHRFUNC(RRPL) ; X for (level = 1; level <= 10; level++) X { X skillc = (level == skilllevel) ? '*' : ' ' ; X if (allhighscores[level].score) X SPRINTF(buffer,"%c %2d = %5d0 %s", X skillc,level,allhighscores[level].score,allhighscores[level].who) ; X else X SPRINTF(buffer,"%c %2d = - %s", X skillc,level,allhighscores[level].who) ; X WRITELN(200,330+level*30,buffer) ; X } X if (!autoplay) make_control_panel() ; X if (!autoplay) display_settings() ; X} X X Xmake_selection() /* Get user selection after DEL press. */ X X{ X switch (button) X { X case BUT_AUTO : numplayers = 1 ; X autoplay = TRUE ; X started = TRUE ; X iocursormode(OFFCURSOR) ; X break ; X case BUT_HELP : clear_screen() ; X dohelp() ; X break ; X case BUT_LEVEL : skilllevel = skilllevel % 10 + 1 ; X display_settings() ; X highscore = allhighscores[skilllevel].score ; X break ; X case BUT_PLAYERS : numplayers = numplayers % 4 + 1 ; X display_settings() ; X break ; X case BUT_QUIT : exit(0) ; X case BUT_SCORES : dohighscores() ; X break ; X case BUT_START : autoplay = FALSE ; X started = TRUE ; X iocursormode(OFFCURSOR) ; X lastnumplayers = numplayers ; X } X if (button == BUT_AUTO || button == BUT_START) progstate = INITGAME ; X else progstate = GETBUT ; X} X X Xrestore_screen() /* Called when window needs to be drawn. */ X X{ X int g ; X X if (!redraw++) return ; X clear_screen() ; X if (!started) X { X iocursormode(TRACKCURSOR) ; X make_control_panel() ; X display_settings() ; X dohelp() ; X } X else if (credits) X { X dohelp() ; X BLT_SCRN(3,ciry-37,762,100,RSET) ; X if (credits == 1) X { X drawdot(dotx,doty,BIGDOT) ; X drawcir(circles[LEFT][inc],cirx,ciry) ; X } X else drawcir(circles[RIGHT][inc],cirx,ciry) ; X for (g = POKEY; g <= SHADOW; g++) X if (!bugs[g].eyesonly) drawbug(&bugs[g]) ; X } X else X { X iocursormode(OFFCURSOR) ; X drawmaze() ; X for (g = POKEY; g <= SHADOW; g++) drawbug(&bugs[g]) ; X drawcir(circles[curdir][inc],posx,posy) ; X } X} X X Xerasebugs() /* Erase all bugs from the screen. */ X X{ X int g ; X X for (g = POKEY; g <= SHADOW; g++) X drawbug(&bugs[g]) ; /* Erase all bugs. */ X} X X Xfruitscore(fruit) /* Returns the score for the fruit specified. */ Xint fruit ; X X{ X switch (fruit) X { X case 1 : return(10) ; X case 2 : return(30) ; X case 3 : return(50) ; X case 4 : return(70) ; X case 5 : return(100) ; X case 6 : return(200) ; X case 7 : return(300) ; X case 8 : return(500) ; X } X return(0) ; X} X X Xgeths(fd,record) /* Get one high score record in. */ Xstruct scorerec *record ; Xint fd ; X X{ X char buffer[32],valuestr[7] ; X int i ; X X i = read(fd,buffer,23) ; X for (i = 0; i < 16; i++) record->who[i] = buffer[i] ^ ENKEY ; X record->who[i] = '\0' ; X for (i = 0; i < 7; i++) valuestr[i] = buffer[i+16] ^ ENKEY ; X record->score = atoi(valuestr) ; X} X X Xget_options(argc,argv) Xint argc ; Xchar *argv[] ; X X{ X char *arg,*env ; X char *p ; /* Pointer to string following argument flag. */ X X orgx = 0 ; /* X origin of SUN SID window. */ X orgy = 0 ; /* Y origin of SUN SID window. */ X width = SWIDTH ; /* Width of SUN SID window. */ X height = SHEIGHT ; /* Height of SUN SID window. */ X speed = SPEED ; /* Default speed of Sun machine that this game is on.*/ X STRCPY(titlestring,"sidtool - Sun Interactive Debugger V2.1. Rich Burridge") ; X STRCPY(m_name,M_NAME) ; /* Default sidtool maze filename. */ X STRCPY(a_name,A_NAME) ; /* Default sidtool animate filename. */ X STRCPY(s_name,S_NAME) ; /* Default sidtool highscore filename. */ X STRCPY(h_name,H_NAME) ; /* Default sidtool help filename. */ X demomode = FALSE ; X X if ((env = getenv("SID_MAZE")) != NULL) STRCPY(m_name,env) ; X if ((env = getenv("SID_ANIMATE")) != NULL) STRCPY(a_name,env) ; X if ((env = getenv("SID_SCORE")) != NULL) STRCPY(s_name,env) ; X if ((env = getenv("SID_HELP")) != NULL) STRCPY(h_name,env) ; X X while (argc > 1 && (arg = argv[1])[0] == '-') X { X p = arg + 2 ; X switch (arg[1]) X { X case 'a' : STRCPY(a_name,p) ; /* New animate filename. */ X break ; X case 'c' : speed = atoi(p) ; /* New class (speed) of machine. */ X break ; X case 'd' : demomode = TRUE ; /* Run in self demonstration mode. */ X break ; X case 'h' : STRCPY(h_name,p) ; /* New help filename. */ X break ; X case 'm' : STRCPY(m_name,p) ; /* New maze filename. */ X break ; X case 's' : STRCPY(s_name,p) ; /* New high score filename. */ X } X argc-- ; X argv++ ; X } X} X X Xget_string(fd,s) /* Get next line from specified file. */ XFILE *fd ; Xchar s[MAXLINE] ; X X{ X int c,i ; X X i = 0 ; X while (i < MAXLINE-1 && (c = getc(fd)) != EOF && c != '\n') X if (c != '\0') s[i++] = c ; X X if (c == EOF) return(-1) ; X s[i] = '\0' ; X return(i) ; X} X X Xhandlecollision(g) Xregister struct bugrec *g ; X X{ X int i ; X struct bugrec *tg ; X X if (g->bluetime > 0) destroyblue(g) ; X else X { X drawbug(g) ; /* Erase one that ate screen. */ X explodecircle(posx,posy) ; X for (tg = &bugs[POKEY]; tg <= &bugs[SHADOW]; tg++) X if (tg != g) drawbug(tg) ; X if (autoplay) X { X progstate = DOLEAVE ; X longjmp(exception,val) ; X } X else if (!numcir[player]) X { X SCHRFUNC(RXOR) ; X WRITELN(339,YBASE+SQUARE*16,"GAME OVER!") ; X for (i = 0; i < 80; i++) LONGPAUSE() ; X WRITELN(339,YBASE+SQUARE*16,"GAME OVER!") ; X SCHRFUNC(RRPL) ; X if (numplayers == 1) X { X progstate = DOLEAVE ; X longjmp(exception,val) ; X } X } X else for (i = 0; i < 50; i++) LONGPAUSE() ; X changeplayers(0) ; X } X} X X Xnewbugs(drawthem) Xint drawthem ; X X{ X register struct bugrec *p ; X X for (p = &bugs[POKEY]; p <= &bugs[SHADOW]; p++) X { X p->dir = UP ; X p->mx = startpos[GIND(p)].x ; X p->my = startpos[GIND(p)].y ; X TRANSPT(p->mx,p->my,p->scrx,p->scry) ; X p->bluetime = 0 ; X p->eyesonly = 0 ; X p->boxtime = ((-2*skilllevel+25) / 5) * startpos[GIND(p)].time ; X if (!p->boxtime) p->inbox = 0 ; X else p->inbox = 1 ; X p->enteringbox = 0 ; X p->count = 0 ; X p->delay = 5 ; X p->pic = GIND(p) % 2 ; X p->intunnel = 0 ; X if (drawthem) drawbug(p) ; X } X} X X Xplay() /* Initialise for next player to play. */ X X{ X fruiton = 0 ; X blueblink = 200 ; X blueincblink = 25 ; X if (numplayers == 1) X { X player = 1 ; X drawmaze() ; X blinkpause() ; X } X else X { X player = numplayers ; X changeplayers(1) ; X } X remove = TRUE ; X} X X Xpuths(fd,record) /* Put one high score record out. */ Xstruct scorerec record ; Xint fd ; X X{ X char buffer[32],valuestr[7] ; X int i,value ; X X for (i = 0; i < 16; i++) buffer[i] = record.who[i] ^ ENKEY ; X value = record.score ; X SPRINTF(valuestr,"%d",value) ; X for (i = 0; i < 7; i++) buffer[i+16] = valuestr[i] ^ ENKEY ; X WRITE(fd,buffer,23) ; X} X X Xrandomrange(low,high) /* Return a random number between low and high. */ Xint low,high ; X X{ X return((((int) random() & 077777) % (high-low+1)) + low) ; X} X X Xfunction_keys(state) /* Set or reset the function keys. */ Xint state ; X X{ X int count = 176 ; /* 0xB0 -- the starting entry for strings. */ X int fd,i ; X X if ((fd = open("/dev/kbd",0,0)) < 0) X { X FPRINTF(stderr,"sidtool: can't open /dev/kbd\n") ; X exit(1) ; X } X for (i = 0; i < 9; i++) /* Set up function keys R7-R15, saving old values. */ X { X if (state == KEY_SET) get_key(fd,key_stations[i],old_key_vals[i],count) ; X set_key(fd,key_stations[i],new_key_vals[i],count++) ; X } X CLOSE(fd) ; X} END_OF_sid_stuff.c if test 13593 -ne `wc -c