ftp.nice.ch/pub/next/developer/objc/screen/ScreenMunger.2.0.N.bs.tar.gz#/ScreenMunger/diet.c

This is diet.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 <stdlib.h>
#import <string.h>
#import <sys/signal.h>

/* diet.c -- squish the screen vertically, and reverse it too
 *
 * 5/92, CWS -- Added support for signal trapping.  Cleaned up the code.
 * This now runs forever until the user kills it.
 */


// width of 56 is 14 bytes
#define PC_WIDTH 56
#define PC_HEIGHT 52
#define X_TILES 20
#define Y_TILES 16

extern open();
extern ioctl();
extern close();
extern sleep();

// 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*bytes_per_row + 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;
{
    bcopy(old_screen, vid_base, num_bytes * sizeof(unsigned char));
    free(old_screen);
    fprintf(stdout, "\nCaught signal %d...\n", sig);
    exit(0);
}

// handle SIGTSTP; restores screen memory, then calls SIGSTOP
void pause(sig)
   int sig;
{
    bcopy(old_screen, vid_base, num_bytes * sizeof(unsigned char));
    raise(SIGSTOP);
}


#define DELAY 1000

main() {
  int fd, i, j, k, e;
  unsigned char *piece_to_move, *d;
  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(1);
  }

  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(3);
  }

// open the /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(4);
  }
  
  if (ioctl(fd, DKIOCGADDR, &vid_base) < 0) {
    fprintf(stdout, "ioctl errno: %d\n", errno);
    exit(5);
  }

  old_screen=(unsigned char *) malloc(num_bytes * sizeof(unsigned char));
  bcopy(vid_base, old_screen, num_bytes);
  
  d=(unsigned char *)malloc(bytes_per_row * sizeof(unsigned char));
  for(k=0; k<bytes_per_row; k++) d[k]=255;

// do the drawing here

  for(;;) {
    
    for (i=0; i<(VIDEO_H/2); i++) {
      bcopy(d,
	    &vid_base[coordtoindex(0,i)],
	    bytes_per_row);
      bcopy(d,
	    &vid_base[coordtoindex(0,(VIDEO_H-i))],
	    bytes_per_row);
      for(j=0;j<DELAY;j++);	
    }
    
    for(i=0; i<(VIDEO_H/2); i++){
      bcopy(&old_screen[coordtoindex(0,(VIDEO_H/2)-i)],
	    &vid_base[coordtoindex(0,(VIDEO_H/2)-i)],
	    bytes_per_row);
      bcopy(&old_screen[coordtoindex(0,((VIDEO_H/2)+i))],
	    &vid_base[coordtoindex(0, ((VIDEO_H/2)+i))],
	    bytes_per_row);
      for(j=0;j<DELAY;j++);	
    }
    
    for(i=0;i<(VIDEO_H/2);i++){
      bcopy(d,
	    &vid_base[coordtoindex(0,i)],
	    bytes_per_row);
      bcopy(d,
	    &vid_base[coordtoindex(0,(VIDEO_H-i))],
	    bytes_per_row);
      for(j=0;j<DELAY;j++);	
    }

 for(i=0;i<(VIDEO_H/2);i++){
      bcopy(&old_screen[coordtoindex(0,(VIDEO_H/2)-i)],
	    &vid_base[coordtoindex(0, ((VIDEO_H/2)+i))],
	    bytes_per_row);
      bcopy(&old_screen[coordtoindex(0,((VIDEO_H/2)+i))],
	    &vid_base[coordtoindex(0,(VIDEO_H/2)-i)],
	    bytes_per_row);
      for(j=0;j<DELAY;j++);	
    }
  }


// do this if/when done with the loop above; useful for a limited number of
// repeats of the drawing algorhithim

  sleep(1);
  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.