This is snake3.c in view mode; [Download] [Up]
#import <stdio.h> #import <nextdev/video.h> #import <sys/file.h> #import <sys/ioctl.h> #import <objc/objc.h> #import <sys/signal.h> #define PC_WIDTH 160 #define PC_HEIGHT 166 #define X_TILES (VIDEO_W / PC_WIDTH) #define Y_TILES (VIDEO_H / PC_HEIGHT) // some pseudo-constants, will change from display to display unsigned char *old_screen = NULL, *vid_base = NULL; long num_bytes = (VIDEO_MW * VIDEO_H / NPPB), bytes_per_row = (VIDEO_MW/NPPB); // various small utility routines for moving memory around long coordtoindex(x,y) long x, y; { return (((y*VIDEO_MW)/NPPB)+x); } void get_piece(x, y, piece, source) long x,y; unsigned char *piece, *source; { long i,j; for(j=0;j<PC_HEIGHT;j++){ for(i=0;i<(PC_WIDTH/4);i++){ piece[coordtoindex(i,j)]= source[coordtoindex(((x*(PC_WIDTH/4))+i),((y*PC_HEIGHT)+j))]; } } } void place_piece(x,y,piece,dest) long x,y; unsigned char *piece, *dest; { long i,j; for(j=0;j<PC_HEIGHT;j++){ for(i=0;i<(PC_WIDTH/4);i++){ dest[coordtoindex(((x*(PC_WIDTH/4))+i),((y*PC_HEIGHT)+j))]= piece[coordtoindex(i,j)]; } } } void erase_piece(x,y,dest) long x,y; unsigned char *dest; { long i,j; for(j=0;j<PC_HEIGHT;j++){ for(i=0;i<(PC_WIDTH/4);i++){ dest[coordtoindex(((x*(PC_WIDTH/4))+i),((y*PC_HEIGHT)+j))]=255; } } } // general signal handler; simply restores screen memory and exits. void handle(sig) int sig; { fprintf(stdout, "\nCatching signal %d...\n", sig); bcopy(old_screen, vid_base, num_bytes * sizeof(unsigned char)); free(old_screen); exit(0); } // handle SIGTSTP; simply restores screen memory, but does not exit. void pause(sig) int sig; { // fprintf(stdout, "\nCatching signal %d...\n", sig); // SIGSTOP'll give a message, so we don't need this. bcopy(old_screen, vid_base, num_bytes * sizeof(unsigned char)); raise(SIGSTOP); } main() { int fd, i, j, k; unsigned char *piece_to_move; short direction, oldDirection, steps; long curx, cury; long newx, newy; BOOL valid; // do the signal trapping stuff if (signal(SIGINT, &handle)) { fprintf(stdout, "Couldn't establish new error handler for SIGINT.\n"); exit(2); } if (signal(SIGTERM, &handle)) { fprintf(stdout, "Couldn't establish new error handler for SIGTERM.\n"); exit(2); } if (signal(SIGTSTP, &pause)) { fprintf(stdout, "Couldn't establish new errorhandler for SIGTSTP.\n"); exit(2); } // open /dev/vid0, and get the address of screen memory fd = open("/dev/vid0", O_RDWR, NULL); if (fd <= 0) { fprintf(stdout,"open result:%d\n", errno); exit(1); } if (ioctl(fd, DKIOCGADDR, &vid_base) < 0) { fprintf(stdout, "ioctl errno: %d\n", errno); exit(1); } num_bytes=(VIDEO_MW*VIDEO_H)/NPPB; bytes_per_row=(VIDEO_MW/NPPB); old_screen=(unsigned char *) malloc(num_bytes * sizeof(unsigned char)); piece_to_move=(unsigned char *) malloc(PC_HEIGHT*(PC_WIDTH/4)*sizeof(unsigned char)); bcopy(vid_base, old_screen, num_bytes); srand(getpid()*time(0)); curx=0; cury=0; get_piece(curx,cury,piece_to_move, vid_base); for(;;){ erase_piece(curx, cury, vid_base); valid=NO; steps=(4.0*(float) (random()/(float) (pow(2,31)-1))); while(!valid){ direction=(2.0*(float) (random()/(float) (pow(2,31)-1))); if(direction!=oldDirection) valid=YES; } while(steps){ switch(direction){ case 0: // left newx=curx-1; newy=cury; break; case 1: // right newx=curx+1; newy=cury; break; case 2: // up newx=curx; newy=cury-1; break; case 3: // down newx=curx; newy=cury+1; break; } if((newx<X_TILES) && (newx>=0) && (newy<Y_TILES) && (newy>=0)) { get_piece(newx, newy, piece_to_move, vid_base); place_piece(curx, cury, piece_to_move, vid_base); erase_piece(newx, newy, vid_base); curx=newx; cury=newy; } else break; steps--; } oldDirection=direction; } // do this if/when done with the loop above; useful for a limited number of // repeats of the drawing algorhithim sleep(5); bcopy(old_screen, vid_base, num_bytes); free(old_screen); close(fd); exit(0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.