Пример #1
0
void main(void)
{
   static void *s;
   static unsigned int i, j;
   static unsigned char *buffer;
   static unsigned int len, offset;

   intrinsic_di();
   
   zx_border(INK_MAGENTA);
   ioctl(1, IOCTL_OTERM_PAUSE, 0);
   ioctl(1, IOCTL_OTERM_CLS);

   while (1)
   {      
      // Title
      
      printf("\n\n\nTRITONE MUSIC DEMO\nmusic by Frank Triggs\n");
      printf("http://tinyurl.com/mefafxa\n\n");
      
      // Song List
      
      for (i = 0; i != sizeof(song_list) / sizeof(struct songs); ++i)
         printf("   %u. %s\n", i+1, song_list[i].name);

      // Gather Song Selection
      
      printf("\n\nPlaylist by number: ");
      
      fflush(stdin);
      getline(&buffer, &len, stdin);

      for (offset = 0; sscanf(buffer + offset, "%u%n", &i, &j) == 1; offset += j)
      {
         if ((i > 0) && (i < (sizeof(song_list) / sizeof(struct songs) + 1)))
         {            
            // Decompress into Workspace
            
            printf("\n   Decompressing \"%s\"\n", song_list[--i].name);
            dzx7_standard(song_list[i].start, WORKSPACE);
            
            // Play Song Until Keypress
            
            in_wait_nokey();
            
            printf("   Now playing \"%s\"\n", song_list[i].name);
            for (s = WORKSPACE; s && (in_test_key() == 0); s = bit_play_tritone(s))
            {
               // could do things here while song plays
            }
            
            in_wait_nokey();
         }
         else
         {
            printf("\n\t%u: INVALID", i);
         }
      }
   }
}
Пример #2
0
main()
{
   uchar i;
   struct sp1_ss *s;
   struct sprentry *se;
   void *temp;
   
   #asm
   di
   #endasm

   // Initialize MALLOC.LIB
   
   heap = 0L;                  // heap is empty
   sbrk(40000, 10000);         // make available memory from 40000-49999
   
   // Initialize SP1.LIB
   
   zx_border(BLACK);
   sp1_Initialize(SP1_IFLAG_MAKE_ROTTBL | SP1_IFLAG_OVERWRITE_TILES | SP1_IFLAG_OVERWRITE_DFILE, INK_BLACK | PAPER_WHITE, ' ');
   sp1_TileEntry(' ', hash);   // redefine graphic associated with space character

   sp1_Invalidate(&cr);        // invalidate entire screen so that it is all initially drawn
   sp1_UpdateNow();            // draw screen area managed by sp1 now
   
   // Create Ten Masked Software-Rotated Sprites
   
   for (i=0; i!=10; i++) {

      s = sprtbl[i].s = sp1_CreateSpr(SP1_DRAW_XOR2LB, SP1_TYPE_2BYTE, 3, 0, i);
      sp1_AddColSpr(s, SP1_DRAW_XOR2, 0, 48, i);
      sp1_AddColSpr(s, SP1_DRAW_XOR2RB, 0, 0, i);
      sp1_MoveSprAbs(s, &cr, gr_window, 10, 14, 0, 4);

   };
   
   while (1) {                                  // main loop
   
      sp1_UpdateNow();                          // draw screen now
      
      for (i=0; i!=10; i++) {                    // move all sprites
 
         se = &sprtbl[i];
         
         sp1_MoveSprRel(se->s, &cr, 0, 0, 0, se->dy, se->dx);
         
         if (se->s->row > 21)                    // if sprite went off screen, reverse direction
            se->dy = - se->dy;
            
         if (se->s->col > 29)                    // notice if coord moves less than 0, it becomes
            se->dx = - se->dx;                   //   255 which is also caught by these cases

      }
      
   }  // end main loop

}
Пример #3
0
void hit_border() {
#ifdef SOUND
		bit_synth(15, 35, 34, 33, 32);
#endif

#ifdef SPECTRUM
#if (spritesize == 8)
zx_border (INK_CYAN);
#endif
#endif

#if defined(MSX) || defined(SVI) || defined(SC3000) || defined(MTX)
#if (spritesize == 8)
msx_color(WHITE, BLACK, CYAN);
#endif
#endif

#ifdef BORDERS
		/* draw/refresh borders */
		draw(0,0,32*spritesize-1,0);
		draw(0,0,0,21*spritesizeh);
		draw(32*spritesize-1,0,32*spritesize-1,21*spritesizeh);
#endif
}
Пример #4
0
main()
{
    int f, g, a, b, c;

    zx_border(0);
    zx_cls(0);
    printPaper(0);
    printInk(6);
    printAt(4, 22);
    printf("BIFROST*");
    printAt(5, 23);
    printf("ENGINE");
    printAt(6, 24);
    printf("DEMO");
    printInk(4);
    printAt(10, 24);
    printf("with");
    printAt(11, 23);
    printf("z88dk!");

    BIFROSTH_resetTileImages(_ctiles);
    
    for (f = 0; f < 81; ++f) {
        BIFROSTH_tilemap[f] = BIFROSTH_STATIC + f;
    }

    BIFROSTH_start();

    while (1) {
        pressAnyKey();

        printInk(5);
        printAt(20, 1);
        printf("Demonstrating static tiles");

        for (f = 0; f < 81; ++f) {
            BIFROSTH_tilemap[f] = BIFROSTH_STATIC + (rand()%26)+8;
        }
        pressAnyKey();

        printInk(5);
        printAt(20, 1);
        printf("Animated tiles (4 frames) ");

        pressSpeedKey();

        printInk(5);
        printAt(20, 17);
        printf("2");

        BIFROSTH_resetAnim2Frames();
        pressSpeedKey();
        BIFROSTH_resetAnim4Frames();

        printInk(5);
        printAt(20, 1);
        printf("Directly modifying areas      ");

        M_BIFROSTH_SETTILE(4, 4, BIFROSTH_DISABLED);
        M_BIFROSTH_SETTILE(4, 5, BIFROSTH_DISABLED);

        printAt(9, 9);
        printf("BIFR");
        printAt(10, 9);
        printf("OST*");

        for (c = 0; c < 8; ++c) {
            a = rand()%8;
            for (b = 0; b < 2; ++b) {
                for (f = 8+72+0; f < 8+72+16; ++f) {
                    for (g = 9; g < 13; ++g) {
                        *BIFROSTH_findAttrH(f, g) = (b == 0 ? a*8 : a);
                        a = (a == 7 ? 3 : a+1);
                    }
                }
            }
        }
    }
}
Пример #5
0
Файл: ex5b.c Проект: z88dk/z88dk
main()
{
   uchar i;
   struct sp1_ss *s;
   struct sprentry *se;
   void *temp;
   
   #asm
   di
   #endasm

   // Initialize MALLOC.LIB
   
   heap = 0L;                  // heap is empty
   sbrk(40000, 10000);         // add 40000-49999 to malloc

   // Initialize SP1.LIB
   
   zx_border(INK_BLACK);
   sp1_Initialize(SP1_IFLAG_MAKE_ROTTBL | SP1_IFLAG_OVERWRITE_TILES | SP1_IFLAG_OVERWRITE_DFILE, INK_BLACK | PAPER_WHITE, ' ');

   sp1_TileEntry(' ', hash);     // redefine graphic associated with space character
   sp1_TileEntry('H', horline);  // 'H' will be the horizontal line graphic
   sp1_TileEntry('V', verline);  // 'V' will be the vertical line graphic
   sp1_TileEntry('C', intline);  // 'C' will be the intersection graphic

   // Print a Tic-Tac-Toe Pattern
   
   for (i=0; i!=32; ++i)       // draw the two horizontal lines in tic-tac-toe pattern
   {
      sp1_PrintAt( 7, i, INK_RED | PAPER_GREEN, 'H');
      sp1_PrintAt(16, i, INK_RED | PAPER_GREEN, 'H');
   }
   
   for (i=0; i!=24; ++i)       // draw the two vertical lines in tic-tac-toe pattern
   {
      sp1_PrintAt(i, 10, INK_RED | PAPER_GREEN, 'V');
      sp1_PrintAt(i, 21, INK_RED | PAPER_GREEN, 'V');
   }
   
   sp1_PrintAt( 7, 10, INK_RED | PAPER_GREEN, 'C');    // where the lines intersect
   sp1_PrintAt( 7, 21, INK_RED | PAPER_GREEN, 'C');    // print the intersection graphic
   sp1_PrintAt(16, 10, INK_RED | PAPER_GREEN, 'C');
   sp1_PrintAt(16, 21, INK_RED | PAPER_GREEN, 'C');

   // Create Four Rectangles that Cover the Four Tic-Tac-Toe Lines
   
   sr1.row =  7; sr1.col =  0; sr1.width = 32; sr1.height =  1;    // top horizontal line
   sr2.row = 16; sr2.col =  0; sr2.width = 32; sr2.height =  1;    // bottom horizontal line
   sr3.row =  0; sr3.col = 10, sr3.width =  1; sr3.height = 24;    // leftmost vertical line
   sr4.row =  0; sr4.col = 21, sr4.width =  1; sr4.height = 24;    // rightmost vertical line

   sp1_Invalidate(&cr);        // invalidate entire screen so that it is all initially drawn
   sp1_UpdateNow();            // draw screen area managed by sp1 now

   // Create Ten Masked Software-Rotated Sprites
   
   for (i=0; i!=10; i++)
   {
      s = sprtbl[i].s = sp1_CreateSpr(SP1_DRAW_MASK2LB, SP1_TYPE_2BYTE, 3, 0, i);
      sp1_AddColSpr(s, SP1_DRAW_MASK2, 0, 48, i);
      sp1_AddColSpr(s, SP1_DRAW_MASK2RB, 0, 0, i);
      sp1_MoveSprAbs(s, &cr, gr_window, 10, 14, 0, 4);

   };
   
   while (1) {                                   // main loop
   
      sp1_Validate(&sr1);                        // validate areas so that they are not drawn
      sp1_Validate(&sr2);
      sp1_Validate(&sr3);
      sp1_Validate(&sr4);

      sp1_UpdateNow();                           // draw screen now
      
      for (i=0; i!=10; i++) {                    // move all sprites
 
         se = &sprtbl[i];
         
         sp1_MoveSprRel(se->s, &cr, 0, 0, 0, se->dy, se->dx);
         
         if (se->s->row > 21)                    // if sprite went off screen, reverse direction
            se->dy = - se->dy;
            
         if (se->s->col > 29)                    // notice if coord moves less than 0, it becomes
            se->dx = - se->dx;                   //   255 which is also caught by these cases

      }
      
   }  // end main loop

}
Пример #6
0
Файл: main.c Проект: z88dk/z88dk
int
main(void)
{
   unsigned char idle = 0;

   // the crt has disabled interrupts before main is called
   
   // z88dk tracks the border colour so that beeper audio does not change the border colour while playing.
   // (this project contains a 3rd party ntropic player that does not obey z88dk convention so we set the border to same colour)
   zx_border(INK_BLACK);

   // set up the block memory allocator with one queue
   // max size requested by sp1 will be 24 bytes or block size of 25 (+1 for overhead)
   balloc_reset(0);                                              // make queue 0 empty
   balloc_addmem(0, sizeof(block_of_ram)/25, 24, block_of_ram);  // add free memory from bss section
   balloc_addmem(0, 8, 24, (void *)0xd101);                      // another eight from an unused area

   // interrupt mode 2
   setup_int();

   // sp1.lib
   sp1_Initialize(SP1_IFLAG_MAKE_ROTTBL | SP1_IFLAG_OVERWRITE_TILES | SP1_IFLAG_OVERWRITE_DFILE, INK_BLACK | PAPER_BLACK, ' ');
   // sp1_Validate(&cr);  // not necessary since sp1_Initialize will not mark screen for update
   
   ps0.bounds = &cr;
   ps0.flags = SP1_PSSFLAG_INVALIDATE;
   ps0.visit = 0;

   intrinsic_ei();

   // setup our font
   pt = font;
   for (i = 0; i < 96; ++i, pt += 8)
      sp1_TileEntry(32 + i, pt);

   // setup the bg tiles
   pt = tiles;
   for (i = 0; i < TILES_LEN; ++i, pt += 8)
      sp1_TileEntry(TILES_BASE + i, pt);

   init_sprites();

   draw_menu();

   srand(tick);  // 256 different games are possible

   while(1)
   {
      key = in_inkey();
      if (key)
      {
         if (key == '4')
         {
            playfx(FX_SELECT);

            in_wait_nokey();
            run_redefine_keys();
            idle = 0;
            draw_menu();
         }
         if (key == '1' || key == '2' || key == '3')
         {
            playfx(FX_SELECT);

            joy_k.left  = in_key_scancode(keys[0]);
            joy_k.right = in_key_scancode(keys[1]);
            // we don't use up/down in this game
            joy_k.down  = in_key_scancode(keys[0]);
            joy_k.up    = in_key_scancode(keys[1]);
            joy_k.fire  = in_key_scancode(keys[2]);

            if (key == '1')
               joyfunc = (JOYFUNC)in_stick_keyboard;
            if (key == '2')
               joyfunc = (JOYFUNC)in_stick_kempston;
            if (key == '3')
               joyfunc = (JOYFUNC)in_stick_sinclair1;

            // run game
            run_intro();

            run_play();
            idle = 0;
            draw_menu();
         }
      }

      if (idle++ == 255)
      {
         // go back to the welcome screen after a while
         // if the player doesn't do anything
         idle = 0;
         draw_menu();
      }

      wait();
      sp1_UpdateNow();
   }
}
Пример #7
0
main()
{
   uchar i;
   struct sp1_ss *s;
   struct sprentry *se;
   void *temp;
   
   #asm
   di
   #endasm

   // Initialize MALLOC.LIB
   
   heap = 0L;                  // heap is empty
   sbrk(40000, 10000);         // add 40000-49999 to malloc

   // Initialize SP1.LIB
   
   zx_border(INK_BLACK);
   sp1_Initialize(SP1_IFLAG_MAKE_ROTTBL | SP1_IFLAG_OVERWRITE_TILES | SP1_IFLAG_OVERWRITE_DFILE, INK_BLACK | PAPER_WHITE, ' ');
   sp1_TileEntry(' ', hash);   // redefine graphic associated with space character

   sp1_Invalidate(&cr);        // invalidate entire screen so that it is all initially drawn
   sp1_UpdateNow();            // draw screen area managed by sp1 now
   
   // Create Ten Masked Software-Rotated Sprites
   
   for (i=0; i!=10; i++) {

      s = sprtbl[i].s = sp1_CreateSpr(SP1_DRAW_MASK2LB, SP1_TYPE_2BYTE, 3, 0, i);
      sp1_AddColSpr(s, SP1_DRAW_MASK2, 0, 48, i);
      sp1_AddColSpr(s, SP1_DRAW_MASK2RB, 0, 0, i);
      sp1_MoveSprAbs(s, &cr, gr_window, 10, 14, 0, 4);
      
      if (i < 5)                           // for the first five sprites
      {      
         attr  = INK_RED;                  // store colour in global variable
         amask = 0xf8;                     // store INK-only mask (set bits indicate what parts of background attr are kept)
      }
      else
      {
         attr  = INK_BLUE | PAPER_GREEN;
         amask = 0xc0;                     // mask will keep background flash and bright  
      }
      
      sp1_IterateSprChar(s, colourSpr);    // colour the sprite

   };
   
   while (1) {                                  // main loop
   
      sp1_UpdateNow();                          // draw screen now
      
      for (i=0; i!=10; i++) {                    // move all sprites
 
         se = &sprtbl[i];
         
         sp1_MoveSprRel(se->s, &cr, 0, 0, 0, se->dy, se->dx);
         
         if (se->s->row > 21)                    // if sprite went off screen, reverse direction
            se->dy = - se->dy;
            
         if (se->s->col > 29)                    // notice if coord moves less than 0, it becomes
            se->dx = - se->dx;                   //   255 which is also caught by these cases

      }
      
   }  // end main loop

}
Пример #8
0
void main()
{
restart:

#ifdef JOYSTICK
	hit_border();
#ifndef LOMEM
#if defined(MSX) || defined(SVI) || defined(SC3000) || defined(EINSTEIN)
	msx_text();
#endif

#ifdef SPECTRUM
#ifdef ZX81
	hrg_off();
	zx_colour(112);
#endif
#endif

	printf("%c",12);
	  printf("\n  CHOOSE YOUR JOYSTICK INTERFACE\n\n");
	for (k=0 ; k!=GAME_DEVICES; k++)
	  printf("    %u - %s\n\n",k+1,joystick_type[k]);

	stick=0;
	while ((stick<1) || (stick>GAME_DEVICES)) {
	  stick=getk()-48;
	  }
#else
	stick=1;
#endif
#endif

#ifdef SPECTRUM
#ifdef ZX81
	hrg_on();
	zx_colour(112);
#endif
#endif


#ifdef CLOCK
    srand(clock());
#endif
	tt=-1;

#ifdef ZX81
#if (spritesize == 2)
	speed=500;
#else
	speed=300;
#endif
#else
#ifdef C128
#else
	speed=300;
#endif
#endif

start_level:
#ifdef ZX81
	speed-=100;
#else
	speed-=200;
#endif

	tt++; t=0; p=1;
	clg();
	hit_border();

#ifdef LAMBDA
	zx_border (INK_CYAN);
	zx_colour(112);
#endif


  for (m=1; m<=4; m+=2)
	for (n=0; n<=30; n+=2) {
		putsprite(spr_or,(n*spritesize),((m+3)*spritesizeh),brick_l);
		putsprite(spr_or,((n+1)*spritesize),((m+3)*spritesizeh),brick_r);
		putsprite(spr_or,(n*spritesize),((m+4)*spritesizeh),brick_r);
		putsprite(spr_or,((n+1)*spritesize),((m+4)*spritesizeh),brick_l);
	#if (spritesize == 8)
	#ifdef SPECTRUM
	#ifdef ZX81
		*zx_cyx2aaddr(m+3,n) = m<<4;
		*zx_cyx2aaddr(m+3,n+1) = m<<4;
		*zx_cyx2aaddr(m+4,n) = (m+1)<<4;
		*zx_cyx2aaddr(m+4,n+1) = (m+1)<<4;
	#else
		*zx_cyx2aaddr(m+3,n) = m<<3;
		*zx_cyx2aaddr(m+3,n+1) = m<<3;
		*zx_cyx2aaddr(m+4,n) = (m+1)<<3;
		*zx_cyx2aaddr(m+4,n+1) = (m+1)<<3;
	#endif
	#endif
	#endif
	
	#ifdef LAMBDA
		*zx_cyx2aaddr(m+3,n) = m<<4;
		*zx_cyx2aaddr(m+3,n+1) = m<<4;
		*zx_cyx2aaddr(m+4,n) = (m+1)<<4;
		*zx_cyx2aaddr(m+4,n+1) = (m+1)<<4;
	#endif
	
	#if defined(MSX) || defined(SVI) || defined(SC3000) || defined(MTX) || defined(EINSTEIN)
	#if (spritesize == 8)
		set_attr(m+3,n,((m+1)<<1)|0x10);
		set_attr(m+3,n+1,((m+1)<<1)|0x10);
		set_attr(m+4,n,(m<<1)|0x10);
		set_attr(m+4,n+1,(m<<1)|0x10);
	#endif
	#endif
	}
  for (n=0; n<=30; n+=2) {
		putsprite(spr_or,(n*spritesize),((m+3)*spritesizeh),brick_l);
		putsprite(spr_or,((n+1)*spritesize),((m+3)*spritesizeh),brick_r);
	#if (spritesize == 8)
	#ifdef SPECTRUM
	#ifdef ZX81
		*zx_cyx2aaddr(m+3,n) = 6<<4;
		*zx_cyx2aaddr(m+3,n+1) = 6<<4;
	#else
		*zx_cyx2aaddr(m+3,n) = 6<<3;
		*zx_cyx2aaddr(m+3,n+1) = 6<<3;
	#endif
	#endif
	#endif
	
	#ifdef LAMBDA
		*zx_cyx2aaddr(m+3,n) = 6<<4;
		*zx_cyx2aaddr(m+3,n+1) = 6<<4;
	#endif
	
	#if defined(MSX) || defined(SVI) || defined(SC3000) || defined(MTX) || defined(EINSTEIN)
	#if (spritesize == 8)
		set_attr(m+3,n,LIGHT_YELLOW|0x10);
		set_attr(m+3,n+1,LIGHT_YELLOW|0x10);
	#endif
	#endif
	}
	
	u=0; v=0; a=14; t=0; w=0;

  for (r=0; r<=6; r++) {
			m=10;  n=8+rand()%15;
			p=0; a=13;

#if (spritesize == 2)
	putsprite(spr_or,(a*spritesize),(21*spritesizeh)-1,paddle);
#else
	putsprite(spr_or,(a*spritesize),(21*spritesizeh),paddle);
#endif

#ifndef LOMEM
	for (i=0; i<=6; i++) {
	  putsprite (spr_and, (24+i)*spritesize, 23*spritesizeh, ball);
	  if (i>r)
		putsprite (spr_or, (24+i)*spritesize, 23*spritesizeh, ball);
	}
#endif

		g=200;

		/* Let's show where the ball stars before the dance begins */
		putsprite(spr_or,(n*spritesize),(m*spritesizeh),ball);

		hit_border();
#ifdef SOUND
		for (i=1; i<14; i++) {
			bit_synth(4, 199+i, 200+i, 239+i, 240+i);
			putsprite(spr_xor,(n*spritesize),(m*spritesizeh),ball);
		}
		bit_synth(9, 255, 254, 253, 252);
#endif

		putsprite(spr_and,(n*spritesize),(m*spritesizeh),ball);

		while (m <= 20) {

			/* delay */
			do_delay();

			move_ball();

			/* total score count is 574 */
			if (t>=573) goto start_level;

			if (u==20)
				putsprite(spr_and,(v*spritesize),(u*spritesizeh),bounce);
			else
				putsprite(spr_and,(v*spritesize),(u*spritesizeh),ball);

			/* Intermediate step to move the ball smoothly */
			putsprite(spr_xor,(((n+v)*spritesize)>>1),(((m+u)*spritesizeh)>>1),ball);
			do_delay();
			putsprite(spr_xor,(((n+v)*spritesize)>>1),(((m+u)*spritesizeh)>>1),ball);

			u=m; v=n;
			if (m==20)
				putsprite(spr_or,(n*spritesize),(m*spritesizeh),bounce);
			else
				putsprite(spr_or,(n*spritesize),(m*spritesizeh),ball);

/*
	#ifdef SOUND
		bit_click();
	#endif
*/

#ifdef JOYSTICK
			if (joystick(stick) & MOVE_LEFT) {
				move_left();
				if (joystick(stick) & MOVE_FIRE)
					move_left();
			}
			if (joystick(stick) & MOVE_RIGHT) {
				move_right();
				if (joystick(stick) & MOVE_FIRE)
					move_right();
			}
#else
			k=getk();
			switch (k) {
				case '2':
					move_left();
					break
				case '1':
					move_left();
					move_left();
					break;
				case '9':
					move_right();
					break;
				case '0':
					move_right();
					move_right();
					break;
			}
#endif
		}
		/* ball is lost */

#if (spritesize == 2)
	  putsprite(spr_and,(a*spritesize),(21*spritesizeh)-1,paddle);
#else
	  putsprite(spr_and,(a*spritesize),(21*spritesizeh),paddle);
#endif
  }


#ifdef ZX81
#if (spritesize == 2)
  #asm
			ld	a,$1e
			ld	i,a
  #endasm
#endif
#endif

#ifndef LOMEM
#ifdef BANNERS
  putsprite(spr_or,40,(12*spritesizeh),scorebanner);
  sprintf (scoretxt,"%05u",tt*1000+t);

  k=0;
  for (i=0; i<5; i++) {
    putsprite (spr_or, 140+i+k, 12*spritesizeh+7, &bigdigit[(scoretxt[i]-48)*38]);
	if (scoretxt[i]=='1')
		k+=5;
	else
		k+=14;
  }

#else
  printf("%c\n\n Score: %u ",12,tt*1000+t);
#endif
#endif

/*  return (tt*1000+t); */
#ifdef SOUND
bit_fx2(5);
#endif
while (getk()) {}
while (!getk()) {}

goto restart;

}
Пример #9
0
void main(void)
{
   unsigned int i;

   // introduction
   
   zx_border(INK_BLACK);
   zx_cls(INK_WHITE | PAPER_BLACK);
   
   fzx_state_init(&fs, &ff_ao_Dutch, &screen);   // sets xor mode by default
   
   fs.fgnd_attr = INK_WHITE | PAPER_BLACK;
   fs.fgnd_mask = 0;
   
   fs.y = (fs.paper.height - fs.font->height) / 2;
   fs.x = (fs.paper.width - fs.left_margin - fzx_string_extent(fs.font, txt_intro)) / 2;
   
   fzx_puts(&fs, txt_intro);
   
   in_wait_nokey();
   in_wait_key();
   in_wait_nokey();
   
   // or mode, fzx text printed ink-only

   fzx_state_init(&fs, &ff_ao_Cayeux, &screen);

   fs.fzx_draw = _fzx_draw_or;
   fs.fgnd_attr = INK_BLACK;
   fs.fgnd_mask = 0x38;        // do not change the paper!

   do
   {
      zx_cls(INK_BLACK | PAPER_BLACK);
      
      zx_cls_wc(&tl, INK_RED | PAPER_RED);
      zx_cls_wc(&tr, INK_GREEN | PAPER_GREEN);
      zx_cls_wc(&bl, INK_BLUE | PAPER_BLUE);
      zx_cls_wc(&br, INK_YELLOW | PAPER_YELLOW);
      
      for (i=0; i!=20; ++i)
      {
         if (in_test_key()) break;
         print_random_location(txt_hello);
         z80_delay_ms(250);        // so that the loop takes ~5s
      }
      
   } while (!in_test_key());
   
   in_wait_nokey();
   
   // xor mode
   
   zx_border(INK_MAGENTA);
   
   fzx_state_init(&fs, &ff_utz_Phraktur, &screen);
   
   fs.fzx_draw = _fzx_draw_xor;
   fs.fgnd_attr = INK_WHITE | PAPER_BLACK;
   fs.fgnd_mask = 0;

   do
   {
      zx_cls(INK_MAGENTA | PAPER_MAGENTA);

      for (i=0; i!=20; ++i)
      {
         if (in_test_key()) break;
         print_random_location(txt_xor);
         z80_delay_ms(250);        // so that the loop takes ~5s
      }
      
   } while (!in_test_key());
   
   in_wait_nokey();

   // reset mode
   
   zx_border(INK_BLACK);
   
   fzx_state_init(&fs, &ff_ao_Sinclair, &screen);
   
   fs.fzx_draw = _fzx_draw_reset;
   fs.fgnd_attr = INK_BLUE | PAPER_CYAN;
   fs.fgnd_mask = 0;

   do
   {
      zx_cls(INK_BLACK | PAPER_GREEN);
      
      for (i = 0x4000; i != 0x5800; ++i)
         *(char *)(i) = hash[zx_saddr2py((void *)(i)) & 0x07];

      for (i=0; i!=20; ++i)
      {
         if (in_test_key()) break;
         print_random_location(txt_reset);
         z80_delay_ms(250);        // so that the loop takes ~5s
      }
      
   } while (!in_test_key());
   
   in_wait_nokey();
}